ListView 和 RecyclerView 的简单使用

ListView 和 RecyclerView 的简单使用


在安卓App中,列表展示的功能十分常见。ListView 和 RecyclerView 都是用于 Android 开发中列表展示时所用的常见控件。

初学Android控件时,应该就属这两个控件的用法最为复杂,所以在此总结一下这两个控件的用法,方便复习和查阅。

ListView 和 RecyclerView 使用的大致相同点

  • 使用前都需要准备适配器 Adapter :其实这两个控件的使用在初学者眼里之所以看起来复杂,最大的原因就是需要根据自己的业务来写一个Adapter类。(当然也可以用系统的 Adapter 而不自己重写,但是就会存在一些需求没办法定制)

  • 使用前都需要准备 item 的 layout :除了准备一个适配器 Adapter 之外,还需要为列表中的每一项准备一个共用的 layout 。这里就不展开说了,因为这些 layout 的写法一般是根据需求来的, layout 中可能会包含 ImageView 、TextView 、CheckBox 等等。

  • 使用时都是先初始化一个前面第一点提到的适配器Adapter,向其传入前面第二点提到的 layout 和所需要展示的数据集合等一些参数,然后将这个适配器通过 ListView.setAdapter(adapter) 方法,使适配器作为参数传入即可(RecyclerView在此之前还有一个步骤,后面会介绍到,只是一行代码的事,所以我认为使用时整体的步骤与 ListView 是基本相同的)。

  • 关于使用步骤,Adapter 的不同实现,会出现传入参数上的差异,可能会导致部分人觉得这里使用时的相同点有点错误,其实我在这里只是想表达在使用时需要用到前面所提到的一些东西,具体的细微差别在使用时还是存在的,不用太纠结这部分。

ListView的基本使用

  1. 首先,咱们先完成工作量最大的Adapter的编写。
public class MyTypeAdapter extends ArrayAdapter<MyType> {
    
    
    private int resourceId;
    public MyTypeAdapter(Context context, int resourceId, List<MyType> list){
    
    
        super(context,textViewResourceId,list);
        this.resourceId = resourceId;
    }

    @Override
    public View getView(final int position,  View convertView, ViewGroup parent) {
    
    
        MyType myType = getItem(position);//这里的数据类型和你要展示的数据是一样的
        View view = LayoutInflater.from(getContext()).inflate(resourceId,parent,false);
        ImageView image = view.findViewById(R.id.image);
        TextView text = view.findViewById(R.id.text);
        image.setImageResource(myType.getImageId());
        text.setText(myType.getText());
        return view;
    }
}
  1. 其次,完成 ListView 中每一项的共用 item_layout 。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <ImageView
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center" />
</LinearLayout>
  1. 最后,做完了准备工作,在需要使用 ListView 的布局文件中添加它。然后和使用其他控件一样,在 Activity 中获取,实例化Adapter,并将需要展示的数据集合传入。最后一步,将 Adapter 设置给 ListView ,大功告成。

  2. 如何开启点击事件
    4.1 对整个 item 的点击事件,只需要对 ListView 增加事件监听即可,在 onItemClick 方法中, position 表示点击的 item 为第几项,一般通过这个下标进行对应的数据处理。

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    
    
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    
    
        //do something...
    }
});

4.2 对 item 中某个控件的点击事件,则需要在 Adapter 中,在 getView 方法中获取绑定到控件之后,向其正常添加点击事件即可。同样的,getView 方法也有一个 position 参数,也是表示点击的 item 下标。

ListView的基本优化

  • 对 ListView 优化应该从哪里入手呢?想想我们对这个控件的使用准备,显然最先想到的应该是咱们编写的 Adapter 了。

  • 通过新建一个内部类 ViewHolder 将子项的各个控件作为成员属性,重写 getView 方法。

  • 对传入该方法的参数 convertView 进行判断,如果为 null 则进行布局和控件的加载,并将 viewHolder 通过 setTag 存储到 view 中,如果不为 null 则直接 view.getTag() 。

  • 这个做法可以使控件和布局不必每次都被重复加载。

 @Override
public View getView(final int position, View convertView, ViewGroup parent) {
    
    
	if (convertView == null){
    
    
		view = LayoutInflater.from(getContext()).inflate(resourceId, parent, false);
		viewHolder = new ViewHolder();
		viewHolder.image = view.findViewById(R.id.image);
		viewHolder.text = view.findViewById(R.id.text);
		view.setTag(viewHolder);//将ViewHolder存储到View中
	} else {
    
    
		view = convertView;
		viewHolder = (ViewHolder) view.getTag();
	}
    return view;
}

static class ViewHolder {
    
    
	TextView text;
	ImageView image;
}

上面讲的就是 ListView 的一些基本内容,还有许多东西需要去探索。接下来讲的关于 RecyclerView 其实也大同小异,只要理解了需要 Adapter 作为桥梁去连接数据和 ListView ,那其实 RecyclerView 的基本使用也和 ListView 没有很大区别。


RecyclerView 的基本使用

  1. 使用前添加依赖
    implementation 'com.android.support:recyclerview-v7:27.1.1'
    Androidx的话是:
    implementation 'androidx.recyclerview:recyclerview:1.1.0'

  2. 和 ListView 没两样,Adapter 先搞一个,让它继承 RecyclerView.Adapter<> 将其中的泛型指定为 adapter.ViewHolder 。

    定义内部类继承 RecyclerView.ViewHolder 。传入的参数通常是 RecyclerView 子项的最外层布局。构造函数接受数据源。由于它继承于 RecyclerView.Adapter ,所以必须重写 onCreateViewHolder() , onBindViewHolder() 和 getItemCount() 三个方法。

    第一个方法用于创建 ViewHolder 实例并把加载的布局传入构造函数并返回 holder ,第二个方法则是子项的控件进行绑定并对每个子项赋值,第三个方法返回 recylerview 的子项数目。

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    
    
    private  List<MyType> mList;
    static class ViewHolder extends RecyclerView.ViewHolder{
    
    
        ImageView mImage;
        TextView mText;
        
        public ViewHolder (View view) {
    
    
            super(view);
            mImage = (ImageView) view.findViewById(R.id.image);
            mText = (TextView) view.findViewById(R.id.text);
        }
    }

    public MyAdapter (List <MyType> list){
    
    
        mList = list;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
    
    
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout,parent,false);
        ViewHolder holder = new ViewHolder(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position){
    
    
        MyType myType = mList.get(position);
        holder.mImage.setImageResource(myType.getImageId());
        holder.mText.setText(myType.getText());
    }

    @Override
    public int getItemCount(){
    
    
        return mList.size();
    }
  1. 其次编写 item_layout ,这个和 ListView 没有任何区别,除非你需要一些其他的列表布局,不过这些都是细微的差别。

  2. 正式使用,和 ListView 的使用相似,获取 RecyclerView 后实例化适配器,传入一些必要的参数,然后 setAdapter ,但在 setAdapter 之前需要使用 LayoutManager 指定布局方式,这就是前面提到的一行代码的事(虽然看到是两行,但是硬要写成一行也不是不行)。LineatLayoutManager 指的是线性布局。

LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
  1. 点击事件:对于整个子项的点击事件,在 viewHolder 中添加保存最外层 view ,在 onCreatViewHolder 中通过 holder.view.setOnClickListener 进行设置子项的点击事件;对于子项中的控件的点击事件,也同样在这里进行设置事件监听即可。

  2. 其他布局

    RecyclerView 还可以实现横向滚动,只需要将子项的布局 item_layout 进行修改,即不要使宽度占满屏幕,其他根据需要调整,然后再使用时候设置 LayoutManager 时写

LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
recyclerView.setLayoutManager(layoutManager);

RecyclerView 还有 GridLayoutManager 和 StaggeredGridLayoutManager 。

GridLayoutManager layoutManager = new GridLayoutManager(this,5);

设置网格布局的代码如上,第二个参数是网格的列数。瀑布流也大同小异,网上查一下资料就行了。

ListView 和 RecyclerView 的对比

  • ListView 的布局就是普通的列表展示,而 RecyclerView 可以横向滚动,还有瀑布流、表格之类的展示,可以适用于不同的业务需求

  • ListView 需要自行优化,自定义 ViewHolder 等一些内容

  • RecyclerView 还有一些其他的优点,但是我还没有研究过,所以就不多说了。如果只是用于展示一些简单的文字数据的话用 ListView 代码量应该会少一点。

总结

  • 其实这两个控件的使用都不是很复杂,只是相对于之前学习的其他控件而言,这两个控件就显得相对有些麻烦。
    其实使用起来只需要和上面写的一样分四步来看,就很容易记住了。
    第一步:在需要的地方添加 ListView \ RecyclerView ,这一步和其他控件没有区别
    第二步:编写 Adapter ,把这一步做完基本就搞定百分之九十的工作了
    第三步:编写 item_layout ,这个根据业务需求写即可
    第四步:在 Activity \ Fragment 或其他使用 ListView 的地方绑定控件,实例化 Adapter 并传入数据,将该 Adapter 设置给 ListView 即可

  • 后面有时间的话再研究研究 RecyclerView ,这东西里面还是有很多要学的。写这一篇东西也参考了其他的博客,简单的使用方法说来说去也都是一回事,难免有点雷同。
    有机会的会加一篇 《ListView 和 RecyclerView 的简单实践》,贴上一些图,看着会有看头一点


猜你喜欢

转载自blog.csdn.net/qq_39121188/article/details/113388014