1.SwipeToLoadLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
<com.aspsine.swipetoloadlayout.SwipeToLoadLayout
android:id="@+id/swipeToLoadLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/transparent"
app:swipe_style="above">
<android.support.v7.widget.RecyclerView
android:id="@id/swipe_target"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/transparent"
android:clipToPadding="false" />
</com.aspsine.swipetoloadlayout.SwipeToLoadLayout>
clipToPadding = false 滑动时忽略toppadding设置。默认true
int firstVisiblePostion = layoutManager.findFirstVisibleItemPosition();
int lastVisiblePosition = layoutManager.findLastVisibleItemPosition();
//adapter
//onBindViewHolder
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
int type = getItemViewType(holder.getLayoutPosition());
switch (type) {
case TYPE_ONE:
onBindTypeOneHolder((ViewPagerHolder) holder);
break;
case TYPE_HEADERINFO:
onBindHeaderInfoHolder((HeaderInfoHolder) holder);
break;
case TYPE_WORKITEM_PIC:
onBindWorkItemPicHolder((WorkItemPic) holder);
break;
case TYPE_WORKITEM_VIDEO:
onBindWorkItemVideoHolder((WorkItemVideo) holder);
break;
//TODO ADD OTHER TYPE
}
}
//onCreateViewHolder
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView;
switch (viewType) {
case TYPE_BANNER:
itemView = inflate(parent, R.layout.layout_viewpager_px_banner);
ViewGroup.LayoutParams params = itemView.getLayoutParams();
params.width = bannerWidth;
params.height = bannerHeight;
itemView.setLayoutParams(params);
return new ViewPagerHolder(itemView);
case TYPE_HEADERINFO:
itemView = inflate(parent, R.layout.layout_px_headerinfo);
return new HeaderInfoHolder(itemView);
case TYPE_WORKITEM_PIC:
itemView = inflate(parent, R.layout.layout_px_workitem_pic);
return new WorkItemPic(itemView);
case TYPE_WORKITEM_VIDEO:
itemView = inflate(parent, R.layout.layout_px_workitem_video);
return new WorkItemVideo(itemView);
case TYPE_WORKITEM_AUDIO:
itemView = inflate(parent, R.layout.layout_px_workitem_audio);
return new WorkItemAudio(itemView);
case TYPE_WORKITEM_OFFICE:
itemView = inflate(parent, R.layout.layout_px_workitem_office);
return new WorkItemOffice(itemView);
case TYPE_WORKITEM_OTHER:
itemView = inflate(parent, R.layout.layout_px_workitem_other);
return new WorkItemOther(itemView);
}
throw new IllegalArgumentException("WRONG TYPE");
}
//getItemViewType
@Override
public int getItemViewType(int position) {
if (position == 0) {
return TYPE_BANNER;
} else if (position == 1) {
return TYPE_HEADERINFO;
} else {
//return others
}
}
//static ViewHolder
static class WorkItemBasic extends RecyclerView.ViewHolder {
TextView tvNumb, tvName, tvOrgName;
View parentView;
public WorkItemBasic(View itemView) {
super(itemView);
tvNumb = (TextView) itemView.findViewById(R.id.tv_numb);
tvName = (TextView) itemView.findViewById(R.id.tv_name);
tvOrgName = (TextView) itemView.findViewById(R.id.tv_orgname);
parentView = itemView.findViewById(R.id.layout_parent);
}
}
private void initRecyclerView() {
// layoutManager = new LinearLayoutManager(this);
//快速滑动
layoutManager = new FastScrollLinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
//分割线
datuDivider = new RecycleViewDivider(
this, LinearLayoutManager.VERTICAL, Utils.dip2px(this, 12), getResources().getColor(R.color.chatbgcolor), new int[]{0, 1});
recyclerView.addItemDecoration(datuDivider);
//item变更动画。itemChange 图片明暗闪烁处理
recyclerView.setItemAnimator(new PxRecyclerViewItemAnimation());
mAdapter = new RecyclerPxAdapter(this);
recyclerView.setAdapter(mAdapter);
recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
//滑动停止
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
int firstVisiblePostion = layoutManager.findFirstVisibleItemPosition();
isFastScrollTop = false;
if (firstVisiblePostion > 15) {
changeCenterContent("回到顶部");
} else {
changeCenterContent("");
}
if (!ViewCompat.canScrollVertically(recyclerView, 1)) {
DebugUtils.error("onScrollStateChanged 到达底部了");
// }
if (!ViewCompat.canScrollVertically(recyclerView, -1)) {
// DebugUtils.error("onScrollStateChanged 到达顶部了");
}
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
DebugUtils.error("评选之onScrolled dx :" + dx + " dy : " + dy);
int firstVisiblePostion = layoutManager.findFirstVisibleItemPosition();
if (dy >= 0) {
//向上滑动
} else {
if (firstVisiblePostion == 0) {
//向下滑动至顶部
} else if (dy < -100) {
//向下滑动速度超过100
}
}
}
});
}
//正在滚动
public static final int SCROLL_STATE_IDLE = 0;
//正在被外部拖拽,一般为用户正在用手指滚动
public static final int SCROLL_STATE_DRAGGING = 1;
//自动滚动开始
public static final int SCROLL_STATE_SETTLING = 2;
//快速滑动
public class FastScrollLinearLayoutManager extends LinearLayoutManager {
public FastScrollLinearLayoutManager(Context context) {
super(context);
}
public FastScrollLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
}
public FastScrollLinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
LinearSmoothScroller linearSmoothScroller = new LinearSmoothScroller(recyclerView.getContext()) {
@Override
public PointF computeScrollVectorForPosition(int targetPosition) {
return FastScrollLinearLayoutManager.this.computeScrollVectorForPosition(targetPosition);
}
//控制速度。
@Override
protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
return super.calculateSpeedPerPixel(displayMetrics);
}
@Override
protected int calculateTimeForScrolling(int dx) {
//控制滑动距离和滑动时间的关系
if (dx < 3000) {
dx = 3000;
}
if (dx > 5000) {
dx = 5000;
}
int time = super.calculateTimeForScrolling(dx);
return time;
}
};
linearSmoothScroller.setTargetPosition(position);
startSmoothScroll(linearSmoothScroller);
}
}
recyclerView.smoothScrollToPosition(0);
//自定义分割线
//可以指定位置不要绘制
public class RecycleViewDivider extends RecyclerView.ItemDecoration {
private Paint mPaint;
private Drawable mDivider;
private int mDividerHeight = 2;//分割线高度,默认为1px
private int mOrientation;//列表的方向:LinearLayoutManager.VERTICAL或LinearLayoutManager.HORIZONTAL
private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
private int[] noNeedDividePoss;
/**
* 默认分割线:高度为2px,颜色为灰色
*
* @param context
* @param orientation 列表方向
*/
public RecycleViewDivider(Context context, int orientation) {
if (orientation != LinearLayoutManager.VERTICAL && orientation != LinearLayoutManager.HORIZONTAL) {
throw new IllegalArgumentException("请输入正确的参数!");
}
mOrientation = orientation;
final TypedArray a = context.obtainStyledAttributes(ATTRS);
mDivider = a.getDrawable(0);
a.recycle();
}
/**
* 自定义分割线
*
* @param context
* @param orientation 列表方向
* @param drawableId 分割线图片
*/
public RecycleViewDivider(Context context, int orientation, int drawableId) {
this(context, orientation);
mDivider = ContextCompat.getDrawable(context, drawableId);
mDividerHeight = mDivider.getIntrinsicHeight();
}
/**
* 自定义分割线
*
* @param context
* @param orientation 列表方向
* @param dividerHeight 分割线高度
* @param dividerColor 分割线颜色
*/
public RecycleViewDivider(Context context, int orientation, int dividerHeight, int dividerColor) {
this(context, orientation);
mDividerHeight = dividerHeight;
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(dividerColor);
mPaint.setStyle(Paint.Style.FILL);
}
public RecycleViewDivider(Context context, int orientation, int dividerHeight, int dividerColor, int[] noNeedDividePoss) {
this(context, orientation, dividerHeight, dividerColor);
this.noNeedDividePoss = noNeedDividePoss;
}
private boolean isContain(int pos, RecyclerView parent) {
if (noNeedDividePoss != null && noNeedDividePoss.length > 0) {
for (int i = 0; i < noNeedDividePoss.length; i++) {
if (noNeedDividePoss[i] == pos)
return true;
}
}
if (pos == parent.getAdapter().getItemCount() - 1)
return true;
return false;
}
//获取分割线尺寸
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
int childAdapterPosition = parent.getChildAdapterPosition(view);
if (isContain(childAdapterPosition,parent) && mOrientation == LinearLayoutManager.VERTICAL) {
DebugUtils.error("px divide noneed show pos :" + childAdapterPosition);
outRect.set(0, 0, 0, 0);
return;
}
if (mOrientation == LinearLayoutManager.HORIZONTAL) {
outRect.set(0, 0, mDividerHeight, 0);
} else {
outRect.set(0, 0, 0, mDividerHeight);
}
}
//绘制分割线
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDraw(c, parent, state);
if (mOrientation == LinearLayoutManager.VERTICAL) {
drawVertical(c, parent);
} else {
drawHorizontal(c, parent);
}
}
//绘制横向 item 分割线
private void drawHorizontal(Canvas canvas, RecyclerView parent) {
final int left = parent.getPaddingLeft();
final int right = parent.getMeasuredWidth() - parent.getPaddingRight();
// final int childSize = parent.getChildCount();
final int childSize = parent.getChildCount() - 1;
for (int i = 0; i < childSize; i++) {
if (isContain(i,parent))
continue;
final View child = parent.getChildAt(i);
RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
final int top = child.getBottom() + layoutParams.bottomMargin;
final int bottom = top + mDividerHeight;
if (mDivider != null) {
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(canvas);
}
if (mPaint != null) {
canvas.drawRect(left, top, right, bottom, mPaint);
}
}
}
//绘制纵向 item 分割线
private void drawVertical(Canvas canvas, RecyclerView parent) {
final int top = parent.getPaddingTop();
final int bottom = parent.getMeasuredHeight() - parent.getPaddingBottom();
final int childSize = parent.getChildCount() - 1;
for (int i = 0; i < childSize; i++) {
if (isContain(i,parent))
continue;
final View child = parent.getChildAt(i);
RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
final int left = child.getRight() + layoutParams.rightMargin;
final int right = left + mDividerHeight;
if (mDivider != null) {
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(canvas);
}
if (mPaint != null) {
canvas.drawRect(left, top, right, bottom, mPaint);
}
}
}
}
//闪烁
https://blog.csdn.net/Scorpio_gao/article/details/53732669
闪烁主要由于RecyclerView使用的默认的动画导致的,所以解决的方法就是修改默认的动画。
首先把默认的动画(DefaultItemAnimator)代码复制到自定义的MyItemAnimator类里面。
接着找到animateChangeImpl方法修改其中的两行代码。
// 去掉alpha(0)
oldViewAnim.alpha(0).setListener(new VpaListenerAdapter() {...}).start();
oldViewAnim.setListener(new VpaListenerAdapter() {...}).start();
// 去掉alpha(1)
newViewAnimation.translationX(0).translationY(0).setDuration(getChangeDuration()).
alpha(1).setListener(new VpaListenerAdapter() {...}).start();
newViewAnimation.translationX(0).translationY(0).setDuration(getChangeDuration()).
setListener(new VpaListenerAdapter() {...}).start();
//删除item
public void removeItemPosition(int position) {
this.mList.remove(position);
notifyItemRemoved(position);
//防止被删除item位置一下的没有调用onbindview,导致对应position不一致
if (position != this.mList.size()) {
notifyItemRangeChanged(position, mList.size() - position);
}
}
//优雅的更新item
https://www.jianshu.com/p/c5ca75d3a78c
RecyclerView.ViewHolder viewHolder = mRecyclerView.findViewHolderForAdapterPosition(i);
if (viewHolder != null && viewHolder instanceof ItemHolder) {
ItemHolder itemHolder = (ItemHolder) itemHolder
itemHolder.mButton.togglestate();
}
}
Android: Cannot resolve method 'findFirstVisibleItemPosition()'?
mLayoutManager is an object of class RecyclerView.LayoutManager
is wrong, you should use
android.support.v7.widget.LinearLayoutManager
for
mLayoutManager