diff options
author | Sunny Goyal <sunnygoyal@google.com> | 2017-04-26 22:34:49 -0700 |
---|---|---|
committer | Sunny Goyal <sunnygoyal@google.com> | 2017-04-27 05:35:28 -0700 |
commit | da1dfa32d0dd56c8c9b4667ebd75d847329285b6 (patch) | |
tree | 5266bc8609e7ef5d6966d094f6a903254092b31d | |
parent | 83519d3fb107aa2a02d3042219cdc994d8d7797d (diff) | |
download | packages_apps_Trebuchet-da1dfa32d0dd56c8c9b4667ebd75d847329285b6.tar.gz packages_apps_Trebuchet-da1dfa32d0dd56c8c9b4667ebd75d847329285b6.tar.bz2 packages_apps_Trebuchet-da1dfa32d0dd56c8c9b4667ebd75d847329285b6.zip |
Creating a custom drawable to customize shadow.
> Fixing DrapTargetBar set to visible (with alpha = 0) in the start
causing unnecessary draw
Bug: 37616877
Change-Id: Iaaff96099910f504f6e2f81c9376ddacde50ff6a
31 files changed, 338 insertions, 10 deletions
diff --git a/proguard.flags b/proguard.flags index 6cbab08e2..2ad9cacf2 100644 --- a/proguard.flags +++ b/proguard.flags @@ -82,6 +82,10 @@ *; } +-keep class com.android.launcher3.graphics.ShadowDrawable { + public <init>(...); +} + # Proguard will strip methods required for talkback to properly scroll to # next row when focus is on the last item of last row when using a RecyclerView # Keep optimized and shrunk proguard to prevent issues like this when using diff --git a/res/drawable-hdpi/ic_info_launcher.png b/res/drawable-hdpi/ic_info_launcher.png Binary files differdeleted file mode 100644 index 11162e1e7..000000000 --- a/res/drawable-hdpi/ic_info_launcher.png +++ /dev/null diff --git a/res/drawable-hdpi/ic_remove_launcher.png b/res/drawable-hdpi/ic_remove_launcher.png Binary files differdeleted file mode 100644 index ad2b9af24..000000000 --- a/res/drawable-hdpi/ic_remove_launcher.png +++ /dev/null diff --git a/res/drawable-hdpi/ic_uninstall_launcher.png b/res/drawable-hdpi/ic_uninstall_launcher.png Binary files differdeleted file mode 100644 index 426683c6d..000000000 --- a/res/drawable-hdpi/ic_uninstall_launcher.png +++ /dev/null diff --git a/res/drawable-mdpi/ic_info_launcher.png b/res/drawable-mdpi/ic_info_launcher.png Binary files differdeleted file mode 100644 index 6fbe5e395..000000000 --- a/res/drawable-mdpi/ic_info_launcher.png +++ /dev/null diff --git a/res/drawable-mdpi/ic_remove_launcher.png b/res/drawable-mdpi/ic_remove_launcher.png Binary files differdeleted file mode 100644 index 2bb281d59..000000000 --- a/res/drawable-mdpi/ic_remove_launcher.png +++ /dev/null diff --git a/res/drawable-mdpi/ic_uninstall_launcher.png b/res/drawable-mdpi/ic_uninstall_launcher.png Binary files differdeleted file mode 100644 index bfcbc6dfa..000000000 --- a/res/drawable-mdpi/ic_uninstall_launcher.png +++ /dev/null diff --git a/res/drawable-v24/ic_info_shadow.xml b/res/drawable-v24/ic_info_shadow.xml new file mode 100644 index 000000000..9bd7e16d0 --- /dev/null +++ b/res/drawable-v24/ic_info_shadow.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + 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. +--> +<com.android.launcher3.graphics.ShadowDrawable + xmlns:android="http://schemas.android.com/apk/res/android" + android:src="@drawable/ic_info_no_shadow" /> diff --git a/res/drawable-v24/ic_remove_shadow.xml b/res/drawable-v24/ic_remove_shadow.xml new file mode 100644 index 000000000..16a630e5f --- /dev/null +++ b/res/drawable-v24/ic_remove_shadow.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + 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. +--> +<com.android.launcher3.graphics.ShadowDrawable + xmlns:android="http://schemas.android.com/apk/res/android" + android:src="@drawable/ic_remove_no_shadow" /> diff --git a/res/drawable-v24/ic_uninstall_shadow.xml b/res/drawable-v24/ic_uninstall_shadow.xml new file mode 100644 index 000000000..2532157ab --- /dev/null +++ b/res/drawable-v24/ic_uninstall_shadow.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + 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. +--> +<com.android.launcher3.graphics.ShadowDrawable + xmlns:android="http://schemas.android.com/apk/res/android" + android:src="@drawable/ic_uninstall_no_shadow" /> diff --git a/res/drawable-xhdpi/ic_info_launcher.png b/res/drawable-xhdpi/ic_info_launcher.png Binary files differdeleted file mode 100644 index 041f2b3c0..000000000 --- a/res/drawable-xhdpi/ic_info_launcher.png +++ /dev/null diff --git a/res/drawable-xhdpi/ic_remove_launcher.png b/res/drawable-xhdpi/ic_remove_launcher.png Binary files differdeleted file mode 100644 index ff94eb8e9..000000000 --- a/res/drawable-xhdpi/ic_remove_launcher.png +++ /dev/null diff --git a/res/drawable-xhdpi/ic_uninstall_launcher.png b/res/drawable-xhdpi/ic_uninstall_launcher.png Binary files differdeleted file mode 100644 index 2c7ab56e9..000000000 --- a/res/drawable-xhdpi/ic_uninstall_launcher.png +++ /dev/null diff --git a/res/drawable-xxhdpi/ic_info_launcher.png b/res/drawable-xxhdpi/ic_info_launcher.png Binary files differdeleted file mode 100644 index 8e602da02..000000000 --- a/res/drawable-xxhdpi/ic_info_launcher.png +++ /dev/null diff --git a/res/drawable-xxhdpi/ic_remove_launcher.png b/res/drawable-xxhdpi/ic_remove_launcher.png Binary files differdeleted file mode 100644 index 78ca0804c..000000000 --- a/res/drawable-xxhdpi/ic_remove_launcher.png +++ /dev/null diff --git a/res/drawable-xxhdpi/ic_uninstall_launcher.png b/res/drawable-xxhdpi/ic_uninstall_launcher.png Binary files differdeleted file mode 100644 index 43aba6ec0..000000000 --- a/res/drawable-xxhdpi/ic_uninstall_launcher.png +++ /dev/null diff --git a/res/drawable-xxxhdpi/ic_info_launcher.png b/res/drawable-xxxhdpi/ic_info_launcher.png Binary files differdeleted file mode 100644 index 3540de1a1..000000000 --- a/res/drawable-xxxhdpi/ic_info_launcher.png +++ /dev/null diff --git a/res/drawable-xxxhdpi/ic_remove_launcher.png b/res/drawable-xxxhdpi/ic_remove_launcher.png Binary files differdeleted file mode 100644 index 418d81ad6..000000000 --- a/res/drawable-xxxhdpi/ic_remove_launcher.png +++ /dev/null diff --git a/res/drawable-xxxhdpi/ic_uninstall_launcher.png b/res/drawable-xxxhdpi/ic_uninstall_launcher.png Binary files differdeleted file mode 100644 index 724437a2a..000000000 --- a/res/drawable-xxxhdpi/ic_uninstall_launcher.png +++ /dev/null diff --git a/res/drawable/ic_info_no_shadow.xml b/res/drawable/ic_info_no_shadow.xml index 5f145c9f1..91a3a565a 100644 --- a/res/drawable/ic_info_no_shadow.xml +++ b/res/drawable/ic_info_no_shadow.xml @@ -17,8 +17,9 @@ android:width="24dp" android:height="24dp" android:viewportWidth="24.0" - android:viewportHeight="24.0"> + android:viewportHeight="24.0" + android:tint="?android:attr/textColorPrimary" > <path - android:fillColor="?android:attr/textColorPrimary" + android:fillColor="#FFFFFFFF" android:pathData="M11 17h2v-6h-2v6zm1-15C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zM11 9h2V7h-2v2z"/> </vector> diff --git a/res/drawable/ic_remove_no_shadow.xml b/res/drawable/ic_remove_no_shadow.xml new file mode 100644 index 000000000..ef538a611 --- /dev/null +++ b/res/drawable/ic_remove_no_shadow.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + 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. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0" + android:tint="?android:attr/textColorPrimary" > + <path + android:fillColor="#FFFFFFFF" + android:pathData="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/> +</vector> diff --git a/res/drawable/ic_uninstall_no_shadow.xml b/res/drawable/ic_uninstall_no_shadow.xml new file mode 100644 index 000000000..5bab4222e --- /dev/null +++ b/res/drawable/ic_uninstall_no_shadow.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + 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. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0" + android:tint="?android:attr/textColorPrimary" > + <path + android:fillColor="#FFFFFFFF" + android:pathData="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/> +</vector> diff --git a/res/layout/drop_target_bar_horz.xml b/res/layout/drop_target_bar_horz.xml index fcbb54e39..ed18192c5 100644 --- a/res/layout/drop_target_bar_horz.xml +++ b/res/layout/drop_target_bar_horz.xml @@ -20,6 +20,7 @@ android:theme="@style/HomeScreenElementTheme" android:layout_width="match_parent" android:layout_height="@dimen/dynamic_grid_drop_target_size" + android:visibility="invisible" android:layout_gravity="center_horizontal|top" android:focusable="false"> diff --git a/res/layout/drop_target_bar_vert.xml b/res/layout/drop_target_bar_vert.xml index 54d9dfe3a..e2a65d4a5 100644 --- a/res/layout/drop_target_bar_vert.xml +++ b/res/layout/drop_target_bar_vert.xml @@ -21,6 +21,7 @@ android:orientation="vertical" android:layout_height="match_parent" android:layout_gravity="left" + android:visibility="invisible" android:focusable="false" android:paddingTop="@dimen/vert_drop_target_vertical_gap" > diff --git a/res/values/attrs.xml b/res/values/attrs.xml index 18f409f34..18759f817 100644 --- a/res/values/attrs.xml +++ b/res/values/attrs.xml @@ -16,7 +16,7 @@ */ --> -<resources> +<resources xmlns:android="http://schemas.android.com/apk/res/android"> <!-- BubbleTextView specific attributes. --> <declare-styleable name="BubbleTextView"> @@ -111,4 +111,8 @@ </attr> </declare-styleable> + <declare-styleable name="ShadowDrawable"> + <attr name="android:src" /> + <attr name="android:shadowColor" /> + </declare-styleable> </resources> diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 75618b894..7dd9e5315 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -146,6 +146,7 @@ <dimen name="blur_size_medium_outline">2dp</dimen> <dimen name="blur_size_click_shadow">4dp</dimen> <dimen name="click_shadow_high_shift">2dp</dimen> + <dimen name="drawable_shadow_size">2dp</dimen> <!-- Pending widget --> <dimen name="pending_widget_min_padding">8dp</dimen> diff --git a/res/values/drawables.xml b/res/values/drawables.xml new file mode 100644 index 000000000..fea17b153 --- /dev/null +++ b/res/values/drawables.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + 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. +--> +<resources> + <drawable name="ic_info_shadow">@drawable/ic_info_no_shadow</drawable> + <drawable name="ic_remove_shadow">@drawable/ic_remove_no_shadow</drawable> + <drawable name="ic_uninstall_shadow">@drawable/ic_uninstall_no_shadow</drawable> +</resources>
\ No newline at end of file diff --git a/src/com/android/launcher3/DeleteDropTarget.java b/src/com/android/launcher3/DeleteDropTarget.java index 9097ed23d..975675a6f 100644 --- a/src/com/android/launcher3/DeleteDropTarget.java +++ b/src/com/android/launcher3/DeleteDropTarget.java @@ -40,7 +40,7 @@ public class DeleteDropTarget extends ButtonDropTarget { // Get the hover color mHoverColor = getResources().getColor(R.color.delete_target_hover_tint); - setDrawable(R.drawable.ic_remove_launcher); + setDrawable(R.drawable.ic_remove_shadow); } @Override diff --git a/src/com/android/launcher3/InfoDropTarget.java b/src/com/android/launcher3/InfoDropTarget.java index 2f61a01ed..7b3bded17 100644 --- a/src/com/android/launcher3/InfoDropTarget.java +++ b/src/com/android/launcher3/InfoDropTarget.java @@ -40,12 +40,10 @@ public class InfoDropTarget extends UninstallDropTarget { } @Override - protected void onFinishInflate() { - super.onFinishInflate(); + protected void setupUi() { // Get the hover color mHoverColor = Themes.getColorAccent(getContext()); - - setDrawable(R.drawable.ic_info_launcher); + setDrawable(R.drawable.ic_info_shadow); } @Override diff --git a/src/com/android/launcher3/UninstallDropTarget.java b/src/com/android/launcher3/UninstallDropTarget.java index 0fac29f30..45c14d6bb 100644 --- a/src/com/android/launcher3/UninstallDropTarget.java +++ b/src/com/android/launcher3/UninstallDropTarget.java @@ -28,10 +28,13 @@ public class UninstallDropTarget extends ButtonDropTarget { @Override protected void onFinishInflate() { super.onFinishInflate(); + setupUi(); + } + + protected void setupUi() { // Get the hover color mHoverColor = getResources().getColor(R.color.uninstall_target_hover_tint); - - setDrawable(R.drawable.ic_uninstall_launcher); + setDrawable(R.drawable.ic_uninstall_shadow); } @Override diff --git a/src/com/android/launcher3/graphics/ShadowDrawable.java b/src/com/android/launcher3/graphics/ShadowDrawable.java new file mode 100644 index 000000000..5e76649ca --- /dev/null +++ b/src/com/android/launcher3/graphics/ShadowDrawable.java @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * 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.android.launcher3.graphics; + +import android.content.res.Resources; +import android.content.res.TypedArray; +import android.graphics.Bitmap; +import android.graphics.BlurMaskFilter; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.ColorFilter; +import android.graphics.Paint; +import android.graphics.PixelFormat; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; + +import com.android.launcher3.R; +import com.android.launcher3.Utilities; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; + +/** + * A drawable which adds shadow around a child drawable. + */ +public class ShadowDrawable extends Drawable { + + private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG); + + private final ShadowDrawableState mState; + + public ShadowDrawable() { + this(new ShadowDrawableState()); + } + + private ShadowDrawable(ShadowDrawableState state) { + mState = state; + } + + @Override + public void draw(Canvas canvas) { + Rect bounds = getBounds(); + if (bounds.isEmpty()) { + return; + } + if (mState.mLastDrawnBitmap == null) { + regenerateBitmapCache(); + } + canvas.drawBitmap(mState.mLastDrawnBitmap, null, bounds, mPaint); + } + + @Override + public void setAlpha(int alpha) { + mPaint.setAlpha(alpha); + invalidateSelf(); + } + + @Override + public void setColorFilter(ColorFilter colorFilter) { + mPaint.setColorFilter(colorFilter); + invalidateSelf(); + } + + @Override + public ConstantState getConstantState() { + return mState; + } + + @Override + public int getOpacity() { + return PixelFormat.TRANSLUCENT; + } + + @Override + public int getIntrinsicHeight() { + return mState.mIntrinsicHeight; + } + + @Override + public int getIntrinsicWidth() { + return mState.mIntrinsicWidth; + } + + /** + * Sets the color for the generated shadow + */ + public void setShadowColor(int color) { + if (mState.mShadowColor != color) { + mState.mShadowColor = color; + mState.mLastDrawnBitmap = null; + invalidateSelf(); + } + } + + private void regenerateBitmapCache() { + Bitmap bitmap = Bitmap.createBitmap(mState.mIntrinsicWidth, mState.mIntrinsicHeight, + Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(bitmap); + + // Call mutate, so that the pixel allocation by the underlying vector drawable is cleared. + Drawable d = mState.mChildState.newDrawable().mutate(); + d.setBounds(mState.mShadowSize, mState.mShadowSize, + mState.mIntrinsicWidth - mState.mShadowSize, + mState.mIntrinsicHeight - mState.mShadowSize); + d.draw(canvas); + + Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG); + paint.setMaskFilter(new BlurMaskFilter(mState.mShadowSize, BlurMaskFilter.Blur.NORMAL)); + int[] offset = new int[2]; + Bitmap shadow = bitmap.extractAlpha(paint, offset); + + paint.setMaskFilter(null); + paint.setColor(mState.mShadowColor); + bitmap.eraseColor(Color.TRANSPARENT); + canvas.drawBitmap(shadow, offset[0], offset[1], paint); + d.draw(canvas); + + if (Utilities.isAtLeastO()) { + bitmap = bitmap.copy(Bitmap.Config.HARDWARE, false); + } + mState.mLastDrawnBitmap = bitmap; + } + + @Override + public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, + Resources.Theme theme) throws XmlPullParserException, IOException { + super.inflate(r, parser, attrs, theme); + + final TypedArray a = theme == null + ? r.obtainAttributes(attrs, R.styleable.ShadowDrawable) + : theme.obtainStyledAttributes(attrs, R.styleable.ShadowDrawable, 0, 0); + + try { + Drawable d = a.getDrawable(R.styleable.ShadowDrawable_android_src); + if (d == null) { + throw new XmlPullParserException("missing src attribute"); + } + mState.mShadowColor = a.getColor( + R.styleable.ShadowDrawable_android_shadowColor, Color.BLACK); + mState.mShadowSize = r.getDimensionPixelSize(R.dimen.drawable_shadow_size); + + mState.mIntrinsicHeight = d.getIntrinsicHeight() + 2 * mState.mShadowSize; + mState.mIntrinsicWidth = d.getIntrinsicWidth() + 2 * mState.mShadowSize; + mState.mChangingConfigurations = d.getChangingConfigurations(); + + mState.mChildState = d.getConstantState(); + } finally { + a.recycle(); + } + } + + private static class ShadowDrawableState extends ConstantState { + + int mChangingConfigurations; + int mIntrinsicWidth; + int mIntrinsicHeight; + + int mShadowColor; + int mShadowSize; + + Bitmap mLastDrawnBitmap; + ConstantState mChildState; + + @Override + public Drawable newDrawable() { + return new ShadowDrawable(this); + } + + @Override + public int getChangingConfigurations() { + return mChangingConfigurations; + } + } +} |