Merge "Add new expandable preference component" into sc-dev

This commit is contained in:
YUKAI HUNG
2021-04-21 14:20:26 +00:00
committed by Android (Google) Code Review
5 changed files with 308 additions and 0 deletions

View File

@@ -0,0 +1,25 @@
<!--
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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M18.59,16.41L20,15l-8,-8 -8,8 1.41,1.41L12,9.83"/>
</vector>

View File

@@ -0,0 +1,25 @@
<!--
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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M5.41,7.59L4,9l8,8 8,-8 -1.41,-1.41L12,14.17"/>
</vector>

View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
android:gravity="center_vertical"
android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingRight="?android:attr/listPreferredItemPaddingRight"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:background="?android:attr/selectableItemBackground"
android:orientation="horizontal"
android:clipToPadding="false"
android:baselineAligned="false">
<TextView
android:id="@+id/expand_title"
android:layout_width="0px"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingEnd="4dp"
android:singleLine="true"
android:textAlignment="viewStart"
android:text="@string/battery_system_usage_for_past_24"
style="@style/PreferenceCategoryTitleTextStyle"/>
<ImageView
android:id="@+id/expand_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_settings_expand_more"/>
</LinearLayout>

View File

@@ -0,0 +1,98 @@
/*
* 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.settings.fuelgauge;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;
import com.android.settings.R;
/** A preference for expandable section divider. */
public class ExpandDividerPreference extends Preference {
private static final String TAG = "ExpandDividerPreference";
@VisibleForTesting
static final String PREFERENCE_KEY = "expandable_divider";
@VisibleForTesting TextView mTextView;
@VisibleForTesting ImageView mImageView;
private OnExpandListener mOnExpandListener;
private boolean mIsExpanded = false;
/** A callback listener for expand state is changed by users. */
public interface OnExpandListener {
void onExpand(boolean isExpanded);
}
public ExpandDividerPreference(Context context) {
this(context, /*attrs=*/ null);
}
public ExpandDividerPreference(Context context, AttributeSet attrs) {
super(context, attrs);
setLayoutResource(R.layout.preference_expand_divider);
setKey(PREFERENCE_KEY);
}
@Override
public void onBindViewHolder(PreferenceViewHolder view) {
super.onBindViewHolder(view);
mTextView = (TextView) view.findViewById(R.id.expand_title);
mImageView = (ImageView) view.findViewById(R.id.expand_icon);
refreshState();
}
@Override
public void onClick() {
mIsExpanded = !mIsExpanded;
refreshState();
if (mOnExpandListener != null) {
mOnExpandListener.onExpand(mIsExpanded);
}
}
void setTitle(String titleContent) {
if (mTextView != null) {
mTextView.setText(titleContent);
}
}
void setIsExpanded(boolean isExpanded) {
mIsExpanded = isExpanded;
refreshState();
}
void setOnExpandListener(OnExpandListener listener) {
mOnExpandListener = listener;
}
private void refreshState() {
final int iconId =
mIsExpanded
? R.drawable.ic_settings_expand_less
: R.drawable.ic_settings_expand_more;
if (mImageView != null) {
mImageView.setImageResource(iconId);
}
}
}

View File

@@ -0,0 +1,110 @@
/*
* 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.settings.fuelgauge;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.widget.ImageView;
import android.widget.TextView;
import com.android.settings.R;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
@RunWith(RobolectricTestRunner.class)
public final class ExpandDividerPreferenceTest {
private Context mContext;
private ExpandDividerPreference mExpandDividerPreference;
@Mock private ImageView mImageView;
@Mock private TextView mTextView;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
mExpandDividerPreference = new ExpandDividerPreference(mContext);
doReturn(R.id.expand_title).when(mTextView).getId();
doReturn(R.id.expand_icon).when(mImageView).getId();
}
@Test
public void testConstructor_returnExpectedResult() {
assertThat(mExpandDividerPreference.getKey())
.isEqualTo(ExpandDividerPreference.PREFERENCE_KEY);
assertThat(mExpandDividerPreference.getLayoutResource())
.isEqualTo(R.layout.preference_expand_divider);
}
@Test
public void testSetTitle_setTitleContentIntoTextView() {
final String titleContent = "title content";
mExpandDividerPreference.mTextView = mTextView;
mExpandDividerPreference.setTitle(titleContent);
verify(mTextView).setText(titleContent);
}
@Test
public void testOnClick_switchExpandStateAndInvokeCallback() {
final boolean[] isExpandedArray = new boolean[] {false};
mExpandDividerPreference.mImageView = mImageView;
mExpandDividerPreference.setOnExpandListener(
isExpanded -> isExpandedArray[0] = isExpanded);
// Click the item first time from false -> true.
mExpandDividerPreference.onClick();
// Verifies the first time click result.
verify(mImageView).setImageResource(R.drawable.ic_settings_expand_less);
assertThat(isExpandedArray[0]).isTrue();
// Clicks the item second time from true -> false.
mExpandDividerPreference.onClick();
// Verifies the second time click result.
verify(mImageView).setImageResource(R.drawable.ic_settings_expand_more);
assertThat(isExpandedArray[0]).isFalse();
}
@Test
public void testSetIsExpanded_updateStateButNotInvokeCallback() {
final boolean[] isExpandedArray = new boolean[] {false};
mExpandDividerPreference.mImageView = mImageView;
mExpandDividerPreference.setOnExpandListener(
isExpanded -> isExpandedArray[0] = isExpanded);
mExpandDividerPreference.setIsExpanded(true);
verify(mImageView).setImageResource(R.drawable.ic_settings_expand_less);
assertThat(isExpandedArray[0]).isFalse();
}
}