Android 自定义View基础(四)--ListView

来源:互联网 发布:不以 乎 句式 编辑:程序博客网 时间:2024/06/11 04:17

这篇文章主要是总结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;}
0 0
原创粉丝点击