diff --git a/project.properties b/project.properties
index dc64c26eb..fce0b28ee 100644
--- a/project.properties
+++ b/project.properties
@@ -12,5 +12,4 @@ proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.
# Project target.
target=android-21
-android.library.reference.1=../../code/FloatingActionButton/FloatingActionButton
-android.library.reference.2=../../code/material-menu/library/src/main
+android.library.reference.1=..\\..\\code\\FloatingActionButton\\FloatingActionButton
diff --git a/res/values-v21/themes.xml b/res/values-v21/themes.xml
new file mode 100644
index 000000000..af2c01397
--- /dev/null
+++ b/res/values-v21/themes.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/com/hippo/ehviewer/drawable/MaterialIndicatorDrawable.java b/src/com/hippo/ehviewer/drawable/MaterialIndicatorDrawable.java
new file mode 100644
index 000000000..b0cde2dd9
--- /dev/null
+++ b/src/com/hippo/ehviewer/drawable/MaterialIndicatorDrawable.java
@@ -0,0 +1,695 @@
+/*
+ * Copyright (C) 2014 Balys Valentukevicius
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.hippo.ehviewer.drawable;
+
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.Paint.Style;
+import android.graphics.PixelFormat;
+import android.graphics.drawable.Animatable;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.util.Property;
+import android.util.TypedValue;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.Interpolator;
+
+
+public class MaterialIndicatorDrawable extends Drawable implements Animatable {
+
+ private static final String STATE_KEY = "material_menu_icon_state";
+
+ public enum IconState {
+ BURGER, ARROW
+ }
+
+ public enum AnimationState {
+ BURGER_ARROW;
+
+ public IconState getFirstState() {
+ switch (this) {
+ case BURGER_ARROW:
+ return IconState.BURGER;
+ default:
+ return null;
+ }
+ }
+
+ public IconState getSecondState() {
+ switch (this) {
+ case BURGER_ARROW:
+ return IconState.ARROW;
+ default:
+ return null;
+ }
+ }
+ }
+
+ public enum Stroke {
+ /**
+ * 3 dip
+ */
+ REGULAR(3),
+ /**
+ * 2 dip
+ */
+ THIN(2),
+ /**
+ * 1 dip
+ */
+ EXTRA_THIN(1);
+
+ private final int strokeWidth;
+
+ Stroke(int strokeWidth) {
+ this.strokeWidth = strokeWidth;
+ }
+
+ protected static Stroke valueOf(int strokeWidth) {
+ switch (strokeWidth) {
+ case 3:
+ return REGULAR;
+ case 2:
+ return THIN;
+ case 1:
+ return EXTRA_THIN;
+ default:
+ return THIN;
+ }
+ }
+ }
+
+ public static final int DEFAULT_COLOR = Color.WHITE;
+ public static final int DEFAULT_SCALE = 1;
+ public static final int DEFAULT_TRANSFORM_DURATION = 800;
+ public static final int DEFAULT_PRESSED_DURATION = 400;
+
+ private static final int BASE_DRAWABLE_WIDTH = 40;
+ private static final int BASE_DRAWABLE_HEIGHT = 40;
+ private static final int BASE_ICON_WIDTH = 20;
+ private static final int BASE_CIRCLE_RADIUS = 18;
+
+ private static final float ARROW_MID_LINE_ANGLE = 180;
+ private static final float ARROW_TOP_LINE_ANGLE = 135;
+ private static final float ARROW_BOT_LINE_ANGLE = 225;
+
+ private static final float TRANSFORMATION_START = 0;
+ private static final float TRANSFORMATION_MID = 1.0f;
+ private static final float TRANSFORMATION_END = 2.0f;
+
+ private static final int DEFAULT_CIRCLE_ALPHA = 200;
+
+ private final float diph;
+ private final float dip1;
+ private final float dip2;
+ private final float dip3;
+ private final float dip4;
+
+ private final int width;
+ private final int height;
+ private final float strokeWidth;
+ private final float iconWidth;
+ private final float topPadding;
+ private final float sidePadding;
+ private final float circleRadius;
+
+ private final Stroke stroke;
+
+ private final Object lock = new Object();
+
+ private final Paint gridPaint = new Paint();
+ private final Paint iconPaint = new Paint();
+ private final Paint circlePaint = new Paint();
+
+ private float transformationValue = 0f;
+ private float pressedProgressValue = 0f;
+ private boolean transformationRunning = false;
+
+ private IconState currentIconState = IconState.BURGER;
+ private AnimationState animationState = AnimationState.BURGER_ARROW;
+
+ private IconState animatingIconState;
+ private boolean drawTouchCircle;
+ private boolean neverDrawTouch;
+ private boolean rtlEnabled;
+
+ private ObjectAnimator transformation;
+ private ObjectAnimator pressedCircle;
+
+ private MaterialMenuState materialMenuState;
+
+ public MaterialIndicatorDrawable(Context context, int color, Stroke stroke) {
+ this(context, color, stroke, DEFAULT_SCALE, DEFAULT_TRANSFORM_DURATION, DEFAULT_PRESSED_DURATION);
+ }
+
+ public MaterialIndicatorDrawable(Context context, int color, Stroke stroke, int transformDuration, int pressedDuration) {
+ this(context, color, stroke, DEFAULT_SCALE, transformDuration, pressedDuration);
+ }
+
+ public MaterialIndicatorDrawable(Context context, int color, Stroke stroke, int scale, int transformDuration, int pressedDuration) {
+ Resources resources = context.getResources();
+ // convert each separately due to various densities
+ this.dip1 = dpToPx(resources, 1) * scale;
+ this.dip2 = dpToPx(resources, 2) * scale;
+ this.dip3 = dpToPx(resources, 3) * scale;
+ this.dip4 = dpToPx(resources, 4) * scale;
+ this.diph = dip1 / 2;
+
+ this.stroke = stroke;
+ this.width = (int) (dpToPx(resources, BASE_DRAWABLE_WIDTH) * scale);
+ this.height = (int) (dpToPx(resources, BASE_DRAWABLE_HEIGHT) * scale);
+ this.iconWidth = dpToPx(resources, BASE_ICON_WIDTH) * scale;
+ this.circleRadius = dpToPx(resources, BASE_CIRCLE_RADIUS) * scale;
+ this.strokeWidth = dpToPx(resources, stroke.strokeWidth) * scale;
+
+ this.sidePadding = (width - iconWidth) / 2;
+ this.topPadding = (height - 5 * dip3) / 2;
+
+ initPaint(color);
+ initAnimations(transformDuration, pressedDuration);
+
+ materialMenuState = new MaterialMenuState();
+ }
+
+ private MaterialIndicatorDrawable(int color, Stroke stroke, long transformDuration, long pressedDuration,
+ int width, int height, float iconWidth, float circleRadius, float strokeWidth, float dip1
+ ) {
+ this.dip1 = dip1;
+ this.dip2 = dip1 * 2;
+ this.dip3 = dip1 * 3;
+ this.dip4 = dip1 * 4;
+ this.diph = dip1 / 2;
+ this.stroke = stroke;
+ this.width = width;
+ this.height = height;
+ this.iconWidth = iconWidth;
+ this.circleRadius = circleRadius;
+ this.strokeWidth = strokeWidth;
+ this.sidePadding = (width - iconWidth) / 2;
+ this.topPadding = (height - 5 * dip3) / 2;
+
+ initPaint(color);
+ initAnimations((int) transformDuration, (int) pressedDuration);
+
+ materialMenuState = new MaterialMenuState();
+ }
+
+ private void initPaint(int color) {
+ gridPaint.setAntiAlias(false);
+ gridPaint.setColor(Color.GREEN);
+ gridPaint.setStrokeWidth(1);
+
+ iconPaint.setAntiAlias(true);
+ iconPaint.setStyle(Style.STROKE);
+ iconPaint.setStrokeWidth(strokeWidth);
+ iconPaint.setColor(color);
+
+ circlePaint.setAntiAlias(true);
+ circlePaint.setStyle(Style.FILL);
+ circlePaint.setColor(color);
+ circlePaint.setAlpha(DEFAULT_CIRCLE_ALPHA);
+
+ setBounds(0, 0, width, height);
+ }
+
+ /*
+ * Drawing
+ */
+
+ @Override public void draw(Canvas canvas) {
+ final float ratio = transformationValue <= 1 ? transformationValue : 2 - transformationValue;
+
+ if (rtlEnabled) {
+ canvas.save();
+ canvas.scale(-1, 1, 0, 0);
+ canvas.translate(-getIntrinsicWidth(), 0);
+ }
+
+ drawTopLine(canvas, ratio);
+ drawMiddleLine(canvas, ratio);
+ drawBottomLine(canvas, ratio);
+
+ if (rtlEnabled) {
+ canvas.restore();
+ }
+
+ if (drawTouchCircle) drawTouchCircle(canvas);
+ }
+
+ private void drawTouchCircle(Canvas canvas) {
+ canvas.restore();
+ canvas.drawCircle(width / 2, height / 2, pressedProgressValue, circlePaint);
+ }
+
+ private void drawMiddleLine(Canvas canvas, float ratio) {
+ canvas.restore();
+ canvas.save();
+
+ float rotation = 0;
+ float pivotX = width / 2;
+ float pivotY = width / 2;
+ float startX = sidePadding;
+ float startY = topPadding + dip3 / 2 * 5;
+ float stopX = width - sidePadding;
+ float stopY = topPadding + dip3 / 2 * 5;
+ int alpha = 255;
+
+ switch (animationState) {
+ case BURGER_ARROW:
+ // rotate by 180
+ if (isMorphingForward()) {
+ rotation = ratio * ARROW_MID_LINE_ANGLE;
+ } else {
+ rotation = ARROW_MID_LINE_ANGLE + (1 - ratio) * ARROW_MID_LINE_ANGLE;
+ }
+ // shorten one end
+ stopX -= ratio * resolveStrokeModifier(ratio) / 2;
+ break;
+ }
+
+ iconPaint.setAlpha(alpha);
+ canvas.rotate(rotation, pivotX, pivotY);
+ canvas.drawLine(startX, startY, stopX, stopY, iconPaint);
+ iconPaint.setAlpha(255);
+ }
+
+ private void drawTopLine(Canvas canvas, float ratio) {
+ canvas.save();
+
+ float rotation = 0, pivotX = 0, pivotY = 0;
+ float rotation2 = 0;
+ // pivot at center of line
+ float pivotX2 = width / 2 + dip3 / 2;
+ float pivotY2 = topPadding + dip2;
+
+ float startX = sidePadding;
+ float startY = topPadding + dip2;
+ float stopX = width - sidePadding;
+ float stopY = topPadding + dip2;
+ int alpha = 255;
+
+ switch (animationState) {
+ case BURGER_ARROW:
+ if (isMorphingForward()) {
+ // rotate until required angle
+ rotation = ratio * ARROW_BOT_LINE_ANGLE;
+ } else {
+ // rotate back to start doing a 360
+ rotation = ARROW_BOT_LINE_ANGLE + (1 - ratio) * ARROW_TOP_LINE_ANGLE;
+ }
+ // rotate by middle
+ pivotX = width / 2;
+ pivotY = height / 2;
+
+ // shorten both ends
+ stopX -= resolveStrokeModifier(ratio);
+ startX += dip3 * ratio;
+
+ break;
+ }
+
+ iconPaint.setAlpha(alpha);
+ canvas.rotate(rotation, pivotX, pivotY);
+ canvas.rotate(rotation2, pivotX2, pivotY2);
+ canvas.drawLine(startX, startY, stopX, stopY, iconPaint);
+ iconPaint.setAlpha(255);
+ }
+
+ private void drawBottomLine(Canvas canvas, float ratio) {
+ canvas.restore();
+ canvas.save();
+
+ float rotation = 0, pivotX = 0, pivotY = 0;
+ float rotation2 = 0;
+ // pivot at center of line
+ float pivotX2 = width / 2 + dip3 / 2;
+ float pivotY2 = height - topPadding - dip2;
+
+ float startX = sidePadding;
+ float startY = height - topPadding - dip2;
+ float stopX = width - sidePadding;
+ float stopY = height - topPadding - dip2;
+
+ switch (animationState) {
+ case BURGER_ARROW:
+ if (isMorphingForward()) {
+ // rotate to required angle
+ rotation = ARROW_TOP_LINE_ANGLE * ratio;
+ } else {
+ // rotate back to start doing a 360
+ rotation = ARROW_TOP_LINE_ANGLE + (1 - ratio) * ARROW_BOT_LINE_ANGLE;
+ }
+ // pivot center of canvas
+ pivotX = width / 2;
+ pivotY = height / 2;
+
+ // shorten both ends
+ stopX = width - sidePadding - resolveStrokeModifier(ratio);
+ startX = sidePadding + dip3 * ratio;
+ break;
+ }
+
+ canvas.rotate(rotation, pivotX, pivotY);
+ canvas.rotate(rotation2, pivotX2, pivotY2);
+ canvas.drawLine(startX, startY, stopX, stopY, iconPaint);
+ }
+
+ private boolean isMorphingForward() {
+ return transformationValue <= TRANSFORMATION_MID;
+ }
+
+ private float resolveStrokeModifier(float ratio) {
+ switch (stroke) {
+ case REGULAR:
+ return ratio * dip3;
+ case THIN:
+ return ratio * (dip3 + diph);
+ case EXTRA_THIN:
+ return ratio * dip4;
+ }
+ return 0;
+ }
+
+ @Override public void setAlpha(int alpha) {
+ iconPaint.setAlpha(alpha);
+ }
+
+ @Override public void setColorFilter(ColorFilter cf) {
+ iconPaint.setColorFilter(cf);
+ }
+
+ @Override public int getOpacity() {
+ return PixelFormat.TRANSPARENT;
+ }
+
+ /*
+ * Accessor methods
+ */
+
+ public void setColor(int color) {
+ iconPaint.setColor(color);
+ circlePaint.setColor(color);
+ invalidateSelf();
+ }
+
+ public void setTransformationDuration(int duration) {
+ transformation.setDuration(duration);
+ }
+
+ public void setPressedDuration(int duration) {
+ pressedCircle.setDuration(duration);
+ }
+
+ public void setInterpolator(Interpolator interpolator) {
+ transformation.setInterpolator(interpolator);
+ }
+
+ public void setNeverDrawTouch(boolean neverDrawTouch) {
+ this.neverDrawTouch = neverDrawTouch;
+ }
+
+ public void setIconState(IconState iconState) {
+ synchronized (lock) {
+ if (transformationRunning) {
+ transformation.cancel();
+ transformationRunning = false;
+ }
+
+ if (currentIconState == iconState) return;
+
+ switch (iconState) {
+ case BURGER:
+ animationState = AnimationState.BURGER_ARROW;
+ transformationValue = TRANSFORMATION_START;
+ break;
+ case ARROW:
+ animationState = AnimationState.BURGER_ARROW;
+ transformationValue = TRANSFORMATION_MID;
+ break;
+ }
+ currentIconState = iconState;
+ invalidateSelf();
+ }
+ }
+
+ public void animateIconState(IconState state, boolean drawTouch) {
+ synchronized (lock) {
+ if (transformationRunning) {
+ transformation.end();
+ pressedCircle.end();
+ }
+ drawTouchCircle = drawTouch;
+ animatingIconState = state;
+ start();
+ }
+ }
+
+ public IconState setTransformationOffset(AnimationState animationState, float offset) {
+ if (offset < TRANSFORMATION_START || offset > TRANSFORMATION_END) {
+ throw new IllegalArgumentException(
+ String.format("Value must be between %s and %s", TRANSFORMATION_START, TRANSFORMATION_END)
+ );
+ }
+
+ this.animationState = animationState;
+
+ final boolean isFirstIcon = offset < TRANSFORMATION_MID || offset == TRANSFORMATION_END;
+
+ currentIconState = isFirstIcon ? animationState.getFirstState() : animationState.getSecondState();
+ animatingIconState = isFirstIcon ? animationState.getSecondState() : animationState.getFirstState();
+
+ setTransformationValue(offset);
+
+ return currentIconState;
+ }
+
+ public void setRTLEnabled(boolean rtlEnabled) {
+ this.rtlEnabled = rtlEnabled;
+ invalidateSelf();
+ }
+
+ public IconState getIconState() {
+ return currentIconState;
+ }
+
+ /*
+ * Animations
+ */
+ private final Property transformationProperty
+ = new Property(Float.class, "transformation") {
+ @Override
+ public Float get(MaterialIndicatorDrawable object) {
+ return object.getTransformationValue();
+ }
+
+ @Override
+ public void set(MaterialIndicatorDrawable object, Float value) {
+ object.setTransformationValue(value);
+ }
+ };
+
+ private final Property pressedProgressProperty
+ = new Property(Float.class, "pressedProgress") {
+ @Override
+ public Float get(MaterialIndicatorDrawable object) {
+ return object.getPressedProgress();
+ }
+
+ @Override
+ public void set(MaterialIndicatorDrawable object, Float value) {
+ object.setPressedProgress(value);
+ }
+ };
+
+ public Float getTransformationValue() {
+ return transformationValue;
+ }
+
+ public void setTransformationValue(Float value) {
+ this.transformationValue = value;
+ invalidateSelf();
+ }
+
+ public Float getPressedProgress() {
+ return pressedProgressValue;
+ }
+
+ public void setPressedProgress(Float value) {
+ this.pressedProgressValue = value;
+ circlePaint.setAlpha((int) (DEFAULT_CIRCLE_ALPHA * (1 - value / (circleRadius * 1.22f))));
+ invalidateSelf();
+ }
+
+ private void initAnimations(int transformDuration, int pressedDuration) {
+ transformation = ObjectAnimator.ofFloat(this, transformationProperty, 0);
+ transformation.setInterpolator(new DecelerateInterpolator(3));
+ transformation.setDuration(transformDuration);
+ transformation.addListener(new AnimatorListenerAdapter() {
+ @Override public void onAnimationEnd(Animator animation) {
+ transformationRunning = false;
+ setIconState(animatingIconState);
+ }
+ });
+
+
+ pressedCircle = ObjectAnimator.ofFloat(this, pressedProgressProperty, 0, 0);
+ pressedCircle.setDuration(pressedDuration);
+ pressedCircle.setInterpolator(new DecelerateInterpolator());
+ pressedCircle.addListener(new AnimatorListenerAdapter() {
+ @Override public void onAnimationEnd(Animator animation) {
+ pressedProgressValue = 0;
+ }
+
+ @Override public void onAnimationCancel(Animator animation) {
+ pressedProgressValue = 0;
+ }
+ });
+ }
+
+ private boolean resolveTransformation() {
+ boolean isCurrentBurger = currentIconState == IconState.BURGER;
+ boolean isCurrentArrow = currentIconState == IconState.ARROW;
+ boolean isAnimatingBurger = animatingIconState == IconState.BURGER;
+ boolean isAnimatingArrow = animatingIconState == IconState.ARROW;
+
+ if ((isCurrentBurger && isAnimatingArrow) || (isCurrentArrow && isAnimatingBurger)) {
+ animationState = AnimationState.BURGER_ARROW;
+ return isCurrentBurger;
+ }
+
+ throw new IllegalStateException(
+ String.format("Animating from %s to %s is not supported", currentIconState, animatingIconState)
+ );
+ }
+
+ @Override public void start() {
+ if (transformationRunning || animatingIconState == null || animatingIconState == currentIconState) return;
+ transformationRunning = true;
+
+ final boolean direction = resolveTransformation();
+ transformation.setFloatValues(
+ direction ? TRANSFORMATION_START : TRANSFORMATION_MID,
+ direction ? TRANSFORMATION_MID : TRANSFORMATION_END
+ );
+ transformation.start();
+
+ if (pressedCircle.isRunning()) {
+ pressedCircle.cancel();
+ }
+ if (drawTouchCircle && !neverDrawTouch) {
+ pressedCircle.setFloatValues(0, circleRadius * 1.22f);
+ pressedCircle.start();
+ }
+
+ invalidateSelf();
+ }
+
+ @Override public void stop() {
+ if (isRunning() && transformation.isRunning()) {
+ transformation.end();
+ } else {
+ transformationRunning = false;
+ invalidateSelf();
+ }
+ }
+
+ @Override public boolean isRunning() {
+ return transformationRunning;
+ }
+
+ @Override
+ public int getIntrinsicWidth() {
+ return width;
+ }
+
+ @Override
+ public int getIntrinsicHeight() {
+ return height;
+ }
+
+
+ @Override
+ public ConstantState getConstantState() {
+ materialMenuState.changingConfigurations = getChangingConfigurations();
+ return materialMenuState;
+ }
+
+ @Override
+ public Drawable mutate() {
+ materialMenuState = new MaterialMenuState();
+ return this;
+ }
+
+ /**
+ * Call from {@link android.app.Activity#onSaveInstanceState(android.os.Bundle)} to store current icon state
+ *
+ * @param outState outState
+ */
+ public void onSaveInstanceState(Bundle outState) {
+ outState.putString(STATE_KEY, currentIconState.name());
+ }
+
+ /**
+ * Call from {@link android.app.Activity#onPostCreate(android.os.Bundle)} to restore icon state
+ *
+ * @param state state
+ */
+ public void syncState(Bundle state) {
+ if (state != null) {
+ String iconStateName = state.getString(STATE_KEY);
+ if (iconStateName == null) {
+ iconStateName = MaterialIndicatorDrawable.IconState.BURGER.name();
+ }
+ setIconState(MaterialIndicatorDrawable.IconState.valueOf(iconStateName));
+ }
+ }
+
+ private final class MaterialMenuState extends ConstantState {
+ private int changingConfigurations;
+
+ private MaterialMenuState() {
+ }
+
+ @Override
+ public Drawable newDrawable() {
+ MaterialIndicatorDrawable drawable = new MaterialIndicatorDrawable(
+ circlePaint.getColor(), stroke, transformation.getDuration(),
+ pressedCircle.getDuration(), width, height, iconWidth, circleRadius, strokeWidth, dip1
+ );
+ drawable.setIconState(animatingIconState != null ? animatingIconState : currentIconState);
+ drawable.setRTLEnabled(rtlEnabled);
+ return drawable;
+ }
+
+ @Override
+ public int getChangingConfigurations() {
+ return changingConfigurations;
+ }
+ }
+
+ static float dpToPx(Resources resources, float dp) {
+ return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, resources.getDisplayMetrics());
+ }
+}
diff --git a/src/com/hippo/ehviewer/ui/DownloadActivity.java b/src/com/hippo/ehviewer/ui/DownloadActivity.java
index 18a49976b..c343d9d0c 100644
--- a/src/com/hippo/ehviewer/ui/DownloadActivity.java
+++ b/src/com/hippo/ehviewer/ui/DownloadActivity.java
@@ -37,9 +37,6 @@ import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
-import com.balysv.materialmenu.MaterialMenuDrawable;
-import com.balysv.materialmenu.MaterialMenuDrawable.Stroke;
-import com.balysv.materialmenu.MaterialMenuIcon;
import com.hippo.ehviewer.ImageLoader;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.app.MaterialAlertDialog;
@@ -47,6 +44,8 @@ import com.hippo.ehviewer.cardview.CardViewSalon;
import com.hippo.ehviewer.data.Data;
import com.hippo.ehviewer.data.DownloadInfo;
import com.hippo.ehviewer.data.GalleryInfo;
+import com.hippo.ehviewer.drawable.MaterialIndicatorDrawable;
+import com.hippo.ehviewer.drawable.MaterialIndicatorDrawable.Stroke;
import com.hippo.ehviewer.service.DownloadService;
import com.hippo.ehviewer.service.DownloadServiceConnection;
import com.hippo.ehviewer.util.Config;
@@ -103,8 +102,9 @@ public class DownloadActivity extends AbsActivity implements FitWindowView.OnFit
registerReceiver(mReceiver, filter);
// Menu
- MaterialMenuIcon materialMenu = new MaterialMenuIcon(this, Color.WHITE, Stroke.THIN);
- materialMenu.setState(MaterialMenuDrawable.IconState.ARROW);
+ MaterialIndicatorDrawable materialIndicator = new MaterialIndicatorDrawable(this, Color.WHITE, Stroke.THIN);
+ materialIndicator.setIconState(MaterialIndicatorDrawable.IconState.ARROW);
+ Ui.setMaterialIndicator(getActionBar(), materialIndicator);
mDownloads = Data.getInstance().getAllDownloads();
for (DownloadInfo di : mDownloads)
diff --git a/src/com/hippo/ehviewer/ui/FavouriteActivity.java b/src/com/hippo/ehviewer/ui/FavouriteActivity.java
index 71a7cd1e9..1c54ef990 100644
--- a/src/com/hippo/ehviewer/ui/FavouriteActivity.java
+++ b/src/com/hippo/ehviewer/ui/FavouriteActivity.java
@@ -53,9 +53,6 @@ import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
-import com.balysv.materialmenu.MaterialMenuDrawable;
-import com.balysv.materialmenu.MaterialMenuDrawable.Stroke;
-import com.balysv.materialmenu.MaterialMenuIcon;
import com.hippo.ehviewer.ImageLoader;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.app.MaterialAlertDialog;
@@ -63,6 +60,8 @@ import com.hippo.ehviewer.app.MaterialProgressDialog;
import com.hippo.ehviewer.cardview.CardViewSalon;
import com.hippo.ehviewer.data.Data;
import com.hippo.ehviewer.data.GalleryInfo;
+import com.hippo.ehviewer.drawable.MaterialIndicatorDrawable;
+import com.hippo.ehviewer.drawable.MaterialIndicatorDrawable.Stroke;
import com.hippo.ehviewer.ehclient.EhClient;
import com.hippo.ehviewer.service.DownloadService;
import com.hippo.ehviewer.service.DownloadServiceConnection;
@@ -169,8 +168,9 @@ public class FavouriteActivity extends AbsActivity
bindService(it, mServiceConn, BIND_AUTO_CREATE);
// Menu
- MaterialMenuIcon materialMenu = new MaterialMenuIcon(this, Color.WHITE, Stroke.THIN);
- materialMenu.setState(MaterialMenuDrawable.IconState.ARROW);
+ MaterialIndicatorDrawable materialIndicator = new MaterialIndicatorDrawable(this, Color.WHITE, Stroke.THIN);
+ materialIndicator.setIconState(MaterialIndicatorDrawable.IconState.ARROW);
+ Ui.setMaterialIndicator(getActionBar(), materialIndicator);
// Get View
mDrawerLayout = (SlidingDrawerLayout) findViewById(R.id.drawerlayout);
diff --git a/src/com/hippo/ehviewer/ui/GalleryDetailActivity.java b/src/com/hippo/ehviewer/ui/GalleryDetailActivity.java
index 29bd93b73..2b7b2052d 100644
--- a/src/com/hippo/ehviewer/ui/GalleryDetailActivity.java
+++ b/src/com/hippo/ehviewer/ui/GalleryDetailActivity.java
@@ -58,9 +58,6 @@ import android.widget.TextSwitcher;
import android.widget.TextView;
import android.widget.ViewSwitcher;
-import com.balysv.materialmenu.MaterialMenuDrawable;
-import com.balysv.materialmenu.MaterialMenuDrawable.Stroke;
-import com.balysv.materialmenu.MaterialMenuIcon;
import com.faizmalkani.floatingactionbutton.FloatingActionButton;
import com.hippo.ehviewer.ImageLoader;
import com.hippo.ehviewer.R;
@@ -77,6 +74,8 @@ import com.hippo.ehviewer.data.LofiGalleryDetail;
import com.hippo.ehviewer.data.LofiGalleryInfo;
import com.hippo.ehviewer.data.PreviewImpl;
import com.hippo.ehviewer.data.PreviewList;
+import com.hippo.ehviewer.drawable.MaterialIndicatorDrawable;
+import com.hippo.ehviewer.drawable.MaterialIndicatorDrawable.Stroke;
import com.hippo.ehviewer.drawable.OvalDrawable;
import com.hippo.ehviewer.ehclient.DetailUrlParser;
import com.hippo.ehviewer.ehclient.EhClient;
@@ -294,8 +293,9 @@ public class GalleryDetailActivity extends AbsActivity
mResources = getResources();
// Menu
- MaterialMenuIcon materialMenu = new MaterialMenuIcon(this, Color.WHITE, Stroke.THIN);
- materialMenu.setState(MaterialMenuDrawable.IconState.ARROW);
+ MaterialIndicatorDrawable materialIndicator = new MaterialIndicatorDrawable(this, Color.WHITE, Stroke.THIN);
+ materialIndicator.setIconState(MaterialIndicatorDrawable.IconState.ARROW);
+ Ui.setMaterialIndicator(getActionBar(), materialIndicator);
// Get view
mStandard = (FitWindowView) findViewById(R.id.standard);
diff --git a/src/com/hippo/ehviewer/ui/GalleryListActivity.java b/src/com/hippo/ehviewer/ui/GalleryListActivity.java
index bce0ffb3c..65c660226 100644
--- a/src/com/hippo/ehviewer/ui/GalleryListActivity.java
+++ b/src/com/hippo/ehviewer/ui/GalleryListActivity.java
@@ -65,9 +65,6 @@ import android.widget.SearchView;
import android.widget.Spinner;
import android.widget.TextView;
-import com.balysv.materialmenu.MaterialMenuDrawable;
-import com.balysv.materialmenu.MaterialMenuDrawable.Stroke;
-import com.balysv.materialmenu.MaterialMenuIcon;
import com.etsy.android.grid.StaggeredGridView;
import com.hippo.ehviewer.AppContext;
import com.hippo.ehviewer.AppHandler;
@@ -81,6 +78,8 @@ import com.hippo.ehviewer.data.Data;
import com.hippo.ehviewer.data.GalleryInfo;
import com.hippo.ehviewer.data.ListUrls;
import com.hippo.ehviewer.data.Tag;
+import com.hippo.ehviewer.drawable.MaterialIndicatorDrawable;
+import com.hippo.ehviewer.drawable.MaterialIndicatorDrawable.Stroke;
import com.hippo.ehviewer.ehclient.EhClient;
import com.hippo.ehviewer.network.HttpHelper;
import com.hippo.ehviewer.service.DownloadService;
@@ -159,7 +158,7 @@ public class GalleryListActivity extends AbsActivity implements View.OnClickList
private ActionBar mActionBar;
private int mThemeColor;
- private MaterialMenuIcon mMaterialMenu;
+ private MaterialIndicatorDrawable mMaterialIndicator;
private boolean mDirection;
private SlidingDrawerLayout mDrawerLayout;
@@ -931,8 +930,8 @@ public class GalleryListActivity extends AbsActivity implements View.OnClickList
@Override
public void onDrawerSlide(View view, float f) {
if (view == mLeftMenu) {
- mMaterialMenu.setTransformationOffset(
- MaterialMenuDrawable.AnimationState.BURGER_ARROW,
+ mMaterialIndicator.setTransformationOffset(
+ MaterialIndicatorDrawable.AnimationState.BURGER_ARROW,
mDirection ? 2 - f : f);
}
}
@@ -959,12 +958,12 @@ public class GalleryListActivity extends AbsActivity implements View.OnClickList
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
- mMaterialMenu.syncState(savedInstanceState);
+ mMaterialIndicator.syncState(savedInstanceState);
}
@Override protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
- mMaterialMenu.onSaveInstanceState(outState);
+ mMaterialIndicator.onSaveInstanceState(outState);
}
@Override
@@ -1009,12 +1008,18 @@ public class GalleryListActivity extends AbsActivity implements View.OnClickList
mSearchDialog = createSearchDialog();
longClickDialog = createLongClickDialog();
+ ColorDrawable cd = new ColorDrawable(Color.WHITE);
+ cd.setBounds(0, 0, Ui.dp2pix(32), Ui.dp2pix(32));
+ this.
+
// Menu
- mMaterialMenu = new MaterialMenuIcon(this, Color.WHITE, Stroke.THIN);
+ mMaterialIndicator = new MaterialIndicatorDrawable(this, Color.WHITE, Stroke.THIN);
if (mShowDrawer)
- mMaterialMenu.setState(MaterialMenuDrawable.IconState.BURGER);
+ mMaterialIndicator.setIconState(MaterialIndicatorDrawable.IconState.BURGER);
else
- mMaterialMenu.setState(MaterialMenuDrawable.IconState.ARROW);
+ mMaterialIndicator.setIconState(MaterialIndicatorDrawable.IconState.ARROW);
+ mActionBar = getActionBar();
+ Ui.setMaterialIndicator(mActionBar, mMaterialIndicator);
// Get View
mDrawerLayout = (SlidingDrawerLayout) findViewById(R.id.drawerlayout);
@@ -1044,10 +1049,6 @@ public class GalleryListActivity extends AbsActivity implements View.OnClickList
mLogoutButton.setOnClickListener(this);
// Drawer
- mActionBar = getActionBar();
- mActionBar.setDisplayHomeAsUpEnabled(false);
- if (mShowDrawer && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2)
- mActionBar.setHomeAsUpIndicator(mResources.getDrawable(R.drawable.ic_navigation_drawer));
mDrawerLayout.setDrawerListener(this);
if (!mShowDrawer)
mDrawerLayout.setDrawerLockMode(SlidingDrawerLayout.LOCK_MODE_LOCKED_CLOSED, mLeftMenu);
diff --git a/src/com/hippo/ehviewer/ui/HistoryActivity.java b/src/com/hippo/ehviewer/ui/HistoryActivity.java
index fe376b41c..290509170 100644
--- a/src/com/hippo/ehviewer/ui/HistoryActivity.java
+++ b/src/com/hippo/ehviewer/ui/HistoryActivity.java
@@ -37,15 +37,14 @@ import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
-import com.balysv.materialmenu.MaterialMenuDrawable;
-import com.balysv.materialmenu.MaterialMenuDrawable.Stroke;
-import com.balysv.materialmenu.MaterialMenuIcon;
import com.hippo.ehviewer.ImageLoader;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.app.MaterialAlertDialog;
import com.hippo.ehviewer.cardview.CardViewSalon;
import com.hippo.ehviewer.data.Data;
import com.hippo.ehviewer.data.GalleryInfo;
+import com.hippo.ehviewer.drawable.MaterialIndicatorDrawable;
+import com.hippo.ehviewer.drawable.MaterialIndicatorDrawable.Stroke;
import com.hippo.ehviewer.util.Config;
import com.hippo.ehviewer.util.Theme;
import com.hippo.ehviewer.util.Ui;
@@ -159,7 +158,7 @@ public class HistoryActivity extends AbsActivity
}
@Override
- public void onCreate(Bundle savedInstanceState) {
+ protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.history);
@@ -167,8 +166,9 @@ public class HistoryActivity extends AbsActivity
mFilterMode = Config.getInt(KEY_HISTORY_FILTER, Data.BROWSE | Data.READ);
// Menu
- MaterialMenuIcon materialMenu = new MaterialMenuIcon(this, Color.WHITE, Stroke.THIN);
- materialMenu.setState(MaterialMenuDrawable.IconState.ARROW);
+ MaterialIndicatorDrawable materialIndicator = new MaterialIndicatorDrawable(this, Color.WHITE, Stroke.THIN);
+ materialIndicator.setIconState(MaterialIndicatorDrawable.IconState.ARROW);
+ Ui.setMaterialIndicator(getActionBar(), materialIndicator);
mThemeColor = Config.getRandomThemeColor() ? Theme.getRandomDarkColor() : Config.getThemeColor();
getActionBar().setBackgroundDrawable(new ColorDrawable(mThemeColor));
diff --git a/src/com/hippo/ehviewer/ui/SettingsActivity.java b/src/com/hippo/ehviewer/ui/SettingsActivity.java
index cca013daf..ed3828622 100644
--- a/src/com/hippo/ehviewer/ui/SettingsActivity.java
+++ b/src/com/hippo/ehviewer/ui/SettingsActivity.java
@@ -52,9 +52,6 @@ import android.widget.ListView;
import android.widget.TableLayout;
import android.widget.TextView;
-import com.balysv.materialmenu.MaterialMenuDrawable;
-import com.balysv.materialmenu.MaterialMenuDrawable.Stroke;
-import com.balysv.materialmenu.MaterialMenuIcon;
import com.hippo.ehviewer.AppContext;
import com.hippo.ehviewer.AppHandler;
import com.hippo.ehviewer.R;
@@ -65,6 +62,8 @@ import com.hippo.ehviewer.app.MaterialProgressDialog;
import com.hippo.ehviewer.data.ApiGalleryInfo;
import com.hippo.ehviewer.data.Data;
import com.hippo.ehviewer.data.DownloadInfo;
+import com.hippo.ehviewer.drawable.MaterialIndicatorDrawable;
+import com.hippo.ehviewer.drawable.MaterialIndicatorDrawable.Stroke;
import com.hippo.ehviewer.ehclient.EhClient;
import com.hippo.ehviewer.ehclient.EhInfo;
import com.hippo.ehviewer.network.HttpHelper;
@@ -118,8 +117,9 @@ public class SettingsActivity extends AbsPreferenceActivity implements FitWindow
getActionBar().setBackgroundDrawable(new ColorDrawable(mThemeColor));
// Menu
- MaterialMenuIcon materialMenu = new MaterialMenuIcon(this, Color.WHITE, Stroke.THIN);
- materialMenu.setState(MaterialMenuDrawable.IconState.ARROW);
+ MaterialIndicatorDrawable materialIndicator = new MaterialIndicatorDrawable(this, Color.WHITE, Stroke.THIN);
+ materialIndicator.setIconState(MaterialIndicatorDrawable.IconState.ARROW);
+ Ui.setMaterialIndicator(getActionBar(), materialIndicator);
mFragments = new LinkedList();
diff --git a/src/com/hippo/ehviewer/util/Theme.java b/src/com/hippo/ehviewer/util/Theme.java
index ac58866e2..8b5df06a0 100644
--- a/src/com/hippo/ehviewer/util/Theme.java
+++ b/src/com/hippo/ehviewer/util/Theme.java
@@ -50,7 +50,7 @@ public final class Theme {
public static int getDarkerColor(int color) {
float[] hsv = new float[3];
Color.colorToHSV(color, hsv);
- hsv[2] *= 0.8f;
+ hsv[2] *= 0.9f;
return Color.HSVToColor(hsv);
}
diff --git a/src/com/hippo/ehviewer/util/Ui.java b/src/com/hippo/ehviewer/util/Ui.java
index dddaba41e..ccd3ee107 100644
--- a/src/com/hippo/ehviewer/util/Ui.java
+++ b/src/com/hippo/ehviewer/util/Ui.java
@@ -17,6 +17,7 @@
package com.hippo.ehviewer.util;
import android.annotation.TargetApi;
+import android.app.ActionBar;
import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
@@ -42,6 +43,7 @@ import android.widget.FrameLayout.LayoutParams;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.data.ListUrls;
+import com.hippo.ehviewer.drawable.MaterialIndicatorDrawable;
public class Ui {
@SuppressWarnings("unused")
@@ -272,11 +274,14 @@ public class Ui {
Configuration c = activity.getResources().getConfiguration();
Window w = activity.getWindow();
- w.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
if (c.orientation == Configuration.ORIENTATION_PORTRAIT)
w.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
else if (c.orientation == Configuration.ORIENTATION_LANDSCAPE)
w.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
+
+ // For KK set a color view at top to make color status bar
+ if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT)
+ w.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
}
@@ -291,9 +296,10 @@ public class Ui {
activity.setRequestedOrientation(screenOri);
}
- @TargetApi(Build.VERSION_CODES.KITKAT)
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
public static void translucent(Activity activity, int color, int height) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ int darkColor = Theme.getDarkerColor(color);
+ if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {
View statusBarBgView;
FrameLayout.LayoutParams lp;
ViewGroup decorViewGroup = (ViewGroup) activity.getWindow().getDecorView();
@@ -305,16 +311,33 @@ public class Ui {
lp = (LayoutParams) statusBarBgView.getLayoutParams();
lp.height = height;
lp.gravity = Gravity.TOP;
- statusBarBgView.setBackgroundColor(color);
+ statusBarBgView.setBackgroundColor(darkColor);
statusBarBgView.setLayoutParams(lp);
} else {
statusBarBgView = new View(activity);
statusBarBgView.setId(R.id.translucent_view);
- statusBarBgView.setBackgroundColor(color);
+ statusBarBgView.setBackgroundColor(darkColor);
lp = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, height);
lp.gravity = Gravity.TOP;
decorViewGroup.addView(statusBarBgView, lp);
}
+ } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ activity.getWindow().setStatusBarColor(Theme.getDarkerColor(darkColor));
+ }
+ }
+
+ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
+ public static void setMaterialIndicator(ActionBar actionBar, MaterialIndicatorDrawable d) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
+ actionBar.setDisplayShowHomeEnabled(true);
+ actionBar.setHomeButtonEnabled(true);
+ actionBar.setDisplayHomeAsUpEnabled(false);
+ actionBar.setIcon(d);
+ } else {
+ actionBar.setHomeButtonEnabled(true);
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setHomeAsUpIndicator(d);
+ actionBar.setIcon(null);
}
}
}