RecyclerView 开发中碰见个问题总结
以前使用最多的还是ListView 和GridView 。最近开始在项目中彻底替换成了RecyclerView,完全放弃了ListView和GridView。这篇文章,主要记录下我碰见的一些问题,和相应的解决方案。希望能给大家一些帮助。
1.RecyclerView 中嵌套RecyclerView 每次刷新时。子RecyclerView 的addItemDecoration()调用造成子RecyclerView 的间距拉高。
recyclerView 的addItemDecoration 只会不断累加调整间距。每调用一次就会添加一次间距。
解决方法:
MyDecoration myDecoration = new MyDecoration();
if(recyclerView.getItemDecorationAt(0)==null){
recyclerView.addItemDecoration(myDecoration,0)
}
会判断recyclerView 是否添加过decoration 。如果有过分割线了就不要再进行添加了。 如果不存在就进行添加。
2.在Android5.0版本后的手机中,ScrollView 嵌套 RecyclerView 时,滑动过程中会很卡顿,但是在4.4系统上又很流畅。这个问题主要是在于RecyclerView 的问题。
解决方法:
<android.support.v7.widget.RecyclerView
android:nestedScrollingEnabled="false"
android:id="@+id/recycler"
android:overScrollMode="never"
android:scrollbars="none"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@+id/frameLayout" />
主要是这个方法:
android:nestedScrollingEnabled=”false”
让recyclerView 放弃滑动处理。 这样就不会出现卡顿的问题了。
3.RecyclerView 的decoration 通用版本。支持List 和Grid 和HORIZONTAL布局, 而且回归简单。其他所有的万能decoration写的也太繁琐和冗余了。
解决方法:
/** * 自定义 RecyclerView 分割线 */
public class MyDecoration extends RecyclerView.ItemDecoration {
private Paint mPaint;
private int mDividerHeight = 1;//分割线高度,默认为1px
public DecorationType decorationType = DecorationType.VRTICAL;//默认 横着
public enum DecorationType {
VRTICAL, HORIZONTAL, GRID
}
public MyDecoration(int colorId) {
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(colorId);
mPaint.setStyle(Paint.Style.FILL);
}
public MyDecoration() {
this(Color.parseColor("#dedede"));
}
public MyDecoration(int dividerHeight, int dividerColor) {
this(dividerColor);
mDividerHeight = dividerHeight;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
if(decorationType== DecorationType.VRTICAL) {
outRect.set(0, 0, 0, mDividerHeight);
}else if(decorationType == DecorationType.HORIZONTAL){
outRect.set(0, 0, mDividerHeight, 0);
}else if(decorationType==DecorationType.GRID){
outRect.set(0, 0, mDividerHeight, mDividerHeight);
}
}
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDraw(c, parent, state);
drawVertical(c, parent);
}
//绘制item 分割线
private void drawVertical(Canvas canvas, RecyclerView parent) {
int childCount = parent.getChildCount();
if(decorationType== DecorationType.VRTICAL) {
int left = parent.getPaddingLeft();
int right = parent.getWidth() - parent.getPaddingRight();
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
//获得child的布局信息
int top = child.getBottom();
int bottom = top + mDividerHeight;
canvas.drawLine(left, top, right, bottom, mPaint);
}
}else if(decorationType == DecorationType.HORIZONTAL){
int right = parent.getWidth() - parent.getPaddingRight();
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
//获得child的布局信息
int top = child.getTop();
int bottom = top + mDividerHeight;
canvas.drawLine(right, top, right, bottom, mPaint);
}
}else if(decorationType==DecorationType.GRID){
int left = parent.getPaddingLeft();
int right = parent.getWidth() - parent.getPaddingRight();
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
//获得child的布局信息
int top = child.getBottom();
int bottom = top + mDividerHeight;
canvas.drawLine(left, top, right, bottom, mPaint);
top = child.getTop();
canvas.drawLine(right, top, right, bottom, mPaint);
}
}
}
}
4.去除RecyclerView 滑动到顶部和底部时的阴影
解决方案
android:overScrollMode="never"
是去除右侧的滚动条
android:scrollbars="none"
5.RecyclerView嵌套RecyclerView 时自动滑动的bug修复。
问题描述
子recyclerView 是一个Grid布局对象。 当子布局有值的时候,列表会自动滑动将子recyclerView 全部显示全。然后会造成整个列表每次进去的时候不是在顶部,会往下滑动一段距离。
解决方案
在最外层的RecyclerView 添加下面的属性。当然也可以写在xml布局中。但是我的布局是一个全局公用的属性,所以在代码上写了。
recyclerView.setFocusableInTouchMode(false);