在需求开发迭代时,总是会遇到一些特定的交互功能的实现。
一,获取可见的Item下标
功能开发时,有时需要滑动到指定的下标或滑动到屏幕底部或头部时,会想到获取当前可见的item下标进行进行处理。
//获取第一个可见的Item下标
layoutManager.findFirstCompletelyVisibleItemPosition()
//获取最后一个可见的Item下标
layoutManager.findLastCompletelyVisibleItemPosition()
主要使用了RecyclerView的LayoutManager获取第一个和最后一个可见的Item下标
二,ItemDecorationCount
使用RecyclerView嵌套RecyclerView时,如果给子RecyclerView添加了ItemDecoration后,页面下拉刷新等一些操作时,会发现列表的间距不断的变宽,这是因为RecyclerView对Item的复用导致的,这时就需要使用ItemDecorationCount进行判断,防止重复的添加ItemDecoration。
//判断RecyclerView是否添加分界线,不加此判断,下拉刷新时,间距会不停的重复添加导致间距变大
if (recyclerView.itemDecorationCount==0){
//添加自定义分割线或间距
}
三,Item滑动居中
实现选项列表时,有些场景下会要求选中的Item居中,就需要自己自定义LayoutManager进行实现,如下:
import android.content.Context;
import android.util.DisplayMetrics;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.LinearSmoothScroller;
import androidx.recyclerview.widget.RecyclerView;
public class CenterLinearLayoutManager extends LinearLayoutManager {
static int lastPosition = 0;
static int targetPosition = 0;
public CenterLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
}
@Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
CenterSmoothScroller smoothScroller = new CenterSmoothScroller(recyclerView.getContext());
smoothScroller.setTargetPosition(position);
startSmoothScroll(smoothScroller);
}
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int lastPosition, int position) {
lastPosition = lastPosition;
targetPosition = position;
smoothScrollToPosition(recyclerView, state, position);
}
public static class CenterSmoothScroller extends LinearSmoothScroller {
private static float duration = 400f;
public CenterSmoothScroller(Context context) {
super(context);
}
@Override
public int calculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int snapPreference) {
return (boxStart + (boxEnd - boxStart) / 2) - (viewStart + (viewEnd - viewStart) / 2);
}
@Override
protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
float newDuration = duration / (Math.abs(targetPosition - lastPosition));
return newDuration / displayMetrics.densityDpi;
}
@Override
protected int calculateTimeForScrolling(int dx) {
return super.calculateTimeForScrolling(dx);
}
}
}
使用时
1)创建自定义的LayoutManager
private val centerLayoutManager by lazy {
CenterLinearLayoutManager(
activity,
LinearLayoutManager.HORIZONTAL,
false
)
}
2)滑动到指定下标
centerLayoutManager.smoothScrollToPosition(
recyclerView,
RecyclerView.State(),
position //指定的下标
)
在有些场景下需要结合一中的获取第一个和最后一个可见的下标,计算出屏幕中间的item下标做一些交互处理。