美文网首页recycleview
Brvah在RecyclerView中的使用

Brvah在RecyclerView中的使用

作者: Chenyangqi | 来源:发表于2017-08-26 22:14 被阅读500次

    BRVAH在RecyclerView中的使用


    前言

    RecyclerView虽然好用但是确实比起ListView使用难度上略大,写过五遍以上的原始的RecyclerView.Adapter后我迫切的打开了全球最大单生交友平台GitHub,寻找BaseAdapter for RecyclerView。然后我找到了BAVAH。哈哈赶快学习一下。
    BRVAH github地址:https://github.com/CymChad/BaseRecyclerViewAdapterHelper

    学习目标

    • 加载普通列表布局
    • item点击事件,item子元素点击事件
    • item设置加载动画
    • 下拉刷新上拉加载
    • RecyclerView添加头部和尾部
    • 多类型item列表
    • 恩 暂时就先这么多吧,后续有新需求再持续更新......

    具体实现

    先看看效果,实现凤凰新闻客户端新闻列表,包含banner头部和三张item类型的新闻列表,实现底部自动加载更多,下拉刷新。点击item能够进入新闻详情页面

    image.png M2YRF_4R__5%AY3RUJ5)YOI.png
    image.png

    先来看看实现这么一个复杂的列表所使用的adapter代码量有多少:

    public class DocNewsAdapter extends BaseMultiItemQuickAdapter<BRVAHActivity.NewsBean, BaseViewHolder> {
        private Context context;
        private List<BRVAHActivity.NewsBean> list = new ArrayList<>();
    
        public DocNewsAdapter(Context context, List<BRVAHActivity.NewsBean> list) {
            super(list);
            this.context = context;
            this.list = list;
            addItemType(BRVAHActivity.NewsBean.doc, R.layout.item_doc_news);
            addItemType(BRVAHActivity.NewsBean.slide, R.layout.item_slide_news);
            addItemType(BRVAHActivity.NewsBean.text_live, R.layout.item_textlive_news);
        }
    
        @Override
        protected void convert(BaseViewHolder baseViewHolder, BRVAHActivity.NewsBean item) {
    
            switch (baseViewHolder.getItemViewType()) {
    
                case BRVAHActivity.NewsBean.doc:
                    baseViewHolder.setText(R.id.txt_doc_title, item.docNewsBean.getTitle())
                            .setText(R.id.txt_doc_commentsall, item.docNewsBean.getCommentsall())
                            .setText(R.id.txt_doc_source, item.docNewsBean.getSource())
                            .setText(R.id.txt_doc_updateTime, item.docNewsBean.getUpdateTime());
                    Glide.with(context).load(item.docNewsBean.getThumbnail()).placeholder(R.drawable.ic_fh_defals)
                            .crossFade().into((ImageView) baseViewHolder.getView(R.id.img_doc_thumbnail));
                    baseViewHolder.addOnClickListener(R.id.img_doc_thumbnail);
                    break;
                case BRVAHActivity.NewsBean.slide:
                    baseViewHolder.setText(R.id.txt_slide_title, item.slideNewsBean.getTitle())
                            .setText(R.id.txt_slide_commensall, item.slideNewsBean.getCommentsall())
                            .setText(R.id.txt_slide_resource, item.slideNewsBean.getSource());
                    for (int i = 0; i < item.slideNewsBean.getStyle().getImages().size(); i++) {
                        if (i == 0)
                            Glide.with(context).load(item.slideNewsBean.getStyle().getImages().get(i)).placeholder(R.drawable.ic_fh_defals)
                                    .crossFade().into((ImageView) baseViewHolder.getView(R.id.img_slie_img1));
                        else if (i == 1)
                            Glide.with(context).load(item.slideNewsBean.getStyle().getImages().get(i)).placeholder(R.drawable.ic_fh_defals)
                                    .crossFade().into((ImageView) baseViewHolder.getView(R.id.img_slie_img2));
                        else if (i == 2)
                            Glide.with(context).load(item.slideNewsBean.getStyle().getImages().get(i)).placeholder(R.drawable.ic_fh_defals)
                                    .crossFade().into((ImageView) baseViewHolder.getView(R.id.img_slie_img3));
                    }
                    break;
                case BRVAHActivity.NewsBean.text_live:
                    baseViewHolder.setText(R.id.txt_textlive_title, item.textLiveNewsBean.getTitle());
                    Glide.with(context).load(item.textLiveNewsBean.getThumbnail()).placeholder(R.drawable.ic_fh_defals)
                            .centerCrop().into((ImageView) baseViewHolder.getView(R.id.img_textlive_thumbnail));
                    break;
            }
        }
    }
    

    完成全部功能的activity代码

    
    public class BRVAHActivity extends AppCompatActivity implements BaseQuickAdapter.OnItemClickListener,
            BaseQuickAdapter.OnItemChildClickListener, BaseQuickAdapter.RequestLoadMoreListener, SwipeRefreshLayout.OnRefreshListener {
        Toolbar toolbar;
        LinearLayout container;
        int currentPage = 0, totalPage = 0;
        boolean isRefresh = true;//当前操作是否是下拉刷新
        List<NewsBean> list = new ArrayList<>();
        @BindView(R.id.recyc_news)
        RecyclerView recyclerView;
        DocNewsAdapter adapter;
        @BindView(R.id.swipeRefreshLayout)
        SwipeRefreshLayout mSwipeRefreshLayout;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_brvah);
            ButterKnife.bind(this);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                WindowManager.LayoutParams localLayoutParams = getWindow().getAttributes();
                localLayoutParams.flags = (WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | localLayoutParams.flags);
            }
            toolbar = (Toolbar) findViewById(R.id.tb_toolbar);
            setSupportActionBar(toolbar);
            requestData(currentPage);
            adapter = new DocNewsAdapter(BRVAHActivity.this, list);
            recyclerView.setLayoutManager(new LinearLayoutManager(BRVAHActivity.this));
            recyclerView.setAdapter(adapter);
            //item点击事件
            adapter.setOnItemClickListener(this);
            //item子元素点击事件
            adapter.setOnItemChildClickListener(this);
    //        adapter.openLoadAnimation();
            adapter.isFirstOnly(false);
            //adapter设置头部banner
            adapter.addHeaderView(initBanner());
            //自动加载
            adapter.setOnLoadMoreListener(this);
            //上拉刷新
            mSwipeRefreshLayout.setOnRefreshListener(this);
            mSwipeRefreshLayout.setColorSchemeColors(Color.rgb(47, 223, 189));
        }
    
        /**
         * 初始化banner
         */
        private View initBanner() {
            container = (LinearLayout) findViewById(R.id.container);
            View customBanner = LayoutInflater.from(this).inflate(R.layout.custom_banner, container, false);
            ViewGroup viewGroup = (ViewGroup) customBanner;
            Banner banner = (Banner) viewGroup.getChildAt(0);
            banner.setOnBannerListener(new OnBannerListener() {
                @Override
                public void OnBannerClick(int position) {
                    Toast.makeText(BRVAHActivity.this, "点击了focus news" + position, Toast.LENGTH_SHORT).show();
                }
            });
            return customBanner;
        }
    
        /**
         * 请求新闻数据
         *
         * @param page 第几页新闻
         */
        private void requestData(final int page) {
            OkHttpUtils
                    .get()
                    .url(API.getFh_toutiao() + page)
                    .build()
                    .execute(new StringCallback() {
                        @Override
                        public void onError(Call call, Exception e, int id) {
                            Toast.makeText(BRVAHActivity.this, "网络请求失败,请检查网络设置", Toast.LENGTH_SHORT).show();
                        }
    
                        @Override
                        public void onResponse(String response, int id) {
                            JSONObject data = (JSONObject) JSON.parseArray(response).get(0);
                            totalPage = data.getInteger("totalPage");
                            currentPage = data.getInteger("currentPage");
                            JSONArray item = data.getJSONArray("item");
                            for (int i = 0; i < item.size(); i++) {
                                JSONObject newsData = (JSONObject) item.get(i);
                                String newsType = newsData.getString("type");
                                if (newsType.equals("doc")) {
                                    DocNewsBean docNewsBean = JSON.parseObject(item.get(i).toString(), DocNewsBean.class);
                                    NewsBean newsBean = new NewsBean(NewsBean.doc, docNewsBean, null, null);
                                    list.add(newsBean);
                                } else if (newsType.equals("slide")) {
                                    SlideNewsBean slideNewsBean = JSON.parseObject(item.get(i).toString(), SlideNewsBean.class);
                                    NewsBean newsBean = new NewsBean(NewsBean.slide, null, slideNewsBean, null);
                                    list.add(newsBean);
                                } else if (newsType.equals("text_live")) {
                                    TextLiveNewsBean textLiveNewsBean = JSON.parseObject(item.get(i).toString(), TextLiveNewsBean.class);
                                    NewsBean newsBean = new NewsBean(NewsBean.text_live, null, null, textLiveNewsBean);
                                    list.add(newsBean);
                                }
                            }
                            adapter.notifyDataSetChanged();
                            if (isRefresh) {
                                //结束下拉刷新动画
                                mSwipeRefreshLayout.setRefreshing(false);
                            } else {
                                //结束加载更多动画
                                adapter.loadMoreComplete();
                            }
    
                        }
                    });
        }
    
        /**
         * item的点击事件
         *
         * @param adapter  设置点击事件的Adapter
         * @param view     item的view
         * @param position item位置
         */
        @Override
        public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
            Intent intent = new Intent(BRVAHActivity.this, NewsDitailsActivity.class);
            String url = null;
            if (list.get(position).docNewsBean != null)
                url = list.get(position).docNewsBean.getLink().getWeburl();
            else if (list.get(position).slideNewsBean != null)
                url = list.get(position).slideNewsBean.getLink().getWeburl();
            else if (list.get(position).textLiveNewsBean != null)
                url = list.get(position).textLiveNewsBean.getLink().getWeburl();
            intent.putExtra("url", url);
            startActivity(intent);
        }
    
        /**
         * item子元素点击事件
         *
         * @param adapter
         * @param view
         * @param position
         * @return
         */
        @Override
        public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
            Toast.makeText(BRVAHActivity.this, "点击子元素中的图片" + position, Toast.LENGTH_SHORT).show();
        }
    
    
        @Override
        public void onLoadMoreRequested() {
            isRefresh = false;
            if (currentPage < totalPage) {
                requestData(currentPage + 1);
            } else {
                adapter.loadMoreEnd();
            }
    
        }
    
        /**
         * 下拉刷新
         */
        @Override
        public void onRefresh() {
            isRefresh = true;
            currentPage = 0;
            list.clear();
            requestData(currentPage);
        }
    
        /**
         * 包含三种类型的新闻实体
         */
        public class NewsBean implements MultiItemEntity {
            public DocNewsBean docNewsBean;
            public SlideNewsBean slideNewsBean;
            public TextLiveNewsBean textLiveNewsBean;
            private int itemType;
            public static final int doc = 1;
            public static final int slide = 2;
            public static final int text_live = 3;
    
            public NewsBean(int itemType, DocNewsBean docNewsBean, SlideNewsBean slideNewsBean, TextLiveNewsBean
                    textLiveNewsBean) {
                this.docNewsBean = docNewsBean;
                this.slideNewsBean = slideNewsBean;
                this.textLiveNewsBean = textLiveNewsBean;
                this.itemType = itemType;
            }
    
            @Override
            public int getItemType() {
                return this.itemType;
            }
        }
    }
    

    减少了绝大部分adapter代码量,效率还是非常高的。

    仿照凤凰新闻客户端头条新闻列表部分,使用RecyclerView+BRVAH实现具有banner头部的新闻列表,具有上拉刷新下拉加载,点击查看新闻详情的功能。凤凰新闻-头条新闻列表如下:
    项目使用到的库如下:


    
    dependencies {
        ...
        compile 'com.android.support:recyclerview-v7:26.+'
        compile 'cn.yipianfengye.android:zxing-library:1.1'
        compile 'com.jakewharton:butterknife:8.8.1'
         annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
        compile 'com.zhy:okhttputils:2.6.2'
        compile 'net.qiujuer.genius:ui:2.0.0'
        compile 'net.qiujuer.genius:res:2.0.0'
        compile 'de.hdodenhof:circleimageview:2.1.0'
        compile 'com.github.bumptech.glide:glide:3.7.0'
        testCompile 'junit:junit:4.12'
        compile files('libs/fastjson-1.2.36.jar')
        compile files('libs/glide-3.7.0.jar')
        compile 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.22'
    }
    
    

    1: 加载普通列表布局

    现加载凤凰新闻type为doc的普通新闻数据列表


    初始化Adapter,三部曲没啥好说的

    adapter = new DocNewsAdapter(BRVAHActivity.this, list);
    recyclerView.setLayoutManager(new LinearLayoutManager(BRVAHActivity.this));
    recyclerView.setAdapter(adapter);
    

    Adapter实现如下,传入数据绑定即可(R.layout.item_doc_news是item布局,list是新闻数据实体类)

     public class DocNewsAdapter extends BaseQuickAdapter<DocNewsBean, BaseViewHolder> {
        private Context context;
        private List<DocNewsBean> list = new ArrayList<>();
    
        public DocNewsAdapter(Context context, List<DocNewsBean> list) {
            super(R.layout.item_doc_news,list);
            this.context = context;
            this.list = list;
        }
    
        @Override
        protected void convert(BaseViewHolder baseViewHolder, DocNewsBean item) {
            baseViewHolder.setText(R.id.txt_doc_title, item.getTitle())
                    .setText(R.id.txt_doc_commentsall, item.getCommentsall())
                    .setText(R.id.txt_doc_source, item.getSource())
                    .setText(R.id.txt_doc_updateTime, item.getUpdateTime());
            Glide.with(context).load(item.getThumbnail()).placeholder(R.drawable.ic_fh_defals).crossFade().into((ImageView) baseViewHolder.getView(R.id.img_doc_thumbnail));
        }
    }   
    

    效果如如下:

    123.png

    2:item,item子元素点击事件

    activity中调用

            //item点击事件
            adapter.setOnItemClickListener(this);
            //item子元素点击事件
            adapter.setOnItemChildClickListener(this);
    
    /**
         * item的点击事件
         *
         * @param adapter  设置点击事件的Adapter
         * @param view     item的view
         * @param position item位置
         */
        @Override
        public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
            Toast.makeText(BRVAHActivity.this, "点击了第" + position + "个item", Toast.LENGTH_SHORT)
                    .show();
        }
    
        /**
         * item子元素点击事件
         *
         * @param adapter
         * @param view
         * @param position
         * @return
         */
        @Override
        public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
            Toast.makeText(BRVAHActivity.this, "点击子元素中的图片" + position, Toast.LENGTH_SHORT).show();
        }
    

    子元素的点击需要再Adapter中进行绑定

    /**
     * 新闻列表adapter
     * Created by CYQ on 2017/8/26.
     */
    public class DocNewsAdapter extends BaseQuickAdapter<DocNewsBean, BaseViewHolder> {
        private Context context;
        private List<DocNewsBean> list = new ArrayList<>();
    
        public DocNewsAdapter(Context context, List<DocNewsBean> list) {
            super(R.layout.item_doc_news, list);
            this.context = context;
            this.list = list;
        }
    
        @Override
        protected void convert(BaseViewHolder baseViewHolder, DocNewsBean item) {
            baseViewHolder.setText(R.id.txt_doc_title, item.getTitle())
                    .setText(R.id.txt_doc_commentsall, item.getCommentsall())
                    .setText(R.id.txt_doc_source, item.getSource())
                    .setText(R.id.txt_doc_updateTime, item.getUpdateTime());
            //为子元素中的图片设置点击事件
            Glide.with(context).load(item.getThumbnail()).placeholder(R.drawable.ic_fh_defals).crossFade().into((ImageView)
                    baseViewHolder.getView(R.id.img_doc_thumbnail));
            baseViewHolder.addOnClickListener(R.id.img_doc_thumbnail);
        }
    }
    

    这么简单就实现了item和他的子元素的点击事件,比起原生的Adapter少了太多的代码了。


    item设置加载动画

    个人感觉为item设置动画没太大的实际用途,哈哈BRVAH为item设置动画一行代码搞定

     adapter.openLoadAnimation();
    

    BRVAH为开发者提供了五中默认的动画效果:渐显、缩放、从下到上,从左到右、从右到左通过quickAdapter.openLoadAnimation(BaseQuickAdapter.ALPHAIN);设置即可


    下拉刷新上拉加载

    下拉刷新使用Android SDK自带的SwipeRefreshLayout

    <android.support.v4.widget.SwipeRefreshLayout
            android:id="@+id/swipeRefreshLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
    
            <android.support.v7.widget.RecyclerView
                android:id="@+id/recyc_news"
                android:layout_width="match_parent"
                android:layout_height="match_parent"/>
        </android.support.v4.widget.SwipeRefreshLayout>
    
     //上拉刷新
            mSwipeRefreshLayout.setOnRefreshListener(this);
            mSwipeRefreshLayout.setColorSchemeColors(Color.rgb(47, 223, 189));
            //............
             /**
         * 下拉刷新
         */
        @Override
        public void onRefresh() {
            //刷新操作
        }
    

    上拉加载

    BRVAH提供了自动加载更多的属性,也可以自定义加载更多的view

    //上拉自动加载
    adapter.setOnLoadMoreListener(this);
    ...
    @Override
        public void onLoadMoreRequested() {
            //加载更多操作
        }
    

    恩就是这么方便就实现了列表上拉加载下拉刷新的功能


    添加头部banner
    这里我自定义了一个banner轮播View,BRVAH为RecyclerView提供了和listview一样方便的增加头部的功能addHeadView(youHeadView).

    adapter.addHeaderView(initBanner());
    

    initBanner();是我自定义的广告banner,返回一个view类型,把他替换成你要add的view就OK。

       /**
         * 初始化banner
         */
        private View initBanner() {
            container = (LinearLayout) findViewById(R.id.container);
            View customBanner = LayoutInflater.from(this).inflate(R.layout.custom_banner, container, false);
            ViewGroup viewGroup = (ViewGroup) customBanner;
            Banner banner = (Banner) viewGroup.getChildAt(0);
            banner.setOnBannerListener(new OnBannerListener() {
                @Override
                public void OnBannerClick(int position) {
                    Toast.makeText(BRVAHActivity.this, "点击了focus news" + position, Toast.LENGTH_SHORT).show();
                }
            });
            return customBanner;
        }
    

    多类型item列表

    持续更新中。。。。。

    相关文章

      网友评论

        本文标题:Brvah在RecyclerView中的使用

        本文链接:https://www.haomeiwen.com/subject/rsbvdxtx.html