1
0
Fork 0

the Settings screen now follows the Dynamic Color theme on Android 12 and higher

This commit is contained in:
sspanak 2025-01-09 14:31:11 +02:00
parent 28801ba95b
commit ada5261773
19 changed files with 286 additions and 63 deletions

View file

@ -163,6 +163,7 @@ android {
} }
dependencies { dependencies {
implementation 'com.google.android.material:material:1.12.0'
implementation 'androidx.preference:preference:1.2.1' implementation 'androidx.preference:preference:1.2.1'
implementation 'androidx.constraintlayout:constraintlayout:2.2.0' implementation 'androidx.constraintlayout:constraintlayout:2.2.0'
} }

View file

@ -17,7 +17,7 @@
<application <application
android:icon="@drawable/ic_launcher" android:icon="@drawable/ic_launcher"
android:label="@string/app_name" android:label="@string/app_name"
android:theme="@style/TT9Theme" android:theme="@style/TTheme"
android:supportsRtl="true"> android:supportsRtl="true">
<service android:name="io.github.sspanak.tt9.ime.TraditionalT9" android:permission="android.permission.BIND_INPUT_METHOD" <service android:name="io.github.sspanak.tt9.ime.TraditionalT9" android:permission="android.permission.BIND_INPUT_METHOD"
@ -42,7 +42,7 @@
android:excludeFromRecents="true" android:excludeFromRecents="true"
android:label="" android:label=""
android:name="io.github.sspanak.tt9.ui.dialogs.PopupDialogActivity" android:name="io.github.sspanak.tt9.ui.dialogs.PopupDialogActivity"
android:theme="@style/alertDialog" /> android:theme="@style/TTheme.AddWord" />
<activity <activity
android:label="@string/pref_help" android:label="@string/pref_help"

View file

@ -47,11 +47,11 @@ abstract public class ScreenPreference extends Preference {
if (pref instanceof PreferenceCategory) { if (pref instanceof PreferenceCategory) {
return R.layout.pref_category; return R.layout.pref_category;
} else if (pref instanceof SwitchPreferenceCompat) { } else if (pref instanceof SwitchPreferenceCompat) {
return R.layout.pref_switch; return R.layout.pref_switch_large;
} else if (pref instanceof DropDownPreference) { } else if (pref instanceof DropDownPreference) {
return R.layout.pref_dropdown; return R.layout.pref_dropdown;
} else { } else {
return R.layout.pref_text; return R.layout.pref_default_large;
} }
} }

View file

@ -0,0 +1,54 @@
package io.github.sspanak.tt9.preferences.items;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.preference.PreferenceViewHolder;
import com.google.android.material.search.SearchView;
import io.github.sspanak.tt9.R;
abstract public class ItemSearch extends ItemTextInput {
private final boolean isModernDevice = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S;
public ItemSearch(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public ItemSearch(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public ItemSearch(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public ItemSearch(@NonNull Context context) {
super(context);
}
@Override protected int getDefaultLayout() {
return isModernDevice ? R.layout.pref_search_v31 : R.layout.pref_input_text;
}
@Override protected int getLargeLayout() {
return isModernDevice ? R.layout.pref_search_v31 : R.layout.pref_input_text_large;
}
protected void setTextField(@NonNull PreferenceViewHolder holder) {
if (!isModernDevice) {
super.setTextField(holder);
return;
}
SearchView searchView = holder.itemView.findViewById(R.id.search_view);
if (searchView != null) {
this.textField = searchView.getEditText();
}
}
}

View file

@ -3,11 +3,8 @@ package io.github.sspanak.tt9.preferences.items;
import android.content.Context; import android.content.Context;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.View;
import android.widget.EditText; import android.widget.EditText;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -17,70 +14,86 @@ import androidx.preference.PreferenceViewHolder;
import io.github.sspanak.tt9.R; import io.github.sspanak.tt9.R;
import io.github.sspanak.tt9.preferences.custom.ScreenPreference; import io.github.sspanak.tt9.preferences.custom.ScreenPreference;
import io.github.sspanak.tt9.preferences.settings.SettingsStore; import io.github.sspanak.tt9.preferences.settings.SettingsStore;
import io.github.sspanak.tt9.util.Logger;
abstract public class ItemTextInput extends ScreenPreference implements TextWatcher { abstract public class ItemTextInput extends ScreenPreference {
@NonNull private final Handler debouncer = new Handler(Looper.getMainLooper()); @NonNull private final Handler listener = new Handler(Looper.getMainLooper());
private EditText editText; protected EditText textField;
@NonNull protected String text = "";
public ItemTextInput(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { public ItemTextInput(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes); super(context, attrs, defStyleAttr, defStyleRes);
} }
public ItemTextInput(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { public ItemTextInput(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr); super(context, attrs, defStyleAttr);
} }
public ItemTextInput(@NonNull Context context, @Nullable AttributeSet attrs) { public ItemTextInput(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs); super(context, attrs);
} }
public ItemTextInput(@NonNull Context context) { public ItemTextInput(@NonNull Context context) {
super(context); super(context);
} }
@Override @Override
public void onBindViewHolder(@NonNull PreferenceViewHolder holder) { public void onBindViewHolder(@NonNull PreferenceViewHolder holder) {
super.onBindViewHolder(holder); super.onBindViewHolder(holder);
EditText editText = holder.itemView.findViewById(R.id.input_text_input_field); setTextField(holder);
if (editText == null) { if (textField != null) {
Logger.e(getClass().getSimpleName(), "Cannot attach a text change listener. Unable to find the EditText element."); ignoreEnter();
} else { checkTextChange();
this.editText = editText;
editText.addTextChangedListener(this);
editText.setOnKeyListener(this::ignoreEnter);
} }
} }
@Override protected int getDefaultLayout() { return R.layout.pref_input_text; } @Override protected int getDefaultLayout() { return R.layout.pref_input_text; }
@Override protected int getLargeLayout() { return R.layout.pref_input_text_large; } @Override protected int getLargeLayout() { return R.layout.pref_input_text_large; }
@Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override public void onTextChanged(CharSequence s, int start, int before, int count) {}
@Override
public void afterTextChanged(Editable s) {
debouncer.removeCallbacksAndMessages(null);
debouncer.postDelayed(() -> onChange(s.toString()), getChangeHandlerDebounceTime());
}
protected int getChangeHandlerDebounceTime() { protected int getChangeHandlerDebounceTime() {
return SettingsStore.TEXT_INPUT_DEBOUNCE_TIME; return SettingsStore.TEXT_INPUT_DEBOUNCE_TIME;
} }
protected void setText(CharSequence text) {
protected void setTextField(@NonNull PreferenceViewHolder holder) {
EditText editText = holder.itemView.findViewById(R.id.input_text_input_field);
if (editText != null) { if (editText != null) {
editText.setText(text); this.textField = editText;
} }
} }
protected void setText(CharSequence newText) {
if (textField != null && newText != null && !text.equals(newText.toString())) {
textField.setText(newText);
text = newText.toString();
}
}
/**
* Internal text change detector that calls the onTextChange() when needed.
* IMPORTANT: do not call this method more than once per instance to avoid creating multiple
* listeners and memory leaks.
*/
private void checkTextChange() {
String newText = textField != null ? textField.getText().toString() : "";
if (!text.equals(newText)) {
text = newText;
onTextChange();
}
listener.postDelayed(this::checkTextChange, getChangeHandlerDebounceTime());
}
/** /**
* This prevents IllegalStateException "focus search returned a view that wasn't able to take focus!", * This prevents IllegalStateException "focus search returned a view that wasn't able to take focus!",
* which is thrown when the EditText is focused and it receives a simulated ENTER key event. * which is thrown when the EditText is focused and it receives a simulated ENTER key event.
*/ */
private boolean ignoreEnter(View v, int keyCode, KeyEvent e) { private void ignoreEnter() {
return keyCode == KeyEvent.KEYCODE_ENTER; textField.setOnKeyListener((v, keyCode, e) -> keyCode == KeyEvent.KEYCODE_ENTER);
} }
protected abstract void onChange(String word);
abstract protected void onTextChange();
} }

View file

@ -9,12 +9,12 @@ import androidx.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import io.github.sspanak.tt9.db.DataStore; import io.github.sspanak.tt9.db.DataStore;
import io.github.sspanak.tt9.preferences.items.ItemTextInput; import io.github.sspanak.tt9.preferences.items.ItemSearch;
import io.github.sspanak.tt9.preferences.settings.SettingsStore; import io.github.sspanak.tt9.preferences.settings.SettingsStore;
import io.github.sspanak.tt9.util.ConsumerCompat; import io.github.sspanak.tt9.util.ConsumerCompat;
import io.github.sspanak.tt9.util.Logger; import io.github.sspanak.tt9.util.Logger;
public class PreferenceSearchWords extends ItemTextInput { public class PreferenceSearchWords extends ItemSearch {
public static final String NAME = "dictionary_delete_words_search"; public static final String NAME = "dictionary_delete_words_search";
private static final String LOG_TAG = PreferenceSearchWords.class.getSimpleName(); private static final String LOG_TAG = PreferenceSearchWords.class.getSimpleName();
@ -31,17 +31,15 @@ public class PreferenceSearchWords extends ItemTextInput {
@Override @Override
protected void onChange(String word) { protected void onTextChange() {
search(word); search(text);
} }
@NonNull @NonNull
public String getLastSearchTerm() { public String getLastSearchTerm() {
return lastSearchTerm; return lastSearchTerm;
} }
void search(String word) { void search(String word) {
lastSearchTerm = word == null || word.trim().isEmpty() ? "" : word.trim(); lastSearchTerm = word == null || word.trim().isEmpty() ? "" : word.trim();
@ -56,7 +54,6 @@ public class PreferenceSearchWords extends ItemTextInput {
} }
} }
void setOnWordsHandler(ConsumerCompat<ArrayList<String>> onWords) { void setOnWordsHandler(ConsumerCompat<ArrayList<String>> onWords) {
this.onWords = onWords; this.onWords = onWords;
} }

View file

@ -9,37 +9,37 @@ import androidx.preference.Preference;
import java.util.ArrayList; import java.util.ArrayList;
import io.github.sspanak.tt9.preferences.items.ItemTextInput; import io.github.sspanak.tt9.preferences.items.ItemSearch;
public class PreferenceSearchLanguage extends ItemTextInput { public class PreferenceSearchLanguage extends ItemSearch {
@NonNull private ArrayList<PreferenceSwitchLanguage> languageItems = new ArrayList<>(); @NonNull private ArrayList<PreferenceSwitchLanguage> languageItems = new ArrayList<>();
private Preference noResultItem; private Preference noResultItem;
public PreferenceSearchLanguage(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { public PreferenceSearchLanguage(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes); super(context, attrs, defStyleAttr, defStyleRes);
} }
public PreferenceSearchLanguage(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { public PreferenceSearchLanguage(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr); super(context, attrs, defStyleAttr);
} }
public PreferenceSearchLanguage(@NonNull Context context, @Nullable AttributeSet attrs) { public PreferenceSearchLanguage(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs); super(context, attrs);
} }
public PreferenceSearchLanguage(@NonNull Context context) { public PreferenceSearchLanguage(@NonNull Context context) {
super(context); super(context);
} }
private void showNoResultItem(boolean show) { private void showNoResultItem(boolean show) {
if (noResultItem != null) { if (noResultItem != null) {
noResultItem.setVisible(show); noResultItem.setVisible(show);
} }
} }
@Override @Override
protected void onChange(String word) { protected void onTextChange() {
word = word == null ? "" : word.trim().toLowerCase(); String word = text.trim().toLowerCase();
String wordInTheMiddle = " " + word; String wordInTheMiddle = " " + word;
String wordInParenthesis = "(" + word; String wordInParenthesis = "(" + word;
@ -63,11 +63,13 @@ public class PreferenceSearchLanguage extends ItemTextInput {
showNoResultItem(visibleLanguages == 0); showNoResultItem(visibleLanguages == 0);
} }
PreferenceSearchLanguage setLanguageItems(@NonNull ArrayList<PreferenceSwitchLanguage> languageItems) { PreferenceSearchLanguage setLanguageItems(@NonNull ArrayList<PreferenceSwitchLanguage> languageItems) {
this.languageItems = languageItems; this.languageItems = languageItems;
return this; return this;
} }
void setNoResultItem(Preference noResultItem) { void setNoResultItem(Preference noResultItem) {
this.noResultItem = noResultItem; this.noResultItem = noResultItem;
} }

View file

@ -48,8 +48,8 @@ abstract class AbstractPreferenceCharList extends ItemTextInput {
@Override @Override
protected void onChange(String word) { protected void onTextChange() {
currentChars = word == null ? "" : word; currentChars = text;
validateCurrentChars(); validateCurrentChars();
} }
@ -78,7 +78,7 @@ abstract class AbstractPreferenceCharList extends ItemTextInput {
} }
} }
setText(optional.toString()); setText(currentChars = optional.toString());
} }

View file

@ -5,12 +5,15 @@ import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.inputmethodservice.InputMethodService; import android.inputmethodservice.InputMethodService;
import android.os.Build;
import android.os.Looper; import android.os.Looper;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.util.HashMap; import java.util.HashMap;
import io.github.sspanak.tt9.preferences.PreferencesActivity; import io.github.sspanak.tt9.preferences.PreferencesActivity;
@ -23,6 +26,7 @@ public class UI {
((InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE)).showInputMethodPicker(); ((InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE)).showInputMethodPicker();
} }
public static boolean showSystemSpellCheckerSettings(Context context) { public static boolean showSystemSpellCheckerSettings(Context context) {
ComponentName component = new ComponentName( ComponentName component = new ComponentName(
"com.android.settings", "com.android.settings",
@ -50,7 +54,9 @@ public class UI {
ims.startActivity(prefIntent); ims.startActivity(prefIntent);
} }
public static void confirm(Context context, String title, String message, String OKLabel, Runnable onOk, Runnable onCancel) { public static void confirm(Context context, String title, String message, String OKLabel, Runnable onOk, Runnable onCancel) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
new AlertDialog.Builder(context) new AlertDialog.Builder(context)
.setTitle(title) .setTitle(title)
.setMessage(message) .setMessage(message)
@ -58,12 +64,23 @@ public class UI {
.setNegativeButton(android.R.string.cancel, (dialog, whichButton) -> { if (onCancel != null) onCancel.run(); }) .setNegativeButton(android.R.string.cancel, (dialog, whichButton) -> { if (onCancel != null) onCancel.run(); })
.setCancelable(false) .setCancelable(false)
.show(); .show();
} else {
new MaterialAlertDialogBuilder(context)
.setTitle(title)
.setMessage(message)
.setPositiveButton(OKLabel, (dialog, whichButton) -> { if (onOk != null) onOk.run(); })
.setNegativeButton(android.R.string.cancel, (dialog, whichButton) -> { if (onCancel != null) onCancel.run(); })
.setCancelable(false)
.show();
} }
}
public static void toast(Context context, CharSequence msg) { public static void toast(Context context, CharSequence msg) {
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show(); Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
} }
public static void toastFromAsync(Context context, CharSequence msg) { public static void toastFromAsync(Context context, CharSequence msg) {
if (Looper.myLooper() == null) { if (Looper.myLooper() == null) {
Looper.prepare(); Looper.prepare();
@ -71,10 +88,12 @@ public class UI {
toast(context, msg); toast(context, msg);
} }
public static void toast(Context context, int resourceId) { public static void toast(Context context, int resourceId) {
Toast.makeText(context, resourceId, Toast.LENGTH_SHORT).show(); Toast.makeText(context, resourceId, Toast.LENGTH_SHORT).show();
} }
public static void toastFromAsync(Context context, int resourceId) { public static void toastFromAsync(Context context, int resourceId) {
if (Looper.myLooper() == null) { if (Looper.myLooper() == null) {
Looper.prepare(); Looper.prepare();
@ -82,14 +101,17 @@ public class UI {
toast(context, resourceId); toast(context, resourceId);
} }
public static void toastLong(Context context, int resourceId) { public static void toastLong(Context context, int resourceId) {
Toast.makeText(context, resourceId, Toast.LENGTH_LONG).show(); Toast.makeText(context, resourceId, Toast.LENGTH_LONG).show();
} }
public static void toastLong(Context context, CharSequence msg) { public static void toastLong(Context context, CharSequence msg) {
Toast.makeText(context, msg, Toast.LENGTH_LONG).show(); Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
} }
public static void toastLongFromAsync(Context context, CharSequence msg) { public static void toastLongFromAsync(Context context, CharSequence msg) {
if (Looper.myLooper() == null) { if (Looper.myLooper() == null) {
Looper.prepare(); Looper.prepare();
@ -97,6 +119,7 @@ public class UI {
toastLong(context, msg); toastLong(context, msg);
} }
public static void toastSingle(@NonNull Context context, @NonNull String uniqueId, @NonNull String message, boolean isShort) { public static void toastSingle(@NonNull Context context, @NonNull String uniqueId, @NonNull String message, boolean isShort) {
Toast toast = singleToasts.get(uniqueId); Toast toast = singleToasts.get(uniqueId);
@ -111,14 +134,17 @@ public class UI {
singleToasts.put(uniqueId, toast); singleToasts.put(uniqueId, toast);
} }
public static void toastShortSingle(@NonNull Context context, @NonNull String uniqueId, @NonNull String message) { public static void toastShortSingle(@NonNull Context context, @NonNull String uniqueId, @NonNull String message) {
toastSingle(context, uniqueId, message, true); toastSingle(context, uniqueId, message, true);
} }
public static void toastShortSingle(@NonNull Context context, int resourceId) { public static void toastShortSingle(@NonNull Context context, int resourceId) {
toastSingle(context, String.valueOf(resourceId), context.getString(resourceId), true); toastSingle(context, String.valueOf(resourceId), context.getString(resourceId), true);
} }
public static void toastLongSingle(@NonNull Context context, int resourceId) { public static void toastLongSingle(@NonNull Context context, int resourceId) {
toastSingle(context, String.valueOf(resourceId), context.getString(resourceId), false); toastSingle(context, String.valueOf(resourceId), context.getString(resourceId), false);
} }

View file

@ -55,7 +55,7 @@ abstract class BaseMainLayout {
// Adding the ContextThemeWrapper fixes this error log: // Adding the ContextThemeWrapper fixes this error log:
// "View class SoftKeyXXX is an AppCompat widget that can only be used with a // "View class SoftKeyXXX is an AppCompat widget that can only be used with a
// Theme.AppCompat theme (or descendant)." // Theme.AppCompat theme (or descendant)."
ContextThemeWrapper themedCtx = new ContextThemeWrapper(tt9, R.style.TT9Theme); ContextThemeWrapper themedCtx = new ContextThemeWrapper(tt9, R.style.TTheme);
view = View.inflate(themedCtx, xml, null); view = View.inflate(themedCtx, xml, null);
} }

View file

@ -9,7 +9,7 @@
<TextView <TextView
android:id="@android:id/title" android:id="@android:id/title"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:labelFor="@id/input_text_input_field" android:labelFor="@id/input_text_input_field"
android:text="?android:title" /> android:text="?android:title" />

View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
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="@dimen/preference_search_height">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.search.SearchBar
android:id="@+id/search_bar"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.google.android.material.appbar.AppBarLayout>
<com.google.android.material.search.SearchView
android:id="@+id/search_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_anchor="@id/search_bar" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Derived from https://github.com/androidx/androidx/blob/8cb282cc/preference/preference/res/layout/preference_widget_switch_compat.xml -->
<!-- Thanks to https://stackoverflow.com/a/73782598 -->
<com.google.android.material.materialswitch.MaterialSwitch xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/switchWidget"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="false"
android:clickable="false"
android:background="@null" />

View file

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="TTheme" parent="Theme.Material3.DynamicColors.Dark">
<item name="preferenceTheme">@style/PreferenceOverlay</item>
<!-- title bar -->
<item name="tint">@color/material_dynamic_neutral90</item> <!-- back button color -->
<item name="colorOnSurface">@color/material_dynamic_neutral90</item> <!-- title text color -->
<item name="colorSurfaceContainer">@color/material_dynamic_neutral_variant30</item> <!-- title background -->
<!-- page -->
<item name="android:windowBackground">@color/material_dynamic_neutral10</item> <!-- page background -->
<item name="colorSecondary">@color/material_dynamic_primary70</item> <!-- category title -->
<item name="android:textAppearanceListItem">@style/TextAppearance.Material3.TitleLarge</item> <!-- preference title -->
<!-- <item name="android:popupMenuStyle">@style/AppDropDownStyle</item> &lt;!&ndash; dropdown background &ndash;&gt;-->
</style>
<style name="PreferenceOverlay" parent="@style/PreferenceThemeOverlay">
<item name="switchPreferenceCompatStyle">@style/AppSwitchStyle</item>
</style>
<!-- <style name="AppDropDownStyle" parent="Widget.AppCompat.ListPopupWindow">-->
<!-- <item name="android:background">@color/material_dynamic_neutral_variant30</item>-->
<!-- <item name="popupMenuBackground">@color/material_dynamic_neutral_variant30</item>-->
<!-- </style>-->
<style name="AppSwitchStyle" parent="@style/Preference.SwitchPreferenceCompat.Material">
<item name="widgetLayout">@layout/pref_switch_v31</item>
</style>
<style name="TTheme.AddWord" parent="Theme.Material3.Dark.Dialog.Alert">
<item name="windowNoTitle">true</item> <!-- hide some weird floating rectangle above the dialog -->
<item name="android:textColor">@color/material_dynamic_neutral99</item> <!-- headline (title) text color -->
<item name="android:textColorPrimary">@color/material_dynamic_neutral_variant95</item> <!-- supporting text (body text) color -->
<item name="android:background">@color/material_dynamic_neutral20</item> <!-- container background -->
<item name="colorPrimary">@color/material_dynamic_primary90</item> <!-- label text (button text) color -->
<item name="textAppearanceBodyMedium">@style/TextAppearance.AppCompat.Widget.PopupMenu.Large</item> <!-- body text size -->
<item name="textAppearanceLabelLarge">@style/TextAppearance.MaterialComponents.Button</item> <!-- button text size -->
</style>
</resources>

View file

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="TTheme" parent="Theme.Material3.DynamicColors.Light">
<item name="preferenceTheme">@style/PreferenceOverlay</item>
<!-- title bar -->
<item name="tint">@color/material_dynamic_neutral20</item> <!-- back button color -->
<item name="colorSurfaceContainer">@color/material_dynamic_neutral_variant90</item> <!-- title bar background -->
<!-- page -->
<item name="android:windowBackground">@color/material_dynamic_neutral95</item> <!-- page background -->
<item name="colorSecondary">@color/material_dynamic_primary40</item> <!-- category title -->
<item name="android:textAppearanceListItem">@style/TextAppearance.Material3.TitleLarge</item> <!-- preference title -->
<!-- <item name="android:popupWindowStyle">@style/AppDropDownStyle</item> &lt;!&ndash; dropdown background &ndash;&gt;-->
<!--
// ANY PREFERENCE
android:textColor = preference text color
android:textColorSecondary = preference summary color
// SWITCH
colorOutline = switch outline
colorSurfaceContainerHighest = switch background when off
colorPrimary = switch background when on
colorOnPrimary = switch handle color
colorPrimaryContainer = switch handle color when moving
-->
</style>
<style name="PreferenceOverlay" parent="@style/PreferenceThemeOverlay">
<item name="switchPreferenceCompatStyle">@style/AppSwitchStyle</item>
</style>
<style name="AppSwitchStyle" parent="@style/Preference.SwitchPreferenceCompat.Material">
<item name="widgetLayout">@layout/pref_switch_v31</item>
</style>
<!-- <style name="AppDropDownStyle" parent="Widget.Material3.PopupMenu.ListPopupWindow">-->
<!-- <item name="android:background">@color/material_dynamic_neutral_variant90</item>-->
<!-- <item name="popupMenuBackground">@color/material_dynamic_neutral_variant90</item>-->
<!-- </style>-->
<style name="TTheme.AddWord" parent="Theme.Material3.Light.Dialog.Alert">
<item name="windowNoTitle">true</item> <!-- hide some weird floating rectangle above the dialog -->
<item name="android:textColor">@color/material_dynamic_neutral10</item> <!-- headline (title) text color -->
<item name="android:textColorPrimary">@color/material_dynamic_neutral_variant10</item> <!-- supporting text (body text) color -->
<item name="android:background">@color/material_dynamic_neutral95</item> <!-- container background -->
<item name="colorPrimary">@color/material_dynamic_primary20</item> <!-- label text (button text) color -->
<item name="textAppearanceBodyMedium">@style/TextAppearance.AppCompat.Widget.PopupMenu.Large</item> <!-- body text size -->
<item name="textAppearanceLabelLarge">@style/TextAppearance.MaterialComponents.Button</item> <!-- button text size -->
</style>
</resources>

View file

@ -5,6 +5,7 @@
<dimen name="candidate_padding_horizontal">6sp</dimen> <dimen name="candidate_padding_horizontal">6sp</dimen>
<dimen name="preferences_text_min_height">48dp</dimen> <dimen name="preferences_text_min_height">48dp</dimen>
<dimen name="preference_search_height">72dp</dimen>
<dimen name="soft_key_height">44dp</dimen> <dimen name="soft_key_height">44dp</dimen>
<dimen name="soft_key_icon_size">24sp</dimen> <dimen name="soft_key_icon_size">24sp</dimen>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<style name="TT9Theme" parent="Theme.AppCompat.DayNight" /> <style name="TTheme" parent="Theme.AppCompat.DayNight" />
<style name="hSeparator"> <style name="hSeparator">
<item name="android:layout_height">match_parent</item> <item name="android:layout_height">match_parent</item>
@ -22,7 +22,7 @@
<item name="android:layout_width">match_parent</item> <item name="android:layout_width">match_parent</item>
</style> </style>
<style name="alertDialog" parent="Theme.AppCompat.DayNight.Dialog.Alert"> <style name="TTheme.AddWord" parent="Theme.AppCompat.DayNight.Dialog.Alert">
<item name="android:windowBackground">@android:color/transparent</item> <item name="windowNoTitle">true</item> <!-- hide some weird floating rectangle above the dialog -->
</style> </style>
</resources> </resources>