diff options
| author | Alan Viverette <alanv@google.com> | 2013-10-31 15:41:31 -0700 |
|---|---|---|
| committer | Alan Viverette <alanv@google.com> | 2013-10-31 15:41:31 -0700 |
| commit | 8636ace69640566768f89c2d92d2851ff064a2e9 (patch) | |
| tree | fb901fba60c4747caebac8f084771d5742dd437e /core/java/android/widget/FastScroller.java | |
| parent | 0160bcbe531eebe882999f041348ce0182fc5bab (diff) | |
Allow styling of fast scroll decorations, add default styles
Also fixes bad old-style thumb 9-patches.
BUG: 11030706
Change-Id: I51abba952acf87586449fbda329212b435d1d6df
Diffstat (limited to 'core/java/android/widget/FastScroller.java')
| -rw-r--r-- | core/java/android/widget/FastScroller.java | 245 |
1 files changed, 141 insertions, 104 deletions
diff --git a/core/java/android/widget/FastScroller.java b/core/java/android/widget/FastScroller.java index 01ac8fdba6d0..6d38c8f3d70b 100644 --- a/core/java/android/widget/FastScroller.java +++ b/core/java/android/widget/FastScroller.java @@ -24,7 +24,6 @@ import android.animation.ObjectAnimator; import android.animation.PropertyValuesHolder; import android.content.Context; import android.content.res.ColorStateList; -import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Rect; import android.graphics.drawable.Drawable; @@ -43,7 +42,7 @@ import android.view.ViewConfiguration; import android.view.ViewGroup.LayoutParams; import android.view.ViewGroupOverlay; import android.widget.AbsListView.OnScrollListener; -import com.android.internal.R; +import android.widget.ImageView.ScaleType; /** * Helper class for AbsListView to draw and control the Fast Scroll thumb @@ -76,24 +75,6 @@ class FastScroller { /** Scroll thumb and preview being dragged by user. */ private static final int STATE_DRAGGING = 2; - /** Styleable attributes. */ - private static final int[] ATTRS = new int[] { - android.R.attr.fastScrollTextColor, - android.R.attr.fastScrollThumbDrawable, - android.R.attr.fastScrollTrackDrawable, - android.R.attr.fastScrollPreviewBackgroundLeft, - android.R.attr.fastScrollPreviewBackgroundRight, - android.R.attr.fastScrollOverlayPosition - }; - - // Styleable attribute indices. - private static final int TEXT_COLOR = 0; - private static final int THUMB_DRAWABLE = 1; - private static final int TRACK_DRAWABLE = 2; - private static final int PREVIEW_BACKGROUND_LEFT = 3; - private static final int PREVIEW_BACKGROUND_RIGHT = 4; - private static final int OVERLAY_POSITION = 5; - // Positions for preview image and text. private static final int OVERLAY_FLOATING = 0; private static final int OVERLAY_AT_THUMB = 1; @@ -115,7 +96,7 @@ class FastScroller { private final TextView mSecondaryText; private final ImageView mThumbImage; private final ImageView mTrackImage; - private final ImageView mPreviewImage; + private final View mPreviewImage; /** * Preview image resource IDs for left- and right-aligned layouts. See @@ -127,13 +108,25 @@ class FastScroller { * Padding in pixels around the preview text. Applied as layout margins to * the preview text and padding to the preview image. */ - private final int mPreviewPadding; + private int mPreviewPadding; + + private int mPreviewMinWidth; + private int mPreviewMinHeight; + private int mThumbMinWidth; + private int mThumbMinHeight; + + /** Theme-specified text size. Used only if text appearance is not set. */ + private float mTextSize; - /** Whether there is a track image to display. */ - private final boolean mHasTrackImage; + /** Theme-specified text color. Used only if text appearance is not set. */ + private ColorStateList mTextColor; + + private Drawable mThumbDrawable; + private Drawable mTrackDrawable; + private int mTextAppearance; /** Total width of decorations. */ - private final int mWidth; + private int mWidth; /** Set containing decoration transition animations. */ private AnimatorSet mDecorAnimation; @@ -245,89 +238,143 @@ class FastScroller { } }; - public FastScroller(AbsListView listView) { + public FastScroller(AbsListView listView, int styleResId) { mList = listView; - mOverlay = listView.getOverlay(); final Context context = listView.getContext(); mScaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); + mScrollBarStyle = listView.getScrollBarStyle(); + + mScrollCompleted = true; + mState = STATE_VISIBLE; + mMatchDragPosition = + context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB; + + mTrackImage = new ImageView(context); + mTrackImage.setScaleType(ScaleType.FIT_XY); + mThumbImage = new ImageView(context); + mThumbImage.setScaleType(ScaleType.FIT_XY); + mPreviewImage = new View(context); + mPreviewImage.setAlpha(0f); + + mPrimaryText = createPreviewTextView(context); + mSecondaryText = createPreviewTextView(context); + + setStyle(styleResId); - final Resources res = context.getResources(); - final TypedArray ta = context.getTheme().obtainStyledAttributes(ATTRS); + final ViewGroupOverlay overlay = listView.getOverlay(); + mOverlay = overlay; + overlay.add(mTrackImage); + overlay.add(mThumbImage); + overlay.add(mPreviewImage); + overlay.add(mPrimaryText); + overlay.add(mSecondaryText); - final ImageView trackImage = new ImageView(context); - mTrackImage = trackImage; + getSectionsFromIndexer(); + updateLongList(listView.getChildCount(), listView.getCount()); + setScrollbarPosition(listView.getVerticalScrollbarPosition()); + postAutoHide(); + } + private void updateAppearance() { + final Context context = mList.getContext(); int width = 0; // Add track to overlay if it has an image. - final Drawable trackDrawable = ta.getDrawable(TRACK_DRAWABLE); - if (trackDrawable != null) { - mHasTrackImage = true; - trackImage.setBackground(trackDrawable); - mOverlay.add(trackImage); - width = Math.max(width, trackDrawable.getIntrinsicWidth()); - } else { - mHasTrackImage = false; + mTrackImage.setImageDrawable(mTrackDrawable); + if (mTrackDrawable != null) { + width = Math.max(width, mTrackDrawable.getIntrinsicWidth()); } - final ImageView thumbImage = new ImageView(context); - mThumbImage = thumbImage; - // Add thumb to overlay if it has an image. - final Drawable thumbDrawable = ta.getDrawable(THUMB_DRAWABLE); - if (thumbDrawable != null) { - thumbImage.setImageDrawable(thumbDrawable); - mOverlay.add(thumbImage); - width = Math.max(width, thumbDrawable.getIntrinsicWidth()); + mThumbImage.setImageDrawable(mThumbDrawable); + mThumbImage.setMinimumWidth(mThumbMinWidth); + mThumbImage.setMinimumHeight(mThumbMinHeight); + if (mThumbDrawable != null) { + width = Math.max(width, mThumbDrawable.getIntrinsicWidth()); } - // If necessary, apply minimum thumb width and height. - if (thumbDrawable.getIntrinsicWidth() <= 0 || thumbDrawable.getIntrinsicHeight() <= 0) { - final int minWidth = res.getDimensionPixelSize(R.dimen.fastscroll_thumb_width); - thumbImage.setMinimumWidth(minWidth); - thumbImage.setMinimumHeight( - res.getDimensionPixelSize(R.dimen.fastscroll_thumb_height)); - width = Math.max(width, minWidth); - } + // Account for minimum thumb width. + mWidth = Math.max(width, mThumbMinWidth); - mWidth = width; + mPreviewImage.setMinimumWidth(mPreviewMinWidth); + mPreviewImage.setMinimumHeight(mPreviewMinHeight); - final int previewSize = res.getDimensionPixelSize(R.dimen.fastscroll_overlay_size); - mPreviewImage = new ImageView(context); - mPreviewImage.setMinimumWidth(previewSize); - mPreviewImage.setMinimumHeight(previewSize); - mPreviewImage.setAlpha(0f); - mOverlay.add(mPreviewImage); + if (mTextAppearance != 0) { + mPrimaryText.setTextAppearance(context, mTextAppearance); + mSecondaryText.setTextAppearance(context, mTextAppearance); + } - mPreviewPadding = res.getDimensionPixelSize(R.dimen.fastscroll_overlay_padding); + if (mTextColor != null) { + mPrimaryText.setTextColor(mTextColor); + mSecondaryText.setTextColor(mTextColor); + } + + if (mTextSize > 0) { + mPrimaryText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize); + mSecondaryText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize); + } - final int textMinSize = Math.max(0, previewSize - mPreviewPadding); - mPrimaryText = createPreviewTextView(context, ta); + final int textMinSize = Math.max(0, mPreviewMinHeight); mPrimaryText.setMinimumWidth(textMinSize); mPrimaryText.setMinimumHeight(textMinSize); - mOverlay.add(mPrimaryText); - mSecondaryText = createPreviewTextView(context, ta); mSecondaryText.setMinimumWidth(textMinSize); mSecondaryText.setMinimumHeight(textMinSize); - mOverlay.add(mSecondaryText); - mPreviewResId[PREVIEW_LEFT] = ta.getResourceId(PREVIEW_BACKGROUND_LEFT, 0); - mPreviewResId[PREVIEW_RIGHT] = ta.getResourceId(PREVIEW_BACKGROUND_RIGHT, 0); - mOverlayPosition = ta.getInt(OVERLAY_POSITION, OVERLAY_FLOATING); - ta.recycle(); + refreshDrawablePressedState(); + } - mScrollBarStyle = listView.getScrollBarStyle(); - mScrollCompleted = true; - mState = STATE_VISIBLE; - mMatchDragPosition = context.getApplicationInfo().targetSdkVersion - >= Build.VERSION_CODES.HONEYCOMB; + public void setStyle(int resId) { + final Context context = mList.getContext(); + final TypedArray ta = context.obtainStyledAttributes(null, + com.android.internal.R.styleable.FastScroll, android.R.attr.fastScrollStyle, resId); + final int N = ta.getIndexCount(); + for (int i = 0; i < N; i++) { + final int index = ta.getIndex(i); + switch (index) { + case com.android.internal.R.styleable.FastScroll_position: + mOverlayPosition = ta.getInt(index, OVERLAY_FLOATING); + break; + case com.android.internal.R.styleable.FastScroll_backgroundLeft: + mPreviewResId[PREVIEW_LEFT] = ta.getResourceId(index, 0); + break; + case com.android.internal.R.styleable.FastScroll_backgroundRight: + mPreviewResId[PREVIEW_RIGHT] = ta.getResourceId(index, 0); + break; + case com.android.internal.R.styleable.FastScroll_thumbDrawable: + mThumbDrawable = ta.getDrawable(index); + break; + case com.android.internal.R.styleable.FastScroll_trackDrawable: + mTrackDrawable = ta.getDrawable(index); + break; + case com.android.internal.R.styleable.FastScroll_textAppearance: + mTextAppearance = ta.getResourceId(index, 0); + break; + case com.android.internal.R.styleable.FastScroll_textColor: + mTextColor = ta.getColorStateList(index); + break; + case com.android.internal.R.styleable.FastScroll_textSize: + mTextSize = ta.getDimensionPixelSize(index, 0); + break; + case com.android.internal.R.styleable.FastScroll_minWidth: + mPreviewMinWidth = ta.getDimensionPixelSize(index, 0); + break; + case com.android.internal.R.styleable.FastScroll_minHeight: + mPreviewMinHeight = ta.getDimensionPixelSize(index, 0); + break; + case com.android.internal.R.styleable.FastScroll_thumbMinWidth: + mThumbMinWidth = ta.getDimensionPixelSize(index, 0); + break; + case com.android.internal.R.styleable.FastScroll_thumbMinHeight: + mThumbMinHeight = ta.getDimensionPixelSize(index, 0); + break; + case com.android.internal.R.styleable.FastScroll_padding: + mPreviewPadding = ta.getDimensionPixelSize(index, 0); + break; + } + } - getSectionsFromIndexer(); - refreshDrawablePressedState(); - updateLongList(listView.getChildCount(), listView.getCount()); - setScrollbarPosition(mList.getVerticalScrollbarPosition()); - postAutoHide(); + updateAppearance(); } /** @@ -469,17 +516,11 @@ class FastScroller { /** * Creates a view into which preview text can be placed. */ - private TextView createPreviewTextView(Context context, TypedArray ta) { + private TextView createPreviewTextView(Context context) { final LayoutParams params = new LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); - final Resources res = context.getResources(); - final int minSize = res.getDimensionPixelSize(R.dimen.fastscroll_overlay_size); - final ColorStateList textColor = ta.getColorStateList(TEXT_COLOR); - final float textSize = res.getDimensionPixelSize(R.dimen.fastscroll_overlay_text_size); final TextView textView = new TextView(context); textView.setLayoutParams(params); - textView.setTextColor(textColor); - textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize); textView.setSingleLine(true); textView.setEllipsize(TruncateAt.MIDDLE); textView.setGravity(Gravity.CENTER); @@ -603,7 +644,7 @@ class FastScroller { view.measure(widthMeasureSpec, heightMeasureSpec); // Align to the left or right. - final int width = view.getMeasuredWidth(); + final int width = Math.min(adjMaxWidth, view.getMeasuredWidth()); final int left; final int right; if (mLayoutFromRight) { @@ -1020,7 +1061,7 @@ class FastScroller { } final Rect bounds = mTempBounds; - final ImageView preview = mPreviewImage; + final View preview = mPreviewImage; final TextView showing; final TextView target; if (mShowingPrimary) { @@ -1046,10 +1087,10 @@ class FastScroller { hideShowing.addListener(mSwitchPrimaryListener); // Apply preview image padding and animate bounds, if necessary. - bounds.left -= mPreviewImage.getPaddingLeft(); - bounds.top -= mPreviewImage.getPaddingTop(); - bounds.right += mPreviewImage.getPaddingRight(); - bounds.bottom += mPreviewImage.getPaddingBottom(); + bounds.left -= preview.getPaddingLeft(); + bounds.top -= preview.getPaddingTop(); + bounds.right += preview.getPaddingRight(); + bounds.bottom += preview.getPaddingBottom(); final Animator resizePreview = animateBounds(preview, bounds); resizePreview.setDuration(DURATION_RESIZE); @@ -1097,8 +1138,8 @@ class FastScroller { final int top = container.top; final int bottom = container.bottom; - final ImageView trackImage = mTrackImage; - final ImageView thumbImage = mThumbImage; + final View trackImage = mTrackImage; + final View thumbImage = mThumbImage; final float min = trackImage.getTop(); final float max = trackImage.getBottom(); final float offset = min; @@ -1109,7 +1150,7 @@ class FastScroller { final float previewPos = mOverlayPosition == OVERLAY_AT_THUMB ? thumbMiddle : 0; // Center the preview on the thumb, constrained to the list bounds. - final ImageView previewImage = mPreviewImage; + final View previewImage = mPreviewImage; final float previewHalfHeight = previewImage.getHeight() / 2f; final float minP = top + previewHalfHeight; final float maxP = bottom - previewHalfHeight; @@ -1122,11 +1163,7 @@ class FastScroller { } private float getPosFromMotionEvent(float y) { - final Rect container = mContainerRect; - final int top = container.top; - final int bottom = container.bottom; - - final ImageView trackImage = mTrackImage; + final View trackImage = mTrackImage; final float min = trackImage.getTop(); final float max = trackImage.getBottom(); final float offset = min; @@ -1393,7 +1430,7 @@ class FastScroller { * @return Whether the coordinate is inside the scroller's activation area. */ private boolean isPointInside(float x, float y) { - return isPointInsideX(x) && (mHasTrackImage || isPointInsideY(y)); + return isPointInsideX(x) && (mTrackDrawable != null || isPointInsideY(y)); } private boolean isPointInsideX(float x) { |
