1. 程式人生 > >Android 自定義View基礎(四)--ListView

Android 自定義View基礎(四)--ListView

這篇文章主要是總結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;
}