Separating double shadow logic for BubbleTextView in a separate subclass
This allows better customization and reuse of the double shadow logic and simplified various attribute management Change-Id: I5e277d8399756385452d8bb8c0a0107234a76d34
This commit is contained in:
parent
a9d721df78
commit
9314b7c01d
|
@ -14,4 +14,4 @@
|
|||
limitations under the License.
|
||||
-->
|
||||
|
||||
<com.android.launcher3.BubbleTextView style="@style/BaseIcon.Workspace" />
|
||||
<com.android.launcher3.views.DoubleShadowBubbleTextView style="@style/BaseIcon.Workspace" />
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:focusable="true" >
|
||||
<com.android.launcher3.BubbleTextView
|
||||
<com.android.launcher3.views.DoubleShadowBubbleTextView
|
||||
style="@style/BaseIcon.Workspace"
|
||||
android:id="@+id/folder_icon_name"
|
||||
android:focusable="false"
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="16sp"
|
||||
android:textAlignment="viewStart"
|
||||
launcher:customShadows="false"
|
||||
launcher:deferShadowGeneration="true"
|
||||
launcher:iconDisplay="widget_section"
|
||||
launcher:iconSizeOverride="@dimen/widget_section_icon_size"
|
||||
|
|
|
@ -43,10 +43,15 @@
|
|||
<enum name="shortcut_popup" value="4" />
|
||||
</attr>
|
||||
<attr name="deferShadowGeneration" format="boolean" />
|
||||
<attr name="customShadows" format="boolean" />
|
||||
<attr name="centerVertically" format="boolean" />
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="ShadowInfo">
|
||||
<attr name="ambientShadowColor" format="color" />
|
||||
<attr name="ambientShadowBlur" format="dimension" />
|
||||
<attr name="keyShadowColor" format="color" />
|
||||
<attr name="keyShadowBlur" format="dimension" />
|
||||
<attr name="keyShadowOffset" format="dimension" />
|
||||
</declare-styleable>
|
||||
|
||||
<!-- PagedView specific attributes. These attributes are used to customize
|
||||
|
|
|
@ -119,16 +119,17 @@
|
|||
|
||||
<!-- No shadows in the base theme -->
|
||||
<item name="android:shadowRadius">0</item>
|
||||
<item name="customShadows">false</item>
|
||||
</style>
|
||||
|
||||
<!-- Icon displayed on the worksapce -->
|
||||
<style name="BaseIcon.Workspace">
|
||||
<item name="customShadows">true</item>
|
||||
<item name="android:shadowRadius">2.0</item>
|
||||
<item name="android:shadowColor">?attr/workspaceShadowColor</item>
|
||||
<item name="keyShadowColor">?attr/workspaceKeyShadowColor</item>
|
||||
<item name="ambientShadowColor">?attr/workspaceAmbientShadowColor</item>
|
||||
<item name="ambientShadowBlur">2.5dp</item>
|
||||
<item name="keyShadowColor">?attr/workspaceKeyShadowColor</item>
|
||||
<item name="keyShadowBlur">1dp</item>
|
||||
<item name="keyShadowOffset">.5dp</item>
|
||||
</style>
|
||||
|
||||
<!-- Theme for the popup container -->
|
||||
|
|
|
@ -27,7 +27,6 @@ import android.graphics.Color;
|
|||
import android.graphics.Paint;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Region;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.support.v4.graphics.ColorUtils;
|
||||
|
@ -62,11 +61,6 @@ import java.text.NumberFormat;
|
|||
*/
|
||||
public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver {
|
||||
|
||||
// Dimensions in DP
|
||||
private static final float AMBIENT_SHADOW_RADIUS = 2.5f;
|
||||
private static final float KEY_SHADOW_RADIUS = 1f;
|
||||
private static final float KEY_SHADOW_OFFSET = 0.5f;
|
||||
|
||||
private static final int DISPLAY_WORKSPACE = 0;
|
||||
private static final int DISPLAY_ALL_APPS = 1;
|
||||
private static final int DISPLAY_FOLDER = 2;
|
||||
|
@ -76,22 +70,15 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver {
|
|||
private final Launcher mLauncher;
|
||||
private Drawable mIcon;
|
||||
private final boolean mCenterVertically;
|
||||
private final Drawable mBackground;
|
||||
private OnLongClickListener mOnLongClickListener;
|
||||
private final CheckLongPressHelper mLongPressHelper;
|
||||
private final HolographicOutlineHelper mOutlineHelper;
|
||||
private final StylusEventHelper mStylusEventHelper;
|
||||
private final int mAmbientShadowColor;
|
||||
private final int mKeyShadowColor;
|
||||
|
||||
private boolean mBackgroundSizeChanged;
|
||||
private final float mSlop;
|
||||
|
||||
private Bitmap mPressedBackground;
|
||||
|
||||
private float mSlop;
|
||||
|
||||
private final boolean mDeferShadowGenerationOnTouch;
|
||||
private final boolean mCustomShadowsEnabled;
|
||||
private final boolean mLayoutHorizontal;
|
||||
private final int mIconSize;
|
||||
@ViewDebug.ExportedProperty(category = "launcher")
|
||||
|
@ -154,15 +141,13 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver {
|
|||
super(context, attrs, defStyle);
|
||||
mLauncher = Launcher.getLauncher(context);
|
||||
DeviceProfile grid = mLauncher.getDeviceProfile();
|
||||
mSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
|
||||
|
||||
TypedArray a = context.obtainStyledAttributes(attrs,
|
||||
R.styleable.BubbleTextView, defStyle, 0);
|
||||
mCustomShadowsEnabled = a.getBoolean(R.styleable.BubbleTextView_customShadows, false);
|
||||
mLayoutHorizontal = a.getBoolean(R.styleable.BubbleTextView_layoutHorizontal, false);
|
||||
mDeferShadowGenerationOnTouch =
|
||||
a.getBoolean(R.styleable.BubbleTextView_deferShadowGeneration, false);
|
||||
mAmbientShadowColor = a.getColor(R.styleable.BubbleTextView_ambientShadowColor, 0x33000000);
|
||||
mKeyShadowColor = a.getColor(R.styleable.BubbleTextView_keyShadowColor, 0x66000000);
|
||||
|
||||
int display = a.getInteger(R.styleable.BubbleTextView_iconDisplay, DISPLAY_WORKSPACE);
|
||||
int defaultIconSize = grid.iconSizePx;
|
||||
|
@ -184,23 +169,12 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver {
|
|||
defaultIconSize);
|
||||
a.recycle();
|
||||
|
||||
if (mCustomShadowsEnabled) {
|
||||
// Draw the background itself as the parent is drawn twice.
|
||||
mBackground = getBackground();
|
||||
setBackground(null);
|
||||
|
||||
// Set shadow layer as the larger shadow to that the textView does not clip the shadow.
|
||||
float density = getResources().getDisplayMetrics().density;
|
||||
setShadowLayer(density * AMBIENT_SHADOW_RADIUS, 0, 0, mAmbientShadowColor);
|
||||
} else {
|
||||
mBackground = null;
|
||||
}
|
||||
|
||||
mLongPressHelper = new CheckLongPressHelper(this);
|
||||
mStylusEventHelper = new StylusEventHelper(new SimpleOnStylusPressListener(this), this);
|
||||
|
||||
mOutlineHelper = HolographicOutlineHelper.getInstance(getContext());
|
||||
setAccessibilityDelegate(mLauncher.getAccessibilityDelegate());
|
||||
|
||||
}
|
||||
|
||||
public void applyFromShortcutInfo(ShortcutInfo info) {
|
||||
|
@ -261,19 +235,6 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver {
|
|||
mLongPressHelper.setLongPressTimeout(longPressTimeout);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean setFrame(int left, int top, int right, int bottom) {
|
||||
if (getLeft() != left || getRight() != right || getTop() != top || getBottom() != bottom) {
|
||||
mBackgroundSizeChanged = true;
|
||||
}
|
||||
return super.setFrame(left, top, right, bottom);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean verifyDrawable(Drawable who) {
|
||||
return who == mBackground || super.verifyDrawable(who);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTag(Object tag) {
|
||||
if (tag != null) {
|
||||
|
@ -415,54 +376,14 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver {
|
|||
return result;
|
||||
}
|
||||
|
||||
@SuppressWarnings("wrongcall")
|
||||
protected void drawWithoutBadge(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
if (!mCustomShadowsEnabled) {
|
||||
super.draw(canvas);
|
||||
drawBadgeIfNecessary(canvas);
|
||||
return;
|
||||
}
|
||||
|
||||
final Drawable background = mBackground;
|
||||
if (background != null) {
|
||||
final int scrollX = getScrollX();
|
||||
final int scrollY = getScrollY();
|
||||
|
||||
if (mBackgroundSizeChanged) {
|
||||
background.setBounds(0, 0, getRight() - getLeft(), getBottom() - getTop());
|
||||
mBackgroundSizeChanged = false;
|
||||
}
|
||||
|
||||
if ((scrollX | scrollY) == 0) {
|
||||
background.draw(canvas);
|
||||
} else {
|
||||
canvas.translate(scrollX, scrollY);
|
||||
background.draw(canvas);
|
||||
canvas.translate(-scrollX, -scrollY);
|
||||
}
|
||||
}
|
||||
|
||||
// If text is transparent, don't draw any shadow
|
||||
if ((getCurrentTextColor() >> 24) == 0) {
|
||||
getPaint().clearShadowLayer();
|
||||
super.draw(canvas);
|
||||
drawBadgeIfNecessary(canvas);
|
||||
return;
|
||||
}
|
||||
|
||||
// We enhance the shadow by drawing the shadow twice
|
||||
float density = getResources().getDisplayMetrics().density;
|
||||
getPaint().setShadowLayer(density * AMBIENT_SHADOW_RADIUS, 0, 0, mAmbientShadowColor);
|
||||
super.draw(canvas);
|
||||
canvas.save(Canvas.CLIP_SAVE_FLAG);
|
||||
canvas.clipRect(getScrollX(), getScrollY() + getExtendedPaddingTop(),
|
||||
getScrollX() + getWidth(),
|
||||
getScrollY() + getHeight(), Region.Op.INTERSECT);
|
||||
getPaint().setShadowLayer(
|
||||
density * KEY_SHADOW_RADIUS, 0.0f, density * KEY_SHADOW_OFFSET, mKeyShadowColor);
|
||||
super.draw(canvas);
|
||||
canvas.restore();
|
||||
|
||||
public void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
drawBadgeIfNecessary(canvas);
|
||||
}
|
||||
|
||||
|
@ -470,7 +391,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver {
|
|||
* Draws the icon badge in the top right corner of the icon bounds.
|
||||
* @param canvas The canvas to draw to.
|
||||
*/
|
||||
private void drawBadgeIfNecessary(Canvas canvas) {
|
||||
protected void drawBadgeIfNecessary(Canvas canvas) {
|
||||
if (!mForceHideBadge && (hasBadge() || mBadgeScale > 0)) {
|
||||
getIconBounds(mTempIconBounds);
|
||||
mTempSpaceForBadgeOffset.set((getWidth() - mIconSize) / 2, getPaddingTop());
|
||||
|
@ -508,14 +429,6 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver {
|
|||
outBounds.set(left, top, right, bottom);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
|
||||
if (mBackground != null) mBackground.setCallback(this);
|
||||
mSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
if (mCenterVertically) {
|
||||
|
@ -529,12 +442,6 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver {
|
|||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
if (mBackground != null) mBackground.setCallback(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTextColor(int color) {
|
||||
mTextColor = color;
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* 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.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Region;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import com.android.launcher3.BubbleTextView;
|
||||
import com.android.launcher3.R;
|
||||
|
||||
/**
|
||||
* Extension of {@link BubbleTextView} which draws two shadows on the text (ambient and key shadows}
|
||||
*/
|
||||
public class DoubleShadowBubbleTextView extends BubbleTextView {
|
||||
|
||||
private final ShadowInfo mShadowInfo;
|
||||
|
||||
public DoubleShadowBubbleTextView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public DoubleShadowBubbleTextView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public DoubleShadowBubbleTextView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
mShadowInfo = new ShadowInfo(context, attrs, defStyle);
|
||||
setShadowLayer(mShadowInfo.ambientShadowBlur, 0, 0, mShadowInfo.ambientShadowColor);
|
||||
}
|
||||
@Override
|
||||
public void onDraw(Canvas canvas) {
|
||||
// If text is transparent, don't draw any shadow
|
||||
if ((getCurrentTextColor() >> 24) == 0) {
|
||||
getPaint().clearShadowLayer();
|
||||
super.onDraw(canvas);
|
||||
return;
|
||||
}
|
||||
|
||||
// We enhance the shadow by drawing the shadow twice
|
||||
getPaint().setShadowLayer(
|
||||
mShadowInfo.ambientShadowBlur, 0, 0, mShadowInfo.ambientShadowColor);
|
||||
|
||||
drawWithoutBadge(canvas);
|
||||
canvas.save(Canvas.CLIP_SAVE_FLAG);
|
||||
canvas.clipRect(getScrollX(), getScrollY() + getExtendedPaddingTop(),
|
||||
getScrollX() + getWidth(),
|
||||
getScrollY() + getHeight(), Region.Op.INTERSECT);
|
||||
|
||||
getPaint().setShadowLayer(mShadowInfo.keyShadowBlur, 0.0f,
|
||||
mShadowInfo.keyShadowOffset, mShadowInfo.keyShadowColor);
|
||||
drawWithoutBadge(canvas);
|
||||
canvas.restore();
|
||||
|
||||
drawBadgeIfNecessary(canvas);
|
||||
}
|
||||
|
||||
public static class ShadowInfo {
|
||||
public final float ambientShadowBlur;
|
||||
public final int ambientShadowColor;
|
||||
|
||||
public final float keyShadowBlur;
|
||||
public final float keyShadowOffset;
|
||||
public final int keyShadowColor;
|
||||
|
||||
public ShadowInfo(Context c, AttributeSet attrs, int defStyle) {
|
||||
|
||||
TypedArray a = c.obtainStyledAttributes(
|
||||
attrs, R.styleable.ShadowInfo, defStyle, 0);
|
||||
|
||||
ambientShadowBlur = a.getDimension(R.styleable.ShadowInfo_ambientShadowBlur, 0);
|
||||
ambientShadowColor = a.getColor(R.styleable.ShadowInfo_ambientShadowColor, 0);
|
||||
|
||||
keyShadowBlur = a.getDimension(R.styleable.ShadowInfo_keyShadowBlur, 0);
|
||||
keyShadowOffset = a.getDimension(R.styleable.ShadowInfo_keyShadowOffset, 0);
|
||||
keyShadowColor = a.getColor(R.styleable.ShadowInfo_keyShadowColor, 0);
|
||||
a.recycle();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue