diff --git a/res/drawable/ic_settings_expand_less.xml b/res/drawable/ic_settings_expand_less.xml new file mode 100644 index 00000000000..a6a22413e73 --- /dev/null +++ b/res/drawable/ic_settings_expand_less.xml @@ -0,0 +1,25 @@ + + + + diff --git a/res/drawable/ic_settings_expand_more.xml b/res/drawable/ic_settings_expand_more.xml new file mode 100644 index 00000000000..7a4042d06aa --- /dev/null +++ b/res/drawable/ic_settings_expand_more.xml @@ -0,0 +1,25 @@ + + + + diff --git a/res/layout/preference_expand_divider.xml b/res/layout/preference_expand_divider.xml new file mode 100644 index 00000000000..685ec0ea2e6 --- /dev/null +++ b/res/layout/preference_expand_divider.xml @@ -0,0 +1,50 @@ + + + + + + + + + + diff --git a/src/com/android/settings/fuelgauge/ExpandDividerPreference.java b/src/com/android/settings/fuelgauge/ExpandDividerPreference.java new file mode 100644 index 00000000000..06476df4564 --- /dev/null +++ b/src/com/android/settings/fuelgauge/ExpandDividerPreference.java @@ -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); + } + } +} diff --git a/tests/robotests/src/com/android/settings/fuelgauge/ExpandDividerPreferenceTest.java b/tests/robotests/src/com/android/settings/fuelgauge/ExpandDividerPreferenceTest.java new file mode 100644 index 00000000000..f9009a145b8 --- /dev/null +++ b/tests/robotests/src/com/android/settings/fuelgauge/ExpandDividerPreferenceTest.java @@ -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(); + } +}