diff options
| author | 2018-12-10 00:25:02 +0800 | |
|---|---|---|
| committer | 2018-12-18 18:09:10 +0800 | |
| commit | 2badb3e13b8ae87a39a1806761b326d1e8b176b3 (patch) | |
| tree | 88798ed1cc82de885dfa5095d9cf5c9df9483faf | |
| parent | 25e0861b277a890d4d2bcc763a9414e28af04fc5 (diff) | |
Create a bar char preference widget
- Per Q design, we will show a bar chart in Settings > Privacy page.
Permission team also needs this bar chart in their page.
- Create a new library named SettingsLibBarChartPreference
Test: visual, robotest
Change-Id: Iff5a1233357a6aa6a667c0059f542a1b444b59a2
Fixes: 117623686
12 files changed, 968 insertions, 0 deletions
diff --git a/packages/SettingsLib/Android.bp b/packages/SettingsLib/Android.bp index 042808a07f8f..2321790fa960 100644 --- a/packages/SettingsLib/Android.bp +++ b/packages/SettingsLib/Android.bp @@ -19,6 +19,7 @@ android_library { "SettingsLibLayoutPreference", "SettingsLibActionButtonsPreference", "SettingsLibEntityHeaderWidgets", + "SettingsLibBarChartPreference" ], // ANDROIDMK TRANSLATION ERROR: unsupported assignment to LOCAL_SHARED_JAVA_LIBRARIES diff --git a/packages/SettingsLib/BarChartPreference/Android.bp b/packages/SettingsLib/BarChartPreference/Android.bp new file mode 100644 index 000000000000..477e8979b03b --- /dev/null +++ b/packages/SettingsLib/BarChartPreference/Android.bp @@ -0,0 +1,13 @@ +android_library { + name: "SettingsLibBarChartPreference", + + srcs: ["src/**/*.java"], + resource_dirs: ["res"], + + static_libs: [ + "androidx.preference_preference", + ], + + sdk_version: "system_current", + min_sdk_version: "21", +} diff --git a/packages/SettingsLib/BarChartPreference/AndroidManifest.xml b/packages/SettingsLib/BarChartPreference/AndroidManifest.xml new file mode 100644 index 000000000000..4b9f1ab8d6cc --- /dev/null +++ b/packages/SettingsLib/BarChartPreference/AndroidManifest.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2018 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. + --> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.settingslib.widget"> + + <uses-sdk android:minSdkVersion="21" /> + +</manifest> diff --git a/packages/SettingsLib/BarChartPreference/res/layout/settings_bar_chart.xml b/packages/SettingsLib/BarChartPreference/res/layout/settings_bar_chart.xml new file mode 100644 index 000000000000..1a4d7b7dee14 --- /dev/null +++ b/packages/SettingsLib/BarChartPreference/res/layout/settings_bar_chart.xml @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2018 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. + --> + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:settings="http://schemas.android.com/apk/res-auto" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginStart="16dp" + android:layout_marginEnd="16dp" + android:gravity="center" + android:orientation="vertical"> + + <TextView + android:id="@+id/bar_chart_title" + android:layout_width="wrap_content" + android:layout_height="48dp" + android:gravity="center" + android:textAppearance="@style/BarChart.Text.HeaderTitle"/> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center|bottom"> + + <com.android.settingslib.widget.BarView + android:id="@+id/bar_view1" + style="@style/BarViewStyle" + settings:barColor="#FA7B17"/> + <com.android.settingslib.widget.BarView + android:id="@+id/bar_view2" + style="@style/BarViewStyle" + settings:barColor="#F439A0"/> + <com.android.settingslib.widget.BarView + android:id="@+id/bar_view3" + style="@style/BarViewStyle" + settings:barColor="#A142F4"/> + <com.android.settingslib.widget.BarView + android:id="@+id/bar_view4" + style="@style/BarViewStyle" + settings:barColor="#24C1E0"/> + </LinearLayout> + + <Button + android:id="@+id/bar_chart_details" + style="@android:style/Widget.DeviceDefault.Button.Borderless.Colored" + android:layout_width="wrap_content" + android:layout_height="48dp" + android:gravity="center"/> + +</LinearLayout> diff --git a/packages/SettingsLib/BarChartPreference/res/layout/settings_bar_view.xml b/packages/SettingsLib/BarChartPreference/res/layout/settings_bar_view.xml new file mode 100644 index 000000000000..b053317b9de1 --- /dev/null +++ b/packages/SettingsLib/BarChartPreference/res/layout/settings_bar_view.xml @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2018 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. + --> + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="center" + android:orientation="vertical"> + + <View + android:id="@+id/bar_view" + android:layout_width="8dp" + android:layout_height="wrap_content" + android:background="?android:attr/colorAccent"/> + + <ImageView + android:id="@+id/icon_view" + android:layout_width="@dimen/settings_bar_view_icon_size" + android:layout_height="@dimen/settings_bar_view_icon_size" + android:scaleType="fitCenter" + android:layout_marginTop="12dp" + android:layout_marginBottom="12dp"/> + + <TextView + android:id="@+id/bar_title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="10dp" + android:layout_marginBottom="2dp" + android:singleLine="true" + android:ellipsize="marquee" + android:textAppearance="@style/BarChart.Text.Title"/> + + <TextView + android:id="@+id/bar_summary" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginBottom="12dp" + android:singleLine="true" + android:ellipsize="marquee" + android:textAppearance="@style/BarChart.Text.Summary"/> + +</LinearLayout>
\ No newline at end of file diff --git a/packages/SettingsLib/BarChartPreference/res/values/attrs.xml b/packages/SettingsLib/BarChartPreference/res/values/attrs.xml new file mode 100644 index 000000000000..df3eb0a36919 --- /dev/null +++ b/packages/SettingsLib/BarChartPreference/res/values/attrs.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2018 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> + + <declare-styleable name="SettingsBarView"> + <!-- The color of bar view --> + <attr name="barColor" format="color" /> + </declare-styleable> + +</resources> diff --git a/packages/SettingsLib/BarChartPreference/res/values/dimens.xml b/packages/SettingsLib/BarChartPreference/res/values/dimens.xml new file mode 100644 index 000000000000..7148afa2d62f --- /dev/null +++ b/packages/SettingsLib/BarChartPreference/res/values/dimens.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2018 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> + <dimen name="settings_bar_view_max_height">106dp</dimen> + <dimen name="settings_bar_view_icon_size">24dp</dimen> +</resources>
\ No newline at end of file diff --git a/packages/SettingsLib/BarChartPreference/res/values/styles.xml b/packages/SettingsLib/BarChartPreference/res/values/styles.xml new file mode 100644 index 000000000000..647d0800fe82 --- /dev/null +++ b/packages/SettingsLib/BarChartPreference/res/values/styles.xml @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2018 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> + <style name="BarViewStyle"> + <item name="android:layout_width">0dp</item> + <item name="android:layout_height">wrap_content</item> + <item name="android:layout_weight">1</item> + <item name="android:layout_marginStart">8dp</item> + <item name="android:layout_marginEnd">8dp</item> + </style> + + <style name="BarChart.Text" + parent="@android:style/TextAppearance.Material.Subhead"> + <item name="android:fontFamily">@*android:string/config_headlineFontFamilyMedium</item> + <item name="android:textColor">?android:attr/textColorPrimary</item> + </style> + + <style name="BarChart.Text.HeaderTitle"> + <item name="android:textSize">14sp</item> + </style> + + <style name="BarChart.Text.Title"> + <item name="android:textSize">22sp</item> + </style> + + <style name="BarChart.Text.Summary" + parent="@android:style/TextAppearance.Material.Body1"> + <item name="android:textColor">?android:attr/textColorSecondary</item> + <item name="android:textSize">14sp</item> + </style> +</resources>
\ No newline at end of file diff --git a/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarChartPreference.java b/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarChartPreference.java new file mode 100644 index 000000000000..89ebf4d1300a --- /dev/null +++ b/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarChartPreference.java @@ -0,0 +1,242 @@ +/* + * Copyright (C) 2018 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.util.AttributeSet; +import android.view.View; +import android.widget.Button; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.StringRes; +import androidx.preference.Preference; +import androidx.preference.PreferenceViewHolder; + +import java.util.Arrays; + +/** + * This BarChartPreference shows four bar views in this preference at most. + * + * <p>The following code sample shows a typical use, with an XML layout and code to initialize the + * contents of the BarChartPreference: + * + * <pre> + * <com.android.settingslib.widget.BarChartPreference + * android:key="bar_chart"/> + * </pre> + * + * <p>This code sample demonstrates how to initialize the contents of the BarChartPreference defined + * in the previous XML layout: + * + * <pre> + * BarViewInfo[] viewsInfo = new BarViewInfo [] { + * new BarViewInfo(icon, 18, res of summary), + * new BarViewInfo(icon, 25, res of summary), + * new BarViewInfo(icon, 10, res of summary), + * new BarViewInfo(icon, 3, res of summary), + * }; + * </pre> + * + * <pre> + * BarChartPreference preference = ((BarChartPreference) findPreference("bar_chart")); + * + * preference.setBarChartTitleRes(R.string.title_res); + * preference.setBarChartDetailsRes(R.string.details_res); + * preference.setBarChartDetailsClickListener(v -> doSomething()); + * preference.setAllBarViewsData(viewsInfo); + * </pre> + */ +public class BarChartPreference extends Preference { + + private static final String TAG = "BarChartPreference"; + private static final int MAXIMUM_BAR_VIEWS = 4; + private static final int[] BAR_VIEWS = { + R.id.bar_view1, + R.id.bar_view2, + R.id.bar_view3, + R.id.bar_view4 + }; + + private int mMaxBarHeight; + private @StringRes int mTitleId; + private @StringRes int mDetailsId; + private BarViewInfo[] mBarViewsInfo; + private View.OnClickListener mDetailsOnClickListener; + + /** + * Constructs a new BarChartPreference with the given context's theme. + * It sets a layout with settings bar chart style + * + * @param context The Context the view is running in, through which it can + * access the current theme, resources, etc. + */ + public BarChartPreference(Context context) { + super(context); + init(); + } + + /** + * Constructs a new BarChartPreference with the given context's theme and the supplied + * attribute set. + * It sets a layout with settings bar chart style + * + * @param context the Context the view is running in + * @param attrs the attributes of the XML tag that is inflating the view. + */ + public BarChartPreference(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + /** + * Constructs a new BarChartPreference with the given context's theme, the supplied + * attribute set, and default style attribute. + * It sets a layout with settings bar chart style + * + * @param context The Context the view is running in, through which it can + * access the current theme, resources, etc. + * @param attrs The attributes of the XML tag that is inflating the view. + * @param defStyleAttr An attribute in the current theme that contains a + * reference to a style resource that supplies default + * values for the view. Can be 0 to not look for + * defaults. + */ + public BarChartPreference(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(); + } + + /** + * Constructs a new BarChartPreference with the given context's theme, the supplied + * attribute set, and default styles. + * It sets a layout with settings bar chart style + * + * @param context The Context the view is running in, through which it can + * access the current theme, resources, etc. + * @param attrs The attributes of the XML tag that is inflating the view. + * @param defStyleAttr An attribute in the current theme that contains a + * reference to a style resource that supplies default + * values for the view. Can be 0 to not look for + * defaults. + * @param defStyleRes A resource identifier of a style resource that + * supplies default values for the view, used only if + * defStyleAttr is 0 or can not be found in the theme. + * Can be 0 to not look for defaults. + */ + public BarChartPreference(Context context, AttributeSet attrs, int defStyleAttr, + int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + init(); + } + + /** + * Set the text resource for bar chart title. + */ + public void setBarChartTitle(@StringRes int resId) { + mTitleId = resId; + notifyChanged(); + } + + /** + * Set the text resource for bar chart details. + */ + public void setBarChartDetails(@StringRes int resId) { + mDetailsId = resId; + notifyChanged(); + } + + /** + * Register a callback to be invoked when bar chart details view is clicked. + */ + public void setBarChartDetailsClickListener(@Nullable View.OnClickListener clickListener) { + mDetailsOnClickListener = clickListener; + notifyChanged(); + } + + /** + * Set all bar view information which you'd like to show in preference. + * + * <p>This method helps you do a sort by {@linkBarViewInfo#mBarNumber} in descending order. + * + * @param barViewsInfo the barViewsInfo contain at least one {@link BarViewInfo}. + */ + public void setAllBarViewsInfo(@NonNull BarViewInfo[] barViewsInfo) { + mBarViewsInfo = barViewsInfo; + // Do a sort in descending order, the first element would have max {@link + // BarViewInfo#mBarNumber} + Arrays.sort(mBarViewsInfo); + caculateAllBarViewsHeight(); + notifyChanged(); + } + + @Override + public void onBindViewHolder(PreferenceViewHolder holder) { + super.onBindViewHolder(holder); + holder.setDividerAllowedAbove(true); + holder.setDividerAllowedBelow(true); + + bindChartTitleView(holder); + bindChartDetailsView(holder); + updateBarChart(holder); + } + + private void init() { + setSelectable(false); + setLayoutResource(R.layout.settings_bar_chart); + mMaxBarHeight = getContext().getResources().getDimensionPixelSize( + R.dimen.settings_bar_view_max_height); + } + + private void bindChartTitleView(PreferenceViewHolder holder) { + final TextView titleView = (TextView) holder.findViewById(R.id.bar_chart_title); + titleView.setText(mTitleId); + } + + private void bindChartDetailsView(PreferenceViewHolder holder) { + final Button detailsView = (Button) holder.findViewById(R.id.bar_chart_details); + detailsView.setText(mDetailsId); + detailsView.setOnClickListener(mDetailsOnClickListener); + } + + private void updateBarChart(PreferenceViewHolder holder) { + for (int index = 0; index < MAXIMUM_BAR_VIEWS; index++) { + final BarView barView = (BarView) holder.findViewById(BAR_VIEWS[index]); + + // If there is no bar views data can be shown. + if (mBarViewsInfo == null || index >= mBarViewsInfo.length) { + barView.setVisibility(View.GONE); + continue; + } + barView.setVisibility(View.VISIBLE); + barView.updateBarViewUI(mBarViewsInfo[index]); + } + } + + private void caculateAllBarViewsHeight() { + // Since we sorted this array in advance, the first element must have the max {@link + // BarViewInfo#mBarNumber}. + final int maxBarViewNumber = mBarViewsInfo[0].getBarNumber(); + // If the max number of bar view is zero, then we don't caculate the unit for bar height. + final int unit = maxBarViewNumber == 0 ? 0 : mMaxBarHeight / maxBarViewNumber; + + for (BarViewInfo barView : mBarViewsInfo) { + barView.setBarHeight(barView.getBarNumber() * unit); + } + } +} diff --git a/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarView.java b/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarView.java new file mode 100644 index 000000000000..6243a2de387a --- /dev/null +++ b/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarView.java @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2018 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.TypedArray; +import android.util.AttributeSet; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.annotation.ColorInt; +import androidx.annotation.VisibleForTesting; + +/** + * A extension view for bar chart. + */ +public class BarView extends LinearLayout { + + private static final String TAG = "BarView"; + + private View mBarView; + private ImageView mIcon; + private TextView mBarTitle; + private TextView mBarSummary; + + /** + * Constructs a new BarView with the given context's theme. + * + * @param context The Context the view is running in, through which it can + * access the current theme, resources, etc. + */ + public BarView(Context context) { + super(context); + init(); + } + + /** + * Constructs a new BarView with the given context's theme and the supplied + * attribute set. + * + * @param context the Context the view is running in + * @param attrs the attributes of the XML tag that is inflating the view. + */ + public BarView(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + + // Get accent color + TypedArray a = context.obtainStyledAttributes(new int[]{android.R.attr.colorAccent}); + @ColorInt final int colorAccent = a.getColor(0, 0); + + // Get bar color from layout XML + a = context.obtainStyledAttributes(attrs, R.styleable.SettingsBarView); + @ColorInt final int barColor = a.getColor(R.styleable.SettingsBarView_barColor, + colorAccent); + a.recycle(); + + mBarView.setBackgroundColor(barColor); + } + + /** + * This helps update the bar view UI with a {@link BarViewInfo}. + * + * @param barViewInfo A {@link BarViewInfo} saves bar view status. + */ + public void updateBarViewUI(BarViewInfo barViewInfo) { + //Set height of bar view + mBarView.getLayoutParams().height = barViewInfo.getBarHeight(); + mIcon.setImageDrawable(barViewInfo.getIcon()); + // For now, we use the bar number as title. + mBarTitle.setText(Integer.toString(barViewInfo.getBarNumber())); + mBarSummary.setText(barViewInfo.getSummaryRes()); + } + + @VisibleForTesting + CharSequence getTitle() { + return mBarTitle.getText(); + } + + @VisibleForTesting + CharSequence getSummary() { + return mBarSummary.getText(); + } + + private void init() { + LayoutInflater.from(getContext()).inflate(R.layout.settings_bar_view, this); + setOrientation(LinearLayout.VERTICAL); + setGravity(Gravity.CENTER); + + mBarView = findViewById(R.id.bar_view); + mIcon = (ImageView) findViewById(R.id.icon_view); + mBarTitle = (TextView) findViewById(R.id.bar_title); + mBarSummary = (TextView) findViewById(R.id.bar_summary); + } + + private void setOnClickListner(View.OnClickListener listener) { + mBarView.setOnClickListener(listener); + } +} diff --git a/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarViewInfo.java b/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarViewInfo.java new file mode 100644 index 000000000000..aa83ce99d200 --- /dev/null +++ b/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarViewInfo.java @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2018 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.graphics.drawable.Drawable; +import android.view.View; + +import androidx.annotation.IntRange; +import androidx.annotation.Nullable; +import androidx.annotation.StringRes; + +import java.util.Comparator; + +/** + * A class responsible for saving bar view information. + */ +public class BarViewInfo implements Comparable<BarViewInfo> { + + private final Drawable mIcon; + private View.OnClickListener mListener; + private @StringRes int mSummaryRes; + // A number indicates this bar's height. The larger number shows a higher bar view. + private int mBarNumber; + // A real height of bar view. + private int mBarHeight; + + /** + * Construct a BarViewInfo instance. + * + * @param icon the icon of bar view. + * @param barNumber the number of bar view. The larger number show a more height of bar view. + * @param summaryRes the resource identifier of the string resource to be displayed + * @return BarViewInfo object. + */ + public BarViewInfo(Drawable icon, @IntRange(from = 0) int barNumber, + @StringRes int summaryRes) { + mIcon = icon; + mBarNumber = barNumber; + mSummaryRes = summaryRes; + } + + /** + * Set number for bar view. + * + * @param barNumber the number of bar view. The larger number shows a higher bar view. + */ + public void setBarNumber(@IntRange(from = 0) int barNumber) { + mBarNumber = barNumber; + } + + /** + * Set summary resource for bar view + * + * @param resId the resource identifier of the string resource to be displayed + */ + public void setSummary(@StringRes int resId) { + mSummaryRes = resId; + } + + /** + * Set a click listner for bar view. + * + * @param listener the click listner is attached on bar view. + */ + public void setClickListener(@Nullable View.OnClickListener listener) { + mListener = listener; + } + + /** + * Get the icon of bar view. + * + * @return Drawable the icon of bar view. + */ + public Drawable getIcon() { + return mIcon; + } + + /** + * Get the OnClickListener of bar view. + * + * @return View.OnClickListener the click listner of bar view. + */ + public View.OnClickListener getListener() { + return mListener; + } + + /** + * Get the real height of bar view. + * + * @return the real height of bar view. + */ + public int getBarHeight() { + return mBarHeight; + } + + /** + * Get summary resource of bar view. + * + * @return summary resource of bar view. + */ + public int getSummaryRes() { + return mSummaryRes; + } + + /** + * Get the number of app uses this permisssion. + * + * @return the number of app uses this permission. + */ + public int getBarNumber() { + return mBarNumber; + } + + @Override + public int compareTo(BarViewInfo other) { + // Descending order + return Comparator.comparingInt((BarViewInfo barViewInfo) -> barViewInfo.mBarNumber) + .compare(other, this); + } + + /** + * Set a real height for bar view. + * + * <p>This method should not be called by outside. It usually should be called by + * {@link BarChartPreference#caculateAllBarViewsHeight} + * + * @param barHeight the real bar height for bar view. + */ + void setBarHeight(@IntRange(from = 0) int barHeight) { + mBarHeight = barHeight; + } +} diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BarChartPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BarChartPreferenceTest.java new file mode 100644 index 000000000000..371c3d46dfb4 --- /dev/null +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BarChartPreferenceTest.java @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2018 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 static com.google.common.truth.Truth.assertThat; + +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.view.View; +import android.widget.TextView; + +import androidx.preference.PreferenceViewHolder; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +@RunWith(RobolectricTestRunner.class) +public class BarChartPreferenceTest { + + private Context mContext; + private View mBarChartView; + private Drawable mIcon; + private BarView mBarView1; + private BarView mBarView2; + private BarView mBarView3; + private BarView mBarView4; + private PreferenceViewHolder mHolder; + private BarChartPreference mPreference; + + @Before + public void setUp() { + mContext = RuntimeEnvironment.application; + mBarChartView = View.inflate(mContext, R.layout.settings_bar_chart, null /* parent */); + mHolder = PreferenceViewHolder.createInstanceForTests(mBarChartView); + mPreference = new BarChartPreference(mContext, null /* attrs */); + mPreference.setBarChartTitle(R.string.debug_app); + mPreference.setBarChartDetails(R.string.debug_app); + + + mIcon = mContext.getDrawable(R.drawable.ic_menu); + mBarView1 = (BarView) mBarChartView.findViewById(R.id.bar_view1); + mBarView2 = (BarView) mBarChartView.findViewById(R.id.bar_view2); + mBarView3 = (BarView) mBarChartView.findViewById(R.id.bar_view3); + mBarView4 = (BarView) mBarChartView.findViewById(R.id.bar_view4); + } + + @Test + public void setBarChartTitleRes_setTitleRes_showInBarChartTitle() { + final TextView titleView = (TextView) mBarChartView.findViewById(R.id.bar_chart_title); + + mPreference.setBarChartTitle(R.string.debug_app); + mPreference.onBindViewHolder(mHolder); + + assertThat(titleView.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(titleView.getText()).isEqualTo(mContext.getText(R.string.debug_app)); + } + + @Test + public void setBarChartDetailsRes_setDetailsRes_showInBarChartDetails() { + final TextView detailsView = (TextView) mBarChartView.findViewById(R.id.bar_chart_details); + + mPreference.setBarChartDetails(R.string.debug_app); + mPreference.onBindViewHolder(mHolder); + + assertThat(detailsView.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(detailsView.getText()).isEqualTo(mContext.getText(R.string.debug_app)); + } + + @Test + public void setBarChartDetailsClickListener_setClickListener_detailsViewAttachClickListener() { + final TextView detailsView = (TextView) mBarChartView.findViewById(R.id.bar_chart_details); + + mPreference.setBarChartDetailsClickListener(v -> { + }); + mPreference.onBindViewHolder(mHolder); + + assertThat(detailsView.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(detailsView.hasOnClickListeners()).isTrue(); + } + + @Test + public void setAllBarViewsInfo_setOneBarViewInfo_showOneBarView() { + final BarViewInfo[] barViewsInfo = new BarViewInfo[]{ + new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app) + }; + + mPreference.setAllBarViewsInfo(barViewsInfo); + mPreference.onBindViewHolder(mHolder); + + assertThat(mBarView1.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mBarView1.getTitle()).isEqualTo("10"); + + assertThat(mBarView2.getVisibility()).isEqualTo(View.GONE); + assertThat(mBarView3.getVisibility()).isEqualTo(View.GONE); + assertThat(mBarView4.getVisibility()).isEqualTo(View.GONE); + } + + @Test + public void setAllBarViewsInfo_setTwoBarViewsInfo_showTwoBarViews() { + final BarViewInfo[] barViewsInfo = new BarViewInfo[]{ + new BarViewInfo(mIcon, 20 /* barNumber */, R.string.debug_app), + new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app) + }; + + mPreference.setAllBarViewsInfo(barViewsInfo); + mPreference.onBindViewHolder(mHolder); + + assertThat(mBarView1.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mBarView1.getTitle()).isEqualTo("20"); + assertThat(mBarView2.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mBarView2.getTitle()).isEqualTo("10"); + + assertThat(mBarView3.getVisibility()).isEqualTo(View.GONE); + assertThat(mBarView4.getVisibility()).isEqualTo(View.GONE); + } + + @Test + public void setAllBarViewsInfo_setThreeBarViewsInfo_showThreeBarViews() { + final BarViewInfo[] barViewsInfo = new BarViewInfo[]{ + new BarViewInfo(mIcon, 20 /* barNumber */, R.string.debug_app), + new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app), + new BarViewInfo(mIcon, 5 /* barNumber */, R.string.debug_app) + }; + + mPreference.setAllBarViewsInfo(barViewsInfo); + mPreference.onBindViewHolder(mHolder); + + assertThat(mBarView1.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mBarView1.getTitle()).isEqualTo("20"); + assertThat(mBarView2.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mBarView2.getTitle()).isEqualTo("10"); + assertThat(mBarView3.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mBarView3.getTitle()).isEqualTo("5"); + + assertThat(mBarView4.getVisibility()).isEqualTo(View.GONE); + } + + @Test + public void setAllBarViewsInfo_setFourBarViewsInfo_showFourBarViews() { + final BarViewInfo[] barViewsInfo = new BarViewInfo[]{ + new BarViewInfo(mIcon, 20 /* barNumber */, R.string.debug_app), + new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app), + new BarViewInfo(mIcon, 5 /* barNumber */, R.string.debug_app), + new BarViewInfo(mIcon, 2 /* barNumber */, R.string.debug_app), + }; + + mPreference.setAllBarViewsInfo(barViewsInfo); + mPreference.onBindViewHolder(mHolder); + + assertThat(mBarView1.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mBarView1.getTitle()).isEqualTo("20"); + assertThat(mBarView2.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mBarView2.getTitle()).isEqualTo("10"); + assertThat(mBarView3.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mBarView3.getTitle()).isEqualTo("5"); + assertThat(mBarView4.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mBarView4.getTitle()).isEqualTo("2"); + } + + @Test + public void setAllBarViewsInfo_setFourBarViewsInfo_barViewWasSortedInDescending() { + final BarViewInfo[] barViewsInfo = new BarViewInfo[]{ + new BarViewInfo(mIcon, 30 /* barNumber */, R.string.debug_app), + new BarViewInfo(mIcon, 50 /* barNumber */, R.string.debug_app), + new BarViewInfo(mIcon, 5 /* barNumber */, R.string.debug_app), + new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app), + }; + + mPreference.setAllBarViewsInfo(barViewsInfo); + mPreference.onBindViewHolder(mHolder); + + assertThat(mBarView1.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mBarView1.getTitle()).isEqualTo("50"); + assertThat(mBarView2.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mBarView2.getTitle()).isEqualTo("30"); + assertThat(mBarView3.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mBarView3.getTitle()).isEqualTo("10"); + assertThat(mBarView4.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mBarView4.getTitle()).isEqualTo("5"); + } + + @Test + public void setAllBarViewsInfo_setValidSummaryRes_barViewShouldShowSummary() { + final BarViewInfo[] barViewsInfo = new BarViewInfo[]{ + new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app), + }; + + mPreference.setAllBarViewsInfo(barViewsInfo); + mPreference.onBindViewHolder(mHolder); + + assertThat(mBarView1.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mBarView1.getSummary()).isEqualTo(mContext.getText(R.string.debug_app)); + } +} |