Android developers using advanced -RecyclerView controls (including pull-down refresh the page load LAC)

Disclaimer: This article is a blogger original article, shall not be reproduced without the bloggers allowed. https://blog.csdn.net/fukaimei/article/details/90446316

Foreword

Android RecyclerView control in June 2014 Google's I / O conference on the launch of the unique characteristics of the 5.0 Android, the function of the control is very powerful, it replaces the original ListView and GridView controls, which in addition to achieve linear layout, external grid layout style may also be implemented cascade style layout. And in RecyclerView realized the function reuse mechanism in the source code, so in terms of rendering interface data and filling the ListView even better than the original, in the sliding process is relatively smooth.

Then the following RecyclerView see how to use it, this article will introduce the use of a linear layout styles RecyclerView, grid layout style, layout style waterfall and nested layout styles.

RecyclerView achieve linear layout styles

First introduced related libraries in the project's build.gradle AS before using RecyclerView control.

implementation 'com.android.support:recyclerview-v7:28.0.0'

As can be seen dependencies, the dependencies are in v7 package, where the layout directory path to write full-time quote xml layout file using this layout: android.support.v7.widget.RecyclerView. Layout is as follows:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/color_page_bg"
    android:orientation="vertical">

    <com.hjq.bar.TitleBar
        android:id="@+id/mTitleBar"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:background="@color/colorPrimaryDark"
        app:bar_style="transparent"
        app:icon_back="true" />

    <include layout="@layout/item_loading_view" />

    <com.scwang.smartrefresh.layout.SmartRefreshLayout
        android:id="@+id/refreshLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:srlEnableFooterFollowWhenLoadFinished="true"
        app:srlEnableScrollContentWhenLoaded="true">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/rvMovieList"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginTop="5dp"
            android:visibility="gone" />

        <com.scwang.smartrefresh.layout.footer.ClassicsFooter
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:srlClassicsSpinnerStyle="Translate" />

    </com.scwang.smartrefresh.layout.SmartRefreshLayout>

</LinearLayout>

Controls com.scwang.smartrefresh.layout.SmartRefreshLayout In this layout is to use the currently RecyclerView be achieved on the drop-down refresh Raja upload pagination open source library more fire on GitHub, the specific method used can go to the open-source address to see the address of the library is open: https://github.com/scwang90/SmartRefreshLayout .

Create a directory xml layout in the layout, the layout is a layout adapted for linear layout RecyclerView loaded item entry. The layout style is as follows:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/color_page_bg"
    android:paddingLeft="10dp"
    android:paddingTop="5dp"
    android:paddingRight="10dp"
    android:paddingBottom="5dp">

    <android.support.v7.widget.CardView
        android:id="@+id/home_cardview"
        android:layout_width="100dp"
        android:layout_height="135dp"
        app:cardCornerRadius="4dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <ImageView
            android:id="@+id/home_item_movie_list_pic"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="fitXY" />

    </android.support.v7.widget.CardView>


    <TextView
        android:id="@+id/home_item_movie_list_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="12dp"
        android:text="肖申克的救赎"
        android:textColor="@color/color_black"
        android:textSize="18sp"
        android:textStyle="bold"
        app:layout_constraintStart_toEndOf="@+id/home_cardview"
        app:layout_constraintTop_toTopOf="@+id/home_cardview" />

    <TextView
        android:id="@+id/home_item_movie_list_director"
        style="@style/home_style_movie_list_tv"
        android:text="导演:弗兰克·达拉邦特"
        app:layout_constraintStart_toEndOf="@+id/home_cardview"
        app:layout_constraintTop_toBottomOf="@+id/home_item_movie_list_title" />

    <TextView
        android:id="@+id/home_item_movie_list_Starring"
        style="@style/home_style_movie_list_tv"
        android:layout_marginRight="10dp"
        android:text="主演:摩根·弗里曼,蒂姆·罗宾斯"
        app:layout_constraintStart_toEndOf="@+id/home_cardview"
        app:layout_constraintTop_toBottomOf="@+id/home_item_movie_list_director" />

    <TextView
        android:id="@+id/home_item_movie_list_type"
        style="@style/home_style_movie_list_tv"
        android:layout_marginRight="10dp"
        android:text="类型:剧情、犯罪"
        app:layout_constraintStart_toEndOf="@+id/home_cardview"
        app:layout_constraintTop_toBottomOf="@+id/home_item_movie_list_Starring" />

    <TextView
        android:id="@+id/home_item_movie_list_regions"
        style="@style/home_style_movie_list_tv"
        android:layout_marginRight="10dp"
        android:text="地区:美国"
        app:layout_constraintStart_toEndOf="@+id/home_cardview"
        app:layout_constraintTop_toBottomOf="@+id/home_item_movie_list_type" />

</android.support.constraint.ConstraintLayout>

Then create a Adapter to bind view, rendering and fill data and monitor interface settings RecyclerView item entry click event. code show as below:

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {

    private Context mContext;
    private List<MovieDataModel> mList;
    private MovieDataModel data;
    private OnItemClikListener mOnItemClikListener;

    public RecyclerViewAdapter(Context context, List<MovieDataModel> mList) {
        this.mContext = context;
        this.mList = mList;
    }

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

    @Override
    public void onBindViewHolder(final ViewHolder holder, final int position) {
        data = mList.get(position);
        RequestOptions options = new RequestOptions()
                .placeholder(R.drawable.img_default_movie)
                .error(R.drawable.img_default_movie);
        Glide.with(mContext).load(data.getDownimgurl()).apply(options).into(holder.home_item_movie_list_pic);
        holder.home_item_movie_list_title.setText(data.getDownLoadName());
        holder.home_item_movie_list_director.setText(data.getDirector());
        holder.home_item_movie_list_Starring.setText(data.getStarring());
        holder.home_item_movie_list_type.setText(data.getType());
        holder.home_item_movie_list_regions.setText(data.getRegions());

        if (mOnItemClikListener != null) {
            // 设置item条目短按点击事件的监听
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int pos = holder.getLayoutPosition();
                    mOnItemClikListener.onItemClik(holder.itemView, pos);
                }
            });

            // 设置item条目长按点击事件的监听
            holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    int pos = holder.getLayoutPosition();
                    mOnItemClikListener.onItemLongClik(holder.itemView, pos);
                    return false;
                }
            });
        }
    }

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

    public static class ViewHolder extends RecyclerView.ViewHolder {

        private ImageView home_item_movie_list_pic;
        private TextView home_item_movie_list_title;
        private TextView home_item_movie_list_director;
        private TextView home_item_movie_list_Starring;
        private TextView home_item_movie_list_type;
        private TextView home_item_movie_list_regions;

        public ViewHolder(View itemView) {
            super(itemView);
            home_item_movie_list_pic = (ImageView) itemView.findViewById(R.id.home_item_movie_list_pic);
            home_item_movie_list_title = (TextView) itemView.findViewById(R.id.home_item_movie_list_title);
            home_item_movie_list_director = (TextView) itemView.findViewById(R.id.home_item_movie_list_director);
            home_item_movie_list_Starring = (TextView) itemView.findViewById(R.id.home_item_movie_list_Starring);
            home_item_movie_list_type = (TextView) itemView.findViewById(R.id.home_item_movie_list_type);
            home_item_movie_list_regions = (TextView) itemView.findViewById(R.id.home_item_movie_list_regions);
        }
    }

    // 定义item条目点击事件接口
    public interface OnItemClikListener {
        void onItemClik(View view, int position);

        void onItemLongClik(View view, int position);
    }

    public void setItemClikListener(OnItemClikListener mOnItemClikListener) {
        this.mOnItemClikListener = mOnItemClikListener;
    }

}

And finally analyzing the data provided in the Activity or Fragment. code show as below:

/**
 * RecyclerView线性布局样式
 */
public class RecyclerViewActivity extends BaseActivity {

    @BindView(R.id.mTitleBar)
    TitleBar mTitleBar;
    @BindView(R.id.loading_view_ll)
    LinearLayout loading_view_ll;
    @BindView(R.id.loading_view)
    ImageView mLoadingView;
    @BindView(R.id.refreshLayout)
    RefreshLayout refreshLayout;
    @BindView(R.id.rvMovieList)
    RecyclerView rvMovieList;

    private boolean refreshType;
    private int page;
    private int oldListSize;
    private int newListSize;
    private int addListSize;
    private String viewType;
    private RecyclerViewAdapter adapter;

    private List<MovieDataModel> mList = new ArrayList<>();

    @Override
    protected int getLayoutId() {
        return R.layout.activity_recycler_view;
    }

    @Override
    protected void initView() {

        ButterKnife.bind(this);
        Intent intent = getIntent();
        viewType = intent.getStringExtra("ViewType");
        mTitleBar.setOnTitleBarListener(new OnTitleBarListener() {

            @Override
            public void onLeftClick(View v) {
                finish();
            }

            @Override
            public void onTitleClick(View v) {
            }

            @Override
            public void onRightClick(View v) {
            }
        });
        AnimationDrawable anim = (AnimationDrawable) mLoadingView.getDrawable();
        anim.start();

    }

    @Override
    protected void initData() {

        // 开启自动加载功能(非必须)
        refreshLayout.setEnableAutoLoadMore(true);
        refreshLayout.setOnRefreshListener(new OnRefreshListener() {
            @Override
            public void onRefresh(@NonNull final RefreshLayout refreshLayout) {
                refreshLayout.getLayout().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        refreshType = true;
                        page = 1;
                        parsingMovieListJson();
                        refreshLayout.finishRefresh();
                        refreshLayout.resetNoMoreData();//setNoMoreData(false);
                    }
                }, 2000);
            }
        });
        refreshLayout.setOnLoadMoreListener(new OnLoadMoreListener() {
            @Override
            public void onLoadMore(@NonNull final RefreshLayout refreshLayout) {
                refreshLayout.getLayout().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        refreshType = false;
                        if (page > 2) {
                            ToastUtil.showToast("暂无更多的数据啦");
                            // 将不会再次触发加载更多事件
                            refreshLayout.finishLoadMoreWithNoMoreData();
                            return;
                        }
                        parsingMovieListJson();
                        refreshLayout.setEnableLoadMore(true);
                        refreshLayout.finishLoadMore();
                    }
                }, 2000);
            }
        });
        //触发自动刷新
        refreshLayout.autoRefresh();

    }

    private void parsingMovieListJson() {

        try {
            // 从assets目录中获取json数据,在真实的项目开发中需要通过网络请求从服务器json数据
            String jsonData = BaseTools.getAssetsJson(this, "movie" + page + ".json");
            if (refreshType && mList != null) {
                mList.clear();
                oldListSize = 0;
            } else {
                oldListSize = mList.size();
            }
            // 使用Google的Gson开始解析json数据
            Gson gson = new Gson();
            MovieBaseModel movieBaseModel = gson.fromJson(jsonData, MovieBaseModel.class);
            List<MovieDataModel> movieDataModelList = movieBaseModel.getData();
            for (MovieDataModel movieDataModel : movieDataModelList) {
                MovieDataModel data = new MovieDataModel();
                data.setMovClass(movieDataModel.getMovClass());
                data.setDownLoadName(movieDataModel.getDownLoadName());
                data.setDownimgurl(movieDataModel.getDownimgurl());
                data.setDownLoadUrl(movieDataModel.getDownLoadUrl());
                data.setMvdesc(movieDataModel.getMvdesc());
                OtherBaseModel otherModelDesc = gson.fromJson(movieDataModel.getMvdesc(), OtherBaseModel.class);
                List<String> headerList = otherModelDesc.getHeader();
                data.setDirector(headerList.get(1));
                data.setStarring(headerList.get(2));
                data.setType(headerList.get(3));
                data.setRegions(headerList.get(4));
                mList.add(data);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        newListSize = mList.size();
        addListSize = newListSize - oldListSize;

        if (refreshType) {
            // 设置RecyclerView样式为竖直线性布局
            rvMovieList.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
            adapter = new RecyclerViewAdapter(this, mList);
            if (viewType.equals("NoDividingLine")) {
                mTitleBar.setTitle("线性布局样式");
            } else {
                mTitleBar.setTitle("线性布局(有分割线)样式");
                // 设置分割线
                rvMovieList.addItemDecoration(new CustomDecoration(
                        this, LinearLayoutManager.VERTICAL, R.drawable.divider_mileage, 15));
            }
            rvMovieList.setAdapter(adapter);
        } else {
            adapter.notifyItemRangeInserted(mList.size() - addListSize, mList.size());
            adapter.notifyItemRangeChanged(mList.size() - addListSize, mList.size());
        }
        page++;

        rvMovieList.setVisibility(View.VISIBLE);
        loading_view_ll.setVisibility(View.GONE);

        // item条目的点击事件回调
        adapter.setItemClikListener(new RecyclerViewAdapter.OnItemClikListener() {

            // 短按点击事件回调
            @Override
            public void onItemClik(View view, int position) {
                String videoTitle = mList.get(position).getDownLoadName();
                ToastUtil.showToast(videoTitle);
            }

            // 长按点击事件回调
            @Override
            public void onItemLongClik(View view, int position) {

            }
        });

    }

}

Can be seen from the above code, refreshLayout.setOnRefreshListener (new OnRefreshListener () method is implemented the function of the pull-down refresh the data, refreshLayout.setOnLoadMoreListener (new OnLoadMoreListener () is implemented on the LAC paging data upload function and rvMovieList.setLayoutManager (new LinearLayoutManager ( this, LinearLayoutManager.VERTICAL, false)) this code is set to vertical linear RecyclerView style layout. rvMovieList.addItemDecoration (new CustomDecoration (this, LinearLayoutManager.VERTICAL, R.drawable.divider_mileage, 15)) the code is implemented RecyclerView item effect dividing line between entries, and different RecyclerView the ListView is RecyclerView default is no dividing line, if developers need to implement the dividing line can only function if their own definition. Finally adapter.setItemClikListener (new RecyclerViewAdapter.OnItemClikListener () the callback interface is implemented RecyclerView item entry click event callback.

Activity in analog manner in the acquired network requests data from the server and parses json view provided to the interface, json data structure follows:

{
    "Code":200,
    "Msg":"数据获取成功",
    "Data":[
        {
            "movClass":"科幻片",
            "downLoadName":"海市蜃城",
            "downLoadUrl":"",
            "mvdesc":"{"header": ["别名:", "导演:孙田", "主演:刘端端,王滢,高强,刘依琳", "类型:科幻片 悬疑 科幻", "地区:大陆", "语言:国语", "上映:2019", "片长:91", "更新:2019-05-20 00:42:56", "总播放量:", "今日播放量:0", "总评分数:0", "评分次数:0"], "desc": "阿可是一个游戏公司的CEO兼游戏设计师,最近一直在设计一款即将上市的游戏《魔界通缉》,这款游戏为玩家提供了更加真实的体验,在最后的一次玩家测试时,一位玩家差点因为游戏丢了性命,且一直未查明原因。压力很大的阿可开始生活中经常出现幻觉。同时眼睛也出了问题。游戏设计如期完成,期间阿可一直阻止公司召开游戏发布会,希望能查清游戏的安全性,但被一个神秘人阻挠。游戏发布会如期召开,引起粉丝疯狂捧场,神秘人在发布会上也代替了阿可的发言。游戏上线后阿可发现游戏开始慢慢控制玩家,同时发生了越来越多的不可思议的事情。当阿可想删除游戏源代码时,所有玩家对阿可开始了真正的通缉……"}",
            "downimgurl":"https://tupian.tupianzy.com/pic/upload/vod/2019-05-20/201905201558283504.jpg",
            "mv_update_time":"2019-05-20",
            "downdtitle":"zuidam3u8,zuidall,迅雷下载",
            "id":"10313",
            "mv_md5_id":"4b406e86b4eaeea68fb7fc7c0608c348",
            "type":"00000000001"
        }
    ]
}

FIG interface operating results as follows:
Linear layout styleLinear layout (dividing line) pattern

Wherein the first map is a linear layout style RecyclerView default rendering operation without dividing lines, there is a second run custom effect dividing line of FIG.

RecyclerView achieve grid layout style

RecyclerView achieve grid layout style and layout item need only modify the portion Adapter, Activity code.

xml layout item layout code as follows:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/cv_top_movie"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginStart="3dp"
    android:layout_marginTop="3dp"
    android:layout_marginEnd="3dp"
    android:layout_marginBottom="3dp"
    android:foreground="?attr/selectableItemBackgroundBorderless"
    app:cardCornerRadius="2dp"
    app:cardElevation="2dp">

    <LinearLayout
        android:id="@+id/ll_item_top"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:paddingBottom="3dp">

        <ImageView
            android:id="@+id/iv_photo"
            android:layout_width="match_parent"
            android:layout_height="145dp"
            android:scaleType="fitXY"
            app:layout_collapseMode="parallax"
            app:layout_collapseParallaxMultiplier="0.7"
            tools:background="@color/color_page_bg" />

        <TextView
            android:id="@+id/tv_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="3dp"
            android:ellipsize="marquee"
            android:focusable="true"
            android:focusableInTouchMode="true"
            android:singleLine="true"
            android:text="肖申克的救赎"
            android:textColor="@color/colorTitle"
            android:textSize="12sp" />

        <TextView
            android:id="@+id/tv_regions"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:text="地区:美国"
            android:textSize="10sp" />

    </LinearLayout>
</android.support.v7.widget.CardView>

Modify the code in the following Activity:

// 设置RecyclerView样式为网格布局,一行显示3列
rvMovieList.setLayoutManager(new GridLayoutManager(this, 3));
adapter = new GridLayoutRVAdapter(this, mList);
rvMovieList.setAdapter(adapter);

See, GridLayoutManager is set to RecyclerView grid layout style, wherein the second row shows three parameter setting item entry.

FIG interface operating results as follows:
Grid layout style

Achieve RecyclerView waterfall flow layout style

RecyclerView cascade layout styles may be used in the actual project development is relatively small, more commonly used is the first two linear layout and grid layout, but the cascade style more in the power business with the App, such as Taobao Android App home page on the end use RecyclerView cascade layout style. FIG follows:
Here Insert Picture Description
RecyclerView cascade layout styles based on a grid layout styles can be modified to achieve, first modify the entry item layout style, layout code as follows:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/cv_top_movie"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginStart="3dp"
    android:layout_marginTop="3dp"
    android:layout_marginEnd="3dp"
    android:layout_marginBottom="3dp"
    android:foreground="?attr/selectableItemBackgroundBorderless"
    app:cardCornerRadius="2dp"
    app:cardElevation="2dp">

    <LinearLayout
        android:id="@+id/ll_item_top"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:paddingBottom="3dp">

        <ImageView
            android:id="@+id/iv_photo"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:adjustViewBounds="true"
            android:scaleType="fitXY"
            app:layout_collapseMode="parallax"
            app:layout_collapseParallaxMultiplier="0.7"
            tools:background="@color/color_page_bg" />

        <TextView
            android:id="@+id/tv_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="3dp"
            android:ellipsize="marquee"
            android:focusable="true"
            android:focusableInTouchMode="true"
            android:singleLine="true"
            android:text="肖申克的救赎"
            android:textColor="@color/colorTitle"
            android:textSize="12sp" />

        <TextView
            android:id="@+id/tv_regions"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:text="地区:美国"
            android:textSize="10sp" />

    </LinearLayout>
</android.support.v7.widget.CardView>

Layout file can be seen from the code, the code and the layout of the grid cascade of two different, is to modify the control ImageView height of image is "wrap_content" value, and the grid is changed to a fixed value, there is a the image is that it is in control ImageView waterfall add the android: adjustViewBounds = "true" attribute, the role of this property is suitable for the display images can be displayed from the effects cascade styles look better.

Activity then modify the code, modify the code as follows:

// 设置RecyclerView样式为瀑布流布局,一行显示2列
rvMovieList.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
adapter = new StaggeredGridRVAdapter(this, mList);
rvMovieList.setAdapter(adapter);

StaggeredGridLayoutManager code is set to RecyclerView grid layout style, wherein the first parameter set 2 line item entry display, the second parameter set displayed vertically.

FIG interface operating results as follows:
Cascade layout style

Achieve RecyclerView nested layout styles

Before implementing RecyclerView nested layout style look at the layout of nested json data structure:

{
    "reason":"成功的返回",
    "data":[
        {
            "title":"高清电影",
            "content":[
                {
                    "name":"异类侵袭",
                    "tag":"地区:大陆",
                    "url":"",
                    "thumbnail_pic_s":"https://tupian.tupianzy.com/pic/upload/vod/2019-05-19/201905191558252942.png"
                }
            ]
        },
        {
            "title":"热门剧集",
            "content":[
                {
                    "name":"筑梦情缘[DVD版]",
                    "tag":"地区:大陆",
                    "url":"",
                    "thumbnail_pic_s":"https://tupian.tupianzy.com/pic/upload/vod/2019-05-10/201905101557455675.jpg"
                }
            ]
        }
    ],
    "error_code":0
}

As can be seen from the data structure in json, "data" field is a field array, the array contains a number of fields in a set of fields, the array can be RecyclerView field as a parent layout field as a plurality of sets is a RecyclerView sub-layout. That is nested layout is a layout RecyclerView RecyclerView of one or more nested.

The nested layout style is mainly Adapter Set data binding is too much trouble, for the first time the definition of a parent Adapter, Adapter child by a parent Adapter mapped to go. Adapter parent code is as follows:

public class MovieTypesAdapter extends RecyclerView.Adapter<MovieTypesAdapter.ViewHolder> {

    private Context mContext;
    private List<MovieTypesDataModel> mList;
    private MovieTypesDataModel data;
    private OnItemClikListener mOnItemClikListener;

    public MovieTypesAdapter(Context context, List<MovieTypesDataModel> mList) {
        this.mContext = context;
        this.mList = mList;
    }

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

    @Override
    public void onBindViewHolder(final ViewHolder holder, final int position) {

        data = mList.get(position);
        holder.movieTypesTitle.setText(data.getTitle());

        MovieTypesChildAdapter childAdapter = (MovieTypesChildAdapter) holder.movieTypesChild.getAdapter();
        //适配器复用
        if (childAdapter == null) {
            RecyclerView.LayoutManager manager = new GridLayoutManager(mContext, 3);
            holder.movieTypesChild.setLayoutManager(manager);
            holder.movieTypesChild.setAdapter(new MovieTypesChildAdapter(mContext, data.getContent(), position));
        } else {
            childAdapter.setData(data.getContent()); //重新设置数据
            childAdapter.notifyDataSetChanged();
        }

        if (mOnItemClikListener != null) {
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int pos = holder.getLayoutPosition();
                    mOnItemClikListener.onItemClik(holder.itemView, pos);
                }
            });

            holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    int pos = holder.getLayoutPosition();
                    mOnItemClikListener.onItemLongClik(holder.itemView, pos);
                    return false;
                }
            });
        }
    }

    @Override
    public int getItemCount() {
        return mList == null ? 0 : mList.size();
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {

        private TextView movieTypesTitle;
        private RecyclerView movieTypesChild;

        public ViewHolder(View itemView) {
            super(itemView);
            movieTypesTitle = (TextView) itemView.findViewById(R.id.movieTypesTitle);
            movieTypesChild = (RecyclerView) itemView.findViewById(R.id.movieTypesChild);
        }
    }

    public interface OnItemClikListener {
        void onItemClik(View view, int position);

        void onItemLongClik(View view, int position);
    }

    public void setItemClikListener(OnItemClikListener mOnItemClikListener) {
        this.mOnItemClikListener = mOnItemClikListener;
    }

}

Adapter sub-code is as follows:

public class MovieTypesChildAdapter extends RecyclerView.Adapter<MovieTypesChildAdapter.ViewHolder> {

    private Context mContext;
    private List<MovieTypesDataModel.MovieTypesContentModel> childList;
    private int mPosition;
    private MovieTypesDataModel.MovieTypesContentModel data;
    private OnItemClikListener mOnItemClikListener;

    public MovieTypesChildAdapter(Context context, List<MovieTypesDataModel.MovieTypesContentModel> childList) {
        this.mContext = context;
        this.childList = childList;
    }

    public MovieTypesChildAdapter(Context context, List<MovieTypesDataModel.MovieTypesContentModel> childList, int position) {
        this.mContext = context;
        this.childList = childList;
        this.mPosition = position;
    }

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

    @Override
    public void onBindViewHolder(final ViewHolder holder, final int position) {
        data = childList.get(position);
        RequestOptions options = new RequestOptions()
                .placeholder(R.drawable.img_default_movie)
                .error(R.drawable.img_default_movie);
        Glide.with(mContext).load(data.getThumbnail_pic_s()).apply(options).into(holder.iv_photo);
        holder.tv_name.setText(data.getName());
        holder.tv_regions.setText(data.getTag());
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int pos = holder.getLayoutPosition();
                NestRVActivity.instance.OnClickListener(mPosition, pos);

            }
        });

        holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                return false;
            }
        });

    }

    @Override
    public int getItemCount() {
        return childList == null ? 0 : childList.size();
    }

    public void setData(List<MovieTypesDataModel.MovieTypesContentModel> childList) {
        this.childList = childList;
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {

        private ImageView iv_photo;
        private TextView tv_name;
        private TextView tv_regions;

        public ViewHolder(View itemView) {
            super(itemView);
            iv_photo = (ImageView) itemView.findViewById(R.id.iv_photo);
            tv_name = (TextView) itemView.findViewById(R.id.tv_name);
            tv_regions = (TextView) itemView.findViewById(R.id.tv_regions);
        }
    }

    public interface OnItemClikListener {
        void onItemClik(View view, int position);

        void onItemLongClik(View view, int position);
    }

    public void setItemClikListener(OnItemClikListener mOnItemClikListener) {
        this.mOnItemClikListener = mOnItemClikListener;
    }

}

FIG interface operating results as follows:
Here Insert Picture Description

apk installer download experience Address

It can scan the following QR code to download and install, or click the link below https://fukaimei.top/apk/RecyclerViewTest.apk to download and install experience.
Here Insert Picture Description
-------- The end --------

If you find this blog to write good words, appreciation cup of coffee ~
Here Insert Picture Description


Download a Demo program source (GitHub)
Demo program source Download bis (Code Cloud)

Guess you like

Origin blog.csdn.net/fukaimei/article/details/90446316