Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1029)

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/widget/ClipDrawableProgressBar.java

Issue 1170843002: [Andorid] Migrate to ClipDrawable progress bar. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: ChromeShell test fix 2 Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/android/java/src/org/chromium/chrome/browser/widget/ClipDrawableProgressBar.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/ClipDrawableProgressBar.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/ClipDrawableProgressBar.java
new file mode 100644
index 0000000000000000000000000000000000000000..eabd8e3fa80c023bace448cfc7261f561d89fa75
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/ClipDrawableProgressBar.java
@@ -0,0 +1,248 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.widget;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Color;
+import android.graphics.Rect;
+import android.graphics.drawable.ClipDrawable;
+import android.graphics.drawable.ColorDrawable;
+import android.support.v4.view.ViewCompat;
+import android.util.AttributeSet;
+import android.view.Gravity;
+import android.widget.ImageView;
+
+import org.chromium.base.ApiCompatibilityUtils;
+import org.chromium.chrome.R;
+
+/**
+ * An alternative progress bar implemented using ClipDrawable for simplicity and performance.
+ */
+public class ClipDrawableProgressBar extends ImageView {
+
+ // ClipDrawable's max is a fixed constant 10000.
+ // http://developer.android.com/reference/android/graphics/drawable/ClipDrawable.html
+ private static final int CLIP_DRAWABLE_MAX = 10000;
+
+ private final Rect mDirtyBound = new Rect();
+ private InvalidationListener mListener;
+ private int mProgressBarColor = Color.TRANSPARENT;
+ private int mBackgroundColor = Color.TRANSPARENT;
+ private boolean mIsLastInvalidationProgressChange;
+ private float mProgress;
+ private int mDesiredVisibility;
+
+ /**
+ * Interface for listening to drawing invalidation.
+ */
+ public interface InvalidationListener {
+ /**
+ * Called on drawing invalidation.
+ * @param dirtyRect Invalidated area.
+ */
+ void onInvalidation(Rect dirtyRect);
+ }
+
+ /**
+ * Constructor for inflating from XML.
+ */
+ public ClipDrawableProgressBar(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(context, attrs, 0);
+ }
+
+ private void init(Context context, AttributeSet attrs, int defStyle) {
+ mDesiredVisibility = getVisibility();
+
+ assert attrs != null;
+ TypedArray a = context.obtainStyledAttributes(
+ attrs, R.styleable.ClipDrawableProgressBar, defStyle, 0);
+ mProgressBarColor = a.getColor(
+ R.styleable.ClipDrawableProgressBar_progressBarColor, Color.TRANSPARENT);
+ assert mProgressBarColor != Color.TRANSPARENT;
+ mBackgroundColor = a.getColor(
+ R.styleable.ClipDrawableProgressBar_backgroundColor, Color.TRANSPARENT);
+ a.recycle();
+
+ setImageDrawable(new ClipDrawable(new ColorDrawable(mProgressBarColor), Gravity.START,
+ ClipDrawable.HORIZONTAL));
+ setBackgroundColor(mBackgroundColor);
+ }
+
+ /**
+ * Get the progress bar's current level of progress.
+ *
+ * @return The current progress, between 0.0 and 1.0.
+ */
+ public float getProgress() {
+ return mProgress;
+ }
+
+ /**
+ * Set the current progress to the specified value.
+ *
+ * @param progress The new progress, between 0.0 and 1.0.
+ */
+ public void setProgress(float progress) {
+ assert 0.0f <= progress && progress <= 1.0f;
+ if (mProgress == progress) return;
+
+ float currentProgress = mProgress;
+ mProgress = progress;
+ getDrawable().setLevel(Math.round(progress * CLIP_DRAWABLE_MAX));
+
+ if (getVisibility() == VISIBLE && mListener != null) {
+ if (mIsLastInvalidationProgressChange) {
+ float left = Math.min(currentProgress, progress);
+ float right = Math.max(currentProgress, progress);
+
+ if (ApiCompatibilityUtils.isLayoutRtl(this)) {
+ float leftTemp = left;
+ left = 1.0f - right;
+ right = 1.0f - leftTemp;
+ }
+
+ mDirtyBound.set((int) (left * getWidth()), 0,
+ (int) Math.ceil(right * getWidth()), getHeight());
+ mListener.onInvalidation(mDirtyBound);
+ } else {
+ mListener.onInvalidation(null);
+ }
+
+ mIsLastInvalidationProgressChange = true;
+ }
+ }
+
+ /**
+ * @return Background color of this progress bar.
+ */
+ public int getProgressBarBackgroundColor() {
+ return mBackgroundColor;
+ }
+
+ /**
+ * Adds an observer to be notified of drawing invalidation.
+ *
+ * @param listener The observer to be added.
+ */
+ public void setInvalidationListener(InvalidationListener listener) {
+ mListener = listener;
+ mIsLastInvalidationProgressChange = false;
+ }
+
+ /**
+ * Get a rect that contains all the non-opaque pixels.
+ * @param alphaBound Instance used to return the result.
+ */
+ public void getAlphaDrawRegion(Rect alphaBound) {
+ if (getAlpha() < 1.0f) {
+ alphaBound.set(0, 0, getWidth(), getHeight());
+ return;
+ }
+
+ alphaBound.setEmpty();
+ if (Color.alpha(mBackgroundColor) < 255) {
+ if (ApiCompatibilityUtils.isLayoutRtl(this)) {
+ alphaBound.set(0, 0, (int) Math.ceil(mProgress * getWidth()), getHeight());
+ } else {
+ alphaBound.set((int) (mProgress * getWidth()), 0, getWidth(), getHeight());
+ }
+ }
+ if (Color.alpha(mProgressBarColor) < 255) {
+ if (ApiCompatibilityUtils.isLayoutRtl(this)) {
+ alphaBound.union((int) (mProgress * getWidth()), 0, getWidth(), getHeight());
+ } else {
+ alphaBound.union(0, 0, (int) Math.ceil(mProgress * getWidth()), getHeight());
+ }
+ }
+
+ return;
+ }
+
+ /**
+ * @return Whether the actual internal visibility is changed.
+ */
+ private boolean updateInternalVisibility() {
+ int oldVisibility = getVisibility();
+ int newVisibility = mDesiredVisibility;
+ if (getAlpha() == 0 && mDesiredVisibility == VISIBLE) {
+ newVisibility = INVISIBLE;
+ }
+
+ if (oldVisibility != newVisibility) {
+ super.setVisibility(newVisibility);
+ if (mListener != null) {
+ mListener.onInvalidation(null);
+ mIsLastInvalidationProgressChange = false;
+ }
+ return true;
+ }
+
+ return false;
+ }
+
+ // View implementations.
+
+ /**
+ * Note that this visibility might not be respected for optimization. For example, if alpha
+ * is 0, it will remain View#INVISIBLE even if this is called with View#VISIBLE.
+ */
+ @Override
+ public void setVisibility(int visibility) {
+ mDesiredVisibility = visibility;
+ updateInternalVisibility();
+ }
+
+ @Override
+ public void setBackgroundColor(int color) {
+ if (color == Color.TRANSPARENT) {
+ setBackground(null);
+ } else {
+ super.setBackgroundColor(color);
+ }
+
+ mBackgroundColor = color;
+
+ if (mListener != null && getVisibility() == VISIBLE) {
+ mListener.onInvalidation(null);
+ mIsLastInvalidationProgressChange = false;
+ }
+ }
+
+ @Override
+ protected boolean onSetAlpha(int alpha) {
+ boolean result = super.onSetAlpha(alpha);
+
+ if (mListener != null && !updateInternalVisibility()) {
+ mListener.onInvalidation(null);
+ mIsLastInvalidationProgressChange = false;
+ }
+
+ return result;
+ }
+
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ super.onSizeChanged(w, h, oldw, oldh);
+
+ if (mListener != null && getVisibility() == VISIBLE && (w != oldw || h != oldh)) {
+ mListener.onInvalidation(null);
+ mIsLastInvalidationProgressChange = false;
+ }
+ }
+
+ @Override
+ public void onRtlPropertiesChanged(int layoutDirection) {
+ int currentLayoutDirection = ViewCompat.getLayoutDirection(this);
+ super.onRtlPropertiesChanged(layoutDirection);
+
+ if (mListener != null && getVisibility() == VISIBLE
+ && currentLayoutDirection != layoutDirection) {
+ mListener.onInvalidation(null);
+ mIsLastInvalidationProgressChange = false;
+ }
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698