RecyclerView的基本用法、注意事项以及如何提高开发效率

前言:

RecyclerView是support.v7包中的控件,可以说是ListView和GridView的增强升级版。目前官方更加推荐使用RecyclerView。

与ListView相比,具有包含但不止以下的优点:
1.能实现横向滚动的ListView效果。
2.能实现瀑布流效果,且支持正反向
3.能实现横向滚动的GridView
等等。

关于RecyclerView和ListView的区别。给大家推荐一篇文章 RecyclerView和ListView使用对比分析。它没有一昧的贬低ListView。毕竟在某些地方,ListView还是很有优点的。比如:在ListView中有个setEmptyView()用来处理Adapter中数据为空的情况;但是在RecyclerView中没有这个API,所以在RecyclerView中需要进行一些数据判断来实现数据为空的情况;

上述博文比较客观的分析ListView与RecyclerView的差异,而在实际场景中,我们应该根据自己的需求来选择使用RecyclerView还是ListView,毕竟,适合业务需求的才是最好的。

 
上个简单的效果图:
这里写图片描述

用法:

RecyclerView和其他用于界面数据滑动展示的控件(GridView,ListView,Spinner等)一样,都少不了数据源,适配器,以及监听逻辑处理这三块。
下面就来讲解写RecyclerView的使用方法:
1.引用(导包)
2.布局文件引用
3.构造适配器
4.主程序,包括数据源以及逻辑处理等

 

Step 1:引用(导包)

两种方式:
1.直接在build.gradle(Module:app)的dependencies添加
implementation 'com.android.support:recyclerview-v7:27.1.1’
如图:
这里写图片描述
添加完成后点击右上角的“Sync Now”即可。
 
2.打开Project Structure,选中app,将选项卡切换到dependencies,然后点击“Library dependency”
如图:
这里写图片描述

在搜索框中搜索“recyclerView”,选择“com.android.support:recyclerview-v7:27.1.1”,然后点击ok即可。
这里写图片描述

Step 2:.布局文件引用
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

  <android.support.v7.widget.RecyclerView
      android:id="@+id/rv"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"/>

</LinearLayout>
Step 3:构造适配器(重点)

直接贴出完整代码。

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> implements View.OnClickListener{
    private static final String TAG = "MyAdapter";

    private onRecyclerViewListener onRecyclerViewListener;
    private List<Person> mList;
    private Context context;

    public MyAdapter(Context context, List<Person> mList) {
        this.context = context;
        this.mList = mList;
    }


    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        MyViewHolder viewHolder;
        View inflate = LayoutInflater.from(context).inflate(R.layout.adapter_item_person_info, parent, false);
        viewHolder = new MyViewHolder(inflate);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        Person person=mList.get(position);
        holder.ivEditHead.setTag(position);
        holder.ivDelete.setTag(position);
        holder.tvPersonInfo.setText(person.getAddress());
        //todo 关于图片加载,建议使用Glide,一个开源的图片加载和缓存处理的第三方框架,这里就不给大家演示了,后续会专门出一篇Glide的使用文章
        holder.ivEditHead.setImageResource(person.getHeadIconId());
        holder.ivEditHead.setOnClickListener(this);
        holder.ivDelete.setOnClickListener(this);
    }

    @Override
    public int getItemCount() {
        return mList.size();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
                case R.id.iv_edit_head:
                   int position= (int) v.getTag();
                    Log.i(TAG, "onClick: position:::"+position);
                    onRecyclerViewListener.editHeadIcon(position);
                    break;
                case R.id.iv_delete:
                    int position1= (int) v.getTag();
                    onRecyclerViewListener.deleteInfo(position1);
                    break;
                default:
                    break;
            }
    }

    class MyViewHolder extends RecyclerView.ViewHolder{

        ImageView ivEditHead;
        TextView tvPersonInfo;
        ImageView ivDelete;
        public MyViewHolder(View itemView) {
            super(itemView);
            ivEditHead = itemView.findViewById(R.id.iv_edit_head);
            tvPersonInfo = itemView.findViewById(R.id.tv_person_info);
            ivDelete = itemView.findViewById(R.id.iv_delete);
        }
    }

    public void setOnRecyclerViewListener(MyAdapter.onRecyclerViewListener onRecyclerViewListener) {
        this.onRecyclerViewListener = onRecyclerViewListener;
    }

    interface onRecyclerViewListener {
        void editHeadIcon(int position);

        void deleteInfo(int position);
    }
}

 
关于适配器的使用,需要注意以下几点:
1.在onCreateViewHolder(…)方法中加载我们自定义的item的布局。
2.RecyclerView不存在像ListView.setOnItemClickListener(…)的监听事件的接口。这一点注意一下,但是我们完全可以在RecyclerView.Adapter中添加监听事件的接口。
3.这里需要强调的一点是,当我们在Adapter中添加监听事件的时候,注意子项的监听事件要放在最外层,即让Adapter去实现OnClickListener接口,而不是让ViewHolder去实现OnClickListener接口
 
如图,正确做法:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> implements View.OnClickListener{
......
........

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        Person person=mList.get(position);
        holder.ivEditHead.setTag(position);
        holder.ivDelete.setTag(position);
        holder.tvPersonInfo.setText(person.getAddress());
        //todo 关于图片加载,建议使用Glide,一个开源的图片加载和缓存处理的第三方框架,这里就不给大家演示了,后续会专门出一篇Glide的使用文章
        holder.ivEditHead.setImageResource(person.getHeadIconId());
        holder.ivEditHead.setOnClickListener(this);
        holder.ivDelete.setOnClickListener(this);
    }
......
......
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
                case R.id.iv_edit_head:
                   int position= (int) v.getTag();
                    Log.i(TAG, "onClick: position:::"+position);
                    onRecyclerViewListener.editHeadIcon(position);
                    break;
                case R.id.iv_delete:
                    int position1= (int) v.getTag();
                    onRecyclerViewListener.deleteInfo(position1);
                    break;
                default:
                    break;
            }
    }
.......
   ......
}

 
下图的做法是不推荐的:
这里写图片描述
大家记着,ViewHolder中只进行控件的绑定就行了。
 

Step 4:4.主程序,包括数据源以及逻辑处理等

主程序代码直接贴出:

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    private RecyclerView mRecyclerView;
    private List<Person> mList = new ArrayList<>();
    private int[] headIconId = new int[]{
            R.mipmap.icon_head, R.mipmap.icon_head1, R.mipmap.icon_head2,
    };
    private String[] address = new String[]{
            "江苏省南京市栖霞区左岸家园",
            "江苏省南京市雨花台区软件大道",
            "北京市昌平区回龙观街道泷泽家园",
            "山西省太原市太谷县山"
    };
    private MyAdapter myAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();
        initRecyclerView();
    }

    private void initData() {
        Random random = new Random();
        for (int i = 0; i < 30; i++) {
            //生成0-3之间的随机数,包括0,不包括3。
            int j = random.nextInt(3);
            int k = random.nextInt(4);
            mList.add(new Person(headIconId[j], address[k]));
        }

        Log.i(TAG, "initData: mList:::" + mList);
    }

    private void initRecyclerView() {
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        mRecyclerView = findViewById(R.id.rv);
        myAdapter = new MyAdapter(MainActivity.this,mList);
        mRecyclerView.setLayoutManager(linearLayoutManager);
        mRecyclerView.setAdapter(myAdapter);
        //如果可以确定每个item的高度是固定的,设置这个选项可以提高性能
        mRecyclerView.setHasFixedSize(true);
        //添加Android自带的分割线
        mRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
        // RecyclerView比ListView相比优点在于可定制强,
        // 也正是由于RecyclerView的可定制性太强,好多功能实现都需要自己来写,
        // RecyclerView不像ListView给开发者提供了setOnItemClickListener()方法,但是要实现监听也不难实现,
        myAdapter.setOnRecyclerViewListener(new MyAdapter.onRecyclerViewListener() {
            @Override
            public void editHeadIcon(int position) {
                showToast("点击了头像编辑");
            }

            @Override
            public void deleteInfo(int position) {
                if (position < mList.size() && position >= 0) {
                    mList.remove(position);
                    myAdapter.notifyDataSetChanged();
                }else {
                    showToast("error!");
                }
            }
        });
    }


    private void showToast(String str) {
        Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();
    }
}

代码比较简单,相信大家都能看的懂。initData()方法中是进行模拟数据源的构造。真正开发的时候,我们的数据来源往往是来源于网络。initRecyclerView()则是对RecyclerView的初始化和使用。

好了,上述内容只是对RecyclerView的最最简单,最最基本的使用方法演示。日后将会记录下关于RecyclerView的高级点的用法,敬请关注。
 
另外,考虑到,RecyclerView的基本用法比较常用。大家完全可以把RecyclerView的适配器代码以及RecyclerView的初始化代码设置到Android Studio的live Template模板中去。这样下次再次编写适配器的时候,只需一个“关键词”就能自动补出Adapter代码。我们只要略微改改就行。

具体操作步骤,如下:
点击As的“Setting”------>“Editor”-------->“Live Template”-------->“点击右上角的‘+’号,点击添加‘Live Template’”,然后在"Abbreviation"添加你定义的关键词,在编辑区,添加你想要快速补充的代码即可。代码中如果有带定义的数据类型的话可以用value(value左右两边各有一个$,这里打不出来,你知道就行)来代替。
如下图:

这里写图片描述

在完成之后,注意点击下方的“Define”按钮,去设置代码作用范围。最后点击"Apply"即可使用。
这里写图片描述

下次在需要编写RecyclerView适配器的时候,直接点击自定义的关键词,即可快速补全代码。从而提高开发效率。
这里写图片描述

好了,至此完结。如有问题,请留言。
 

另外,建议大家坚持更新博客,哪怕是记录自己之前使用过的知识点。相信我,最后总会有收货的。现阶段,你们可能向我一样,写不出牛逼的博客。但是没关系,随着我们对知识体系的完善,开发项目的经验的增长,一定会越来越好,加油,学无止!

 
附上代码示例,如果需要的话,直接改改也能用。
https://download.csdn.net/download/zhangqunshuai/10560821

  • 5
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
RecyclerView 是 Android 系统中的一个视图组件,它可以用来展示列表、网格等数据集合。相对于 ListView 和 GridView,RecyclerView 更加灵活,支持自定义布局和动画等功能。使用 RecyclerView,我们需要定义一个 Adapter 来管理数据,以及一个 LayoutManager 来控制布局方式。 以下是 RecyclerView使用步骤: 1. 在布局文件中定义 RecyclerView 组件。 2. 定义 RecyclerView 的 Adapter,继承自 RecyclerView.Adapter,并实现三个方法:onCreateViewHolder、onBindViewHolder 和 getItemCount。 3. 定义 RecyclerView 的 LayoutManager,可以使用系统提供的 LinearLayoutManager、GridLayoutManager 或者自定义实现。 4. 在 Activity 或者 Fragment 中获取 RecyclerView 对象,并设置 Adapter 和 LayoutManager。 5. 可选的,可以设置 RecyclerView 的 ItemDecoration 和 ItemAnimator,用于美化界面和实现动画效果。 下面是一份简单的示例代码: 1. 在布局文件中定义 RecyclerView 组件: ``` <androidx.recyclerview.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 2. 定义 RecyclerView 的 Adapter: ``` public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> { private List<String> mData; public MyAdapter(List<String> data) { mData = data; } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout, parent, false); return new ViewHolder(view); } @Override public void onBindViewHolder(@NonNull ViewHolder holder, int position) { holder.textView.setText(mData.get(position)); } @Override public int getItemCount() { return mData.size(); } static class ViewHolder extends RecyclerView.ViewHolder { TextView textView; ViewHolder(@NonNull View itemView) { super(itemView); textView = itemView.findViewById(R.id.text_view); } } } ``` 3. 定义 RecyclerView 的 LayoutManager: ``` RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this); ``` 4. 在 Activity 或者 Fragment 中获取 RecyclerView 对象,并设置 Adapter 和 LayoutManager: ``` RecyclerView recyclerView = findViewById(R.id.recycler_view); recyclerView.setLayoutManager(layoutManager); recyclerView.setAdapter(new MyAdapter(data)); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值