Merge changes from topic "settings-action-button"

* changes:
  Remove setButtonPositive method
  Apply new action button visual design
  Create a new visual design for action buttons
This commit is contained in:
TreeHugger Robot
2018-11-16 10:45:29 +00:00
committed by Android (Google) Code Review
21 changed files with 314 additions and 161 deletions

View File

@@ -0,0 +1,25 @@
<!--
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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41z"/>
</vector>

View File

@@ -0,0 +1,31 @@
<!--
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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M15,4V3H9v1H4v2h1v13c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2V6h1V4H15zM17,19H7V6h10V19z"/>
<path
android:fillColor="#FF000000"
android:pathData="M9,8h2v9h-2z"/>
<path
android:fillColor="#FF000000"
android:pathData="M13,8h2v9h-2z"/>
</vector>

View File

@@ -0,0 +1,31 @@
<!--
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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M12,5.99L19.53,19H4.47L12,5.99M12,2L1,21h22L12,2L12,2z"/>
<path
android:fillColor="#FF000000"
android:pathData="M13,16l-2,0l0,2l2,0l0,-2z"/>
<path
android:fillColor="#FF000000"
android:pathData="M13,10l-2,0l0,4l2,0l0,-4z"/>
</vector>

View File

@@ -0,0 +1,28 @@
<!--
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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M18,15v3H6v-3H4v3c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2v-3H18z"/>
<path
android:fillColor="#FF000000"
android:pathData="M17,11.5l-1.41,-1.41l-2.59,2.58l0,-8.67l-2,0l0,8.67l-2.59,-2.58l-1.41,1.41l5,5z"/>
</vector>

View File

@@ -0,0 +1,25 @@
<!--
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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M19,19H5V5h7V3H5C3.89,3 3,3.9 3,5v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2v-7h-2V19zM14,3v2h3.59l-9.83,9.83l1.41,1.41L19,6.41V10h2V3H14z"/>
</vector>

View File

@@ -19,47 +19,28 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingTop="24dp"
android:paddingStart="68dp"
android:paddingEnd="24dp"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:orientation="horizontal">
<FrameLayout
<Button
android:id="@+id/button1"
style="@style/SettingsActionButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_height="wrap_content">
<Button
android:id="@+id/button1_positive"
style="@style/ActionPrimaryButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp" />
<Button
android:id="@+id/button1_negative"
style="@style/ActionSecondaryButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp" />
</FrameLayout>
android:paddingTop="20dp"
android:paddingBottom="20dp"/>
<Space
android:layout_width="16dp"
android:layout_width="8dp"
android:layout_height="wrap_content" />
<FrameLayout
<Button
android:id="@+id/button2"
style="@style/SettingsActionButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_height="wrap_content">
<Button
android:id="@+id/button2_positive"
style="@style/ActionPrimaryButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp" />
<Button
android:id="@+id/button2_negative"
style="@style/ActionSecondaryButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp" />
</FrameLayout>
android:paddingTop="20dp"
android:paddingBottom="20dp"/>
</LinearLayout>

View File

@@ -4002,8 +4002,6 @@
<string name="uninstall_all_users_text">Uninstall for all users</string>
<!-- [CHAR LIMIT=NONE] Manage applications, individual application info screen, button label under Storage heading. Button to install an application for the user. -->
<string name="install_text">Install</string>
<!-- [CHAR LIMIT=25] Manage applications, individual application info screen, button label under Storage heading. Button to disable an existing application. -->
<string name="disable_text">Disable</string>
<!-- [CHAR LIMIT=25] Manage applications, individual application info screen, button label under Storage heading. Button to re-enable an existing application. -->
<string name="enable_text">Enable</string>
<!-- Manage applications, individual application info screen, button label under Storage heading. Button to clear all data associated with tis app (for example, remove all cached emails for an Email app) -->

View File

@@ -426,6 +426,11 @@
<style name="ActionSecondaryButton" parent="android:Widget.DeviceDefault.Button"/>
<style name="SettingsActionButton" parent="android:Widget.DeviceDefault.Button.Borderless.Colored">
<item name="android:drawablePadding">4dp</item>
<item name="android:drawableTint">@*android:color/btn_colored_borderless_text_material</item>
</style>
<style name="LockPatternContainerStyle">
<item name="android:maxHeight">400dp</item>
<item name="android:maxWidth">420dp</item>

View File

@@ -25,7 +25,8 @@
android:key="header_view"
android:layout="@layout/settings_entity_header"
android:selectable="false"
android:order="-10000" />
android:order="-10000"
settings:allowDividerBelow="true"/>
<com.android.settings.applications.LayoutPreference
android:key="instant_app_buttons"
@@ -40,7 +41,8 @@
<Preference
android:key="notification_settings"
android:title="@string/notifications_label"
settings:controller="com.android.settings.applications.appinfo.AppNotificationPreferenceController" />
settings:controller="com.android.settings.applications.appinfo.AppNotificationPreferenceController"
settings:allowDividerAbove="true"/>
<com.android.settings.widget.FixedLineSummaryPreference
android:key="permission_settings"

View File

@@ -16,12 +16,14 @@
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:title="@string/device_details_title">
<com.android.settings.applications.LayoutPreference
android:key="bluetooth_device_header"
android:layout="@layout/settings_entity_header"
android:selectable="false"/>
android:selectable="false"
settings:allowDividerBelow="true"/>
<com.android.settings.widget.ActionButtonPreference
android:key="action_buttons" />

View File

@@ -23,7 +23,8 @@
android:key="connection_header"
android:layout="@layout/settings_entity_header"
android:selectable="false"
android:order="-10000"/>
android:order="-10000"
settings:allowDividerBelow="true"/>
<!-- Buttons -->
<com.android.settings.widget.ActionButtonPreference

View File

@@ -167,10 +167,7 @@ public class AppStorageSettings extends AppInfoWithHeader
.setComputingString(R.string.computing_size)
.setErrorString(R.string.invalid_size_value)
.build();
mButtonsPref = ((ActionButtonPreference) findPreference(KEY_HEADER_BUTTONS))
.setButton1Positive(false)
.setButton2Positive(false);
mButtonsPref = ((ActionButtonPreference) findPreference(KEY_HEADER_BUTTONS));
mStorageUsed = findPreference(KEY_STORAGE_USED);
mChangeStorageButton = (Button) ((LayoutPreference) findPreference(KEY_CHANGE_STORAGE))
.findViewById(R.id.button);
@@ -178,7 +175,9 @@ public class AppStorageSettings extends AppInfoWithHeader
mChangeStorageButton.setOnClickListener(this);
// Cache section
mButtonsPref.setButton2Text(R.string.clear_cache_btn_text);
mButtonsPref
.setButton2Text(R.string.clear_cache_btn_text)
.setButton2Icon(R.drawable.ic_settings_delete);
// URI permissions section
mUri = (PreferenceCategory) findPreference(KEY_URI_CATEGORY);
@@ -304,16 +303,20 @@ public class AppStorageSettings extends AppInfoWithHeader
|| !isManageSpaceActivityAvailable) {
mButtonsPref
.setButton1Text(R.string.clear_user_data_text)
.setButton1Icon(R.drawable.ic_settings_delete)
.setButton1Enabled(false);
mCanClearData = false;
} else {
if (appHasSpaceManagementUI) {
mButtonsPref.setButton1Text(R.string.manage_space_text);
} else {
mButtonsPref.setButton1Text(R.string.clear_user_data_text);
mButtonsPref
.setButton1Text(R.string.clear_user_data_text)
.setButton1Icon(R.drawable.ic_settings_delete);
}
mButtonsPref
.setButton1Text(R.string.clear_user_data_text)
.setButton1Icon(R.drawable.ic_settings_delete)
.setButton1OnClickListener(v -> handleClearDataClick());
}
@@ -384,7 +387,9 @@ public class AppStorageSettings extends AppInfoWithHeader
private void processClearMsg(Message msg) {
int result = msg.arg1;
String packageName = mAppEntry.info.packageName;
mButtonsPref.setButton1Text(R.string.clear_user_data_text);
mButtonsPref
.setButton1Text(R.string.clear_user_data_text)
.setButton1Icon(R.drawable.ic_settings_delete);
if (result == OP_SUCCESSFUL) {
Log.i(TAG, "Cleared user data for package : " + packageName);
updateSize();

View File

@@ -167,11 +167,11 @@ public class AppButtonsPreferenceController extends BasePreferenceController imp
if (isAvailable()) {
mButtonsPref = ((ActionButtonPreference) screen.findPreference(KEY_ACTION_BUTTONS))
.setButton1Text(R.string.uninstall_text)
.setButton1Icon(R.drawable.ic_settings_delete)
.setButton2Text(R.string.force_stop)
.setButton2Icon(R.drawable.ic_settings_force_stop)
.setButton1OnClickListener(new UninstallAndDisableButtonListener())
.setButton2OnClickListener(new ForceStopButtonListener())
.setButton1Positive(false)
.setButton2Positive(false)
.setButton2Enabled(false);
}
}
@@ -547,16 +547,16 @@ public class AppButtonsPreferenceController extends BasePreferenceController imp
if (mHomePackages.contains(mAppEntry.info.packageName)
|| isSystemPackage(mActivity.getResources(), mPm, mPackageInfo)) {
// Disable button for core system applications.
mButtonsPref.setButton1Text(R.string.disable_text)
.setButton1Positive(false);
mButtonsPref.setButton1Text(R.string.uninstall_text)
.setButton1Icon(R.drawable.ic_settings_delete);
} else if (mAppEntry.info.enabled && !isDisabledUntilUsed()) {
mButtonsPref.setButton1Text(R.string.disable_text)
.setButton1Positive(false);
mButtonsPref.setButton1Text(R.string.uninstall_text)
.setButton1Icon(R.drawable.ic_settings_delete);
disableable = !mApplicationFeatureProvider.getKeepEnabledPackages()
.contains(mAppEntry.info.packageName);
} else {
mButtonsPref.setButton1Text(R.string.enable_text)
.setButton1Positive(true);
mButtonsPref.setButton1Text(R.string.install_text)
.setButton1Icon(R.drawable.ic_settings_install);
disableable = true;
}

View File

@@ -53,8 +53,8 @@ public class BluetoothDetailsButtonsController extends BluetoothDetailsControlle
protected void init(PreferenceScreen screen) {
mActionButtons = ((ActionButtonPreference) screen.findPreference(getPreferenceKey()))
.setButton1Text(R.string.forget)
.setButton1Icon(R.drawable.ic_settings_delete)
.setButton1OnClickListener((view) -> onForgetButtonPressed())
.setButton1Positive(false)
.setButton1Enabled(true);
}
@@ -68,17 +68,17 @@ public class BluetoothDetailsButtonsController extends BluetoothDetailsControlle
if (!mConnectButtonInitialized || !previouslyConnected) {
mActionButtons
.setButton2Text(R.string.bluetooth_device_context_disconnect)
.setButton2OnClickListener(view -> mCachedDevice.disconnect())
.setButton2Positive(false);
.setButton2Icon(R.drawable.ic_settings_close)
.setButton2OnClickListener(view -> mCachedDevice.disconnect());
mConnectButtonInitialized = true;
}
} else {
if (!mConnectButtonInitialized || previouslyConnected) {
mActionButtons
.setButton2Text(R.string.bluetooth_device_context_connect)
// TODO (b/119646923) Icon is not ready.
.setButton2OnClickListener(
view -> mCachedDevice.connect(true /* connectAllProfiles */))
.setButton2Positive(true);
view -> mCachedDevice.connect(true /* connectAllProfiles */));
mConnectButtonInitialized = true;
}
}

View File

@@ -171,11 +171,9 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment
mActionButtons = ((ActionButtonPreference) findPreference(KEY_ACTION_BUTTONS))
.setButton1Text(R.string.tts_play)
.setButton1Positive(true)
.setButton1OnClickListener(v -> speakSampleText())
.setButton1Enabled(false)
.setButton2Text(R.string.tts_reset)
.setButton2Positive(false)
.setButton2OnClickListener(v -> resetTts())
.setButton1Enabled(true);

View File

@@ -17,11 +17,15 @@
package com.android.settings.widget;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import androidx.annotation.DrawableRes;
import androidx.annotation.StringRes;
import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;
@@ -30,6 +34,7 @@ import com.android.settings.R;
public class ActionButtonPreference extends Preference {
private final String TAG = "ActionButtonPreference";
private final ButtonInfo mButton1Info = new ButtonInfo();
private final ButtonInfo mButton2Info = new ButtonInfo();
@@ -62,12 +67,11 @@ public class ActionButtonPreference extends Preference {
@Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
holder.setDividerAllowedAbove(false);
holder.setDividerAllowedBelow(false);
mButton1Info.mPositiveButton = (Button) holder.findViewById(R.id.button1_positive);
mButton1Info.mNegativeButton = (Button) holder.findViewById(R.id.button1_negative);
mButton2Info.mPositiveButton = (Button) holder.findViewById(R.id.button2_positive);
mButton2Info.mNegativeButton = (Button) holder.findViewById(R.id.button2_negative);
holder.setDividerAllowedAbove(true);
holder.setDividerAllowedBelow(true);
mButton1Info.mButton = (Button) holder.findViewById(R.id.button1);
mButton2Info.mButton = (Button) holder.findViewById(R.id.button2);
mButton1Info.setUpButton();
mButton2Info.setUpButton();
@@ -82,6 +86,22 @@ public class ActionButtonPreference extends Preference {
return this;
}
public ActionButtonPreference setButton1Icon(@DrawableRes int iconResId) {
if (iconResId == 0) {
return this;
}
final Drawable icon;
try {
icon = getContext().getDrawable(iconResId);
mButton1Info.mIcon = icon;
notifyChanged();
} catch (Resources.NotFoundException exception) {
Log.e(TAG, "Resource does not exist: " + iconResId);
}
return this;
}
public ActionButtonPreference setButton1Enabled(boolean isEnabled) {
if (isEnabled != mButton1Info.mIsEnabled) {
mButton1Info.mIsEnabled = isEnabled;
@@ -99,6 +119,22 @@ public class ActionButtonPreference extends Preference {
return this;
}
public ActionButtonPreference setButton2Icon(@DrawableRes int iconResId) {
if (iconResId == 0) {
return this;
}
final Drawable icon;
try {
icon = getContext().getDrawable(iconResId);
mButton2Info.mIcon = icon;
notifyChanged();
} catch (Resources.NotFoundException exception) {
Log.e(TAG, "Resource does not exist: " + iconResId);
}
return this;
}
public ActionButtonPreference setButton2Enabled(boolean isEnabled) {
if (isEnabled != mButton2Info.mIsEnabled) {
mButton2Info.mIsEnabled = isEnabled;
@@ -123,65 +159,41 @@ public class ActionButtonPreference extends Preference {
return this;
}
public ActionButtonPreference setButton1Positive(boolean isPositive) {
if (isPositive != mButton1Info.mIsPositive) {
mButton1Info.mIsPositive = isPositive;
public ActionButtonPreference setButton1Visible(boolean isVisible) {
if (isVisible != mButton1Info.mIsVisible) {
mButton1Info.mIsVisible = isVisible;
notifyChanged();
}
return this;
}
public ActionButtonPreference setButton2Positive(boolean isPositive) {
if (isPositive != mButton2Info.mIsPositive) {
mButton2Info.mIsPositive = isPositive;
notifyChanged();
}
return this;
}
public ActionButtonPreference setButton1Visible(boolean isPositive) {
if (isPositive != mButton1Info.mIsVisible) {
mButton1Info.mIsVisible = isPositive;
notifyChanged();
}
return this;
}
public ActionButtonPreference setButton2Visible(boolean isPositive) {
if (isPositive != mButton2Info.mIsVisible) {
mButton2Info.mIsVisible = isPositive;
public ActionButtonPreference setButton2Visible(boolean isVisible) {
if (isVisible != mButton2Info.mIsVisible) {
mButton2Info.mIsVisible = isVisible;
notifyChanged();
}
return this;
}
static class ButtonInfo {
private Button mPositiveButton;
private Button mNegativeButton;
private Button mButton;
private CharSequence mText;
private Drawable mIcon;
private View.OnClickListener mListener;
private boolean mIsPositive = true;
private boolean mIsEnabled = true;
private boolean mIsVisible = true;
void setUpButton() {
setUpButton(mPositiveButton);
setUpButton(mNegativeButton);
if (!mIsVisible) {
mPositiveButton.setVisibility(View.INVISIBLE);
mNegativeButton.setVisibility(View.INVISIBLE);
} else if (mIsPositive) {
mPositiveButton.setVisibility(View.VISIBLE);
mNegativeButton.setVisibility(View.INVISIBLE);
mButton.setText(mText);
mButton.setOnClickListener(mListener);
mButton.setEnabled(mIsEnabled);
mButton.setCompoundDrawablesWithIntrinsicBounds(
null /* left */, mIcon /* top */, null /* right */, null /* bottom */);
if (mIsVisible) {
mButton.setVisibility(View.VISIBLE);
} else {
mPositiveButton.setVisibility(View.INVISIBLE);
mNegativeButton.setVisibility(View.VISIBLE);
mButton.setVisibility(View.GONE);
}
}
private void setUpButton(Button button) {
button.setText(mText);
button.setOnClickListener(mListener);
button.setEnabled(mIsEnabled);
}
}
}

View File

@@ -278,10 +278,9 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController
mButtonsPref = ((ActionButtonPreference) screen.findPreference(KEY_BUTTONS_PREF))
.setButton1Text(R.string.forget)
.setButton1Positive(false)
.setButton1Icon(R.drawable.ic_settings_delete)
.setButton1OnClickListener(view -> forgetNetwork())
.setButton2Text(R.string.wifi_sign_in_button_text)
.setButton2Positive(true)
.setButton2OnClickListener(view -> signIntoNetwork());
mSignalStrengthPref =

View File

@@ -75,12 +75,12 @@ public class LayoutPreferenceTest {
@Test
public void disableSomeView_shouldMaintainStateAfterBind() {
mPreference.findViewById(R.id.button1_positive).setEnabled(false);
mPreference.findViewById(R.id.button2_positive).setEnabled(true);
mPreference.findViewById(R.id.button1).setEnabled(false);
mPreference.findViewById(R.id.button2).setEnabled(true);
mPreference.onBindViewHolder(mHolder);
assertThat(mPreference.findViewById(R.id.button1_positive).isEnabled()).isFalse();
assertThat(mPreference.findViewById(R.id.button2_positive).isEnabled()).isTrue();
assertThat(mPreference.findViewById(R.id.button1).isEnabled()).isFalse();
assertThat(mPreference.findViewById(R.id.button2).isEnabled()).isTrue();
}
}

View File

@@ -308,7 +308,7 @@ public class AppButtonsPreferenceControllerTest {
final boolean controllable = mController.handleDisableable();
verify(mButtonPrefs).setButton1Text(R.string.disable_text);
verify(mButtonPrefs).setButton1Text(R.string.uninstall_text);
assertThat(controllable).isFalse();
}
@@ -320,7 +320,7 @@ public class AppButtonsPreferenceControllerTest {
final boolean controllable = mController.handleDisableable();
verify(mButtonPrefs).setButton1Text(R.string.disable_text);
verify(mButtonPrefs).setButton1Text(R.string.uninstall_text);
assertThat(controllable).isTrue();
}
@@ -332,7 +332,7 @@ public class AppButtonsPreferenceControllerTest {
final boolean controllable = mController.handleDisableable();
verify(mButtonPrefs).setButton1Text(R.string.enable_text);
verify(mButtonPrefs).setButton1Text(R.string.install_text);
assertThat(controllable).isTrue();
}

View File

@@ -56,8 +56,8 @@ public class BluetoothDetailsButtonsControllerTest extends BluetoothDetailsContr
super.setUp();
final View buttons = View.inflate(
RuntimeEnvironment.application, R.layout.two_action_buttons, null /* parent */);
mConnectButton = buttons.findViewById(R.id.button2_positive);
mForgetButton = buttons.findViewById(R.id.button1_positive);
mConnectButton = buttons.findViewById(R.id.button2);
mForgetButton = buttons.findViewById(R.id.button1);
mController =
new BluetoothDetailsButtonsController(mContext, mFragment, mCachedDevice, mLifecycle);
mButtonsPref = ActionButtonPreferenceTest.createMock();

View File

@@ -25,6 +25,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.widget.Button;
@@ -59,41 +60,17 @@ public class ActionButtonPreferenceTest {
mPref.setButton1Visible(false).setButton2Visible(false);
mPref.onBindViewHolder(mHolder);
assertThat(mRootView.findViewById(R.id.button1_positive).getVisibility())
.isEqualTo(View.INVISIBLE);
assertThat(mRootView.findViewById(R.id.button1_negative).getVisibility())
.isEqualTo(View.INVISIBLE);
assertThat(mRootView.findViewById(R.id.button2_positive).getVisibility())
.isEqualTo(View.INVISIBLE);
assertThat(mRootView.findViewById(R.id.button2_negative).getVisibility())
.isEqualTo(View.INVISIBLE);
assertThat(mRootView.findViewById(R.id.button1).getVisibility())
.isEqualTo(View.GONE);
assertThat(mRootView.findViewById(R.id.button2).getVisibility())
.isEqualTo(View.GONE);
mPref.setButton1Visible(true).setButton2Visible(true);
mPref.onBindViewHolder(mHolder);
assertThat(mRootView.findViewById(R.id.button1_positive).getVisibility())
assertThat(mRootView.findViewById(R.id.button1).getVisibility())
.isEqualTo(View.VISIBLE);
assertThat(mRootView.findViewById(R.id.button1_negative).getVisibility())
.isEqualTo(View.INVISIBLE);
assertThat(mRootView.findViewById(R.id.button2_positive).getVisibility())
.isEqualTo(View.VISIBLE);
assertThat(mRootView.findViewById(R.id.button2_negative).getVisibility())
.isEqualTo(View.INVISIBLE);
}
@Test
public void setPositiveNegative_shouldHideOppositeButton() {
mPref.setButton1Positive(true).setButton2Positive(false);
mPref.onBindViewHolder(mHolder);
assertThat(mRootView.findViewById(R.id.button1_positive).getVisibility())
.isEqualTo(View.VISIBLE);
assertThat(mRootView.findViewById(R.id.button1_negative).getVisibility())
.isEqualTo(View.INVISIBLE);
assertThat(mRootView.findViewById(R.id.button2_positive).getVisibility())
.isEqualTo(View.INVISIBLE);
assertThat(mRootView.findViewById(R.id.button2_negative).getVisibility())
assertThat(mRootView.findViewById(R.id.button2).getVisibility())
.isEqualTo(View.VISIBLE);
}
@@ -102,36 +79,69 @@ public class ActionButtonPreferenceTest {
mPref.setButton1Enabled(true).setButton2Enabled(false);
mPref.onBindViewHolder(mHolder);
assertThat(mRootView.findViewById(R.id.button1_positive).isEnabled()).isTrue();
assertThat(mRootView.findViewById(R.id.button1_negative).isEnabled()).isTrue();
assertThat(mRootView.findViewById(R.id.button2_positive).isEnabled()).isFalse();
assertThat(mRootView.findViewById(R.id.button2_negative).isEnabled()).isFalse();
assertThat(mRootView.findViewById(R.id.button1).isEnabled()).isTrue();
assertThat(mRootView.findViewById(R.id.button2).isEnabled()).isFalse();
}
@Test
public void setText() {
public void setText_shouldShowSameText() {
mPref.setButton1Text(R.string.settings_label);
mPref.onBindViewHolder(mHolder);
assertThat(((Button) mRootView.findViewById(R.id.button1_positive)).getText())
.isEqualTo(mContext.getText(R.string.settings_label));
assertThat(((Button) mRootView.findViewById(R.id.button1_negative)).getText())
assertThat(((Button) mRootView.findViewById(R.id.button1)).getText())
.isEqualTo(mContext.getText(R.string.settings_label));
}
@Test
public void setButtonIcon_iconMustDisplayAboveText() {
mPref.setButton1Text(R.string.settings_label);
mPref.setButton1Icon(R.drawable.ic_settings);
mPref.onBindViewHolder(mHolder);
final Drawable[] drawablesAroundText =
((Button) mRootView.findViewById(R.id.button1))
.getCompoundDrawables();
assertThat(drawablesAroundText[1 /* top */]).isNotNull();
}
@Test
public void setButtonIcon_iconResourceIdIsZero_shouldNotDisplayIcon() {
mPref.setButton1Text(R.string.settings_label);
mPref.setButton1Icon(0);
mPref.onBindViewHolder(mHolder);
final Drawable[] drawablesAroundText =
((Button) mRootView.findViewById(R.id.button1))
.getCompoundDrawables();
assertThat(drawablesAroundText[1 /* top */]).isNull();
}
@Test
public void setButtonIcon_iconResourceIdNotExisting_shouldNotDisplayIconAndCrash() {
mPref.setButton1Text(R.string.settings_label);
mPref.setButton1Icon(999999999 /* not existing id */);
// Should not crash here
mPref.onBindViewHolder(mHolder);
final Drawable[] drawablesAroundText =
((Button) mRootView.findViewById(R.id.button1))
.getCompoundDrawables();
assertThat(drawablesAroundText[1 /* top */]).isNull();
}
public static ActionButtonPreference createMock() {
final ActionButtonPreference pref = mock(ActionButtonPreference.class);
when(pref.setButton1Text(anyInt())).thenReturn(pref);
when(pref.setButton1Positive(anyBoolean())).thenReturn(pref);
when(pref.setButton1Icon(anyInt())).thenReturn(pref);
when(pref.setButton1Enabled(anyBoolean())).thenReturn(pref);
when(pref.setButton1Visible(anyBoolean())).thenReturn(pref);
when(pref.setButton1OnClickListener(any(View.OnClickListener.class))).thenReturn(pref);
when(pref.setButton2Text(anyInt())).thenReturn(pref);
when(pref.setButton2Positive(anyBoolean())).thenReturn(pref);
when(pref.setButton2Icon(anyInt())).thenReturn(pref);
when(pref.setButton2Enabled(anyBoolean())).thenReturn(pref);
when(pref.setButton2Visible(anyBoolean())).thenReturn(pref);
when(pref.setButton2OnClickListener(any(View.OnClickListener.class))).thenReturn(pref);
return pref;
}
}
}