RecyclerView+BaseRecyclerHelper开发指南

来源:互联网 发布:js判断ie版本是否大于9 编辑:程序博客网 时间:2024/06/16 08:29

序言

RecyclerView可以替换ListView和GridView.

BaseRecyclerHelper优化并简化了RecyclerView的使用.

特别说明

1.RecyclerView

强烈建议对RecyclerView有一定了解后,再使用BaseRecyclerHelper.

如果你对RecyclerView还不熟悉,请参考:

教程:

http://blog.csdn.net/lmj623565791/article/details/45059587

http://blog.csdn.net/skykingf/article/details/50827141

视频:

http://www.imooc.com/learn/424

http://www.imooc.com/learn/731

 

2.BaseRecyclerHelper

强烈建议对照官方demo进行学习

Github首页:

https://github.com/CymChad/BaseRecyclerViewAdapterHelper


 

开始使用

一.添加RecyclerView依赖

点击Structure,再点击右边绿色+号,添加recyclerview依赖



二.添加BaseRecyclerHelper依赖

网址:https://github.com/CymChad/BaseRecyclerViewAdapterHelper

步骤:

1.先在 build.gradle(Project:XXXX) 的 repositories 添加:

allprojects {repositories {maven { url "https://jitpack.io"}}}

 


2.然后在 build.gradle(Module:app) 的 dependencies 添加:

dependencies { compile 'com.github.CymChad:BaseRecyclerViewAdapterHelper:VERSION_CODE'}


用真实发行版本号, 替换VERSION_CODE

版本号网址 https://github.com/CymChad/BaseRecyclerViewAdapterHelper/releases,用最新的就好了, 我现在用的是2.8.0

注意:两个gradle都必须要写,要不然无法加载成功。

 

三.最好添加这么一行代码,避免和xUtils冲突的bug(只是可能有冲突)

defaultConfig {useLibrary 'org.apache.http.legacy'}


现在可以正式开始使用了!

三.使用方法

(一)普通使用

1.Activity代码
//先声明Videovideo;//实体类List<Video> list;//实体类集合RecyclerViewrecyclerView;VideoAdapteradapter; public void initView(){recyclerView= (RecyclerView)view.findViewById(R.id.lv_video_tch);adapter =new  VideoAdapter(R.layout.item_video,list);//当前item布局recyclerView.setAdapter(adapter);//用setAdapter方法设置适配器 LinearLayoutManager linearLayoutManager =newLinearLayoutManager(this) {@Overridepublic booleancanScrollVertically(){//这里是防止嵌套滑动不流畅return false;  }};recyclerView.setLayoutManager(linearLayoutManager);//设置recyclerview的显示方式,这里用ListView的方式显示recyclerView.addItemDecoration(new DividerItemDecoration( getActivity(),DividerItemDecoration.HORIZONTAL));//简单分割线,可以暂时不用} public void getVideoList(){//…Xtuils获取数据for(…){//添加到用户List中list.add(video_tchToStu);//quickAdapter.notifyDataSetChanged();//用这个也可以,和listview的notifydataset一模一样adapter.notifyItemInserted(i);//用这个也可以,都是把数据添加到适配器中,这个是用for循环依次添加}}
2.Adapter代码

适配器的代码比listview和recyclerview原始代码减少70%以上!!非常强大!

(1)需要注意的,如何拿到每个item内部的控件

if (item.tags.equals("1")){helper.setText(R.id.txv_tags,"天猫");}else {//拿到控件helper.getView(R.id.txv_tags).setVisibility(View.GONE);}

或者

Button bf = (Button) helper.getView(R.id.btn_video_more);bf.setText(item.header);

 

(2)Adapter全部代码示例

1.适配器必须继承BaseQuickAdapter类,先写出来,然后ctrl+1自动重写convert()方法,和构造函数, BaseQuickAdapter有两个泛型类,第一个是你的实体类,第二个是BaseViewHolder.

 

2.构造方法用ctrl+1自动生成,第一个参数是你的Item布局,第二个参数是实体类集合数据

 

3.Convert()方法就是用来转化行布局内的控件的,两个参数helper和item,helper就是帮助类,item就是你的实体类集合的每一个对象


4.继承BaseQuickAdapter类,先写出来,然后ctrl+1或alt+回车自动重写convert()方法,和构造函数


5.converted()方法内通过setText()方法给item布局内的textview控件赋值!

public class videoAdapter extendsBaseQuickAdapter<Video,BaseViewHolder> {privateBitmapUtilsbitmapUtils;publicVideoAdapter (intlayoutResId,List<Video> data){super(layoutResId, data);bitmapUtils= Utils.getInstance();} @Overrideprotected void convert(BaseViewHolder helper, Videoitem) {helper.setText(R.id.txv_username_video_comment,item.username);helper.setText(R.id.txv_contentvideo,item.contentvideo);bitmapUtils.display(helper.getView(R.id.imgv_avatar_video_comment),item.avatar);}    }}
3.按钮点击事件

非常方便,再也不用像listview一样声明很多接口了!

(1)     Item的点击事件

直接在Activity里写,如果复制粘贴报红了,把@override的部分删了,再ctrl+1重新生成一下就好了!以下同理. 

(方法:通过mRecyclerView.addOnItemTouchListener,传入OnItemClickListener)

mRecyclerView.addOnItemTouchListener(newOnItemClickListener( ){@Overridepublic voidSimpleOnItemClick(BaseQuickAdapter adapter, View view, int position) {         //你的业务逻辑代码}});


(2)Item的长按事件

(方法:通过mRecyclerView.addOnItemTouchListener,传入OnItemLongClickListener)

mRecyclerView.addOnItemTouchListener(newOnItemLongClickListener( ) {@Overridepublic void SimpleOnItemLongClick(BaseQuickAdapter adapter, View view, int position) {//你的业务逻辑代码} });


(3)Item子控件的点击事件

1.在adapter的convert方法里面通过viewHolder.addOnClickListener绑定一下的控件id

@Overrideprotected void convert(BaseViewHolder helper, Status item) {        helper.setText(R.id.tweetName,item.getUserName())               .setText(R.id.tweetText, item.getText())               .setText(R.id.tweetDate, item.getCreatedAt())               .setVisible(R.id.tweetRT, item.isRetweet())               .addOnClickListener(R.id.tweetAvatar);//连点的方式可以      helper.addOnClickListener(R.id.tweetName);//单独写也可以    }


2.在Activity的mRecyclerView.addOnItemTouchListener,传入OnItemChildClickListener。

mRecyclerView.addOnItemTouchListener(new OnItemChildClickListener( ) {@Override      public voidSimpleOnItemChildClick(BaseQuickAdapter adapter, View view, int position) { //你的业务逻辑代码}});

 

(4)Item子控件的长按事件

 1.在adapter的convert方法里面通过viewHolder.addOnLongClickListener绑定一下的控件id

@Overrideprotected void convert(BaseViewHolder helper, Status item) {       helper.setText(R.id.tweetName, item.getUserName())               .setText(R.id.tweetText, item.getText())               .setText(R.id.tweetDate, item.getCreatedAt())               .setVisible(R.id.tweetRT, item.isRetweet())               .addOnLongClickListener(R.id.tweetText)               .linkify(R.id.tweetText);    }

 

 2.在Activity的mRecyclerView.addOnItemTouchListener,传入OnItemChildLongClickListener。

 mRecyclerView.addOnItemTouchListener(newOnItemChildLongClickListener( ) {  @Override  publicvoid SimpleOnItemChildLongClick(BaseQuickAdapter adapter, View view, intposition) {//你的业务逻辑代码         }});

 

(5)如果添加了多种不同的Item事件

重写以下任意方法

mRecyclerView.addOnItemTouchListener(newSimpleClickListener() {@Overridepublicvoid onItemClick(BaseQuickAdapter adapter, View view, int position) {//你的业务逻辑代码}@Overridepublic void onItemLongClick(BaseQuickAdapter adapter, View view, int position) {//你的业务逻辑代码}@Overridepublic void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {//你的业务逻辑代码} @Override   publicvoid onItemChildLongClick(BaseQuickAdapter adapter, View view, int position) { //你的业务逻辑代码              }});


四.局部刷新

方法很多,总之就是notifyXXX()的方法,传入当前int position的值

Insert是局部增加

Changed是局部改变

Remove的是局部删除


 举例说明:

长按删除的实现

recyclerView.addOnItemTouchListener(new OnItemLongClickListener(){ @Overridepublic void onSimpleItemLongClick(BaseQuickAdapteradapter, View view,intposition) {list.remove(position);adapter.notifyItemRemoved(position);}});


五.下拉刷新

二.下拉刷新 SwipeRefreshLayout

(1)布局

说明:SwipeRefreshLayout嵌套你的RecyclerView

<android.support.v4.widget.SwipeRefreshLayoutandroid:id="@+id/swipeLayout"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"> <android.support.v7.widget.RecyclerViewandroid:id="@+id/rv_video_other"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_centerHorizontal="true"android:background="@color/white"/> </android.support.v4.widget.SwipeRefreshLayout>

(2)加载完成自动滚到顶部

recyclerView.scrollToPosition(0);

(3)java代码实现

a)实现接口

public class VideoOtherFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener

b)声明并实例化

SwipeRefreshLayout mSwipeRefreshLayout;initView(){//下拉刷新mSwipeRefreshLayout =(SwipeRefreshLayout)view.findViewById(R.id.swipeLayout);mSwipeRefreshLayout.setColorSchemeColors(Color.rgb(47,223,189));//设置刷新小动画的颜色,可以不写.}


c)回调接口,传入当前上下文

initEvent() {mSwipeRefreshLayout.setOnRefreshListener(this);}


d)刷新的回调方法

一定要写到线程里!

private int delayMillis=1000;//刷新动画的持续事件 @Overridepublic void onRefresh() {quickAdapter.setEnableLoadMore(false);//上拉加载停止newHandler().postDelayed(newRunnable(){@Overridepublic void run() {list.clear();getVideoListAll();//获取数据的代码,在这里完成数据刷新和加载recyclerView.scrollToPosition(0);//RecyclerView滑动到最上头(第0个位置),视需要添加mSwipeRefreshLayout.setRefreshing(false);quickAdapter.setEnableLoadMore(true);//上拉加载开启}}, delayMillis);} //以下可以暂时不看,是添加一条item行用的private voidfetchingNewData() {for(inti=0; i < 3;i++) {list.add(i,newVideo_all());quickAdapter.notifyItemInserted(i);}


六.上拉加载

这里举了一个上拉分页加载服务器数据的例子.

1.PHP

$sql = "SELECT * from 某表名 WHERE 字段={$videoid}  AND cvparentid={$cvparentid}";        $index = 0;if (!empty($_REQUEST['index'])) {        $index = $_REQUEST['index'];} $pagesize = 10;if (!empty($_REQUEST['pagesize'])) {        $pagesize = $_REQUEST['pagesize'];}

解释: 

第一个参数是开始的item下标,第二个参数是每页显示几个

如 LIMIT 45,10 表示从第45个Item开始,每页显示10个,也就是在第五页

$sql.= " ORDER BY 某字段 DESC LIMIT {$index} , {$pagesize}";

 

2.获取数据的方法

int pageno = 1;//当前页--默认是第一页int pagesize = 7;//每页显示几条 List<CommentVideo> list;List<CommentVideo> currentList = new ArrayList<>();//用addAll,把获取到的数据去重添加到这个集合中 /** * 获得评论列表 *@param pageno 当前页码 */private void getReCommentvideo(int pageno){    int index = (pageno- 1) * pagesize;//(当前页码-1)*页面容量=当前下标    RequestParamsparams = new RequestParams();    params.addBodyParameter("videoid", video_all.videoid +"");    params.addBodyParameter("cvparentid", cvparentid +"");    params.addBodyParameter("index", index + "");    params.addBodyParameter("pagesize", pagesize +"");//设置上来显示几个    new HttpUtils().send(HttpRequest.HttpMethod.POST,            Constans_lekao.URL_LIST_COMMENTVIDEO_NEW,            params,            new RequestCallBack<String>() {                @Override                public voidonSuccess(ResponseInfo<String> info) {                    String result =info.result.trim();                    result =result.substring(result.indexOf(Constans_lekao.BRACKET));                               try{                        JSONObject jsonObject =new JSONObject(result);                        JSONArray jsonArray =jsonObject.getJSONArray("list");                        for (int i = 0; i <jsonArray.length(); i++) {                            //获得实体类集合,过程省略                            //添加到用户List中                            list.add(commentVideo);                        }                         //数据全部加载完成时                        if (list.size() == 0) {                            Log.i("wxs", "vrAct in---?+");                            //这两个都要写                            quickAdapter.loadMoreEnd(false);//关闭上拉加载更多                           quickAdapter.setEnableLoadMore(false);                           mSwipeRefreshLayout.setEnabled(true);//下拉刷新开启                            return;                        }                         currentList.addAll(list);//添加数据,注意AddAll                        list.clear();//一定要clear一下,否则会重复添加!                       quickAdapter.notifyDataSetChanged();                    } catch (Exception e) {                    e.printStackTrace();                    }                }                 @Override                public voidonFailure(HttpException e, String s) {                  quickAdapter.loadMoreFail();//显示加载失败                }           });}

3.实现RequestLoadMoreListener

public class VideoRecommentActivity extends Activity implements BaseQuickAdapter.RequestLoadMoreListener

4.注册监听器

滑动到最后一个Item的时候回调onLoadMoreRequested方法

quickAdapter.setOnLoadMoreListener(this);//加载更多

5.重写方法

@Overridepublic void onLoadMoreRequested() {//上拉加载    mSwipeRefreshLayout.setEnabled(false);    recyclerView.postDelayed(new Runnable() {        @Override         public void run() {            //获取更多数据            pageno = pageno + 1;//当前页+1            getReCommentvideo(pageno);            quickAdapter.loadMoreComplete();//表示加载完成        }    }, 998);} 

注意:下拉刷新的写法

@Overridepublic void onRefresh() {//下拉刷新quickAdapter.setEnableLoadMore(true);//上拉刷新开启currentList.clear();//清空去重集合pageno = 1;//把当前页重置为1new Handler().postDelayed(new Runnable() {        @Override       public void run() {            getReCommentvideo(pageno);//刷新并回到第一页             recyclerView.scrollToPosition(0);//滑动到最上头(第0个位置)            mSwipeRefreshLayout.setRefreshing(false);        }    }, 1000);//1秒延迟}


七.添加头部或尾部

0.特别注意

错误描述:

添加头部或者尾部布局后

java.lang.IllegalArgumentException:called detach on an already detached childViewHolder{1f2f274cposition=2 id=-1, oldPos=-1, pLpos:-1 scrap [attachedScrap] tmpDetached noparent}…

 

解决:

初始化布局initView()时,最后要调用adapter.notifyDatasetChanged().

而不是在获取数据的时候仅仅adapter.notifyItemInserted(i).

 

网上的解释:

Call notifyDataSetChanged instead of notifyItemRemoved due to a bug inRecyclerView

 

1.Activity

(1)添加头部就这一行代码,非常简单!添加尾部也一样.

quickAdapter.addHeaderView(getHeaderView());

(2)获得头布局的方法

/** * 头部布局的代码 * @return */privateView getHeaderView() {//通过inflater把自己写的头布局的xml文件反射到一个view中View vheader =getActivity().getLayoutInflater().inflate(R.layout.item_header_video_detail,(ViewGroup)recyclerView.getParent(), false);     //给头布局的控件赋值    txv_videoname = (TextView)vheader.findViewById(R.id.txv_videoname);    txv_videocount = (TextView)vheader.findViewById(R.id.txv_videocount);      if (video_all != null) {        //视频名称        txv_videoname.setText("" +video_all.videoname);         //视频播放次数        txv_videocount.setText("" +video_all.videocount);    }    return vheader;}

2.Adapter

适配器代码和头布局没有关系,略.


八.分组列表

使用步骤:

0.分析源码

结论:

a)泛型运用

分组类继承的父类SectionEntity<T>注意以下标红的部分,应用到了泛型,所以适配器或者Activity的点击事件回调时,可以通过Video_all video = (Video_all) item.t 或者sectionList.getPosition().t 的方式获得实体类对象

 

b)isHeader

用来判断是否是头部,正常情况要传true,否则会空指针

public abstract class SectionEntity<T> {    public boolean isHeader;    public T t;    public String header;     public SectionEntity(boolean isHeader, String header) {        this.isHeader = isHeader;        this.header = header;        this.t = null;    } public SectionEntity(T t) {        this.isHeader = false;        this.header = null;        this.t = t;    }}


1.分组头部布局

item_section_header_video_other.xml

<?xml version="1.0"encoding="utf-8"?><RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="5dp"tools:background="@color/white">     <TextView        android:id="@+id/txv_section_header_select"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentLeft="true"        android:layout_centerVertical="true"        android:text="语文"        android:textSize="16sp" />     <Button        android:layout_width="wrap_content"         android:layout_height="wrap_content"        android:layout_alignParentRight="true"        android:text="更多" /></RelativeLayout>


2.分组实体类

必须继承public abstract class SectionEntity<T>

public class MySection extendsSectionEntity<Video_all> {public boolean isMore;//这个参数可以不要,是例子里为了判断是否显示某个控件用的   public MySection(boolean isHeader, String header , boolean isMore) {        super(isHeader, header);//header给是分组布局,TextView显示的文字        this.isMore = isMore;    }     public MySection(Video_all video_all) {        super(video_all);    }     public boolean isMore() {        return isMore;    }     public void setMore(boolean more) {        isMore = more;    }}


3.数据实体类

public class Video_all implementsSerializable{     public int videoid;    public String videoname;    public String videointro;    public String videoimageurl;//视频图片地址    publicString videourl;    public int videodate;    public int videocount;//视频播放次数    publicint videolength;    public int videosize;    public int selectid;    public int userid_tch;    public int status;    public String user_tchname;    //.....getter,setter,tostring省略}


4.分组适配器

public class VideoOtherSectionQadp extends BaseSectionQuickAdapter<MySection,BaseViewHolder> {private BitmapUtils bitmapUtils;  public VideoOtherSectionQadp(int layoutResId, int sectionHeadResId ,List<MySection> data) {         //一个是普通的item布局,一个是分组头部的布局        super(layoutResId,sectionHeadResId, data);        bitmapUtils = Utils.getInstance();}     @Overrideprotected void convertHead(BaseViewHolder helper, MySection item) {//给分组头部textview赋值        helper.setText(R.id.txv_section_header_select,item.header);       }     @Override    protected void convert(BaseViewHolder helper, MySection item) {        Video_all video = (Video_all) item.t;//源码中的泛型!获得实体对象        helper.setText(R.id.txv_videointro, video.videointro);        helper.setText(R.id.txv_videocount, video.videocount + "");        bitmapUtils.display(helper.getView(R.id.imgv_videoimage),                video.videoimageurl);    }}

 

5.Activity或Fragment

(1)准备

Video_all video_all;RecyclerView recyclerView;VideoOtherSectionQadp quickSectionAdapter;ArrayList<MySection> sectionList = new ArrayList<>();//分组集合

(2)数据

private void initData() {    getVideoListAll();//获取数据}

(3)控件

private void initView() {recyclerView = (RecyclerView) view.findViewById(R.id.rv_video_other);quickSectionAdapter = newVideoOtherSectionQadp(R.layout.item_video_all,R.layout.item_section_header_video_other,sectionList);//头部和普通布局    recyclerView.setAdapter(quickSectionAdapter);     //动画recyclerView.setItemAnimator(new DefaultItemAnimator());recyclerView.setLayoutManager(newStaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));//两行的格子布局 //下拉刷新    mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipeLayout);     mSwipeRefreshLayout.setColorSchemeColors(Color.rgb(47,223, 189));} //声明几个List,用来接收不同的分组类型ArrayList<Video_all> ywList = newArrayList<>();//语文ArrayList<Video_all> sxList = newArrayList<>();//数学ArrayList<Video_all> yyList = new ArrayList<>();//英语ArrayList<Video_all> zzList = newArrayList<>();//政治

(4)获得数据,并构造分组

/** * 获得视频列表 */public void getVideoListAll() {new HttpUtils().send(HttpRequest.HttpMethod.POST,Constans_lekao.URL_LIST_VIDEO_ALL,new RequestCallBack<String>() {@Override                public voidonSuccess(ResponseInfo<String> info) {String result =info.result.trim();result =result.substring(result.indexOf(Constans_lekao.BRACKET));                    try {                        //手动解析JSON                        JSONObject jsonObject =new JSONObject(result);                        JSONArray jsonArray =jsonObject.getJSONArray("list");                        for (int i = 0; i <jsonArray.length(); i++) {                            JSONObject jvideo =jsonArray.getJSONObject(i);                            //解析出json对象中的属性                            //获得实体集合数据,省略                             if (selectid == 1){//语文                               ywList.add(video_all);                            }                            if (selectid == 2){//数学                               sxList.add(video_all);                            }                            if (selectid == 3) {//英语                               yyList.add(video_all);                            }                            if (selectid == 4){//政治                               zzList.add(video_all);                            }                          quickSectionAdapter.notifyItemInserted(i);                        }                        //根据业务需求,添加分组头部,和分组添加数据                       //如果结果集大于4,那么只显示4个;如果小于4个,则显示全部结果集                        sectionList.add(newMySection(true, "语文", true));                        if (ywList.size() >4) {                            for (int i = 0; i< 4; i++) {                               sectionList.add(new MySection(ywList.get(i)));                            }                        }else {                            for (int i = 0; i< ywList.size(); i++) {                               sectionList.add(new MySection(ywList.get(i)));                            }                        }                         sectionList.add(newMySection(true, "数学", true));                        if (sxList.size() >4) {                            for (int i = 0; i< 4; i++) {                               sectionList.add(new MySection(sxList.get(i)));                            }                        }else {                            for (int i = 0; i< sxList.size(); i++) {                               sectionList.add(new MySection(sxList.get(i)));                            }                        }                         sectionList.add(newMySection(true, "英语", true));                        if (yyList.size() >4) {                            for (int i = 0; i< 4; i++) {                               sectionList.add(new MySection(yyList.get(i)));                            }                        }else {                            for (int i = 0; i< yyList.size(); i++) {                               sectionList.add(new MySection(yyList.get(i)));                            }                       }                         sectionList.add(newMySection(true, "政治", true));                        if (zzList.size() >4) {                            for (int i = 0; i< 4; i++) {                               sectionList.add(new MySection(zzList.get(i)));                            }                        }else {                            for (int i = 0; i< zzList.size(); i++) {                               sectionList.add(new MySection(zzList.get(i)));                            }                        }                     } catch (JSONException e) {                        e.printStackTrace();                    }                }                 @Override                public voidonFailure(HttpException e, String s) {                 }           });}

(5)点击事件监听

private void initEvent() {   mSwipeRefreshLayout.setOnRefreshListener(this);    recyclerView.addOnItemTouchListener(new OnItemClickListener() {       @Override       public void onSimpleItemClick(BaseQuickAdapter adapter, View view, intposition) {           Intent intent = new Intent(getActivity(), VideoDetailActivity.class);           Bundle bundle = new Bundle();   //这里不是获得list的位置了           //而是通过sectionList的位置获得实体类集合的对象t(泛型)           bundle.putSerializable("video_all", sectionList.get(position).t);           intent.putExtras(bundle);           startActivity(intent);       }   });    recyclerView.addOnItemTouchListener(new OnItemLongClickListener() {       @Override       public void onSimpleItemLongClick(BaseQuickAdapter adapter, View view,int position) {           sectionList.remove(position);           adapter.notifyItemRemoved(position);       }   });}

(6)下拉刷新

private int delayMillis = 1000;private SwipeRefreshLayoutmSwipeRefreshLayout; @Overridepublic void onRefresh() {   //quickAdapter.setEnableLoadMore(false);//上拉刷新停止   new Handler().postDelayed(new Runnable() {       @Override       public void run() {//先清空几个集合           sectionList.clear();           ywList.clear();           sxList.clear();           yyList.clear();           zzList.clear();           getVideoListAll();           //recyclerView.scrollToPosition(0); -->这里不能设置为0           mSwipeRefreshLayout.setRefreshing(false);           //quickAdapter.setEnableLoadMore(true);//上拉刷新开启       }   }, delayMillis);}


(7)分组的按钮点击

@Overrideprotected void convertHead(BaseViewHolderhelper, final MySection item) {   helper.setText(R.id.txv_section_header_select, item.header);   if (item.header.equals("语文")) {       helper.setImageResource(R.id.imgv_section_header_select,R.drawable.yuwen);    }   if (item.header.equals("数学")) {       helper.setImageResource(R.id.imgv_section_header_select,R.drawable.shuxue);    }   if (item.header.equals("英语")) {       helper.setImageResource(R.id.imgv_section_header_select,R.drawable.yingyu);    }   if (item.header.equals("政治")) {       helper.setImageResource(R.id.imgv_section_header_select,R.drawable.zhengzhi);    }   if (item.header.equals("专业课")) {       helper.setImageResource(R.id.imgv_section_header_select,R.drawable.zhuanyeke);    }    helper.setOnClickListener(R.id.btn_video_more,new View.OnClickListener() {       @Override       public void onClick(View v) {        Utils.showToast("VideoOtherSectionQadp,btn,onclick,header="+item.header);       }   });}


6.注意

(1)此时,在下拉刷新时,不要调用 recyclerView.scrollToPosition(0);因为会导致刷新完成后白屏


Bug小结

(一)解决Scrollview嵌套RecyclerView滑动艰涩,不顺畅的问题

现象:

一个界面有多个RecyclerView以及其他一些内容,这时要上下滚动就会使用外面嵌套一个ScrollView,虽然没有遇到像ScrollView嵌套ListView时那样只显示部分,剩余不显示,但是在滑动的时候如果是在RecyclerView上滑动,这时会出现只滑动动该RecyclerView的内容上就会停止,而如果是在其他内容上滑动时就可以很顺畅的滑下去,因此就会感觉到卡顿的样子。

解决:禁止RecyclerView的滑动。

LinearLayoutManagerlinearLayoutManager  = newLinearLayoutManager(getActivity()) {@Overridepublic boolean canScrollVertically() {        return false;    }};

(二)RecyclerView不显示数据的原因

解决:可能因为没有设置布局管理器

LinearLayoutManager layoutManager = newLinearLayoutManager(this);recyclerView.setLayoutManager(layoutManager);

(三)解决notifyxxx()闪屏的方法

资料:

http://blog.csdn.net/chenliguan/article/details/52809758

http://www.jianshu.com/p/654dac931667--->这个说的比较好

解决:给recyclerView添加这行代码

((SimpleItemAnimator)recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);

(四)如果需要获取当前item的position

可以在Adapter中通过helper.getLayoutPosition()来获取

如:

@Overrideprotected void convert(final BaseViewHolderhelper, Lesson item) {helper.getLayoutPosition();}

(五)报错Inconsistency detected

描述:

报错信息

Inconsistencydetected Invalid view holder adapter positionViewHolder{1350756e position=1id=-1, ol…..

解决:

自定义LayoutManager类,然后替换原来的

(1)创建一个类LinearLayoutManagerWrapper继承LinearLayoutManager,重写onLayoutChildren方法

public class WrapContentLinearLayoutManagerextends LinearLayoutManager {   public WrapContentLinearLayoutManager(Context context) {       super(context);    }    public WrapContentLinearLayoutManager(Context context, int orientation,boolean reverseLayout) {       super(context, orientation, reverseLayout);    }    public WrapContentLinearLayoutManager(Context context, AttributeSetattrs, int defStyleAttr, int defStyleRes) {       super(context, attrs, defStyleAttr, defStyleRes);    }    @Override   public void onLayoutChildren(RecyclerView.Recycler recycler,RecyclerView.State state) {       try {           super.onLayoutChildren(recycler, state);       } catch (IndexOutOfBoundsException e) {           e.printStackTrace();       }    }}


(2)设置RecyclerView的布局管理为WrapContentLinearLayoutManager对象

mRecyclerView.setLayoutManager(newWrapContentLinearLayoutManager(this, LinearLayoutManager.VERTICAL,false)); 

经过测试,发现这个异常被catch了,没有再出现这种崩溃的问题,

 

(六)RecyclerView只显示一行

可能是相关的item布局有问题,比如match_parent,导致从头顶到底了.

 

(七)CoordinatorLayout嵌套RecyclerView滑动不正确的问题

思路:

CoordinatorLayout最好只有一个AppbarLayout还有一个滑动容器(如RecyclerView)在其内部.

解决:

RecyclerView使用headview布局!把其他在RecyclerView外面的布局全部用hearder包含.

 

(八)RecyclerView自动滑到第一个的位置的问题

scrollview嵌套recyclerview时,给scrollview下的第一个子控件里加上如下两句即可解决此问题。

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


 

 

2 0
原创粉丝点击