diff --git a/app/src/main/java/com/hippo/drawable/AddDeleteDrawable.java b/app/src/main/java/com/hippo/drawable/AddDeleteDrawable.java index 62b872b3a..bd71db373 100644 --- a/app/src/main/java/com/hippo/drawable/AddDeleteDrawable.java +++ b/app/src/main/java/com/hippo/drawable/AddDeleteDrawable.java @@ -15,6 +15,7 @@ package com.hippo.drawable; +import android.animation.ObjectAnimator; import android.content.Context; import android.content.res.Resources; import android.graphics.Canvas; @@ -24,6 +25,7 @@ import android.graphics.Path; import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.drawable.Drawable; +import android.os.Build; import com.hippo.ehviewer.R; import com.hippo.util.MathUtils; @@ -127,6 +129,30 @@ public class AddDeleteDrawable extends Drawable { invalidateSelf(); } + public void setAdd(long duration) { + setShape(false, duration); + } + + public void setDelete(long duration) { + setShape(true, duration); + } + + public void setShape(boolean delete, long duration) { + if (!((!delete && mProgress == 0f) || (delete && mProgress == 1f))) { + float endProgress = delete ? 1f : 0f; + if (duration <= 0) { + setProgress(endProgress); + } else { + ObjectAnimator oa = ObjectAnimator.ofFloat(this, "progress", endProgress); + oa.setDuration(duration); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { + oa.setAutoCancel(true); + } + oa.start(); + } + } + } + @Override public int getOpacity() { return PixelFormat.TRANSLUCENT; diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.java index 11915aad9..af00c1ff3 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.java @@ -46,6 +46,7 @@ import com.hippo.util.Log; import com.hippo.util.MathUtils; import com.hippo.util.ViewUtils; import com.hippo.widget.FloatingActionButton; +import com.hippo.widget.FloatingActionButtonLayout; // TODO disable click action when animating public class GalleryListScene extends Scene implements SearchBar.Helper, @@ -72,6 +73,7 @@ public class GalleryListScene extends Scene implements SearchBar.Helper, private RecyclerView mContentRecyclerView; private SearchLayout mSearchLayout; private RecyclerView mSearchRecyclerView; + private FloatingActionButtonLayout mFabLayout; private FloatingActionButton mCornerFab; private ViewTransition mViewTransition; @@ -102,7 +104,8 @@ public class GalleryListScene extends Scene implements SearchBar.Helper, mContentRecyclerView = mContentLayout.getRecyclerView(); mSearchLayout = (SearchLayout) findViewById(R.id.search_layout); mSearchRecyclerView = mSearchLayout.getRecyclerView(); - mCornerFab = (FloatingActionButton) findViewById(R.id.fab); + mFabLayout = (FloatingActionButtonLayout) findViewById(R.id.fab_layout); + mCornerFab = mFabLayout.getPrimaryFab(); mViewTransition = new ViewTransition(mContentLayout, mSearchLayout); @@ -139,9 +142,9 @@ public class GalleryListScene extends Scene implements SearchBar.Helper, // Search Layout mSearchLayout.setFitPaddingBottom(b); // Corner Fab - FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mCornerFab.getLayoutParams(); + FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mFabLayout.getLayoutParams(); lp.bottomMargin = b + mCornerFabOriginalBottom; - mCornerFab.setLayoutParams(lp); + mFabLayout.setLayoutParams(lp); } private void setFabState(int fabState) { @@ -204,7 +207,8 @@ public class GalleryListScene extends Scene implements SearchBar.Helper, public void onClick(View v) { if (v == mCornerFab) { if (mFabState == FAB_STATE_NORMAL) { - // + mFabLayout.toggle(); + mAddDeleteDrawable.setShape(mFabLayout.getExpanded(), ANIMATE_TIME); } else if (mFabState == FAB_STATE_SEARCH) { onApplySearch(mSearchBar.getText()); } diff --git a/app/src/main/java/com/hippo/ehviewer/widget/SearchBar.java b/app/src/main/java/com/hippo/ehviewer/widget/SearchBar.java index 5f97066fe..d00ee08e5 100644 --- a/app/src/main/java/com/hippo/ehviewer/widget/SearchBar.java +++ b/app/src/main/java/com/hippo/ehviewer/widget/SearchBar.java @@ -61,7 +61,7 @@ public class SearchBar extends CardView implements View.OnClickListener, TextView.OnEditorActionListener, TextWatcher, SearchEditText.SearchEditTextListener, Messenger.Receiver { - private static final long ANIMATION_TIME = 300; + private static final long ANIMATE_TIME = 300l; private Path mPath = new Path(); private int mWidth; @@ -227,7 +227,7 @@ public class SearchBar extends CardView implements View.OnClickListener, // start animator if (mDrawerArrowDrawable.getProgress() != 1f) { ObjectAnimator oa1 = ObjectAnimator.ofFloat(mDrawerArrowDrawable, "progress", 0f, 1f); - oa1.setDuration(ANIMATION_TIME); + oa1.setDuration(ANIMATE_TIME); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { oa1.setAutoCancel(true); } @@ -235,7 +235,7 @@ public class SearchBar extends CardView implements View.OnClickListener, } if (mAddDeleteDrawable.getProgress() != 1f) { ObjectAnimator oa2 = ObjectAnimator.ofFloat(mAddDeleteDrawable, "progress", 0f, 1f); - oa2.setDuration(ANIMATION_TIME); + oa2.setDuration(ANIMATE_TIME); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { oa2.setAutoCancel(true); } @@ -257,7 +257,7 @@ public class SearchBar extends CardView implements View.OnClickListener, // start animator if (mDrawerArrowDrawable.getProgress() != 0f) { ObjectAnimator oa1 = ObjectAnimator.ofFloat(mDrawerArrowDrawable, "progress", 1f, 0f); - oa1.setDuration(ANIMATION_TIME); + oa1.setDuration(ANIMATE_TIME); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { oa1.setAutoCancel(true); } @@ -265,7 +265,7 @@ public class SearchBar extends CardView implements View.OnClickListener, } if (mAddDeleteDrawable.getProgress() != 0f) { ObjectAnimator oa2 = ObjectAnimator.ofFloat(mAddDeleteDrawable, "progress", 1f, 0f); - oa2.setDuration(ANIMATION_TIME); + oa2.setDuration(ANIMATE_TIME); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { oa2.setAutoCancel(true); } @@ -286,7 +286,7 @@ public class SearchBar extends CardView implements View.OnClickListener, // Show suggestions list if (mProgress != 1f) { ObjectAnimator oa = ObjectAnimator.ofFloat(this, "progress", 0f, 1f); - oa.setDuration(ANIMATION_TIME); + oa.setDuration(ANIMATE_TIME); oa.addListener(new SimpleAnimatorListener() { @Override public void onAnimationStart(Animator animation) { @@ -313,7 +313,7 @@ public class SearchBar extends CardView implements View.OnClickListener, // Hide suggestions list if (mProgress != 0f) { ObjectAnimator oa = ObjectAnimator.ofFloat(this, "progress", 1f, 0f); - oa.setDuration(ANIMATION_TIME); + oa.setDuration(ANIMATE_TIME); oa.addListener(new SimpleAnimatorListener() { @Override public void onAnimationStart(Animator animation) { diff --git a/app/src/main/java/com/hippo/widget/FloatingActionButton.java b/app/src/main/java/com/hippo/widget/FloatingActionButton.java index 999f86629..fb450540a 100644 --- a/app/src/main/java/com/hippo/widget/FloatingActionButton.java +++ b/app/src/main/java/com/hippo/widget/FloatingActionButton.java @@ -37,36 +37,32 @@ public class FloatingActionButton extends View { private GasketDrawer mGasketDrawer; private Drawable mDrawable; - private int mDrawableWidth; + private Drawable.Callback mDrawableCallback; public FloatingActionButton(Context context, AttributeSet attrs) { super(context, attrs); - init(context, attrs, 0, 0); + init(context, attrs); } public FloatingActionButton(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); - init(context, attrs, defStyleAttr, 0); + init(context, attrs); } - @TargetApi(Build.VERSION_CODES.LOLLIPOP) - public FloatingActionButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - init(context, attrs, defStyleAttr, defStyleRes); - } - - private void init(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - mDrawableWidth = UiUtils.dp2pix(context, 24); + private void init(Context context, AttributeSet attrs) { + mDrawableWidth = context.getResources().getDimensionPixelOffset(R.dimen.fab_drawable_size); + mDrawableCallback = new DrawableCallback(); TypedArray a; - a = context.obtainStyledAttributes(attrs, R.styleable.FloatingActionButton, defStyleAttr, defStyleRes); + a = context.obtainStyledAttributes(attrs, R.styleable.FloatingActionButton); int bgColor = a.getColor(R.styleable.FloatingActionButton_color, Color.BLACK); - mDrawable = a.getDrawable(R.styleable.FloatingActionButton_drawable); + setDrawable(a.getDrawable(R.styleable.FloatingActionButton_drawable)); + boolean forceNoElevation = a.getBoolean(R.styleable.FloatingActionButton_forceNoElevation, false); a.recycle(); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && !forceNoElevation) { mGasketDrawer = new GasketDrawerLollipop(this, bgColor); } else { mGasketDrawer = new GasketDrawerOld(this, bgColor); @@ -83,8 +79,7 @@ public class FloatingActionButton extends View { @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - setMeasuredDimension(ViewUtils.getSuitableSize(getSuggestedMinimumWidth(), widthMeasureSpec), - ViewUtils.getSuitableSize(getSuggestedMinimumHeight(), heightMeasureSpec)); + setMeasuredDimension(ViewUtils.getSuitableSize(getSuggestedMinimumWidth(), widthMeasureSpec), ViewUtils.getSuitableSize(getSuggestedMinimumHeight(), heightMeasureSpec)); } @Override @@ -113,6 +108,13 @@ public class FloatingActionButton extends View { } public void setDrawable(Drawable drawable) { + if (mDrawable != null) { + mDrawable.setCallback(null); + } + if (drawable != null) { + drawable.setCallback(mDrawableCallback); + } + mDrawable = drawable; invalidate(); } @@ -125,6 +127,24 @@ public class FloatingActionButton extends View { void setColor(int color); } + private class DrawableCallback implements Drawable.Callback { + @Override + public void invalidateDrawable(Drawable who) { + if (who == mDrawable) { + invalidate(); + } + } + + @Override + public void scheduleDrawable(Drawable who, Runnable what, long when) { + // Empty + } + + @Override + public void unscheduleDrawable(Drawable who, Runnable what) { + // Empty + } + } static class GasketDrawerOld implements GasketDrawer { @@ -163,6 +183,7 @@ public class FloatingActionButton extends View { ViewUtils.removeHardwareAccelerationSupport(mView); } + @Override public void onStateChange(int[] stateSet) { boolean enabled = false; boolean pressed = false; @@ -199,6 +220,7 @@ public class FloatingActionButton extends View { mView.invalidate(); } + @Override public void draw(Canvas canvas) { mBounds.left = mGasketPadding; mBounds.top = mGasketPadding; @@ -207,6 +229,7 @@ public class FloatingActionButton extends View { canvas.drawOval(mBounds, mPaint); } + @Override public void setColor(int color) { mColor = color; mDarkerColor = UiUtils.getDarkerColor(color); diff --git a/app/src/main/java/com/hippo/widget/FloatingActionButtonLayout.java b/app/src/main/java/com/hippo/widget/FloatingActionButtonLayout.java new file mode 100644 index 000000000..8f69a33a8 --- /dev/null +++ b/app/src/main/java/com/hippo/widget/FloatingActionButtonLayout.java @@ -0,0 +1,267 @@ +/* + * Copyright (C) 2015 Hippo Seven + * + * 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 + * 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.widget; + +import android.animation.Animator; +import android.animation.ObjectAnimator; +import android.animation.PropertyValuesHolder; +import android.content.Context; +import android.os.Build; +import android.support.annotation.NonNull; +import android.util.AttributeSet; +import android.view.View; +import android.view.ViewGroup; + +import com.hippo.animation.SimpleAnimatorListener; +import com.hippo.ehviewer.R; + +public class FloatingActionButtonLayout extends ViewGroup { + + private static long ANIMATE_TIME = 300l; + + private static final String STATE_KEY_SUPER = "super"; + private static final String STATE_KEY_CHECKED = "expanded"; + + private int mInterval; + + private boolean mFirst = true; + private boolean mExpanded = false; + private float mMainFabCenterY = -1f; + + public FloatingActionButtonLayout(Context context) { + super(context); + init(context); + } + + public FloatingActionButtonLayout(Context context, AttributeSet attrs) { + super(context, attrs); + init(context); + } + + public FloatingActionButtonLayout(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(context); + } + + private void init(Context context) { + mInterval = context.getResources().getDimensionPixelOffset(R.dimen.floating_action_bar_layout_interval); + } + + @Override + public void addView(@NonNull View child, int index, ViewGroup.LayoutParams params) { + if (!(child instanceof FloatingActionButton)) { + throw new IllegalStateException("FloatingActionBarLayout should only " + + "contain FloatingActionButton, but try to add "+ child.getClass().getName()); + } + super.addView(child, index, params); + } + + public FloatingActionButton getPrimaryFab() { + View v = getChildAt(getChildCount() - 1); + if (v == null) { + return null; + } else { + return (FloatingActionButton) v; + } + } + + public int getSecondaryFabCount() { + return Math.max(0, getChildCount() - 1); + } + + public FloatingActionButton getSecondaryFabAt(int index) { + if (index < 0 || index >= getSecondaryFabCount()) { + return null; + } + return (FloatingActionButton) getChildAt(index); + } + + private int getChildMeasureSpec(int parentMeasureSpec) { + int parentMode = MeasureSpec.getMode(parentMeasureSpec); + int parentSize = MeasureSpec.getSize(parentMeasureSpec); + int childMode; + int childSize; + switch (parentMode) { + default: + case MeasureSpec.AT_MOST: + case MeasureSpec.EXACTLY: + childMode = MeasureSpec.AT_MOST; + childSize = parentSize; + break; + case MeasureSpec.UNSPECIFIED: + childMode = MeasureSpec.UNSPECIFIED; + childSize = parentSize; + } + return MeasureSpec.makeMeasureSpec(childSize, childMode); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + if (mFirst) { + mFirst = false; + boolean expanded = mExpanded; + int count = getChildCount() - 1; + for (int i = 0; i < count; i++) { + getChildAt(i).setVisibility(expanded ? View.VISIBLE : View.INVISIBLE); + } + } + + int childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec); + int childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec); + measureChildren(childWidthMeasureSpec, childHeightMeasureSpec); + + int maxWidth = 0; + int maxHeight = 0; + boolean firstChild = true; + int count = getChildCount(); + for (int i = 0; i < count; i++) { + View child = getChildAt(i); + if (child.getVisibility() == View.GONE) { + continue; + } + + maxWidth = Math.max(maxWidth, child.getMeasuredWidth()); + maxHeight = maxHeight + child.getMeasuredHeight(); + if (firstChild) { + firstChild = false; + } else { + maxHeight += mInterval; + } + } + + // Account for padding too + maxWidth += getPaddingLeft() + getPaddingRight(); + maxHeight += getPaddingTop() + getPaddingBottom(); + + // Check against minimum height and width + maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight()); + maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth()); + + setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, 0), + resolveSizeAndState(maxHeight, heightMeasureSpec, 0)); + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + int interval = mInterval; + int top = getPaddingTop(); + int paddingLeft = getPaddingLeft(); + int vaildWidth = getMeasuredWidth() - paddingLeft - getPaddingRight(); + int count = getChildCount(); + for (int i = 0; i < count; i++) { + View child = getChildAt(i); + if (child.getVisibility() == View.GONE) { + continue; + } + + int childWidth = child.getMeasuredWidth(); + int childHeight = child.getMeasuredHeight(); + int left = paddingLeft + ((vaildWidth - childWidth) / 2); + child.layout(left, top, left + childWidth, top + childHeight); + + if (i == count - 1) { + mMainFabCenterY = top + (childHeight / 2f); + } + + top += (childHeight + interval); + } + } + + public void toggle() { + setExpanded(!mExpanded); + } + + public boolean getExpanded() { + return mExpanded; + } + + public void setExpanded(boolean expanded) { + setExpanded(expanded, true); + } + + public void setExpanded(boolean expanded, boolean animation) { + if (mExpanded != expanded) { + mExpanded = expanded; + + if (mMainFabCenterY == -1f) { + // It is before first onLayout + int count = getChildCount() - 1; + for (int i = 0; i < count; i++) { + getChildAt(i).setVisibility(expanded ? View.VISIBLE : View.INVISIBLE); + } + } else { + int count = getChildCount() - 1; + for (int i = 0; i < count; i++) { + View child = getChildAt(i); + if (animation) { + setChildAnimation(child, expanded); + } else { + child.setVisibility(expanded ? View.VISIBLE : View.INVISIBLE); + if (expanded) { + child.setAlpha(1f); + } + } + } + } + } + } + + private void setChildAnimation(final View child, final boolean expanded) { + float startTranslationY; + float endTranslationY; + float startAlpha; + float endAlpha; + if (expanded) { + startTranslationY = mMainFabCenterY - + (child.getTop() + (child.getHeight() / 2)); + endTranslationY = 0f; + startAlpha = 0f; + endAlpha = 1f; + } else { + startTranslationY = 0f; + endTranslationY = mMainFabCenterY - + (child.getTop() + (child.getHeight() / 2)); + startAlpha = 1f; + endAlpha = 0f; + } + + PropertyValuesHolder translationYPvh = PropertyValuesHolder.ofFloat( + "translationY", startTranslationY, endTranslationY); + PropertyValuesHolder alphaPvh = PropertyValuesHolder.ofFloat( + "alpha", startAlpha, endAlpha); + ObjectAnimator oa = ObjectAnimator.ofPropertyValuesHolder(child, translationYPvh, alphaPvh); + oa.setDuration(ANIMATE_TIME); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { + oa.setAutoCancel(true); + } + oa.addListener(new SimpleAnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + if (expanded) { + child.setVisibility(View.VISIBLE); + } + } + + @Override + public void onAnimationEnd(Animator animation) { + if (!expanded) { + child.setVisibility(View.INVISIBLE); + } + } + }); + oa.start(); + } +} diff --git a/app/src/main/res/drawable/ic_arrow_up_dark.xml b/app/src/main/res/drawable/ic_arrow_up_dark.xml new file mode 100644 index 000000000..75a8d54c0 --- /dev/null +++ b/app/src/main/res/drawable/ic_arrow_up_dark.xml @@ -0,0 +1,39 @@ + + + + + + + diff --git a/app/src/main/res/drawable/ic_go_to_dark.xml b/app/src/main/res/drawable/ic_go_to_dark.xml new file mode 100644 index 000000000..31b35068d --- /dev/null +++ b/app/src/main/res/drawable/ic_go_to_dark.xml @@ -0,0 +1,39 @@ + + + + + + + diff --git a/app/src/main/res/layout/scene_gallery_list.xml b/app/src/main/res/layout/scene_gallery_list.xml index 00e2de477..b55d7631d 100644 --- a/app/src/main/res/layout/scene_gallery_list.xml +++ b/app/src/main/res/layout/scene_gallery_list.xml @@ -15,6 +15,7 @@ --> @@ -40,17 +41,39 @@ android:layout_marginTop="@dimen/search_bar_padding_vertical" auto:forceNoElevation="true"/> - + tools:ignore="RtlHardcoded"> + + + + + + + + diff --git a/app/src/main/res/values-v21/dimens.xml b/app/src/main/res/values-v21/dimens.xml index 64acaa01d..a4773d0de 100644 --- a/app/src/main/res/values-v21/dimens.xml +++ b/app/src/main/res/values-v21/dimens.xml @@ -19,5 +19,7 @@ 56dp 40dp + 60dp + 44dp diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml index 915f9d88e..9853ae832 100644 --- a/app/src/main/res/values/attrs.xml +++ b/app/src/main/res/values/attrs.xml @@ -26,6 +26,7 @@ + diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 7b25015fc..3a73353c2 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -15,6 +15,9 @@ --> + + 16dp + 16dp 320dp @@ -92,6 +95,9 @@ 60dp 44dp + 60dp + 44dp + 24dp 24dp diff --git a/app/src/main/res/values/pathdata.xml b/app/src/main/res/values/pathdata.xml index f1942c3f7..60842c05f 100644 --- a/app/src/main/res/values/pathdata.xml +++ b/app/src/main/res/values/pathdata.xml @@ -21,5 +21,7 @@ M3,6H21V8H3V6M3,11H21V13H3V11M3,16H21V18H3V16Z M15,9A1,1 0 0,1 14,8A1,1 0 0,1 15,7A1,1 0 0,1 16,8A1,1 0 0,1 15,9M9,9A1,1 0 0,1 8,8A1,1 0 0,1 9,7A1,1 0 0,1 10,8A1,1 0 0,1 9,9M16.12,4.37L18.22,2.27L17.4,1.44L15.09,3.75C14.16,3.28 13.11,3 12,3C10.88,3 9.84,3.28 8.91,3.75L6.6,1.44L5.78,2.27L7.88,4.37C6.14,5.64 5,7.68 5,10V11H19V10C19,7.68 17.86,5.64 16.12,4.37M5,16C5,19.86 8.13,23 12,23A7,7 0 0,0 19,16V12H5V16Z M15.07,11.25L14.17,12.17C13.45,12.89 13,13.5 13,15H11V14.5C11,13.39 11.45,12.39 12.17,11.67L13.41,10.41C13.78,10.05 14,9.55 14,9C14,7.89 13.1,7 12,7A2,2 0 0,0 10,9H8A4,4 0 0,1 12,5A4,4 0 0,1 16,9C16,9.88 15.64,10.67 15.07,11.25M13,19H11V17H13M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12C22,6.47 17.5,2 12,2Z + M13,20H11V8L5.5,13.5L4.08,12.08L12,4.16L19.92,12.08L18.5,13.5L13,8V20Z + M10.5,7A6.5,6.5 0 0,0 4,13.5A6.5,6.5 0 0,0 10.5,20H14V18H10.5C8,18 6,16 6,13.5C6,11 8,9 10.5,9H16.17L13.09,12.09L14.5,13.5L20,8L14.5,2.5L13.08,3.91L16.17,7H10.5M18,18H16V20H18V18Z diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index dfb9979e8..7a02e934c 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -35,6 +35,16 @@ @dimen/fab_size_small + + + +