Android入门笔记(三)

三、RecyclerView、ViewHolder 和 Adapter

 

     3.1 功能概括

RecyclerView :任务仅限于回收和定位屏幕上的 View,且其自身不会创建视图,它创建的只是 ViewHolder,通过绑定的 Adapter 来进行工作。

ViewHolder:容纳 View 视图,引用 itemView

Adapter:Adapter 是一个控制器对象,从模型层获取数据,然后提供给 RecyclerView 显示,是沟通的桥梁。其主要工作是创建必要的 ViewHolder( onBindViewHolder方法完成 ) 和 绑定 ViewHolder 至模型层数据( onCreateViewHolder方法完成 )。

       3.2 工作流程

首先,调用 Adapter 的 getitemCount() 方法,RecyclerView 询问数组列表中包含多少个对象。

接着, RecyclerView 调用 Adapter 的 onCreateViewHolder( ViewGroup, int ) 方法创建 ViewHolder 及其要显示的视图。

最后,RecyclerView 会传入 ViewHolder 及其位置,调用 onBindViewHolder( ViewHolder, int ) 方法。Adapter 会找到目标位置的数据并将其绑定到 ViewHolder 的视图上。

        3.3 代码实现

扫描二维码关注公众号,回复: 3329107 查看本文章

(1)创建布局后在 fragment 的 onCreateView 方法中实例化视图,然后设置其 LayoutManager 来对其进行托管,注意:没有 LayoutManager 的支持,不仅 RecyclerView 无法工作,还会导致应用崩溃,而 LayoutManager 的主要工作就是在屏幕上摆放列表项并负责定义屏幕的滚动行为,LinearLayoutManager 支持以竖直列表的形式展示列表项。

private RecyclerView mRecyclerView;


public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.fragment_article_list, container, false);

    mRecyclerView = (RecyclerView) view.findViewById(R.id.article_list);
    mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

    updateUI();

    return view;
}

(2)创建 ViewHolder 内部类,并在其构造方法中进行列表子项的布局实例化。将其构造方法的参数设置为 LayoutInflater 和 ViewGroup(父视图),然后通过 super 方法,通过 latoutInflater.inflate 方法,将列表子视图布局传递至 ViewHolder 的构造函数中,使其基类来实际引用当前设置的列表子项目视图,并可在当前的 ViewHolder 中通过 itemView 来对视图进行操作。

    其次可以设置监听点击的方法,为使 RecyclerView 的功能更加纯粹,所以我们选择在 ViewHolder 中实现 View.onClickListener 接口,并实现其 onClick 方法,之后在构造方法中通过 itemView 调用 setOnClickListener 方法即可实现对当前列表子视图的点击监听。

       最后可以在 ViewHolder 中创建 bind 方法首先对模型和视图的绑定操作(该方法会在 Adapter 的 onBindViewHolder 中调用,来进行视图的数据填充 )

    private class ArticleHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        private Article mArticle;
        private TextView mTitleTextView;
        private TextView mContentTextView;

        public ArticleHolder(LayoutInflater layoutInflater, ViewGroup viewGroup) {
            super(layoutInflater.inflate(R.layout.list_item_article, viewGroup, false));
            itemView.setOnClickListener(this);

            mTitleTextView = (TextView) itemView.findViewById(R.id.list_item_title);
            mContentTextView = (TextView) itemView.findViewById(R.id.list_item_content);
        }

        public void bind (Article article){
            mArticle = article;
            mTitleTextView.setText(article.getTitle());
            mContentTextView.setText(article.getDate().toString());
        }

        @Override
        public void onClick(View view) {
            Toast.makeText(getActivity(),"这篇文章的题目是:" + mArticle.getTitle(), Toast.LENGTH_SHORT).show();
        }
}

(3)创建 Adapter 内部类并继承 RecyclerView.Adapter 类 ,在其构造方法中将列表数据保存至其属性中,待之后使用。重写其父类中的 onCreateViewHolder、onBindViewHolder 和 getItemCount 方法。

       首先 onCreateViewHolder 第一个参数为父视图,第二个参数为该 ViewHolder 的视图类型,可根据这个参数的值来创建 item 的不同视图,在这个方法中应首先通过 LayoutInflater.from 方法获取一个 LayoutInflater,并将其作为参数来实例化该列表的 ViewHolder 。

       其次在 onBindViewHolder 中,通过函数参数来定位该子视图的位置,然后在列表的数据列表中获取该 itemView 的模型,然后调用 ViewHolder 中的 bind 方法来将数据填充至视图中。

       最后设置 gerItemCount 方法的返回值为当前列表的大小,同时可以通过 getItemViewType 方法设置不同 item 的不同 viewType 值,viewType 可在 onCreateViewHolder 中进行判断,进而实现多 item 布局。

    private class ArticleAdapter extends RecyclerView.Adapter<ArticleHolder> {

        private List<Article> mArticles;

        public ArticleAdapter(List<Article> articles) {
            mArticles = articles;
        }

        @NonNull
        @Override
        public ArticleHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {

            LayoutInflater inflater = LayoutInflater.from(getActivity());

            return new ArticleHolder(inflater, viewGroup);
        }

        @Override
        public void onBindViewHolder(@NonNull ArticleHolder articleHolder, int position) {
            Article article = mArticles.get(position);
            articleHolder.bind(article);
        }

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

        @Override
        public int getItemViewType(int position) {
            return position % 2 == 0 ? 1 :0;
        }
    }

 (4)在当前 fragment 中创建 Adapter  属性,编写 updateUI 方法来对 Adapter 和 RecyclerView 来进行绑定。

       首先获取数据池单例,然后通过该单例来获取列表数据,实例化 Adapter 并将列表数据传入 ,然后通过 RecyclerView 的 setAdapter 方法将该 Adapter 绑定至 RecyclerView,最后在 onCreateView 方法中调用 updateUI 方法即完成了 Adapter 和 RecyclerView 的绑定。

    private void updateUI() {
        ArticleLab articleLab = ArticleLab.getInstance(getActivity());
        List<Article> articles = articleLab.getmArticles();

        mAdapter = new ArticleAdapter(articles);
        mRecyclerView.setAdapter(mAdapter);
    }

猜你喜欢

转载自blog.csdn.net/qq_40697071/article/details/82821864