Fading scrollbars return. But you have to opt in.
This commit is contained in:
@ -24,6 +24,7 @@ import android.content.res.Resources;
|
|||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Interpolator;
|
||||||
import android.graphics.LinearGradient;
|
import android.graphics.LinearGradient;
|
||||||
import android.graphics.Matrix;
|
import android.graphics.Matrix;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
@ -514,7 +515,8 @@ import java.util.WeakHashMap;
|
|||||||
* The framework provides basic support for views that wish to internally
|
* The framework provides basic support for views that wish to internally
|
||||||
* scroll their content. This includes keeping track of the X and Y scroll
|
* scroll their content. This includes keeping track of the X and Y scroll
|
||||||
* offset as well as mechanisms for drawing scrollbars. See
|
* offset as well as mechanisms for drawing scrollbars. See
|
||||||
* {@link #scrollBy(int, int)}, {@link #scrollTo(int, int)} for more details.
|
* {@link #scrollBy(int, int)}, {@link #scrollTo(int, int)}, and
|
||||||
|
* {@link #awakenScrollBars()} for more details.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <a name="Tags"></a>
|
* <a name="Tags"></a>
|
||||||
@ -571,6 +573,8 @@ import java.util.WeakHashMap;
|
|||||||
* @attr ref android.R.styleable#View_scrollbarSize
|
* @attr ref android.R.styleable#View_scrollbarSize
|
||||||
* @attr ref android.R.styleable#View_scrollbarStyle
|
* @attr ref android.R.styleable#View_scrollbarStyle
|
||||||
* @attr ref android.R.styleable#View_scrollbars
|
* @attr ref android.R.styleable#View_scrollbars
|
||||||
|
* @attr ref android.R.styleable#View_scrollbarDefaultDelayBeforeFade
|
||||||
|
* @attr ref android.R.styleable#View_scrollbarFadeDuration
|
||||||
* @attr ref android.R.styleable#View_scrollbarTrackHorizontal
|
* @attr ref android.R.styleable#View_scrollbarTrackHorizontal
|
||||||
* @attr ref android.R.styleable#View_scrollbarThumbHorizontal
|
* @attr ref android.R.styleable#View_scrollbarThumbHorizontal
|
||||||
* @attr ref android.R.styleable#View_scrollbarThumbVertical
|
* @attr ref android.R.styleable#View_scrollbarThumbVertical
|
||||||
@ -2214,12 +2218,28 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
|||||||
protected void initializeScrollbars(TypedArray a) {
|
protected void initializeScrollbars(TypedArray a) {
|
||||||
initScrollCache();
|
initScrollCache();
|
||||||
|
|
||||||
if (mScrollCache.scrollBar == null) {
|
|
||||||
mScrollCache.scrollBar = new ScrollBarDrawable();
|
|
||||||
}
|
|
||||||
|
|
||||||
final ScrollabilityCache scrollabilityCache = mScrollCache;
|
final ScrollabilityCache scrollabilityCache = mScrollCache;
|
||||||
|
|
||||||
|
if (scrollabilityCache.scrollBar == null) {
|
||||||
|
scrollabilityCache.scrollBar = new ScrollBarDrawable();
|
||||||
|
}
|
||||||
|
|
||||||
|
final boolean fadeScrollbars = a.getBoolean(R.styleable.View_fadeScrollbars, false);
|
||||||
|
|
||||||
|
if (!fadeScrollbars) {
|
||||||
|
scrollabilityCache.state = ScrollabilityCache.ON;
|
||||||
|
}
|
||||||
|
scrollabilityCache.fadeScrollBars = fadeScrollbars;
|
||||||
|
|
||||||
|
|
||||||
|
scrollabilityCache.scrollBarFadeDuration = a.getInt(
|
||||||
|
R.styleable.View_scrollbarFadeDuration, ViewConfiguration
|
||||||
|
.getScrollBarFadeDuration());
|
||||||
|
scrollabilityCache.scrollBarDefaultDelayBeforeFade = a.getInt(
|
||||||
|
R.styleable.View_scrollbarDefaultDelayBeforeFade,
|
||||||
|
ViewConfiguration.getScrollDefaultDelay());
|
||||||
|
|
||||||
|
|
||||||
scrollabilityCache.scrollBarSize = a.getDimensionPixelSize(
|
scrollabilityCache.scrollBarSize = a.getDimensionPixelSize(
|
||||||
com.android.internal.R.styleable.View_scrollbarSize,
|
com.android.internal.R.styleable.View_scrollbarSize,
|
||||||
ViewConfiguration.get(mContext).getScaledScrollBarSize());
|
ViewConfiguration.get(mContext).getScaledScrollBarSize());
|
||||||
@ -2263,7 +2283,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
|||||||
*/
|
*/
|
||||||
private void initScrollCache() {
|
private void initScrollCache() {
|
||||||
if (mScrollCache == null) {
|
if (mScrollCache == null) {
|
||||||
mScrollCache = new ScrollabilityCache(ViewConfiguration.get(mContext));
|
mScrollCache = new ScrollabilityCache(ViewConfiguration.get(mContext), this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4671,7 +4691,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
|||||||
mScrollX = x;
|
mScrollX = x;
|
||||||
mScrollY = y;
|
mScrollY = y;
|
||||||
onScrollChanged(mScrollX, mScrollY, oldX, oldY);
|
onScrollChanged(mScrollX, mScrollY, oldX, oldY);
|
||||||
invalidate();
|
if (!awakenScrollBars()) {
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4686,6 +4708,120 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
|||||||
scrollTo(mScrollX + x, mScrollY + y);
|
scrollTo(mScrollX + x, mScrollY + y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Trigger the scrollbars to draw. When invoked this method starts an
|
||||||
|
* animation to fade the scrollbars out after a default delay. If a subclass
|
||||||
|
* provides animated scrolling, the start delay should equal the duration
|
||||||
|
* of the scrolling animation.</p>
|
||||||
|
*
|
||||||
|
* <p>The animation starts only if at least one of the scrollbars is
|
||||||
|
* enabled, as specified by {@link #isHorizontalScrollBarEnabled()} and
|
||||||
|
* {@link #isVerticalScrollBarEnabled()}. When the animation is started,
|
||||||
|
* this method returns true, and false otherwise. If the animation is
|
||||||
|
* started, this method calls {@link #invalidate()}; in that case the
|
||||||
|
* caller should not call {@link #invalidate()}.</p>
|
||||||
|
*
|
||||||
|
* <p>This method should be invoked every time a subclass directly updates
|
||||||
|
* the scroll parameters. (See {@link #mScrollX} and {@link #mScrollY})</p>
|
||||||
|
*
|
||||||
|
* <p>This method is automatically invoked by {@link #scrollBy(int, int)}
|
||||||
|
* and {@link #scrollTo(int, int)}.</p>
|
||||||
|
*
|
||||||
|
* @return true if the animation is played, false otherwise
|
||||||
|
*
|
||||||
|
* @see #awakenScrollBars(int)
|
||||||
|
* @see #mScrollX
|
||||||
|
* @see #mScrollY
|
||||||
|
* @see #scrollBy(int, int)
|
||||||
|
* @see #scrollTo(int, int)
|
||||||
|
* @see #isHorizontalScrollBarEnabled()
|
||||||
|
* @see #isVerticalScrollBarEnabled()
|
||||||
|
* @see #setHorizontalScrollBarEnabled(boolean)
|
||||||
|
* @see #setVerticalScrollBarEnabled(boolean)
|
||||||
|
*/
|
||||||
|
protected boolean awakenScrollBars() {
|
||||||
|
return mScrollCache != null &&
|
||||||
|
awakenScrollBars(mScrollCache.scrollBarDefaultDelayBeforeFade);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Trigger the scrollbars to draw. When invoked this method starts an
|
||||||
|
* animation to fade the scrollbars out after a fixed delay. If a subclass
|
||||||
|
* provides animated scrolling, the start delay should equal the duration of
|
||||||
|
* the scrolling animation.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* The animation starts only if at least one of the scrollbars is enabled,
|
||||||
|
* as specified by {@link #isHorizontalScrollBarEnabled()} and
|
||||||
|
* {@link #isVerticalScrollBarEnabled()}. When the animation is started,
|
||||||
|
* this method returns true, and false otherwise. If the animation is
|
||||||
|
* started, this method calls {@link #invalidate()}; in that case the caller
|
||||||
|
* should not call {@link #invalidate()}.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* This method should be invoked everytime a subclass directly updates the
|
||||||
|
* scroll parameters. (See {@link #mScrollX} and {@link #mScrollY})
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param startDelay the delay, in milliseconds, after which the animation
|
||||||
|
* should start; when the delay is 0, the animation starts
|
||||||
|
* immediately
|
||||||
|
* @return true if the animation is played, false otherwise
|
||||||
|
*
|
||||||
|
* @see #mScrollX
|
||||||
|
* @see #mScrollY
|
||||||
|
* @see #scrollBy(int, int)
|
||||||
|
* @see #scrollTo(int, int)
|
||||||
|
* @see #isHorizontalScrollBarEnabled()
|
||||||
|
* @see #isVerticalScrollBarEnabled()
|
||||||
|
* @see #setHorizontalScrollBarEnabled(boolean)
|
||||||
|
* @see #setVerticalScrollBarEnabled(boolean)
|
||||||
|
*/
|
||||||
|
protected boolean awakenScrollBars(int startDelay) {
|
||||||
|
final ScrollabilityCache scrollCache = mScrollCache;
|
||||||
|
|
||||||
|
if (scrollCache == null || !scrollCache.fadeScrollBars) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scrollCache.scrollBar == null) {
|
||||||
|
scrollCache.scrollBar = new ScrollBarDrawable();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isHorizontalScrollBarEnabled() || isVerticalScrollBarEnabled()) {
|
||||||
|
|
||||||
|
// Invalidate to show the scrollbars
|
||||||
|
invalidate();
|
||||||
|
|
||||||
|
if (scrollCache.state == ScrollabilityCache.OFF) {
|
||||||
|
// FIXME: this is copied from WindowManagerService.
|
||||||
|
// We should get this value from the system when it
|
||||||
|
// is possible to do so.
|
||||||
|
final int KEY_REPEAT_FIRST_DELAY = 750;
|
||||||
|
startDelay = Math.max(KEY_REPEAT_FIRST_DELAY, startDelay);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tell mScrollCache when we should start fading. This may
|
||||||
|
// extend the fade start time if one was already scheduled
|
||||||
|
long fadeStartTime = SystemClock.uptimeMillis() + startDelay;
|
||||||
|
scrollCache.fadeStartTime = fadeStartTime;
|
||||||
|
scrollCache.state = ScrollabilityCache.ON;
|
||||||
|
|
||||||
|
// Schedule our fader to run, unscheduling any old ones first
|
||||||
|
if (mAttachInfo != null) {
|
||||||
|
mAttachInfo.mHandler.removeCallbacks(scrollCache);
|
||||||
|
mAttachInfo.mHandler.postAtTime(scrollCache, fadeStartTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark the the area defined by dirty as needing to be drawn. If the view is
|
* Mark the the area defined by dirty as needing to be drawn. If the view is
|
||||||
* visible, {@link #onDraw} will be called at some point in the future.
|
* visible, {@link #onDraw} will be called at some point in the future.
|
||||||
@ -5344,11 +5480,49 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
|||||||
* scrollbars are painted only if they have been awakened first.</p>
|
* scrollbars are painted only if they have been awakened first.</p>
|
||||||
*
|
*
|
||||||
* @param canvas the canvas on which to draw the scrollbars
|
* @param canvas the canvas on which to draw the scrollbars
|
||||||
|
*
|
||||||
|
* @see #awakenScrollBars(int)
|
||||||
*/
|
*/
|
||||||
private void onDrawScrollBars(Canvas canvas) {
|
private void onDrawScrollBars(Canvas canvas) {
|
||||||
// scrollbars are drawn only when the animation is running
|
// scrollbars are drawn only when the animation is running
|
||||||
final ScrollabilityCache cache = mScrollCache;
|
final ScrollabilityCache cache = mScrollCache;
|
||||||
if (cache != null) {
|
if (cache != null) {
|
||||||
|
|
||||||
|
int state = cache.state;
|
||||||
|
|
||||||
|
if (state == ScrollabilityCache.OFF) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean invalidate = false;
|
||||||
|
|
||||||
|
if (state == ScrollabilityCache.FADING) {
|
||||||
|
// We're fading -- get our fade interpolation
|
||||||
|
if (cache.interpolatorValues == null) {
|
||||||
|
cache.interpolatorValues = new float[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
float[] values = cache.interpolatorValues;
|
||||||
|
|
||||||
|
// Stops the animation if we're done
|
||||||
|
if (cache.scrollBarInterpolator.timeToValues(values) ==
|
||||||
|
Interpolator.Result.FREEZE_END) {
|
||||||
|
cache.state = ScrollabilityCache.OFF;
|
||||||
|
} else {
|
||||||
|
cache.scrollBar.setAlpha(Math.round(values[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
// This will make the scroll bars inval themselves after
|
||||||
|
// drawing. We only want this when we're fading so that
|
||||||
|
// we prevent excessive redraws
|
||||||
|
invalidate = true;
|
||||||
|
} else {
|
||||||
|
// We're just on -- but we may have been fading before so
|
||||||
|
// reset alpha
|
||||||
|
cache.scrollBar.setAlpha(255);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
final int viewFlags = mViewFlags;
|
final int viewFlags = mViewFlags;
|
||||||
|
|
||||||
final boolean drawHorizontalScrollBar =
|
final boolean drawHorizontalScrollBar =
|
||||||
@ -5371,19 +5545,22 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
|||||||
final int scrollY = mScrollY;
|
final int scrollY = mScrollY;
|
||||||
final int inside = (viewFlags & SCROLLBARS_OUTSIDE_MASK) == 0 ? ~0 : 0;
|
final int inside = (viewFlags & SCROLLBARS_OUTSIDE_MASK) == 0 ? ~0 : 0;
|
||||||
|
|
||||||
|
int left, top, right, bottom;
|
||||||
|
|
||||||
if (drawHorizontalScrollBar) {
|
if (drawHorizontalScrollBar) {
|
||||||
scrollBar.setParameters(
|
scrollBar.setParameters(computeHorizontalScrollRange(),
|
||||||
computeHorizontalScrollRange(),
|
|
||||||
computeHorizontalScrollOffset(),
|
computeHorizontalScrollOffset(),
|
||||||
computeHorizontalScrollExtent(), false);
|
computeHorizontalScrollExtent(), false);
|
||||||
final int top = scrollY + height - size - (mUserPaddingBottom & inside);
|
|
||||||
final int verticalScrollBarGap = drawVerticalScrollBar ?
|
final int verticalScrollBarGap = drawVerticalScrollBar ?
|
||||||
getVerticalScrollbarWidth() : 0;
|
getVerticalScrollbarWidth() : 0;
|
||||||
onDrawHorizontalScrollBar(canvas, scrollBar,
|
top = scrollY + height - size - (mUserPaddingBottom & inside);
|
||||||
scrollX + (mPaddingLeft & inside),
|
left = scrollX + (mPaddingLeft & inside);
|
||||||
top,
|
right = scrollX + width - (mUserPaddingRight & inside) - verticalScrollBarGap;
|
||||||
scrollX + width - (mUserPaddingRight & inside) - verticalScrollBarGap,
|
bottom = top + size;
|
||||||
top + size);
|
onDrawHorizontalScrollBar(canvas, scrollBar, left, top, right, bottom);
|
||||||
|
if (invalidate) {
|
||||||
|
invalidate(left, top, right, bottom);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (drawVerticalScrollBar) {
|
if (drawVerticalScrollBar) {
|
||||||
@ -5391,12 +5568,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
|||||||
computeVerticalScrollOffset(),
|
computeVerticalScrollOffset(),
|
||||||
computeVerticalScrollExtent(), true);
|
computeVerticalScrollExtent(), true);
|
||||||
// TODO: Deal with RTL languages to position scrollbar on left
|
// TODO: Deal with RTL languages to position scrollbar on left
|
||||||
final int left = scrollX + width - size - (mUserPaddingRight & inside);
|
left = scrollX + width - size - (mUserPaddingRight & inside);
|
||||||
onDrawVerticalScrollBar(canvas, scrollBar,
|
top = scrollY + (mPaddingTop & inside);
|
||||||
left,
|
right = left + size;
|
||||||
scrollY + (mPaddingTop & inside),
|
bottom = scrollY + height - (mUserPaddingBottom & inside);
|
||||||
left + size,
|
onDrawVerticalScrollBar(canvas, scrollBar, left, top, right, bottom);
|
||||||
scrollY + height - (mUserPaddingBottom & inside));
|
if (invalidate) {
|
||||||
|
invalidate(left, top, right, bottom);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5424,7 +5603,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
|||||||
* @see #computeHorizontalScrollExtent()
|
* @see #computeHorizontalScrollExtent()
|
||||||
* @see #computeHorizontalScrollOffset()
|
* @see #computeHorizontalScrollOffset()
|
||||||
* @see android.widget.ScrollBarDrawable
|
* @see android.widget.ScrollBarDrawable
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
protected void onDrawHorizontalScrollBar(Canvas canvas,
|
protected void onDrawHorizontalScrollBar(Canvas canvas,
|
||||||
Drawable scrollBar,
|
Drawable scrollBar,
|
||||||
@ -8731,21 +8910,62 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
|||||||
* is supported. This avoids keeping too many unused fields in most
|
* is supported. This avoids keeping too many unused fields in most
|
||||||
* instances of View.</p>
|
* instances of View.</p>
|
||||||
*/
|
*/
|
||||||
private static class ScrollabilityCache {
|
private static class ScrollabilityCache implements Runnable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scrollbars are not visible
|
||||||
|
*/
|
||||||
|
public static final int OFF = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scrollbars are visible
|
||||||
|
*/
|
||||||
|
public static final int ON = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scrollbars are fading away
|
||||||
|
*/
|
||||||
|
public static final int FADING = 2;
|
||||||
|
|
||||||
|
public boolean fadeScrollBars;
|
||||||
|
|
||||||
public int fadingEdgeLength;
|
public int fadingEdgeLength;
|
||||||
|
public int scrollBarDefaultDelayBeforeFade;
|
||||||
|
public int scrollBarFadeDuration;
|
||||||
|
|
||||||
public int scrollBarSize;
|
public int scrollBarSize;
|
||||||
public ScrollBarDrawable scrollBar;
|
public ScrollBarDrawable scrollBar;
|
||||||
|
public float[] interpolatorValues;
|
||||||
|
public View host;
|
||||||
|
|
||||||
public final Paint paint;
|
public final Paint paint;
|
||||||
public final Matrix matrix;
|
public final Matrix matrix;
|
||||||
public Shader shader;
|
public Shader shader;
|
||||||
|
|
||||||
|
public final Interpolator scrollBarInterpolator = new Interpolator(1, 2);
|
||||||
|
|
||||||
|
private final float[] mOpaque = {255.0f};
|
||||||
|
private final float[] mTransparent = {0.0f};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When fading should start. This time moves into the future every time
|
||||||
|
* a new scroll happens. Measured based on SystemClock.uptimeMillis()
|
||||||
|
*/
|
||||||
|
public long fadeStartTime;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current state of the scrollbars: ON, OFF, or FADING
|
||||||
|
*/
|
||||||
|
public int state = OFF;
|
||||||
|
|
||||||
private int mLastColor;
|
private int mLastColor;
|
||||||
|
|
||||||
public ScrollabilityCache(ViewConfiguration configuration) {
|
public ScrollabilityCache(ViewConfiguration configuration, View host) {
|
||||||
fadingEdgeLength = configuration.getScaledFadingEdgeLength();
|
fadingEdgeLength = configuration.getScaledFadingEdgeLength();
|
||||||
scrollBarSize = configuration.getScaledScrollBarSize();
|
scrollBarSize = configuration.getScaledScrollBarSize();
|
||||||
|
scrollBarDefaultDelayBeforeFade = configuration.getScrollDefaultDelay();
|
||||||
|
scrollBarFadeDuration = configuration.getScrollBarFadeDuration();
|
||||||
|
|
||||||
paint = new Paint();
|
paint = new Paint();
|
||||||
matrix = new Matrix();
|
matrix = new Matrix();
|
||||||
@ -8755,6 +8975,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
|||||||
|
|
||||||
paint.setShader(shader);
|
paint.setShader(shader);
|
||||||
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
|
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
|
||||||
|
this.host = host;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFadeColor(int color) {
|
public void setFadeColor(int color) {
|
||||||
@ -8770,5 +8991,32 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
|||||||
paint.setXfermode(null);
|
paint.setXfermode(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
long now = SystemClock.uptimeMillis();
|
||||||
|
if (now >= fadeStartTime) {
|
||||||
|
|
||||||
|
// the animation fades the scrollbars out by changing
|
||||||
|
// the opacity (alpha) from fully opaque to fully
|
||||||
|
// transparent
|
||||||
|
int nextFrame = (int) now;
|
||||||
|
int framesCount = 0;
|
||||||
|
|
||||||
|
Interpolator interpolator = scrollBarInterpolator;
|
||||||
|
|
||||||
|
// Start opaque
|
||||||
|
interpolator.setKeyFrame(framesCount++, nextFrame, mOpaque);
|
||||||
|
|
||||||
|
// End transparent
|
||||||
|
nextFrame += scrollBarFadeDuration;
|
||||||
|
interpolator.setKeyFrame(framesCount, nextFrame, mTransparent);
|
||||||
|
|
||||||
|
state = FADING;
|
||||||
|
|
||||||
|
// Kick off the fade animation
|
||||||
|
host.invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,16 @@ public class ViewConfiguration {
|
|||||||
*/
|
*/
|
||||||
private static final int SCROLL_BAR_SIZE = 10;
|
private static final int SCROLL_BAR_SIZE = 10;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Duration of the fade when scrollbars fade away in milliseconds
|
||||||
|
*/
|
||||||
|
private static final int SCROLL_BAR_FADE_DURATION = 250;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default delay before the scrollbars fade in milliseconds
|
||||||
|
*/
|
||||||
|
private static final int SCROLL_BAR_DEFAULT_DELAY = 300;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the length of the fading edges in pixels
|
* Defines the length of the fading edges in pixels
|
||||||
*/
|
*/
|
||||||
@ -220,6 +230,20 @@ public class ViewConfiguration {
|
|||||||
return mScrollbarSize;
|
return mScrollbarSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Duration of the fade when scrollbars fade away in milliseconds
|
||||||
|
*/
|
||||||
|
public static int getScrollBarFadeDuration() {
|
||||||
|
return SCROLL_BAR_FADE_DURATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Default delay before the scrollbars fade in milliseconds
|
||||||
|
*/
|
||||||
|
public static int getScrollDefaultDelay() {
|
||||||
|
return SCROLL_BAR_DEFAULT_DELAY;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the length of the fading edges in pixels
|
* @return the length of the fading edges in pixels
|
||||||
*
|
*
|
||||||
|
@ -2480,6 +2480,7 @@ public class WebView extends AbsoluteLayout
|
|||||||
// Log.d(LOGTAG, "startScroll: " + dx + " " + dy);
|
// Log.d(LOGTAG, "startScroll: " + dx + " " + dy);
|
||||||
mScroller.startScroll(mScrollX, mScrollY, dx, dy,
|
mScroller.startScroll(mScrollX, mScrollY, dx, dy,
|
||||||
animationDuration > 0 ? animationDuration : computeDuration(dx, dy));
|
animationDuration > 0 ? animationDuration : computeDuration(dx, dy));
|
||||||
|
awakenScrollBars(mScroller.getDuration());
|
||||||
invalidate();
|
invalidate();
|
||||||
} else {
|
} else {
|
||||||
abortAnimation(); // just in case
|
abortAnimation(); // just in case
|
||||||
@ -4326,6 +4327,7 @@ public class WebView extends AbsoluteLayout
|
|||||||
// resume the webcore update.
|
// resume the webcore update.
|
||||||
final int time = mScroller.getDuration();
|
final int time = mScroller.getDuration();
|
||||||
mPrivateHandler.sendEmptyMessageDelayed(RESUME_WEBCORE_UPDATE, time);
|
mPrivateHandler.sendEmptyMessageDelayed(RESUME_WEBCORE_UPDATE, time);
|
||||||
|
awakenScrollBars(time);
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2444,7 +2444,9 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
|||||||
if (spaceAbove >= absIncrementalDeltaY && spaceBelow >= absIncrementalDeltaY) {
|
if (spaceAbove >= absIncrementalDeltaY && spaceBelow >= absIncrementalDeltaY) {
|
||||||
hideSelector();
|
hideSelector();
|
||||||
offsetChildrenTopAndBottom(incrementalDeltaY);
|
offsetChildrenTopAndBottom(incrementalDeltaY);
|
||||||
invalidate();
|
if (!awakenScrollBars()) {
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
mMotionViewNewTop = mMotionViewOriginalTop + deltaY;
|
mMotionViewNewTop = mMotionViewOriginalTop + deltaY;
|
||||||
} else {
|
} else {
|
||||||
final int firstPosition = mFirstPosition;
|
final int firstPosition = mFirstPosition;
|
||||||
@ -2527,6 +2529,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
|||||||
mBlockLayoutRequests = false;
|
mBlockLayoutRequests = false;
|
||||||
|
|
||||||
invokeOnItemScrollListener();
|
invokeOnItemScrollListener();
|
||||||
|
awakenScrollBars();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1340,8 +1340,23 @@ public class GridView extends AbsListView {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
void setSelectionInt(int position) {
|
void setSelectionInt(int position) {
|
||||||
|
int previousSelectedPosition = mNextSelectedPosition;
|
||||||
|
|
||||||
setNextSelectedPositionInt(position);
|
setNextSelectedPositionInt(position);
|
||||||
layoutChildren();
|
layoutChildren();
|
||||||
|
|
||||||
|
final int next = mStackFromBottom ? mItemCount - 1 - mNextSelectedPosition :
|
||||||
|
mNextSelectedPosition;
|
||||||
|
final int previous = mStackFromBottom ? mItemCount - 1
|
||||||
|
- previousSelectedPosition : previousSelectedPosition;
|
||||||
|
|
||||||
|
final int nextRow = next / mNumColumns;
|
||||||
|
final int previousRow = previous / mNumColumns;
|
||||||
|
|
||||||
|
if (nextRow != previousRow) {
|
||||||
|
awakenScrollBars();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1471,6 +1486,7 @@ public class GridView extends AbsListView {
|
|||||||
if (nextPage >= 0) {
|
if (nextPage >= 0) {
|
||||||
setSelectionInt(nextPage);
|
setSelectionInt(nextPage);
|
||||||
invokeOnItemScrollListener();
|
invokeOnItemScrollListener();
|
||||||
|
awakenScrollBars();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1497,6 +1513,10 @@ public class GridView extends AbsListView {
|
|||||||
invokeOnItemScrollListener();
|
invokeOnItemScrollListener();
|
||||||
moved = true;
|
moved = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (moved) {
|
||||||
|
awakenScrollBars();
|
||||||
|
}
|
||||||
|
|
||||||
return moved;
|
return moved;
|
||||||
}
|
}
|
||||||
@ -1563,6 +1583,10 @@ public class GridView extends AbsListView {
|
|||||||
invokeOnItemScrollListener();
|
invokeOnItemScrollListener();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (moved) {
|
||||||
|
awakenScrollBars();
|
||||||
|
}
|
||||||
|
|
||||||
return moved;
|
return moved;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -829,6 +829,7 @@ public class HorizontalScrollView extends FrameLayout {
|
|||||||
long duration = AnimationUtils.currentAnimationTimeMillis() - mLastScroll;
|
long duration = AnimationUtils.currentAnimationTimeMillis() - mLastScroll;
|
||||||
if (duration > ANIMATED_SCROLL_GAP) {
|
if (duration > ANIMATED_SCROLL_GAP) {
|
||||||
mScroller.startScroll(mScrollX, mScrollY, dx, dy);
|
mScroller.startScroll(mScrollX, mScrollY, dx, dy);
|
||||||
|
awakenScrollBars(mScroller.getDuration());
|
||||||
invalidate();
|
invalidate();
|
||||||
} else {
|
} else {
|
||||||
if (!mScroller.isFinished()) {
|
if (!mScroller.isFinished()) {
|
||||||
@ -1172,6 +1173,7 @@ public class HorizontalScrollView extends FrameLayout {
|
|||||||
mScrollViewMovedFocus = false;
|
mScrollViewMovedFocus = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
awakenScrollBars(mScroller.getDuration());
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1818,13 +1818,29 @@ public class ListView extends AbsListView {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes the item at the supplied position selected.
|
* Makes the item at the supplied position selected.
|
||||||
*
|
*
|
||||||
* @param position the position of the item to select
|
* @param position the position of the item to select
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
void setSelectionInt(int position) {
|
void setSelectionInt(int position) {
|
||||||
setNextSelectedPositionInt(position);
|
setNextSelectedPositionInt(position);
|
||||||
|
boolean awakeScrollbars = false;
|
||||||
|
|
||||||
|
final int selectedPosition = mSelectedPosition;
|
||||||
|
|
||||||
|
if (selectedPosition >= 0) {
|
||||||
|
if (position == selectedPosition - 1) {
|
||||||
|
awakeScrollbars = true;
|
||||||
|
} else if (position == selectedPosition + 1) {
|
||||||
|
awakeScrollbars = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
layoutChildren();
|
layoutChildren();
|
||||||
|
|
||||||
|
if (awakeScrollbars) {
|
||||||
|
awakenScrollBars();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2084,7 +2100,9 @@ public class ListView extends AbsListView {
|
|||||||
|
|
||||||
setSelectionInt(position);
|
setSelectionInt(position);
|
||||||
invokeOnItemScrollListener();
|
invokeOnItemScrollListener();
|
||||||
invalidate();
|
if (!awakenScrollBars()) {
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -2125,7 +2143,8 @@ public class ListView extends AbsListView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (moved) {
|
if (moved && !awakenScrollBars()) {
|
||||||
|
awakenScrollBars();
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2270,7 +2289,9 @@ public class ListView extends AbsListView {
|
|||||||
positionSelector(selectedView);
|
positionSelector(selectedView);
|
||||||
mSelectedTop = selectedView.getTop();
|
mSelectedTop = selectedView.getTop();
|
||||||
}
|
}
|
||||||
invalidate();
|
if (!awakenScrollBars()) {
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
invokeOnItemScrollListener();
|
invokeOnItemScrollListener();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -832,6 +832,7 @@ public class ScrollView extends FrameLayout {
|
|||||||
long duration = AnimationUtils.currentAnimationTimeMillis() - mLastScroll;
|
long duration = AnimationUtils.currentAnimationTimeMillis() - mLastScroll;
|
||||||
if (duration > ANIMATED_SCROLL_GAP) {
|
if (duration > ANIMATED_SCROLL_GAP) {
|
||||||
mScroller.startScroll(mScrollX, mScrollY, dx, dy);
|
mScroller.startScroll(mScrollX, mScrollY, dx, dy);
|
||||||
|
awakenScrollBars(mScroller.getDuration());
|
||||||
invalidate();
|
invalidate();
|
||||||
} else {
|
} else {
|
||||||
if (!mScroller.isFinished()) {
|
if (!mScroller.isFinished()) {
|
||||||
@ -1175,6 +1176,7 @@ public class ScrollView extends FrameLayout {
|
|||||||
mScrollViewMovedFocus = false;
|
mScrollViewMovedFocus = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
awakenScrollBars(mScroller.getDuration());
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5572,6 +5572,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
|
|
||||||
if (duration > ANIMATED_SCROLL_GAP) {
|
if (duration > ANIMATED_SCROLL_GAP) {
|
||||||
mScroller.startScroll(mScrollX, mScrollY, dx, dy);
|
mScroller.startScroll(mScrollX, mScrollY, dx, dy);
|
||||||
|
awakenScrollBars(mScroller.getDuration());
|
||||||
invalidate();
|
invalidate();
|
||||||
} else {
|
} else {
|
||||||
if (!mScroller.isFinished()) {
|
if (!mScroller.isFinished()) {
|
||||||
|
@ -1162,6 +1162,12 @@
|
|||||||
set, else it will be false. -->
|
set, else it will be false. -->
|
||||||
<attr name="isScrollContainer" format="boolean" />
|
<attr name="isScrollContainer" format="boolean" />
|
||||||
|
|
||||||
|
<!-- Defines whether to fade out scrollbars when they are not in use. -->
|
||||||
|
<attr name="fadeScrollbars" format="boolean" />
|
||||||
|
<!-- Defines the delay in milliseconds that a scrollbar takes to fade out. -->
|
||||||
|
<attr name="scrollbarFadeDuration" format="integer" />
|
||||||
|
<!-- Defines the delay in milliseconds that a scrollbar waits before fade out. -->
|
||||||
|
<attr name="scrollbarDefaultDelayBeforeFade" format="integer" />
|
||||||
<!-- Sets the width of vertical scrollbars and height of horizontal scrollbars. -->
|
<!-- Sets the width of vertical scrollbars and height of horizontal scrollbars. -->
|
||||||
<attr name="scrollbarSize" format="dimension" />
|
<attr name="scrollbarSize" format="dimension" />
|
||||||
<!-- Defines the horizontal scrollbar thumb drawable. -->
|
<!-- Defines the horizontal scrollbar thumb drawable. -->
|
||||||
|
@ -1172,7 +1172,10 @@
|
|||||||
<public type="attr" name="thumbnail" />
|
<public type="attr" name="thumbnail" />
|
||||||
<public type="attr" name="detachWallpaper" />
|
<public type="attr" name="detachWallpaper" />
|
||||||
<public type="attr" name="finishOnCloseSystemDialogs" />
|
<public type="attr" name="finishOnCloseSystemDialogs" />
|
||||||
|
<public type="attr" name="scrollbarFadeDuration" />
|
||||||
|
<public type="attr" name="scrollbarDefaultDelayBeforeFade" />
|
||||||
|
<public type="attr" name="fadeScrollbars" />
|
||||||
|
|
||||||
<public type="style" name="Theme.Wallpaper" />
|
<public type="style" name="Theme.Wallpaper" />
|
||||||
<public type="style" name="Theme.Wallpaper.NoTitleBar" />
|
<public type="style" name="Theme.Wallpaper.NoTitleBar" />
|
||||||
<public type="style" name="Theme.Wallpaper.NoTitleBar.Fullscreen" />
|
<public type="style" name="Theme.Wallpaper.NoTitleBar.Fullscreen" />
|
||||||
|
@ -126,6 +126,8 @@
|
|||||||
<item name="panelTextAppearance">?android:attr/textAppearanceInverse</item>
|
<item name="panelTextAppearance">?android:attr/textAppearanceInverse</item>
|
||||||
|
|
||||||
<!-- Scrollbar attributes -->
|
<!-- Scrollbar attributes -->
|
||||||
|
<item name="scrollbarFadeDuration">250</item>
|
||||||
|
<item name="scrollbarDefaultDelayBeforeFade">300</item>
|
||||||
<item name="scrollbarSize">10dip</item>
|
<item name="scrollbarSize">10dip</item>
|
||||||
<item name="scrollbarThumbHorizontal">@android:drawable/scrollbar_handle_horizontal</item>
|
<item name="scrollbarThumbHorizontal">@android:drawable/scrollbar_handle_horizontal</item>
|
||||||
<item name="scrollbarThumbVertical">@android:drawable/scrollbar_handle_vertical</item>
|
<item name="scrollbarThumbVertical">@android:drawable/scrollbar_handle_vertical</item>
|
||||||
|
Reference in New Issue
Block a user