BaseRecyclerHelper开发指南

本文是BaseRecyclerHelper的使用指南,包括添加依赖、普通使用、局部刷新、下拉刷新和上拉加载等。BaseRecyclerHelper简化了RecyclerView的操作,提供头部和尾部添加、分组列表等功能,并针对常见问题如滑动卡顿、数据不显示等提供了解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

序言

RecyclerView可以替换ListView和GridView.

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

特别说明

1.RecyclerView

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

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

教程:

http://blog.youkuaiyun.com/lmj623565791/article/details/45059587

http://blog.youkuaiyun.com/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) {
	@Override
	public 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();
}
 
@Override
protected 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( ){
	@Override
	public voidSimpleOnItemClick(BaseQuickAdapter adapter, View view, int position) {
        	 //你的业务逻辑代码
	}
});


(2)Item的长按事件

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

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


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

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

@Override
protected 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

@Override
protected 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() {
	@Override
	publicvoid onItemClick(BaseQuickAdapter adapter, View view, int position) {
	//你的业务逻辑代码
}


@Override
	public void onItemLongClick(BaseQuickAdapter adapter, View view, int position) {
	//你的业务逻辑代码
}

@Override
	public 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(){
	 @Override
	public void onSimpleItemLongClick(BaseQuickAdapteradapter, View view,intposition) {
		list.remove(position);
		adapter.notifyItemRemoved(position);
	}
});


五.下拉刷新

二.下拉刷新 SwipeRefreshLayout

(1)布局

说明:SwipeRefreshLayout嵌套你的RecyclerView

<android.support.v4.widget.SwipeRefreshLayout
	android:id="@+id/swipeLayout"
	android:layout_width="match_parent"
	android:layout_height="match_parent"
	android:orientation="vertical">
 
<android.support.v7.widget.RecyclerView
	android: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;//刷新动画的持续事件 
@Override
public void onRefresh() {
	quickAdapter.setEnableLoadMore(false);//上拉加载停止
	newHandler().postDelayed(newRunnable(){
@Override
	public 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.重写方法

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

注意:下拉刷新的写法

@Override
public void onRefresh() {
//下拉刷新
quickAdapter.setEnableLoadMore(true);//上拉刷新开启
currentList.clear();//清空去重集合
pageno = 1;//把当前页重置为1
new 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();
}
 
    @Override
protected 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;
 
@Override
public 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)分组的按钮点击

@Override
protected 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()) {
@Override
public boolean canScrollVertically() {
        return false;
    }
};

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

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

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

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

资料:

http://blog.youkuaiyun.com/chenliguan/article/details/52809758

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

解决:给recyclerView添加这行代码

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

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

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

如:

@Override
protected 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"


 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值