Code example for AbsListView

Methods: getAdapter, getWidth, requestDisallowInterceptTouchEvent

0
			// Fall through 
		case STATE_DRAGGING:
			mHandler.removeCallbacks(mScrollFade);
			break; 
		case STATE_EXIT:
			int viewWidth = mList.getWidth();
			doInvalidate(viewWidth - mThumbW, mThumbY, viewWidth, mThumbY + mThumbH);
			break; 
		} 
		mState = state;
		refreshDrawableState(); 
	} 
 
	public int getState() { 
		return mState;
	} 
 
	/** 
	 * Updates the section list. Should be called from the adapter when the data is invalidated or 
	 * changed. 
	 *  
	 * @param resetDragging 
	 *            True to reset current dragging state, false to keep dragging. Depending on how 
	 *            much the underlying data changed, preserving the drag state may or may not be 
	 *            confusing to the user. It's up to the application to make that decision and call 
	 *            with the correct resetDraggging value. 
	 */ 
	public void updateSections(boolean resetDragging) {
		mListAdapter = null;
		if (mFastScrollEnabled) {
			if (mList != null) {
				getSectionsFromIndexer(); 
 
				if (resetDragging) {
					if (mState == STATE_DRAGGING) {
						mList.requestDisallowInterceptTouchEvent(false);
						setState(STATE_VISIBLE);
						final Handler handler = mHandler;
						handler.removeCallbacks(mScrollFade);
						if (!mAlwaysShow) {
							handler.postDelayed(mScrollFade, FADE_TIMEOUT);
						} 
						doInvalidate(); 
					} 
				} 
			} 
		} 
	} 
 
	@Override 
	public void refreshDrawableState() { 
		int[] state = mState == STATE_DRAGGING ? PRESSED_STATES : DEFAULT_STATES;
 
		if (mThumbDrawable != null && mThumbDrawable.isStateful()) {
			mThumbDrawable.setState(state);
		} 
	} 
 
	@Override 
	public void onChildViewAdded(View parent, View child) {
		if (child instanceof AbsListView) {
			initListView((AbsListView) child);
		} 
	} 
 
	@Override 
	public void onChildViewRemoved(View parent, View child) {
		if (child == mList) {
			mList = null;
			mListAdapter = null;
			mSections = null;
		} 
	} 
 
	@Override 
	public void draw(Canvas canvas) {
		super.draw(canvas);
 
		if (mState == STATE_NONE || !mFastScrollEnabled) {
			// No need to draw anything 
			return; 
		} 
 
		final int y = mThumbY;
		final int viewWidth = mList.getWidth();
		final int viewHeight = mList.getHeight();
		final ScrollFade scrollFade = mScrollFade;
 
		int alpha = -1;
		if (mState == STATE_EXIT) {
			alpha = scrollFade.getAlpha();
			if (alpha < ScrollFade.ALPHA_MAX / 2) {
				mThumbDrawable.setAlpha(alpha * 2);
			} 
			int left = viewWidth - (mThumbW * alpha) / ScrollFade.ALPHA_MAX;
			mThumbDrawable.setBounds(left, 0, left + mThumbW, mThumbH);
			mChangedBounds = true;
		} 
 
		canvas.translate(0, y);
		mThumbDrawable.draw(canvas);
		canvas.translate(0, -y);
 
		// If user is dragging the scroll bar, draw the alphabet overlay 
		if (mState == STATE_DRAGGING && mDrawOverlay) {
			if (mOverlayPosition == OVERLAY_AT_THUMB) {
				int left = Math.max(0, viewWidth - mThumbW - mOverlayW);
				int top = Math.max(0, Math.min(y + (mThumbH - mOverlayH) / 2, viewHeight - mOverlayH));
 
				final RectF pos = mOverlayPos;
				pos.left = left;
				pos.right = pos.left + mOverlayW;
				pos.top = top;
				pos.bottom = pos.top + mOverlayH;
				if (mOverlayDrawable != null) {
					mOverlayDrawable.setBounds((int) pos.left, (int) pos.top, (int) pos.right, (int) pos.bottom);
				} 
			} 
			mOverlayDrawable.draw(canvas);
			final Paint paint = mPaint;
			float ascent = paint.ascent();
			float descent = paint.descent();
			final RectF rectF = mOverlayPos;
			final Rect tmpRect = mTmpRect;
			mOverlayDrawable.getPadding(tmpRect);
			final int hOff = (tmpRect.right - tmpRect.left) / 2;
			final int vOff = (tmpRect.bottom - tmpRect.top) / 2;
			canvas.drawText(mSectionText, (int) (rectF.left + rectF.right) / 2 - hOff, (int) (rectF.bottom + rectF.top)
					/ 2 - (ascent + descent) / 2 - vOff, paint);
		} else if (mState == STATE_EXIT) {
			if (alpha == 0) { // Done with exit
				setState(STATE_NONE);
			} else { 
				doInvalidate(viewWidth - mThumbW, y, viewWidth, y + mThumbH);
			} 
		} 
	} 
 
	@Override 
	public void onSizeChanged(int w, int h, int oldw, int oldh) {
		super.onSizeChanged(w, h, oldw, oldh);
 
		if (mThumbDrawable != null) {
			mThumbDrawable.setBounds(w - mThumbW, 0, w, mThumbH);
		} 
		if (mOverlayPosition == OVERLAY_FLOATING) {
			final RectF pos = mOverlayPos;
			pos.left = (w - mOverlayW) / 2;
			pos.right = pos.left + mOverlayW;
			pos.top = h / 10; // 10% from top
			pos.bottom = pos.top + mOverlayH;
			if (mOverlayDrawable != null) {
				mOverlayDrawable.setBounds((int) pos.left, (int) pos.top, (int) pos.right, (int) pos.bottom);
			} 
		} 
	} 
 
	@Override 
	public void onScrollStateChanged(AbsListView view, int scrollState) {
	} 
 
	@Override 
	public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
		updateScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
	} 
 
	private void updateScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
		// Are there enough pages to require fast scroll? Recompute only if 
		// total count changes 
		if (mItemCount != totalItemCount && visibleItemCount > 0) {
			mItemCount = totalItemCount;
			mLongList = mItemCount / visibleItemCount >= MIN_PAGES;
		} 
		if (mAlwaysShow) {
			mLongList = true;
		} 
		if (!mLongList) {
			if (mState != STATE_NONE) {
				setState(STATE_NONE);
			} 
			return; 
		} 
 
		if (totalItemCount - visibleItemCount > 0 && mState != STATE_DRAGGING) {
			final int viewWidth = mList.getWidth();
			doInvalidate(viewWidth - mThumbW, mThumbY, viewWidth, mThumbY + mThumbH);
 
			mThumbY = getThumbPositionForListPosition(firstVisibleItem, visibleItemCount, totalItemCount);
 
			doInvalidate(viewWidth - mThumbW, mThumbY, viewWidth, mThumbY + mThumbH);
 
			if (mChangedBounds) {
				resetThumbPos(); 
				mChangedBounds = false;
			} 
		} 
		mScrollCompleted = true;
		if (firstVisibleItem == mVisibleItem) {
			return; 
		} 
		mVisibleItem = firstVisibleItem;
		if (mState != STATE_DRAGGING) {
			setState(STATE_VISIBLE);
			final Handler handler = mHandler;
			handler.removeCallbacks(mScrollFade);
			if (!mAlwaysShow) {
				handler.postDelayed(mScrollFade, FADE_TIMEOUT);
			} 
		} 
	} 
 
	private void setThumbDrawable(Drawable drawable) {
		mThumbDrawable = drawable;
		if (drawable instanceof NinePatchDrawable) {
			Resources res = getResources();
			mThumbW = res.getDimensionPixelSize(R.dimen.fastscroll_thumb_width);
			mThumbH = res.getDimensionPixelSize(R.dimen.fastscroll_thumb_height);
		} else { 
			mThumbW = drawable.getIntrinsicWidth();
			mThumbH = drawable.getIntrinsicHeight();
		} 
		mChangedBounds = true;
	} 
 
	private void resetThumbPos() { 
		final int viewWidth = mList.getWidth();
		mThumbDrawable.setBounds(viewWidth - mThumbW, 0, viewWidth, mThumbH);
		mThumbDrawable.setAlpha(ScrollFade.ALPHA_MAX);
	} 
 
	private void getSectionsFromIndexer() { 
		Adapter adapter = mList.getAdapter();
		mSectionIndexer = null;
 
		if (!mFastScrollEnabled) {
			mListAdapter = (BaseAdapter) adapter;
			mSections = new String[] { " " };