OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 package org.chromium.chrome.browser.widget; |
| 6 |
| 7 import android.content.Context; |
| 8 import android.graphics.Canvas; |
| 9 import android.graphics.Color; |
| 10 import android.graphics.Paint; |
| 11 import android.support.annotation.IntDef; |
| 12 import android.util.AttributeSet; |
| 13 import android.widget.ScrollView; |
| 14 |
| 15 import org.chromium.base.ApiCompatibilityUtils; |
| 16 import org.chromium.chrome.R; |
| 17 |
| 18 import java.lang.annotation.Retention; |
| 19 import java.lang.annotation.RetentionPolicy; |
| 20 |
| 21 /** |
| 22 * An extension of the ScrollView that supports edge boundaries coming in. |
| 23 */ |
| 24 public class FadingEdgeScrollView extends ScrollView { |
| 25 /** Draw no lines at all. */ |
| 26 public static final int DRAW_NO_EDGE = 0; |
| 27 |
| 28 /** Draw an edge that fades in, depending on how much is left to scroll. */ |
| 29 public static final int DRAW_FADING_EDGE = 1; |
| 30 |
| 31 /** Draw either no line (if there is nothing to scroll) or a fully opaque li
ne. */ |
| 32 public static final int DRAW_HARD_EDGE = 2; |
| 33 |
| 34 @Retention(RetentionPolicy.SOURCE) |
| 35 @IntDef({DRAW_NO_EDGE, DRAW_FADING_EDGE, DRAW_HARD_EDGE}) |
| 36 public @interface EdgeType {} |
| 37 |
| 38 private static final int POSITION_TOP = 0; |
| 39 private static final int POSITION_BOTTOM = 1; |
| 40 |
| 41 private final Paint mSeparatorPaint = new Paint(); |
| 42 private final int mSeparatorColor; |
| 43 private final int mSeparatorHeight; |
| 44 |
| 45 @EdgeType |
| 46 private int mDrawTopEdge = DRAW_FADING_EDGE; |
| 47 @EdgeType |
| 48 private int mDrawBottomEdge = DRAW_FADING_EDGE; |
| 49 |
| 50 public FadingEdgeScrollView(Context context, AttributeSet attrs) { |
| 51 super(context, attrs); |
| 52 |
| 53 mSeparatorColor = |
| 54 ApiCompatibilityUtils.getColor(getResources(), R.color.toolbar_s
hadow_color); |
| 55 mSeparatorHeight = getResources().getDimensionPixelSize(R.dimen.separato
r_height); |
| 56 } |
| 57 |
| 58 @Override |
| 59 protected void dispatchDraw(Canvas canvas) { |
| 60 super.dispatchDraw(canvas); |
| 61 setVerticalFadingEdgeEnabled(true); |
| 62 float topEdgeStrength = getTopFadingEdgeStrength(); |
| 63 float bottomEdgeStrength = getBottomFadingEdgeStrength(); |
| 64 setVerticalFadingEdgeEnabled(false); |
| 65 |
| 66 drawBoundaryLine(canvas, POSITION_TOP, topEdgeStrength, mDrawTopEdge); |
| 67 drawBoundaryLine(canvas, POSITION_BOTTOM, bottomEdgeStrength, mDrawBotto
mEdge); |
| 68 } |
| 69 |
| 70 /** |
| 71 * Sets which edge should be drawn. |
| 72 * @param topEdgeType Whether to draw the edge on the top part of the vie
w. |
| 73 * @param bottomEdgeType Whether to draw the edge on the bottom part of the
view. |
| 74 */ |
| 75 public void setEdgeVisibility(@EdgeType int topEdgeType, @EdgeType int botto
mEdgeType) { |
| 76 mDrawTopEdge = topEdgeType; |
| 77 mDrawBottomEdge = bottomEdgeType; |
| 78 invalidate(); |
| 79 } |
| 80 |
| 81 /** |
| 82 * Draws a line at the top or bottom of the view. This should be called from
dispatchDraw() so |
| 83 * it gets drawn on top of the View's children. |
| 84 * |
| 85 * @param canvas The canvas on which to draw. |
| 86 * @param position Where to draw the line: either POSITION_TOP or POSITI
ON_BOTTOM. |
| 87 * @param edgeStrength A value between 0 and 1 indicating the relative size
of the line. 0 |
| 88 * means no line at all. 1 means a fully opaque line. |
| 89 * @param edgeType How to draw the line. |
| 90 */ |
| 91 private void drawBoundaryLine( |
| 92 Canvas canvas, int position, float edgeStrength, @EdgeType int edgeT
ype) { |
| 93 if (edgeType == DRAW_NO_EDGE) { |
| 94 return; |
| 95 } else if (edgeType == DRAW_FADING_EDGE) { |
| 96 edgeStrength = Math.max(0.0f, Math.min(1.0f, edgeStrength)); |
| 97 } else { |
| 98 edgeStrength = 1.0f; |
| 99 } |
| 100 if (edgeStrength <= 0.0f) return; |
| 101 |
| 102 int adjustedA = (int) (Color.alpha(mSeparatorColor) * edgeStrength); |
| 103 int adjustedR = (int) (Color.red(mSeparatorColor) * edgeStrength); |
| 104 int adjustedG = (int) (Color.green(mSeparatorColor) * edgeStrength); |
| 105 int adjustedB = (int) (Color.blue(mSeparatorColor) * edgeStrength); |
| 106 mSeparatorPaint.setColor(Color.argb(adjustedA, adjustedR, adjustedG, adj
ustedB)); |
| 107 |
| 108 int left = getScrollX(); |
| 109 int right = left + getRight(); |
| 110 |
| 111 if (position == POSITION_BOTTOM) { |
| 112 int bottom = getScrollY() + getBottom() - getTop(); |
| 113 canvas.drawRect(left, bottom - mSeparatorHeight, right, bottom, mSep
aratorPaint); |
| 114 } else if (position == POSITION_TOP) { |
| 115 int top = getScrollY(); |
| 116 canvas.drawRect(left, top, right, top + mSeparatorHeight, mSeparator
Paint); |
| 117 } |
| 118 } |
| 119 } |
OLD | NEW |