序言
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"