Android源码初探之ListView 的 smoothScrollByOffset()
2017-01-13 17:56
591 查看
剧情:
前几天参加了去哪儿网的泛前段的分享会,谈的大多是去哪儿网对FaceBook的ReactNative的优化。谈到ListView的优化问题,大致意思是reactnative在不知道控件高度的情况下不容易直接根据Position找到控件的位置。不嫌事大的小伙伴问了个问题:
请问原声的Android是如何根据Position找到ListView的位置的呢?
答曰:
原声是可以直接根据位置找到的。
全场:嗯嗯嗯嗯~。
宝宝第一个不服,我就不感觉原声有这么厉害。
看了下ListView的方法,大概大神们说的是这个方法。
第一层的smoothScrollByOffset(int offset)仅仅是super了一下父类的方法。
里面是什么呢?
大致意思是让一个比较远的View滚动到一个相对的位置。这个方法还是只进行了一些判断,包括上划下滑,最后一个可见区域如果不足百分之75 就取消掉等等。在进去一层。
貌似终于要开始滑动了。
再进去一层。
结合动画的源码,大致可以看出来,绝对不是不需要计算的,在源码中计算了每此需要滑动的距离,剩余的距离,滑动一格的时间,并且递归调用,直到到了指定的位置为止。
4000
前几天参加了去哪儿网的泛前段的分享会,谈的大多是去哪儿网对FaceBook的ReactNative的优化。谈到ListView的优化问题,大致意思是reactnative在不知道控件高度的情况下不容易直接根据Position找到控件的位置。不嫌事大的小伙伴问了个问题:
请问原声的Android是如何根据Position找到ListView的位置的呢?
答曰:
原声是可以直接根据位置找到的。
全场:嗯嗯嗯嗯~。
宝宝第一个不服,我就不感觉原声有这么厉害。
看了下ListView的方法,大概大神们说的是这个方法。
listview.smoothScrollToPosition(int position);
第一层的smoothScrollByOffset(int offset)仅仅是super了一下父类的方法。
public void smoothScrollByOffset(int offset) { super.smoothScrollByOffset(offset); }
里面是什么呢?
/** * Allows RemoteViews to scroll relatively to a position. */ void smoothScrollByOffset(int position) { int index = -1; if (position < 0) { index = getFirstVisiblePosition();//获取第一个可见的位置 } else if (position > 0) { index = getLastVisiblePosition(); } if (index > -1) { View child = getChildAt(index - getFirstVisiblePosition()); if (child != null) { Rect visibleRect = new Rect();//声明一个矩形 if (child.getGlobalVisibleRect(visibleRect)) { // the child is partially visible int childRectArea = child.getWidth() * child.getHeight(); int visibleRectArea = visibleRect.width() * visibleRect.height(); float visibleArea = (visibleRectArea / (float) childRectArea); final float visibleThreshold = 0.75f; if ((position < 0) && (visibleArea < visibleThreshold)) { // the top index is not perceivably visible so offset // to account for showing that top index as well ++index; } else if ((position > 0) && (visibleArea < visibleThreshold)) { // the bottom index is not perceivably visible so offset // to account for showing that bottom index as well --index; } } smoothScrollToPosition(Math.max(0, Math.min(getCount(), index + position))); } } }
大致意思是让一个比较远的View滚动到一个相对的位置。这个方法还是只进行了一些判断,包括上划下滑,最后一个可见区域如果不足百分之75 就取消掉等等。在进去一层。
public void smoothScrollToPosition(int position) { if (mPositionScroller == null) { mPositionScroller = createPositionScroller(); } mPositionScroller.start(position); }
貌似终于要开始滑动了。
再进去一层。
@Override public void start(final int position) { stop(); if (mDataChanged) { // Wait until we're back in a stable state to try this. mPositionScrollAfterLayout = new Runnable() { @Override public void run() { start(position); } }; return; } final int childCount = getChildCount(); if (childCount == 0) { // Can't scroll without children. return; } final int firstPos = mFirstPosition; final int lastPos = firstPos + childCount - 1; int viewTravelCount; int clampedPosition = Math.max(0, Math.min(getCount() - 1, position)); if (clampedPosition < firstPos) { viewTravelCount = firstPos - clampedPosition + 1; mMode = MOVE_UP_POS; } else if (clampedPosition > lastPos) { viewTravelCount = clampedPosition - lastPos + 1; mMode = MOVE_DOWN_POS; } else { scrollToVisible(clampedPosition, INVALID_POSITION, SCROLL_DURATION); return; } if (viewTravelCount > 0) { mScrollDuration = SCROLL_DURATION / viewTravelCount; } else { mScrollDuration = SCROLL_DURATION; } mTargetPos = clampedPosition; mBoundPos = INVALID_POSITION; mLastSeenPos = INVALID_POSITION; postOnAnimation(this); }
结合动画的源码,大致可以看出来,绝对不是不需要计算的,在源码中计算了每此需要滑动的距离,剩余的距离,滑动一格的时间,并且递归调用,直到到了指定的位置为止。
4000
相关文章推荐
- 【Android 一般进阶】ListView滑动到顶部smoothScrollToPosition
- android ScrollView smoothScrollTo源码分析
- android listView.smoothScrollToPositionFromTop
- ListView scrollListBy.smoothScrollBy不能滚动问题
- AbsListView android:smoothScrollbar
- 笔记6 | 从源码理解分析mScrollX和mScrollY,scrollTo()和scrollBy(),smoothScrollTo和smoothScrollBy
- Android ListView Fast and Smooth Scroll 終極秘技
- android中listview调用setSelection(position)或者smoothScrollToPosition(position)不起作用
- AbsListView android:smoothScrollbar
- 【Android 一般进阶】ListView滑动到顶部smoothScrollToPosition
- android ListView中一些源码测试程序
- 在android里用ExpandableListView实现二层和三层列表源码
- android listview scrollview auto adapter ui
- android源码解析--ListView(上)
- 在android里用ExpandableListView实现二层和三层列表源码
- android2.2源码初探
- android之ScrollView里嵌套ListView
- Android ListView圆角列表完整(附源码)
- Android的ListView异步下载图片官方提供的源码
- android之ScrollView里嵌套ListView(转)