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"
- RecyclerView+BaseRecyclerHelper开发指南
- RecyclerView使用完全指南
- RecyclerView使用完全指南
- Android开发--RecyclerView使用
- 初探RecyclerView开发
- Kotlin简单开发-RecyclerView
- RecyclerView使用完全指南(二)
- 开发指南
- Android开发模板------RecyclerView简介
- Android开发 ---RecyclerView基本用法
- android开发笔记之RecyclerView
- iBatis指南、Hibernate指南、Spring开发指南
- iBatis指南、Hibernate指南、Spring开发指南
- PF_RING开发指南 安装指南
- Android开发---Scrollerview中嵌套RecyclerView RecyclerView显示不全问题
- Android编程权威指南之使用RecyclerView显示列表
- 《android编程权威指南》RecyclerView的notifyItemChanged()方法使用
- RecyclerView
- 【Codeforces 765 C. Table Tennis Game 2】+ 贪心
- 数据结构与算法分析笔记与总结(java实现)--二叉树6:完全二叉树判断练习题
- 利用Java反射实现JavaBean对象相同属性复制并初始化目标对象为空的属性的BeanUtils
- Intersection of Two Arrays
- 栅栏染色
- RecyclerView+BaseRecyclerHelper开发指南
- kubernetes知识链接
- 软件的需求与隐含需求
- kafka topic增加partition
- MXNet官方文档教程(4):使用预训练好的模型
- 蓝桥杯 算法提高 算法训练 十进制数转八进制数
- 有道词典的划词搜索功能加入生成的百度链接
- Make Triangle SPOJ - TRNGL (卡特兰数)
- 华为机试在线训练-牛客网(25)四则运算