Use custom action key icon

1. get icon from getKeyboardSettingsFeatureProvider
2. set color for it

Bug: 269214138
Test: manual, atest KeyboardSettingsFeatureProviderImplTest
Change-Id: I3a2d47e8230aec1404300b000e8b1fcf221e2a65
This commit is contained in:
danielwbhuang
2023-05-22 23:44:23 +08:00
parent 097cd12494
commit 19a5e212de
8 changed files with 268 additions and 25 deletions

View File

@@ -19,8 +19,7 @@
android:layout_marginTop="8dip"
android:layout_marginBottom="8dip"
android:minHeight="?android:attr/listPreferredItemHeight"
android:paddingEnd="?android:attr/scrollbarSize"
android:layout_weight="1">
android:paddingEnd="?android:attr/scrollbarSize">
<ImageView
android:id="@+id/modifier_key_check_icon"
@@ -36,7 +35,7 @@
<TextView
android:id="@+id/modifier_key_text"
android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:textDirection="locale"
@@ -46,4 +45,38 @@
android:ellipsize="marquee"
android:fadingEdge="horizontal" />
<TextView
android:id="@+id/modifier_key_left_bracket"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:textDirection="locale"
android:padding="1dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_toEndOf="@+id/modifier_key_text"
android:fadingEdge="horizontal" />
<ImageView
android:id="@+id/modifier_key_action_key_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="@+id/modifier_key_left_bracket"
android:fadingEdge="horizontal"
android:tint="?android:attr/textColorPrimary"/>
<TextView
android:id="@+id/modifier_key_right_bracket"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:textDirection="locale"
android:padding="1dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_toEndOf="@+id/modifier_key_action_key_icon"
android:fadingEdge="horizontal" />
<View android:layout_width="wrap_content"
android:layout_height="match_parent" />
</RelativeLayout>

View File

@@ -0,0 +1,107 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2023 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:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:gravity="center_vertical"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:background="?android:attr/selectableItemBackground">
<FrameLayout
android:id="@+id/icon_frame"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<androidx.preference.internal.PreferenceImageView
android:id="@android:id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:maxWidth="48dp"
app:maxHeight="48dp" />
</FrameLayout>
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:layout_weight="1">
<TextView android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="?android:attr/textColorPrimary"
android:fadingEdge="horizontal" />
<TextView android:id="@+id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/title"
android:layout_alignStart="@+id/title"
android:layout_alignLeft="@+id/title"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary"
android:maxLines="4" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="15dp"
android:layout_toEndOf="@+id/title"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:id="@+id/modifier_key_left_bracket"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textDirection="locale"
android:paddingStart="1dp"
android:paddingEnd="1dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="?android:attr/textColorPrimary"
android:fadingEdge="horizontal" />
<ImageView
android:id="@+id/modifier_key_action_key_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fadingEdge="horizontal"
android:tint="?android:attr/textColorPrimary"/>
<TextView
android:id="@+id/modifier_key_right_bracket"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textDirection="locale"
android:paddingStart="1dp"
android:paddingEnd="1dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="?android:attr/textColorPrimary"
android:fadingEdge="horizontal" />
</LinearLayout>
</RelativeLayout>
<!-- Preference should place its actual preference widget here. -->
<LinearLayout android:id="@android:id/widget_frame"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="vertical" />
</LinearLayout>

View File

@@ -21,25 +21,22 @@
android:title="@string/modifier_keys_settings"
android:key="modifier_keys_all"
settings:controller="com.android.settings.inputmethod.ModifierKeysPreferenceController">
<Preference
<com.android.settingslib.widget.LayoutPreference
android:key="modifier_keys_caps_lock"
android:title="@string/modifier_keys_caps_lock"
android:summary="@string/modifier_keys_default_summary"/>
android:layout="@layout/modifier_keys_custom_key" />
<Preference
<com.android.settingslib.widget.LayoutPreference
android:key="modifier_keys_ctrl"
android:title="@string/modifier_keys_ctrl"
android:summary="@string/modifier_keys_default_summary"/>
android:layout="@layout/modifier_keys_custom_key" />
<Preference
<com.android.settingslib.widget.LayoutPreference
android:key="modifier_keys_meta"
android:title="@string/modifier_keys_meta"
android:summary="@string/modifier_keys_default_summary"/>
android:layout="@layout/modifier_keys_custom_key" />
<Preference
<com.android.settingslib.widget.LayoutPreference
android:key="modifier_keys_alt"
android:title="@string/modifier_keys_alt"
android:summary="@string/modifier_keys_default_summary"/>
android:layout="@layout/modifier_keys_custom_key" />
<Preference
android:key="modifier_keys_restore"

View File

@@ -17,7 +17,9 @@
package com.android.settings.inputmethod;
import android.content.Context;
import android.graphics.drawable.Drawable;
import androidx.annotation.Nullable;
import androidx.preference.PreferenceScreen;
/**
@@ -41,4 +43,14 @@ public interface KeyboardSettingsFeatureProvider {
* @return true if the category is added successfully.
*/
boolean addFirmwareUpdateCategory(Context context, PreferenceScreen screen);
/**
* Get custom action key icon.
*
* @param context Context for accessing resources.
*
* @return Returns the image of the icon, or null if there is no any custom icon.
*/
@Nullable
Drawable getActionKeyIcon(Context context);
}

View File

@@ -17,6 +17,7 @@
package com.android.settings.inputmethod;
import android.content.Context;
import android.graphics.drawable.Drawable;
import androidx.preference.PreferenceScreen;
@@ -34,4 +35,9 @@ public class KeyboardSettingsFeatureProviderImpl implements KeyboardSettingsFeat
public boolean addFirmwareUpdateCategory(Context context, PreferenceScreen screen) {
return false;
}
@Override
public Drawable getActionKeyIcon(Context context) {
return null;
};
}

View File

@@ -22,6 +22,7 @@ import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.hardware.input.InputManager;
import android.os.Bundle;
import android.text.Spannable;
@@ -39,10 +40,12 @@ import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import androidx.core.graphics.drawable.DrawableCompat;
import androidx.fragment.app.DialogFragment;
import androidx.preference.Preference;
import com.android.settings.R;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.Utils;
import java.util.ArrayList;
@@ -60,6 +63,11 @@ public class ModifierKeysPickerDialogFragment extends DialogFragment {
private String mKeyDefaultName;
private String mKeyFocus;
private Activity mActivity;
private KeyboardSettingsFeatureProvider mFeatureProvider;
private Drawable mActionKeyDrawable;
private TextView mLeftBracket;
private TextView mRightBracket;
private ImageView mActionKeyIcon;
private List<int[]> mRemappableKeyList =
new ArrayList<>(Arrays.asList(
@@ -83,6 +91,8 @@ public class ModifierKeysPickerDialogFragment extends DialogFragment {
super.onCreateDialog(savedInstanceState);
mActivity = getActivity();
FeatureFactory featureFactory = FeatureFactory.getFactory(mActivity);
mFeatureProvider = featureFactory.getKeyboardSettingsFeatureProvider();
InputManager inputManager = mActivity.getSystemService(InputManager.class);
mKeyDefaultName = getArguments().getString(DEFAULT_KEY);
mKeyFocus = getArguments().getString(SELECTION_KEY);
@@ -97,6 +107,10 @@ public class ModifierKeysPickerDialogFragment extends DialogFragment {
for (int i = 0; i < modifierKeys.size(); i++) {
mRemappableKeyMap.put(modifierKeys.get(i), mRemappableKeyList.get(i));
}
Drawable drawable = mFeatureProvider.getActionKeyIcon(mActivity);
if (drawable != null) {
mActionKeyDrawable = DrawableCompat.wrap(drawable);
}
View dialoglayout =
LayoutInflater.from(mActivity).inflate(R.layout.modifier_key_picker_dialog, null);
@@ -226,10 +240,18 @@ public class ModifierKeysPickerDialogFragment extends DialogFragment {
checkIcon.setImageAlpha(255);
view.setBackground(
mActivity.getDrawable(R.drawable.modifier_key_lisetview_background));
if (mActionKeyDrawable != null && i == 2) {
setActionKeyIcon(view);
setActionKeyColor(getColorOfMaterialColorPrimary());
}
} else {
textView.setTextColor(getColorOfTextColorPrimary());
checkIcon.setImageAlpha(0);
view.setBackground(null);
if (mActionKeyDrawable != null && i == 2) {
setActionKeyIcon(view);
setActionKeyColor(getColorOfTextColorPrimary());
}
}
return view;
}
@@ -243,6 +265,21 @@ public class ModifierKeysPickerDialogFragment extends DialogFragment {
}
}
private void setActionKeyIcon(View view) {
mLeftBracket = view.findViewById(R.id.modifier_key_left_bracket);
mRightBracket = view.findViewById(R.id.modifier_key_right_bracket);
mActionKeyIcon = view.findViewById(R.id.modifier_key_action_key_icon);
mLeftBracket.setText("(");
mRightBracket.setText(")");
mActionKeyIcon.setImageDrawable(mActionKeyDrawable);
}
private void setActionKeyColor(int color) {
mLeftBracket.setTextColor(color);
mRightBracket.setTextColor(color);
DrawableCompat.setTint(mActionKeyDrawable, color);
}
private int getColorOfTextColorPrimary() {
return Utils.getColorAttrDefaultColor(mActivity, android.R.attr.textColorPrimary);
}

View File

@@ -17,12 +17,16 @@
package com.android.settings.inputmethod;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.hardware.input.InputManager;
import android.os.Bundle;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.ForegroundColorSpan;
import android.util.Pair;
import android.view.KeyEvent;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
@@ -31,7 +35,9 @@ import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.Utils;
import com.android.settingslib.widget.LayoutPreference;
import java.util.ArrayList;
import java.util.Arrays;
@@ -53,6 +59,7 @@ public class ModifierKeysPreferenceController extends BasePreferenceController {
private FragmentManager mFragmentManager;
private final InputManager mIm;
private PreferenceScreen mScreen;
private Drawable mDrawable;
private final List<Integer> mRemappableKeys = new ArrayList<>(
Arrays.asList(
@@ -61,6 +68,14 @@ public class ModifierKeysPreferenceController extends BasePreferenceController {
KeyEvent.KEYCODE_ALT_LEFT, KeyEvent.KEYCODE_ALT_RIGHT,
KeyEvent.KEYCODE_CAPS_LOCK));
private final List<Pair<String, Integer>> mKeys = new ArrayList<>(
Arrays.asList(
Pair.create(KEY_PREFERENCE_CTRL, R.string.modifier_keys_ctrl),
Pair.create(KEY_PREFERENCE_META, R.string.modifier_keys_meta),
Pair.create(KEY_PREFERENCE_ALT, R.string.modifier_keys_alt),
Pair.create(KEY_PREFERENCE_CAPS_LOCK, R.string.modifier_keys_caps_lock)
));
private String[] mKeyNames = new String[] {
mContext.getString(R.string.modifier_keys_ctrl),
mContext.getString(R.string.modifier_keys_ctrl),
@@ -74,6 +89,9 @@ public class ModifierKeysPreferenceController extends BasePreferenceController {
super(context, key);
mIm = context.getSystemService(InputManager.class);
Objects.requireNonNull(mIm, "InputManager service cannot be null");
KeyboardSettingsFeatureProvider featureProvider =
FeatureFactory.getFactory(context).getKeyboardSettingsFeatureProvider();
mDrawable = featureProvider.getActionKeyIcon(context);
}
public void setFragment(Fragment parent) {
@@ -91,33 +109,59 @@ public class ModifierKeysPreferenceController extends BasePreferenceController {
}
private void refreshUi() {
initDefaultKeysName();
for (Map.Entry<Integer, Integer> entry : mIm.getModifierKeyRemapping().entrySet()) {
int fromKey = entry.getKey();
int toKey = entry.getValue();
int index = mRemappableKeys.indexOf(toKey);
if (isCtrl(fromKey) && mRemappableKeys.contains(toKey)) {
Preference preference = mScreen.findPreference(KEY_PREFERENCE_CTRL);
preference.setSummary(changeSummaryColor(mKeyNames[index]));
setSummaryColor(KEY_PREFERENCE_CTRL, index);
}
if (isMeta(fromKey) && mRemappableKeys.contains(toKey)) {
Preference preference = mScreen.findPreference(KEY_PREFERENCE_META);
preference.setSummary(changeSummaryColor(mKeyNames[index]));
setSummaryColor(KEY_PREFERENCE_META, index);
}
if (isAlt(fromKey) && mRemappableKeys.contains(toKey)) {
Preference preference = mScreen.findPreference(KEY_PREFERENCE_ALT);
preference.setSummary(changeSummaryColor(mKeyNames[index]));
setSummaryColor(KEY_PREFERENCE_ALT, index);
}
if (isCapLock(fromKey) && mRemappableKeys.contains(toKey)) {
Preference preference = mScreen.findPreference(KEY_PREFERENCE_CAPS_LOCK);
preference.setSummary(changeSummaryColor(mKeyNames[index]));
setSummaryColor(KEY_PREFERENCE_CAPS_LOCK, index);
}
}
}
private void initDefaultKeysName() {
for (Pair<String, Integer> key : mKeys) {
LayoutPreference layoutPreference = mScreen.findPreference(key.first);
TextView title = layoutPreference.findViewById(R.id.title);
TextView summary = layoutPreference.findViewById(R.id.summary);
title.setText(key.second);
summary.setText(R.string.modifier_keys_default_summary);
if (key.first.equals(KEY_PREFERENCE_META) && mDrawable != null) {
setActionKeyIcon(layoutPreference, mDrawable);
}
}
}
private static void setActionKeyIcon(LayoutPreference preference, Drawable drawable) {
TextView leftBracket = preference.findViewById(R.id.modifier_key_left_bracket);
TextView rightBracket = preference.findViewById(R.id.modifier_key_right_bracket);
ImageView actionKeyIcon = preference.findViewById(R.id.modifier_key_action_key_icon);
leftBracket.setText("(");
rightBracket.setText(")");
actionKeyIcon.setImageDrawable(drawable);
}
private void setSummaryColor(String key, int targetIndex) {
LayoutPreference layoutPreference = mScreen.findPreference(key);
TextView summary = layoutPreference.findViewById(R.id.summary);
summary.setText(changeSummaryColor(mKeyNames[targetIndex]));
}
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
if (preference.getKey().equals(KEY_RESTORE_PREFERENCE)) {
@@ -137,12 +181,14 @@ public class ModifierKeysPreferenceController extends BasePreferenceController {
ModifierKeysPickerDialogFragment fragment = new ModifierKeysPickerDialogFragment();
fragment.setTargetFragment(mParent, 0);
Bundle bundle = new Bundle();
TextView title = ((LayoutPreference) preference).findViewById(R.id.title);
TextView summary = ((LayoutPreference) preference).findViewById(R.id.summary);
bundle.putString(
ModifierKeysPickerDialogFragment.DEFAULT_KEY,
preference.getTitle().toString());
title.getText().toString());
bundle.putString(
ModifierKeysPickerDialogFragment.SELECTION_KEY,
preference.getSummary().toString());
summary.getText().toString());
fragment.setArguments(bundle);
fragment.show(mFragmentManager, KEY_TAG);
}

View File

@@ -57,4 +57,9 @@ public class KeyboardSettingsFeatureProviderImplTest {
assertThat(mFeatureProvider.addFirmwareUpdateCategory(mContext, screen)).isFalse();
}
@Test
public void getActionKeyIcon_defaultValue_returnsNull() {
assertThat(mFeatureProvider.getActionKeyIcon(mContext)).isNull();
}
}