关于RecyclerView的一些使用见解以及使用过程中踩过的一些坑

  说到RecyclerView,大家肯定再熟悉不过了。所以呢,这里就不啰里啰嗦介绍一大堆关于RecyclerView的知识点了,这篇文章呢,主要介绍我在开发过程中使用到RecyclerView总结的一些经验以及踩过的一些坑。
  首先先说下RecyclerView的一些新特性,从SupportLibrary V23.2开始,Google给RecyclerView的LayoutManager添加了新特性自动测量(auto-measurement),它允许RecyclerView根据内容自动控制高度,这意味着什么呢?回想一下以前的一些应用场景,有这样一个需求,需要一个列表页,列表页某个部位还需要有一个列表页,如果是以前,我们可能会这么做:1.外层先放一个ScrollView,然后在里层放两个ListView,然后重写ListView的onMeasure方法,达到ListView适应ScrollView的效果;2.使用RecyclerView或ListView,然后在它的头布局或其他某个布局中再嵌套RecyclerView或ListView;3.使用ScrollView嵌套LinearLayout,然后在LinearLayout中动态的添加Item以达到复杂的布局效果。这样无疑增加了代码的复杂度以及工作量,而且有时候体验效果还有点不尽人意。但自从有了23.2的这个新特新后,我们可以通过RecyclerView之间或RecyclerView与其他View的互相嵌套实现各种复杂的布局,而且并不用担心滚动适配等问题。

来看下效果:

image

使用起来其实很简单,首先建好父布局,放一个RecyclerView即可:

<?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="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar
        android:id="@id/toolbar"
        style="@style/Test.Toolbar"/>

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

</LinearLayout>

然后是头布局,这里在头布局中再放入一个RecyclerView。

<?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"
    android:orientation="vertical">

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

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="@dimen/size_300"
        android:background="#ffff00"
        android:scaleType="centerCrop"
        android:src="@drawable/img_1"
        />
</LinearLayout>

接着是Item布局

<?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"
    android:gravity="left|center"
    android:orientation="horizontal"
    android:padding="@dimen/size_10">

    <ImageView
        android:layout_width="@dimen/size_40"
        android:layout_height="@dimen/size_40"
        android:src="@drawable/ic_whale"
        />

    <TextView
        android:id="@+id/item_recycler_auto_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingLeft="@dimen/size_20"
        android:textColor="#333333"
        />
</LinearLayout>

最后是Activity代码

public class RecyclerAutoActivity extends ParentActivity {

    protected RecyclerView mRecycler;
    protected ItemAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        super.setContentView(R.layout.activity_recycler_auto);
        initView();
    }

    private void initView() {
        mRecycler = (RecyclerView) findViewById(R.id.recycler_view);
        mRecycler.setLayoutManager(new LinearLayoutManager(getContext()));
        mRecycler.addItemDecoration(new LinearItemDecoration(getContext().getResources().getDimensionPixelOffset(R.dimen.size_1), Color.parseColor("#eeeeee")));
        mRecycler.setAdapter(mAdapter = new ItemAdapter(getContext()));
        List<String> tempList = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            tempList.add("This is content item " + i);
        }
        mAdapter.insertRange(tempList, false);
    }

    class ItemAdapter extends HeaderAdapter<String> {

        public ItemAdapter(Context context) {
            super(context);
        }

        @Override
        public boolean isHasHeader() {
            return true;
        }

        @Override
        public ViewHolderPlus<String> onCreateHeaderHolder(ViewGroup parent, LayoutInflater inflater) {
            return new HeaderHolder(createView(R.layout.header_recycler_auto, parent));
        }

        @Override
        public ViewHolderPlus<String> onCreateItemViewHolder(ViewGroup parent, int viewType, LayoutInflater inflater) {
            return new ItemHolder(createView(R.layout.item_recycler_auto, parent));
        }

        class HeaderHolder extends ViewHolderPlus<String> {

            RecyclerView mRecycler;
            ItemHeaderAdapter mAdapter;

            public HeaderHolder(View itemView) {
                super(itemView);
                mRecycler = (RecyclerView) itemView.findViewById(R.id.header_recycler_auto_recycler);
                mRecycler.setNestedScrollingEnabled(false);
                mRecycler.setLayoutManager(new GridLayoutManager(getContext(), 3));
                mRecycler.addItemDecoration(new GridItemDecoration(3, getContext().getResources().getDimensionPixelOffset(R.dimen.size_10)));
                mRecycler.setAdapter(mAdapter = new ItemHeaderAdapter(getContext()));
            }

            @Override
            public void onBinding(int position, String s) {
                List<String> tempList = new ArrayList<>();
                for (int i = 0; i < 10; i++) {
                    tempList.add("This is header item " + i);
                }
                mAdapter.clear();
                mAdapter.insertRange(tempList, false);
            }

            class ItemHeaderAdapter extends AdapterPlus<String> {

                public ItemHeaderAdapter(Context context) {
                    super(context);
                }

                @Override
                public ViewHolderPlus<String> onCreateViewHolder(ViewGroup parent, int viewType, LayoutInflater inflater) {
                    return new ItemHolder(createView(R.layout.item_recycler_auto, parent));
                }
            }
        }

        class ItemHolder extends ViewHolderPlus<String> {

            protected TextView mText;

            public ItemHolder(View itemView) {
                super(itemView);
                initView(itemView);
            }

            @Override
            public void onBinding(int position, String s) {
                mText.setText(s);
            }

            private void initView(View rootView) {
                mText = (TextView) rootView.findViewById(R.id.item_recycler_auto_text);
            }
        }
    }
}

整个页面大概的布局为RecyclerView添加一个头布局,然后在头布局中再添加一个RecyclerView以及一个ImageView,可以看到展示效果完全没问题。

需要注意的一些坑:
1.RecyclerView中Adapter的Item布局不能设置layout_height=”match_parent”,否则会出现以下情况,每个Item的高度都铺满了屏幕:
image

2.当RecyclerView多层嵌套时,需要在最外层的父布局中加入下面代码,否则可能会出现从其他页面返回该页面时,view自动滚动到其中某个RecyclerView布局顶部的现象:

android:focusable="true"
android:focusableInTouchMode="true"

3.当RecyclerView多层嵌套且外层使用有AppbarLayout时,需要在子RecyclerView的初始化代码中加入下面代码,否则会出现滚动RecyclerView时,只有RecyclerView部分局部滚动的现象:

mRecyclerView.setNestedScrollingEnabled(false);

image 这里写图片描述

RecyclerViewAndroid平台上用于高效地显示大量数据的控件,特别适用于那些需要动态显示列表、网格等类型数据的场景。它比传统的ListView提供了更好的性能和更多的定制性。RecyclerView通过一个可回收的视图池来减少视图的创建,从而优化了内存的使用,并且可以实现垂直或水平滚动列表、网格或瀑布流等布局。 要在Android使用RecyclerView,你需要以下几个步骤: 1. 添加依赖项:在你的`build.gradle`文件添加RecyclerView的依赖库。 ```gradle implementation 'androidx.recyclerview:recyclerview:版本号' ``` 2. 布局文件添加RecyclerView:在你的布局XML文件添加RecyclerView元素。 ```xml <androidx.recyclerview.widget.RecyclerView android:id="@+id/my_recycler_view" android:layout_width="match_parent" android:layout_height="match_parent"/> ``` 3. 创建适配器(Adapter):适配器负责为RecyclerView提供数据集,并将其转换为视图。 ```java public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> { private List<Data> mData; public MyAdapter(List<Data> data) { this.mData = data; } // 创建新视图 @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.my_text_view, parent, false); return new ViewHolder(view); } // 替换内容 @Override public void onBindViewHolder(ViewHolder holder, int position) { Data data = mData.get(position); holder.textView.setText(data.getText()); } // 返回数据集大小 @Override public int getItemCount() { return mData.size(); } // 视图持有者类 public static class ViewHolder extends RecyclerView.ViewHolder { public TextView textView; public ViewHolder(View view) { super(view); textView = view.findViewById(R.id.text_view); } } } ``` 4. 在Activity或Fragment设置RecyclerView: ```java RecyclerView recyclerView = findViewById(R.id.my_recycler_view); recyclerView.setLayoutManager(new LinearLayoutManager(this)); MyAdapter adapter = new MyAdapter(dataList); recyclerView.setAdapter(adapter); ``` RecyclerView非常灵活,你可以通过定义不同的布局管理器(LayoutManager),如`LinearLayoutManager`、`GridLayoutManager`、`StaggeredGridLayoutManager`等,来实现不同类型的列表布局。此外,还可以通过添加不同的ItemDecoration和ItemAnimator来增强布局的个性化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值