android联系人源码解析
源代码请从官方网站下载,本文针对源代码增加上自己的理解。
package com.android.contacts.widget; import android.content.Context; import android.util.AttributeSet; import android.widget.ListView; /** * A ListView that can be asked to scroll (smoothly or otherwise) to a specific * position. This class takes advantage of similar functionality that exists * in {@link ListView} and enhances it. * 联系人应用中自定义组件,增强了ListView的功能。 * 用于滑动到某一个位置 以及 在到达某个位置时是否平滑 */ public class AutoScrollListView extends ListView { /** * Position the element at about 1/3 of the list height */ private static final float PREFERRED_SELECTION_OFFSET_FROM_TOP = 0.33f; private int mRequestedScrollPosition = -1; private boolean mSmoothScrollRequested; public AutoScrollListView(Context context) { super(context); } public AutoScrollListView(Context context, AttributeSet attrs) { super(context, attrs); } public AutoScrollListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } /** * Brings the specified position to view by optionally performing a jump-scroll maneuver: * first it jumps to some position near the one requested and then does a smooth * scroll to the requested position. This creates an impression of full smooth * scrolling without actually traversing the entire list. If smooth scrolling is * not requested, instantly positions the requested item at a preferred offset. * 提供的一个方法,是否平滑滑动到position处 */ public void requestPositionToScreen(int position, boolean smoothScroll) { mRequestedScrollPosition = position; mSmoothScrollRequested = smoothScroll; requestLayout(); } /** * 这个方法在ListView(ListView包含了一系列的Item【项】)中用于布局ListViewItem。 */ @Override protected void layoutChildren() {//重写的ListView中的方法,这个方法,主要就是封装了ListView中的layoutChildren。 super.layoutChildren(); if (mRequestedScrollPosition == -1) { return; } final int position = mRequestedScrollPosition; mRequestedScrollPosition = -1; int firstPosition = getFirstVisiblePosition() + 1; int lastPosition = getLastVisiblePosition(); if (position >= firstPosition && position <= lastPosition) { return; // Already on screen } final int offset = (int) (getHeight() * PREFERRED_SELECTION_OFFSET_FROM_TOP); if (!mSmoothScrollRequested) { setSelectionFromTop(position, offset); // Since we have changed the scrolling position, we need to redo child layout // Calling "requestLayout" in the middle of a layout pass has no effect, // so we call layoutChildren explicitly //如果不需要平滑的滑动到position处,直接调用父类的layoutChildren方法。 super.layoutChildren(); } else { // We will first position the list a couple of screens before or after // the new selection and then scroll smoothly to it. //现在是处理平滑滑动到某个位置了,如何处理那? //我们首先需要将当前的list条目焦点设定在离要滑动的位置2屏内。为什么这么处理那? //设想一下,list有1000个条目,一屏可以存放10条条目,我们当前处在最后一屏(也就是当前显示990~1000),那么我们要平滑滑动的位置为1 //我们的listView要从990一直平滑滑动到1,这要多费功夫, //所以,直接把焦点设定在list的20处(2屏数目),然后从20位置平滑过度到1。 int twoScreens = (lastPosition - firstPosition) * 2; int preliminaryPosition; if (position < firstPosition) { preliminaryPosition = position + twoScreens; if (preliminaryPosition >= getCount()) { preliminaryPosition = getCount() - 1; } if (preliminaryPosition < firstPosition) { setSelection(preliminaryPosition); super.layoutChildren(); } } else { preliminaryPosition = position - twoScreens; if (preliminaryPosition < 0) { preliminaryPosition = 0; } if (preliminaryPosition > lastPosition) { setSelection(preliminaryPosition); super.layoutChildren(); } } smoothScrollToPositionFromTop(position, offset); } } }