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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值