Merge "Improve the features of IllustrationPreference." into sc-dev
This commit is contained in:
@@ -19,5 +19,5 @@ android_library {
|
||||
],
|
||||
|
||||
sdk_version: "system_current",
|
||||
min_sdk_version: "21",
|
||||
min_sdk_version: "28",
|
||||
}
|
||||
|
||||
@@ -16,11 +16,7 @@
|
||||
-->
|
||||
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:top="@dimen/settingslib_illustration_padding"
|
||||
android:left="@dimen/settingslib_illustration_padding"
|
||||
android:right="@dimen/settingslib_illustration_padding"
|
||||
android:bottom="@dimen/settingslib_illustration_padding">
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@color/settingslib_protection_color"/>
|
||||
<corners android:radius="28dp"/>
|
||||
|
||||
@@ -23,14 +23,33 @@
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/lottie_view"
|
||||
android:layout_width="412dp"
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="300dp"
|
||||
android:layout_gravity="center"
|
||||
android:clipToOutline="true"
|
||||
android:background="@drawable/protection_background"
|
||||
android:importantForAccessibility="no"/>
|
||||
android:gravity="center_vertical"
|
||||
android:padding="@dimen/settingslib_illustration_padding"
|
||||
android:orientation="vertical">
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/lottie_view"
|
||||
android:adjustViewBounds="true"
|
||||
android:maxWidth="412dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:clipToOutline="true"
|
||||
android:background="@drawable/protection_background"
|
||||
android:importantForAccessibility="no"/>
|
||||
</LinearLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/middleground_layout"
|
||||
android:layout_width="412dp"
|
||||
android:layout_height="300dp"
|
||||
android:padding="@dimen/settingslib_illustration_padding"
|
||||
android:background="@android:color/transparent"
|
||||
android:layout_gravity="center"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/video_play_button"
|
||||
|
||||
@@ -17,4 +17,46 @@
|
||||
|
||||
<resources>
|
||||
<color name="settingslib_protection_color">@android:color/white</color>
|
||||
|
||||
<!-- Dynamic colors-->
|
||||
<color name="settingslib_color_blue600">#1a73e8</color>
|
||||
<color name="settingslib_color_blue400">#669df6</color>
|
||||
<color name="settingslib_color_blue300">#8ab4f8</color>
|
||||
<color name="settingslib_color_blue100">#d2e3fc</color>
|
||||
<color name="settingslib_color_blue50">#e8f0fe</color>
|
||||
<color name="settingslib_color_green600">#1e8e3e</color>
|
||||
<color name="settingslib_color_green400">#5bb974</color>
|
||||
<color name="settingslib_color_green100">#ceead6</color>
|
||||
<color name="settingslib_color_green50">#e6f4ea</color>
|
||||
<color name="settingslib_color_red600">#d93025</color>
|
||||
<color name="settingslib_color_red400">#ee675c</color>
|
||||
<color name="settingslib_color_red100">#fad2cf</color>
|
||||
<color name="settingslib_color_red50">#fce8e6</color>
|
||||
<color name="settingslib_color_yellow600">#f9ab00</color>
|
||||
<color name="settingslib_color_yellow400">#fcc934</color>
|
||||
<color name="settingslib_color_yellow100">#feefc3</color>
|
||||
<color name="settingslib_color_yellow50">#fef7e0</color>
|
||||
<color name="settingslib_color_grey900">#202124</color>
|
||||
<color name="settingslib_color_grey800">#3c4043</color>
|
||||
<color name="settingslib_color_grey700">#5f6368</color>
|
||||
<color name="settingslib_color_grey600">#80868b</color>
|
||||
<color name="settingslib_color_grey400">#bdc1c6</color>
|
||||
<color name="settingslib_color_grey300">#dadce0</color>
|
||||
<color name="settingslib_color_grey200">#e8eaed</color>
|
||||
<color name="settingslib_color_orange600">#e8710a</color>
|
||||
<color name="settingslib_color_orange400">#fa903e</color>
|
||||
<color name="settingslib_color_orange300">#fcad70</color>
|
||||
<color name="settingslib_color_orange100">#fedfc8</color>
|
||||
<color name="settingslib_color_pink600">#e52592</color>
|
||||
<color name="settingslib_color_pink400">#ff63b8</color>
|
||||
<color name="settingslib_color_pink300">#ff8bcb</color>
|
||||
<color name="settingslib_color_pink100">#fdcfe8</color>
|
||||
<color name="settingslib_color_purple600">#9334e6</color>
|
||||
<color name="settingslib_color_purple400">#af5cf7</color>
|
||||
<color name="settingslib_color_purple300">#c58af9</color>
|
||||
<color name="settingslib_color_purple100">#e9d2fd</color>
|
||||
<color name="settingslib_color_cyan600">#12b5c8</color>
|
||||
<color name="settingslib_color_cyan400">#4ecde6</color>
|
||||
<color name="settingslib_color_cyan300">#78d9ec</color>
|
||||
<color name="settingslib_color_cyan100">#cbf0f8</color>
|
||||
</resources>
|
||||
|
||||
@@ -17,5 +17,5 @@
|
||||
|
||||
<resources>
|
||||
<!-- Padding of illustration -->
|
||||
<dimen name="settingslib_illustration_padding">16dp</dimen>
|
||||
<dimen name="settingslib_illustration_padding">12dp</dimen>
|
||||
</resources>
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.settingslib.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffColorFilter;
|
||||
import android.util.Pair;
|
||||
|
||||
import com.airbnb.lottie.LottieAnimationView;
|
||||
import com.airbnb.lottie.LottieProperty;
|
||||
import com.airbnb.lottie.model.KeyPath;
|
||||
import com.airbnb.lottie.value.LottieFrameInfo;
|
||||
import com.airbnb.lottie.value.SimpleLottieValueCallback;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* ColorUtils is a util class which help the lottie illustration
|
||||
* changes the color of tags in the json file.
|
||||
*/
|
||||
|
||||
public class ColorUtils {
|
||||
|
||||
private static HashMap<String, Integer> sSysColors;
|
||||
static {
|
||||
sSysColors = new HashMap<>();
|
||||
sSysColors.put(".colorAccent", android.R.attr.colorAccent);
|
||||
sSysColors.put(".colorPrimary", android.R.attr.colorPrimary);
|
||||
sSysColors.put(".colorPrimaryDark", android.R.attr.colorPrimaryDark);
|
||||
sSysColors.put(".colorSecondary", android.R.attr.colorSecondary);
|
||||
}
|
||||
|
||||
private static HashMap<String, Pair<Integer, Integer>> sFixedColors;
|
||||
static {
|
||||
sFixedColors = new HashMap<>();
|
||||
sFixedColors.put(".blue600", new Pair<Integer, Integer>(
|
||||
R.color.settingslib_color_blue600, R.color.settingslib_color_blue400));
|
||||
sFixedColors.put(".green600", new Pair<Integer, Integer>(
|
||||
R.color.settingslib_color_green600, R.color.settingslib_color_green400));
|
||||
sFixedColors.put(".red600", new Pair<Integer, Integer>(
|
||||
R.color.settingslib_color_red600, R.color.settingslib_color_red400));
|
||||
sFixedColors.put(".yellow600", new Pair<Integer, Integer>(
|
||||
R.color.settingslib_color_yellow600, R.color.settingslib_color_yellow400));
|
||||
sFixedColors.put(".blue400", new Pair<Integer, Integer>(
|
||||
R.color.settingslib_color_blue400, R.color.settingslib_color_blue100));
|
||||
sFixedColors.put(".green400", new Pair<Integer, Integer>(
|
||||
R.color.settingslib_color_green400, R.color.settingslib_color_green100));
|
||||
sFixedColors.put(".red400", new Pair<Integer, Integer>(
|
||||
R.color.settingslib_color_red400, R.color.settingslib_color_red100));
|
||||
sFixedColors.put(".yellow400", new Pair<Integer, Integer>(
|
||||
R.color.settingslib_color_yellow400, R.color.settingslib_color_yellow100));
|
||||
sFixedColors.put(".blue300", new Pair<Integer, Integer>(
|
||||
R.color.settingslib_color_blue300, R.color.settingslib_color_blue50));
|
||||
sFixedColors.put(".blue50", new Pair<Integer, Integer>(
|
||||
R.color.settingslib_color_blue50, R.color.settingslib_color_grey900));
|
||||
sFixedColors.put(".green50", new Pair<Integer, Integer>(
|
||||
R.color.settingslib_color_green50, R.color.settingslib_color_grey900));
|
||||
sFixedColors.put(".red50", new Pair<Integer, Integer>(
|
||||
R.color.settingslib_color_red50, R.color.settingslib_color_grey900));
|
||||
sFixedColors.put(".yellow50", new Pair<Integer, Integer>(
|
||||
R.color.settingslib_color_yellow50, R.color.settingslib_color_grey900));
|
||||
// Secondary colors
|
||||
sFixedColors.put(".orange600", new Pair<Integer, Integer>(
|
||||
R.color.settingslib_color_orange600, R.color.settingslib_color_orange300));
|
||||
sFixedColors.put(".pink600", new Pair<Integer, Integer>(
|
||||
R.color.settingslib_color_pink600, R.color.settingslib_color_pink300));
|
||||
sFixedColors.put(".purple600", new Pair<Integer, Integer>(
|
||||
R.color.settingslib_color_purple600, R.color.settingslib_color_purple300));
|
||||
sFixedColors.put(".cyan600", new Pair<Integer, Integer>(
|
||||
R.color.settingslib_color_cyan600, R.color.settingslib_color_cyan300));
|
||||
sFixedColors.put(".orange400", new Pair<Integer, Integer>(
|
||||
R.color.settingslib_color_orange400, R.color.settingslib_color_orange100));
|
||||
sFixedColors.put(".pink400", new Pair<Integer, Integer>(
|
||||
R.color.settingslib_color_pink400, R.color.settingslib_color_pink100));
|
||||
sFixedColors.put(".purple400", new Pair<Integer, Integer>(
|
||||
R.color.settingslib_color_purple400, R.color.settingslib_color_purple100));
|
||||
sFixedColors.put(".cyan400", new Pair<Integer, Integer>(
|
||||
R.color.settingslib_color_cyan400, R.color.settingslib_color_cyan100));
|
||||
sFixedColors.put(".gery400", new Pair<Integer, Integer>(
|
||||
R.color.settingslib_color_grey400, R.color.settingslib_color_grey700));
|
||||
sFixedColors.put(".gery300", new Pair<Integer, Integer>(
|
||||
R.color.settingslib_color_grey300, R.color.settingslib_color_grey600));
|
||||
sFixedColors.put(".gery200", new Pair<Integer, Integer>(
|
||||
R.color.settingslib_color_grey200, R.color.settingslib_color_grey800));
|
||||
}
|
||||
|
||||
private static boolean isDarkMode(Context context) {
|
||||
return (context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK)
|
||||
== Configuration.UI_MODE_NIGHT_YES;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the color of tags to the animation.
|
||||
*/
|
||||
public static void applyDynamicColors(Context context, LottieAnimationView animationView) {
|
||||
for (String key : sSysColors.keySet()) {
|
||||
final int color = sSysColors.get(key);
|
||||
animationView.addValueCallback(
|
||||
new KeyPath("**", key, "**"),
|
||||
LottieProperty.COLOR_FILTER,
|
||||
new SimpleLottieValueCallback<ColorFilter>() {
|
||||
@Override
|
||||
public ColorFilter getValue(LottieFrameInfo<ColorFilter> frameInfo) {
|
||||
return new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
for (String key : sFixedColors.keySet()) {
|
||||
final Pair<Integer, Integer> fixedColorPair = sFixedColors.get(key);
|
||||
final int color = isDarkMode(context) ? fixedColorPair.second : fixedColorPair.first;
|
||||
animationView.addValueCallback(
|
||||
new KeyPath("**", key, "**"),
|
||||
LottieProperty.COLOR_FILTER,
|
||||
new SimpleLottieValueCallback<ColorFilter>() {
|
||||
@Override
|
||||
public ColorFilter getValue(LottieFrameInfo<ColorFilter> frameInfo) {
|
||||
return new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import android.os.Parcelable;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
@@ -38,10 +39,14 @@ import com.airbnb.lottie.LottieAnimationView;
|
||||
public class IllustrationPreference extends Preference implements OnPreferenceClickListener {
|
||||
|
||||
static final String TAG = "IllustrationPreference";
|
||||
|
||||
private int mAnimationId;
|
||||
private boolean mIsAnimating;
|
||||
private boolean mIsAutoScale;
|
||||
private ImageView mPlayButton;
|
||||
private LottieAnimationView mIllustrationView;
|
||||
private View mMiddleGroundView;
|
||||
private FrameLayout mMiddleGroundLayout;
|
||||
|
||||
public IllustrationPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
@@ -66,13 +71,20 @@ public class IllustrationPreference extends Preference implements OnPreferenceCl
|
||||
Log.w(TAG, "Invalid illustration resource id.");
|
||||
return;
|
||||
}
|
||||
mMiddleGroundLayout = (FrameLayout) holder.findViewById(R.id.middleground_layout);
|
||||
mPlayButton = (ImageView) holder.findViewById(R.id.video_play_button);
|
||||
mIllustrationView = (LottieAnimationView) holder.findViewById(R.id.lottie_view);
|
||||
mIllustrationView.setAnimation(mAnimationId);
|
||||
mIllustrationView.loop(true);
|
||||
ColorUtils.applyDynamicColors(getContext(), mIllustrationView);
|
||||
mIllustrationView.playAnimation();
|
||||
updateAnimationStatus(mIsAnimating);
|
||||
setOnPreferenceClickListener(this);
|
||||
if (mIsAutoScale) {
|
||||
enableAnimationAutoScale(mIsAutoScale);
|
||||
}
|
||||
if (mMiddleGroundView != null) {
|
||||
enableMiddleGroundView();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -102,16 +114,59 @@ public class IllustrationPreference extends Preference implements OnPreferenceCl
|
||||
return mIllustrationView.isAnimating();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the middle ground view to preference. The user
|
||||
* can overlay a view on top of the animation.
|
||||
*/
|
||||
public void setMiddleGroundView(View view) {
|
||||
mMiddleGroundView = view;
|
||||
if (mMiddleGroundLayout == null) {
|
||||
return;
|
||||
}
|
||||
enableMiddleGroundView();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the middle ground view of preference.
|
||||
*/
|
||||
public void removeMiddleGroundView() {
|
||||
if (mMiddleGroundLayout == null) {
|
||||
return;
|
||||
}
|
||||
mMiddleGroundLayout.removeAllViews();
|
||||
mMiddleGroundLayout.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the auto scale feature of animation view.
|
||||
*/
|
||||
public void enableAnimationAutoScale(boolean enable) {
|
||||
mIsAutoScale = enable;
|
||||
if (mIllustrationView == null) {
|
||||
return;
|
||||
}
|
||||
mIllustrationView.setScaleType(
|
||||
mIsAutoScale ? ImageView.ScaleType.CENTER_CROP : ImageView.ScaleType.CENTER_INSIDE);
|
||||
}
|
||||
|
||||
private void enableMiddleGroundView() {
|
||||
mMiddleGroundLayout.removeAllViews();
|
||||
mMiddleGroundLayout.addView(mMiddleGroundView);
|
||||
mMiddleGroundLayout.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
private void init(Context context, AttributeSet attrs) {
|
||||
setLayoutResource(R.layout.illustration_preference);
|
||||
|
||||
mIsAnimating = true;
|
||||
mIsAutoScale = false;
|
||||
if (attrs != null) {
|
||||
final TypedArray a = context.obtainStyledAttributes(attrs,
|
||||
R.styleable.LottieAnimationView, 0 /*defStyleAttr*/, 0 /*defStyleRes*/);
|
||||
mAnimationId = a.getResourceId(R.styleable.LottieAnimationView_lottie_rawRes, 0);
|
||||
a.recycle();
|
||||
}
|
||||
setOnPreferenceClickListener(this);
|
||||
}
|
||||
|
||||
private void updateAnimationStatus(boolean playAnimation) {
|
||||
|
||||
@@ -22,6 +22,9 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.airbnb.lottie.LottieAnimationView;
|
||||
|
||||
@@ -41,14 +44,15 @@ public class IllustrationPreferenceTest {
|
||||
@Mock
|
||||
LottieAnimationView mAnimationView;
|
||||
|
||||
private Context mContext;
|
||||
private IllustrationPreference mPreference;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
final Context context = RuntimeEnvironment.application;
|
||||
mContext = RuntimeEnvironment.application;
|
||||
final AttributeSet attributeSet = Robolectric.buildAttributeSet().build();
|
||||
mPreference = new IllustrationPreference(context, attributeSet);
|
||||
mPreference = new IllustrationPreference(mContext, attributeSet);
|
||||
ReflectionHelpers.setField(mPreference, "mIllustrationView", mAnimationView);
|
||||
}
|
||||
|
||||
@@ -65,4 +69,27 @@ public class IllustrationPreferenceTest {
|
||||
|
||||
assertThat(mPreference.isAnimating()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setMiddleGroundView_middleGroundView_shouldVisible() {
|
||||
final View view = new View(mContext);
|
||||
final FrameLayout layout = new FrameLayout(mContext);
|
||||
layout.setVisibility(View.GONE);
|
||||
ReflectionHelpers.setField(mPreference, "mMiddleGroundView", view);
|
||||
ReflectionHelpers.setField(mPreference, "mMiddleGroundLayout", layout);
|
||||
|
||||
mPreference.setMiddleGroundView(view);
|
||||
|
||||
assertThat(layout.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enableAnimationAutoScale_shouldChangeScaleType() {
|
||||
final LottieAnimationView animationView = new LottieAnimationView(mContext);
|
||||
ReflectionHelpers.setField(mPreference, "mIllustrationView", animationView);
|
||||
|
||||
mPreference.enableAnimationAutoScale(true);
|
||||
|
||||
assertThat(animationView.getScaleType()).isEqualTo(ImageView.ScaleType.CENTER_CROP);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user