Android 自定義View基礎(四)--ListView
阿新 • • 發佈:2019-02-14
這篇文章主要是總結ListView的使用:
首先來說說ListView,幾乎所有的app都在使用listview,所以熟練使用ListView是作為Android移動開發必不可少的。
Adapter
ViewHolder
setEnpty()
自動隱藏,顯示的ListView
聊天介面的ListView
Adapter
對於ListView而言,Adapter就是“彈夾”,給ListView新增資料和檢視,這裡只講解繼承自BaseAdapter的自定義Adapter。模版程式碼如下:
public class ViewHolderAdapter extends BaseAdapter {
private List<String> list;
private LayoutInflater inflater;
public ViewHolderAdapter(Context context, List<String> list) {
this.list = list;
inflater = LayoutInflater.from(context);
}
//返回item個數
@Override
public int getCount() {
return list == null ? 0 : list.size();
}
//返回position對應的資料
@Override
public Object getItem(int position) {
return list.get(position);
}
//返回position
@Override
public long getItemId(int position) {
return position;
}
//返回item的檢視View
@Override
public View getView (int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.listview_itm, null);
viewHolder = new ViewHolder();
viewHolder.iv = (ImageView)
convertView.findViewById(R.id.list_iv);
viewHolder.tv = (TextView)
convertView.findViewById(R.id.list_tv);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.iv.setText(list.get(position));
viewHolder.tv.setImageResource(R.mipmap.ic_launcher);
return convertView;
}
public final class ViewHolder {
private ImageView iv;
private TextView tv;
}
ViewHolder
如上程式碼中ViewHolder可以提高檢視的重複利用,提高效率。通常都是在adapter中建立內部類。引數就是我們item view中的對應的控制元件。
setEnpty()
在實際開發中,我們都知道,當網路不好的時候,我們的app是無法從服務端獲取資料的,那麼這時就需要載入不同的佈局給使用者。
這裡就需要到setEnpty(),使用程式碼如下
adapter = new ViewHolderAdapter(this, dataList);
lv.setAdapter(adapter);
lv.setEmptyView(findViewById(R.id.empty_view));
新增我們要展示的控制元件,當然這裡可以自定控制元件來實現佈局的載入。
處理沒有資料時應該載入的佈局
自動隱藏,顯示的ListView
這裡在Activity上實現View.OnTouchListener,然後重寫onTouch方法,在方法中我們判斷ActionBar的顯示和隱藏。把如下程式碼中的bin換為,你想隱藏,顯示的控制元件。
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mFirstY = (int) event.getY();
break;
case MotionEvent.ACTION_MOVE:
mCurrentY = (int) event.getY();
if (mCurrentY - mFirstY > mTouchSlop) {
direction = 0;//down
} else if (mFirstY - mCurrentY > mTouchSlop) {
direction = 1;//up
}
Log.e(TAG, "direction==" + direction);
if (direction == 0) {
if (btn.getVisibility() != View.VISIBLE) {
btn.setVisibility(View.VISIBLE);
}
}
if (direction == 1) {
if (btn.getVisibility() != View.GONE) {
btn.setVisibility(View.GONE);
}
}
break;
case MotionEvent.ACTION_UP:
break;
}
return false;//這裡必須返回false,不然listView的基本功能都沒有了
}
然後就是在onCreate中使用listview的setonTouchListener.
//獲取系統認為的最低滑動距離 mTouchSlop==36
mTouchSlop = ViewConfiguration.get(this).getScaledEdgeSlop();
lv.setOnTouchListener(this);
聊天介面的ListView
最後再實現一個類似於聊天介面,簡單實現一下。
首先我們需要兩個itemViewLayout.程式碼如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ImageView
android:id="@+id/icon_in"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher" />
<TextView
android:id="@+id/text_in"
android:layout_marginLeft="20dp"
android:layout_toRightOf="@+id/icon_in"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:background="@android:color/black"
android:textColor="@android:color/white"
android:textSize="20sp" />
</RelativeLayout>
因為兩個除位置不同其它都相同,所以這裡只貼出一個的程式碼。
然後,就是Adapter的實現,與我們以往的同這裡需要多實現兩個方法,
//獲取listView中position的佈局型別
@Override
public int getItemViewType(int position) {
return data.get(position).getType();
}
//獲取listView中的佈局型別個數
@Override
public int getViewTypeCount() {
return 2;
}
在getView中做相應的改變,我們的Adapter中程式碼如下:
public class ChartListAdapter extends BaseAdapter {
private List<ChartBean> data;
private LayoutInflater inflater;
public ChartListAdapter(Context context, List<ChartBean> list) {
this.data = list;
inflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return data == null ? 0 : data.size();
}
@Override
public Object getItem(int position) {
return data.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder=null;
if (convertView == null) {
if (getItemViewType(position)==0){
viewHolder = new ViewHolder();
convertView = inflater.inflate(R.layout.chat_item_itemin, null);
ImageView iv = (ImageView) convertView.findViewById(R.id.icon_in);
TextView tv = (TextView) convertView.findViewById(R.id.text_in);
viewHolder.setIv(iv);
viewHolder.setTv(tv);
}
if (getItemViewType(position)==1){
viewHolder = new ViewHolder();
convertView = inflater.inflate(R.layout.chat_item_itemout, null);
ImageView iv = (ImageView) convertView.findViewById(R.id.icon_out);
TextView tv = (TextView) convertView.findViewById(R.id.text_out);
viewHolder.setIv(iv);
viewHolder.setTv(tv);
}
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.tv.setText(data.get(position).getText());
viewHolder.iv.setImageBitmap(data.get(position).getIcon());
return convertView;
}
//獲取listView中position的佈局型別
@Override
public int getItemViewType(int position) {
return data.get(position).getType();
}
//獲取listView中的佈局型別個數
@Override
public int getViewTypeCount() {
return 2;
}
public final class ViewHolder {
ImageView iv;
TextView tv;
public ImageView getIv() {
return iv;
}
public void setIv(ImageView iv) {
this.iv = iv;
}
public TextView getTv() {
return tv;
}
public void setTv(TextView tv) {
this.tv = tv;
}
}
}
如果你已經看完上面的程式碼,會發現有一個ChartBean,這是什麼呢?實際上這就是一個模擬聊天資訊中的資料的一個基本類,
public class ChartBean {
int type;
private String text;
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Bitmap getIcon() {
return icon;
}
public void setIcon(Bitmap icon) {
this.icon = icon;
}
private Bitmap icon;
}