当前位置: 首页 > news >正文

字体中国设计网百度优化

字体中国设计网,百度优化,建筑企业资质,网站名称设置目录 一、滑动到指定位置(target position)并且置顶 1. RecycleView默认的几个实现方法及缺陷 2. 优化源码实现置顶方案 二、调整平移滑动速率 三、其他方案:置顶、置顶加偏移、居中 1. 其他置顶方案 2. 置顶加偏移 3. 滚动居中 在实…

目录

一、滑动到指定位置(target position)并且置顶

1. RecycleView默认的几个实现方法及缺陷

2. 优化源码实现置顶方案

二、调整平移滑动速率

三、其他方案:置顶、置顶加偏移、居中

1. 其他置顶方案

2. 置顶加偏移

3. 滚动居中


    在实际项目里,RecycleView 可以说是我们最常用到的组件,作为绑定并展示LIST数据的组件,经常需要实现平滑滚动到列表里的某个目标ITEM,并且将其置顶在屏幕最上方,而且在特殊情形下,我们需要控制滑动速度,来控制滚动的时长。

一、滑动到指定位置(target position)并且置顶

1. RecycleView默认的几个实现方法及缺陷

((LinearLayoutManager)recycleView.getLayoutManager()).scrollToPositionWithOffset(int position, int offset);

    如果你没有滑动过程动画的要求,那上面这行代码将offset的值设置为0,就一步到位地满足需求了。

recycleView.scrollToPosition(int position);
recycleView.smoothScrollToPosition(int position);

    以上两个方法遵循的是最少滑动原则,只要target position那项item已经完全可见了,就马上停止滑动;要是target position已经可见了,那根本不会滑动。所以按不同的滑动方向,会出现不同的结果,如果target position在屏幕可视范围的上方,则它默认会将target position置顶;反之,target position在屏幕可视范围的下方,则滚动完成后,target postion会处于屏幕的最下方,无法实现我们的置顶需求。所以缺陷很明显:要么不动,要么无法置顶

2. 优化源码实现置顶方案

    我们看下recycleview提供的方法的源代码,看看是否可以进行改进:

    public void smoothScrollToPosition(int position) {if (mLayoutSuppressed) {return;}if (mLayout == null) {Log.e(TAG, "Cannot smooth scroll without a LayoutManager set. "+ "Call setLayoutManager with a non-null argument.");return;}mLayout.smoothScrollToPosition(this, mState, position);}

    由代码可以看出,RecyclerView的滑动方法是调用LayoutManager的smoothScrollToPosition方法:

    @Overridepublic void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state,int position) {LinearSmoothScroller linearSmoothScroller =new LinearSmoothScroller(recyclerView.getContext());linearSmoothScroller.setTargetPosition(position);startSmoothScroll(linearSmoothScroller);}

    其中LinearSmoothScroller提供了三个滑动策略:

    /*** Align child view's left or top with parent view's left or top** @see #calculateDtToFit(int, int, int, int, int)* @see #calculateDxToMakeVisible(android.view.View, int)* @see #calculateDyToMakeVisible(android.view.View, int)*/public static final int SNAP_TO_START = -1;/*** Align child view's right or bottom with parent view's right or bottom** @see #calculateDtToFit(int, int, int, int, int)* @see #calculateDxToMakeVisible(android.view.View, int)* @see #calculateDyToMakeVisible(android.view.View, int)*/public static final int SNAP_TO_END = 1;/*** <p>Decides if the child should be snapped from start or end, depending on where it* currently is in relation to its parent.</p>* <p>For instance, if the view is virtually on the left of RecyclerView, using* {@code SNAP_TO_ANY} is the same as using {@code SNAP_TO_START}</p>** @see #calculateDtToFit(int, int, int, int, int)* @see #calculateDxToMakeVisible(android.view.View, int)* @see #calculateDyToMakeVisible(android.view.View, int)*/public static final int SNAP_TO_ANY = 0;

    LinearSmoothScroller确定滑动方案的方法:

    /*** When scrolling towards a child view, this method defines whether we should align the top* or the bottom edge of the child with the parent RecyclerView.** @return SNAP_TO_START, SNAP_TO_END or SNAP_TO_ANY; depending on the current target vector* @see #SNAP_TO_START* @see #SNAP_TO_END* @see #SNAP_TO_ANY*/protected int getVerticalSnapPreference() {return mTargetVector == null || mTargetVector.y == 0 ? SNAP_TO_ANY :mTargetVector.y > 0 ? SNAP_TO_END : SNAP_TO_START;}

    重写LinearSmoothScroller的getVerticalSnapPreference方法:

class LinearTopSmoothScroller extends LinearSmoothScroller {public LinearTopSmoothScroller(Context context) {super(context);}@Overrideprotected int getVerticalSnapPreference() {return SNAP_TO_START;}}

    这里为什么返回 SNAP_TO_START?可以看到LinearSmoothScrollerl的方法calculateDtToFit()根据不同滚动策略获取到需要滚动的距离,SNAP_TO_START是按置顶的方案来计算的。所以我们在getVerticalSnapPreference方法里固定返回SNAP_TO_START就可以实现目的。

public int calculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, intsnapPreference) {switch (snapPreference) {case SNAP_TO_START:return boxStart - viewStart;case SNAP_TO_END:return boxEnd - viewEnd;case SNAP_TO_ANY:final int dtStart = boxStart - viewStart;if (dtStart > 0) {return dtStart;}final int dtEnd = boxEnd - viewEnd;if (dtEnd < 0) {return dtEnd;}break;default:throw new IllegalArgumentException("snap preference should be one of the"+ " constants defined in SmoothScroller, starting with SNAP_");}return 0;}

    调用方式一

    void scrollItemToTop(int position) {LinearSmoothScroller smoothScroller = new LinearTopSmoothScroller(this);smoothScroller.setTargetPosition(position);linearLayoutManager.startSmoothScroll(smoothScroller);}

    调用方式二

    自定义一个类继承自 LinearLayoutManager:

private class TopLayoutManager extends LinearLayoutManager {public TopLayoutManager(Context context) {super(context);}public TopLayoutManager(Context context, int orientation, boolean reverseLayout) {super(context, orientation, reverseLayout);}@Overridepublic void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {RecyclerView.SmoothScroller smoothScroller = new LinearTopSmoothScroller(recyclerView.getContext());smoothScroller.setTargetPosition(position);startSmoothScroll(smoothScroller);}private class LinearTopSmoothScroller extends LinearSmoothScroller {public LinearTopSmoothScroller(Context context) {super(context);}@Overrideprotected int getVerticalSnapPreference() {return SNAP_TO_START;}}
}

    调用代码:

TopLayoutManager topLayoutManager = new TopLayoutManager(this);
recycleview.setLayoutManager(topLayoutManager);
recycleview.smoothScrollToPosition(position);

二、调整平移滑动速率

    同理,可以在LinearSmoothScroller类找到决定滚动速度的方法并修改。

    /*** Calculates the scroll speed.** @param displayMetrics DisplayMetrics to be used for real dimension calculations* @return The time (in ms) it should take for each pixel. For instance, if returned value is* 2 ms, it means scrolling 1000 pixels with LinearInterpolation should take 2 seconds.*/protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {return MILLISECONDS_PER_INCH / displayMetrics.densityDpi;}

    上面的MILLISECONDS_PER_INCH的值为25F,如果希望更快可以将值改小,这个方法的返回值表示滚动一个像素需要的时间,单位ms,如果返回值为2ms,表示滚动1000个像素需要花费2秒时长。

    平滑滚动到target position,【置顶+调速】的调用方式:

        RecyclerView.SmoothScroller smoothScroller = new LinearSmoothScroller(this) {@Override protected int getVerticalSnapPreference() {return LinearSmoothScroller.SNAP_TO_START;}@Overrideprotected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {//默认值是25F(MILLISECONDS_PER_INCH),值越小滑动速度越快,值越大则越慢return 100F / displayMetrics.densityDpi;}};smoothScroller.setTargetPosition(position);linearLayoutManager.startSmoothScroll(smoothScroller);

    目前还有一个问题,虽然我们可以调整速度,但是这里始终是一个固定的滚动速度,试想如果滚动的距离特别远,仍然需要滚动很长的时间;又或者滚动距离太近,那么滚动动画一瞬间就结束了,缺少了流畅感。

    所以我们可以根据需要滚动的远或近来设置不同的滚动速度:

        RecyclerView.SmoothScroller smoothScroller = new LinearSmoothScroller(this) {@Override protected int getVerticalSnapPreference() {return LinearSmoothScroller.SNAP_TO_START;}@Overrideprotected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {// 第一个可见位置int firstItem = linearLayoutManager.findFirstVisibleItemPosition();int diff = Math.abs(position - firstItem);// 将 diff 作分母:滚动距离越远,速度越快。 (100f/diff) 数值如果过小会导致速度过快, 可以再乘一个速度因子变量(speedFactor)来调整int speedFactor = 5;float speed = (100f / diff) * speedFactor;return speed / displayMetrics.densityDpi;}};

三、其他方案:置顶、置顶加偏移、居中

1. 其他置顶方案

    另外一个实现置顶方案:可以参考这篇文章,Android RecyclerView滚动定位 ,它主要解决的是滚动到屏幕下面ITEM,无法置顶的问题,思路是:先用scrollToPosition,将要置顶的项先移动显示出来,然后计算这一项离顶部的距离,用scrollBy完成最后的100米!

    这个方案还有个好处就是,如果target position很远(滑动距离很长),也不会导致屏幕滚动过长的时间。向上向下动态滚动(动画过程)距离都不超过一个屏幕的距离。

2. 置顶加偏移

     另外,如果希望置顶后,可以有一定的偏移量(离顶部有一定距离),可以参考这篇文章:

RecyclerView的smooth scroller -- 诸多案例

3. 滚动居中

    如果希望target position在滚动结束后,停留在屏幕中间,可以参考下这篇文章:

RecyclerView smoothScroll to position in the center. android

http://www.ds6.com.cn/news/110971.html

相关文章:

  • 在北京网站建设的岗位职责seo是什么味
  • wordpress耗内存搜索引擎优化案例分析
  • 个人兼职做建设网站学校教育培训机构
  • 中国建筑网官网登录平台广州网站运营专业乐云seo
  • 凡科做的网站好垃圾吴忠seo
  • 济南建站网站网站制作公司官网
  • 怎么做网站策划的模板上海百度推广优化
  • 阿里云网站地图是怎么做的网络流量分析工具
  • 应用网站制作搜索引擎排行榜
  • 湘潭网站开发莱芜seo
  • 万网的怎么做网站地图微信推广平台收费标准
  • 才做的网站怎么搜不到seo工作内容
  • 苏州网站建设师百度排名
  • 让iis做跳转网站c++培训班学费一般多少
  • 页面设计所遵循的原则有哪些厦门seo小谢
  • 网站编程开发中国培训网是国家公认的吗
  • 淘宝网站建设目标是什么意思网上做推广怎么收费
  • 网站横幅图片网站怎么优化关键词
  • 唐山有制作网站的没苏州seo网站管理
  • 网站 创意 方案杭州网站推广大全
  • 做网站必须花钱吗网站seo是什么意思
  • 外贸移动端网站模板seo关键字怎么优化
  • 怎样用flash做游戏下载网站广告推广方案怎么写
  • 网站报价怎么做5118素材网站
  • 山东省住房与建设厅网站首页写软文
  • 润滑油手机网站模板谷歌play商店
  • 青海网站制作多少钱seo网站推广是什么意思
  • 为什么要立刻做网站百度推广费用可以退吗
  • 免费自助建站自助建站平台网络推广公司企业
  • 2023国际新闻热点事件湘潭网站seo