fixed all alignment and size issues, especially on Android 15; got rid of the ConstraintLayout
This commit is contained in:
parent
b9ce74f254
commit
d23efc4e60
9 changed files with 184 additions and 100 deletions
|
|
@ -165,5 +165,4 @@ android {
|
|||
dependencies {
|
||||
implementation 'com.google.android.material:material:1.12.0'
|
||||
implementation 'androidx.preference:preference:1.2.1'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.2.0'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,13 +20,9 @@ public class ItemNumpadWidth extends ItemDropDown {
|
|||
@Override
|
||||
public ItemDropDown populate() {
|
||||
LinkedHashMap<Integer, String> options = new LinkedHashMap<>();
|
||||
options.put(70, "70 %");
|
||||
options.put(75, "75 %");
|
||||
options.put(80, "80 %");
|
||||
options.put(85, "85 %");
|
||||
options.put(90, "90 %");
|
||||
options.put(95, "95 %");
|
||||
options.put(100, "100 %");
|
||||
for (int i = SettingsStore.MIN_WIDTH_PERCENT; i <= 100; i += 5) {
|
||||
options.put(i, i + " %");
|
||||
}
|
||||
super.populateIntegers(options);
|
||||
|
||||
float currentValue = settings.getNumpadWidthPercent();
|
||||
|
|
|
|||
|
|
@ -22,6 +22,9 @@ public class SettingsUI extends SettingsTyping {
|
|||
private final int DEFAULT_LAYOUT;
|
||||
private final boolean DEFAULT_STATUS_ICON;
|
||||
|
||||
public final static int MIN_WIDTH_PERCENT = 50;
|
||||
private int DEFAULT_WIDTH_LANDSCAPE = 0;
|
||||
|
||||
|
||||
SettingsUI(Context context) {
|
||||
super(context);
|
||||
|
|
@ -79,16 +82,29 @@ public class SettingsUI extends SettingsTyping {
|
|||
return getStringifiedInt("pref_numpad_key_height", getNumpadKeyDefaultHeight());
|
||||
}
|
||||
|
||||
public int getNumpadMaxWidth() {
|
||||
return Math.min(context.getResources().getDimensionPixelSize(R.dimen.numpad_max_width), DeviceInfo.getScreenWidth(context));
|
||||
public int getNumpadDefaultWidthPercent() {
|
||||
if (!DeviceInfo.isLandscapeOrientation(context)) {
|
||||
return 100;
|
||||
}
|
||||
|
||||
public int getNumpadWidth() {
|
||||
return getNumpadWidthPercent() * getNumpadMaxWidth() / 100;
|
||||
if (DEFAULT_WIDTH_LANDSCAPE > 0) {
|
||||
return DEFAULT_WIDTH_LANDSCAPE;
|
||||
}
|
||||
|
||||
int screenWidth = DeviceInfo.getScreenWidth(context.getApplicationContext());
|
||||
if (screenWidth < 1) {
|
||||
return 100;
|
||||
}
|
||||
|
||||
int stylesMaxWidth = Math.round(context.getResources().getDimension(R.dimen.numpad_max_width));
|
||||
float width = screenWidth < stylesMaxWidth ? 100 : 100f * stylesMaxWidth / screenWidth;
|
||||
width = width < MIN_WIDTH_PERCENT ? MIN_WIDTH_PERCENT : width;
|
||||
|
||||
return DEFAULT_WIDTH_LANDSCAPE = Math.round(width / 5) * 5;
|
||||
}
|
||||
|
||||
public int getNumpadWidthPercent() {
|
||||
return getStringifiedInt("pref_numpad_width", 100);
|
||||
return getStringifiedInt("pref_numpad_width", getNumpadDefaultWidthPercent());
|
||||
}
|
||||
|
||||
public int getSettingsFontSize() {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package io.github.sspanak.tt9.ui.main;
|
||||
|
||||
import android.graphics.Insets;
|
||||
import android.os.Build;
|
||||
import android.view.ContextThemeWrapper;
|
||||
import android.view.View;
|
||||
|
|
@ -7,6 +8,8 @@ import android.view.ViewGroup;
|
|||
import android.view.WindowInsets;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.core.view.WindowInsetsCompat;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
|
@ -46,24 +49,45 @@ abstract class BaseMainLayout {
|
|||
.setTheme(R.style.TTheme)
|
||||
.build();
|
||||
view = View.inflate(themedContext, xml, null);
|
||||
view.setOnApplyWindowInsetsListener(this::onApplyInsets);
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calculate the bottom padding for the edge-to-edge mode in Android 15+. Without padding,
|
||||
* the bottom of the View will be cut off by the system navigation bar.
|
||||
*/
|
||||
protected int getBottomInsetSize() {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.VANILLA_ICE_CREAM || tt9 == null) {
|
||||
return 0;
|
||||
protected WindowInsets onApplyInsets(@NonNull View v, @NonNull WindowInsets windowInsets) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
|
||||
return preventEdgeToEdge(v, windowInsets);
|
||||
} else {
|
||||
return windowInsets;
|
||||
}
|
||||
}
|
||||
|
||||
final int DEFAULT_SIZE = 96;
|
||||
WindowInsets insets = tt9.getWindow().findViewById(android.R.id.content).getRootWindowInsets();
|
||||
return insets != null ? insets.getStableInsetBottom() : DEFAULT_SIZE;
|
||||
|
||||
/**
|
||||
* Apply the padding to prevent edge-to-edge on Android 15+. Without padding,
|
||||
* the bottom of the View will be cut off by the system navigation bar.
|
||||
*/
|
||||
@RequiresApi(api = Build.VERSION_CODES.VANILLA_ICE_CREAM)
|
||||
protected WindowInsets preventEdgeToEdge(@NonNull View v, @NonNull WindowInsets windowInsets) {
|
||||
Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
|
||||
ViewGroup.MarginLayoutParams layout = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
|
||||
if (layout != null) {
|
||||
layout.rightMargin = insets.right;
|
||||
layout.bottomMargin = insets.bottom;
|
||||
layout.leftMargin = insets.left;
|
||||
v.setLayoutParams(layout);
|
||||
}
|
||||
|
||||
return WindowInsets.CONSUMED;
|
||||
}
|
||||
|
||||
|
||||
void requestPreventEdgeToEdge() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM && view != null) {
|
||||
view.requestApplyInsets();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -95,6 +119,25 @@ abstract class BaseMainLayout {
|
|||
}
|
||||
|
||||
|
||||
boolean setHeight(int height) {
|
||||
if (view == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ViewGroup.LayoutParams params = view.getLayoutParams();
|
||||
if (params == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
params.height = height;
|
||||
view.setLayoutParams(params);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void setWidth(int widthPercent) {}
|
||||
|
||||
|
||||
abstract void showCommandPalette();
|
||||
abstract void hideCommandPalette();
|
||||
abstract boolean isCommandPaletteShown();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package io.github.sspanak.tt9.ui.main;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.os.Build;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewParent;
|
||||
|
|
@ -28,17 +28,6 @@ class MainLayoutNumpad extends BaseMainLayout {
|
|||
super(tt9, R.layout.main_numpad);
|
||||
}
|
||||
|
||||
private void alignView() {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M || view == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
LinearLayout container = view.findViewById(R.id.numpad_container);
|
||||
if (container != null) {
|
||||
container.setGravity(tt9.getSettings().getNumpadAlignment());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override void showCommandPalette() {}
|
||||
@Override void hideCommandPalette() {}
|
||||
|
|
@ -163,42 +152,92 @@ class MainLayoutNumpad extends BaseMainLayout {
|
|||
int getHeight(boolean forceRecalculate) {
|
||||
if (height <= 0 || forceRecalculate) {
|
||||
Resources resources = tt9.getResources();
|
||||
height = getKeyHeightCompat() * 4
|
||||
height =
|
||||
+ Math.round(resources.getDimension(R.dimen.numpad_status_bar_spacing_top))
|
||||
+ resources.getDimensionPixelSize(R.dimen.numpad_status_bar_spacing_bottom)
|
||||
+ resources.getDimensionPixelSize(R.dimen.numpad_suggestion_height)
|
||||
+ Math.round(resources.getDimension(R.dimen.numpad_keys_spacing_bottom))
|
||||
+ getBottomInsetSize();
|
||||
+ getKeyHeightCompat() * 4
|
||||
+ Math.round(resources.getDimension(R.dimen.numpad_keys_spacing_bottom));
|
||||
}
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
|
||||
private void setWidth(int width) {
|
||||
if (view == null || width <= 0) {
|
||||
/**
|
||||
* Adjusts the width of the keyboard to the given percentage of the screen width.
|
||||
*/
|
||||
private void setKeyboardWidth(int widthPercent) {
|
||||
View keyboard = view != null ? view.findViewById(R.id.numpad_container) : null;
|
||||
if (keyboard == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
View widthConstraintWrapper = view.findViewById(R.id.numpad_width_constraint_wrapper);
|
||||
if (widthConstraintWrapper == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ViewGroup.LayoutParams layout = widthConstraintWrapper.getLayoutParams();
|
||||
LinearLayout.LayoutParams layout = (LinearLayout.LayoutParams) keyboard.getLayoutParams();
|
||||
if (layout != null) {
|
||||
layout.width = width;
|
||||
widthConstraintWrapper.setLayoutParams(layout);
|
||||
layout.weight = widthPercent;
|
||||
keyboard.setLayoutParams(layout);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adjust the padding on both sides of the keyboard to make it centered, or aligned to the
|
||||
* left or right.
|
||||
*/
|
||||
private void setBumperWidth(int widthPercent, int gravity) {
|
||||
View leftBumper = view.findViewById(R.id.numpad_bumper_left);
|
||||
View rightBumper = view.findViewById(R.id.numpad_bumper_right);
|
||||
if (leftBumper == null || rightBumper == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int leftPadding = 0;
|
||||
int rightPadding = 0;
|
||||
|
||||
switch (gravity) {
|
||||
case Gravity.CENTER_HORIZONTAL:
|
||||
leftPadding = rightPadding = (100 - widthPercent) / 2;
|
||||
break;
|
||||
|
||||
case Gravity.START:
|
||||
rightPadding = 100 - widthPercent;
|
||||
break;
|
||||
|
||||
case Gravity.END:
|
||||
leftPadding = 100 - widthPercent;
|
||||
break;
|
||||
}
|
||||
|
||||
LinearLayout.LayoutParams layout = (LinearLayout.LayoutParams) leftBumper.getLayoutParams();
|
||||
if (layout != null) {
|
||||
layout.weight = leftPadding;
|
||||
leftBumper.setLayoutParams(layout);
|
||||
}
|
||||
|
||||
layout = (LinearLayout.LayoutParams) rightBumper.getLayoutParams();
|
||||
if (layout != null) {
|
||||
layout.weight = rightPadding;
|
||||
rightBumper.setLayoutParams(layout);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void setWidth(int widthPercent, int gravity) {
|
||||
if (view == null || widthPercent <= 0 || widthPercent > 100) {
|
||||
return;
|
||||
}
|
||||
|
||||
setBumperWidth(widthPercent, gravity);
|
||||
setKeyboardWidth(widthPercent);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
void render() {
|
||||
getView();
|
||||
alignView();
|
||||
setKeyHeight(getKeyHeightCompat());
|
||||
setWidth(tt9.getSettings().getNumpadWidth());
|
||||
setWidth(tt9.getSettings().getNumpadWidthPercent(), tt9.getSettings().getNumpadAlignment());
|
||||
enableClickHandlers();
|
||||
for (SoftKey key : getKeys()) {
|
||||
key.render();
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ class MainLayoutTray extends BaseMainLayout {
|
|||
int getHeight(boolean forceRecalculate) {
|
||||
if (height <= 0 || forceRecalculate) {
|
||||
Resources resources = tt9.getResources();
|
||||
height = resources.getDimensionPixelSize(R.dimen.status_bar_height) + getBottomInsetSize();
|
||||
height = resources.getDimensionPixelSize(R.dimen.status_bar_height);
|
||||
|
||||
if (isCommandPaletteShown() || isTextEditingPaletteShown()) {
|
||||
height += resources.getDimensionPixelSize(R.dimen.main_small_command_palette_height);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package io.github.sspanak.tt9.ui.main;
|
|||
import android.os.Build;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
|
|
@ -58,7 +57,10 @@ public class ResizableMainView extends MainView implements View.OnAttachStateCha
|
|||
}
|
||||
}
|
||||
|
||||
@Override public void onViewAttachedToWindow(@NonNull View v) { setHeight(height, heightSmall, heightNumpad); }
|
||||
@Override public void onViewAttachedToWindow(@NonNull View v) {
|
||||
setHeight(height, heightSmall, heightNumpad);
|
||||
main.setWidth(tt9.getSettings().getNumpadWidthPercent());
|
||||
}
|
||||
@Override public void onViewDetachedFromWindow(@NonNull View v) {}
|
||||
|
||||
|
||||
|
|
@ -136,11 +138,13 @@ public class ResizableMainView extends MainView implements View.OnAttachStateCha
|
|||
settings.setMainViewLayout(SettingsStore.LAYOUT_SMALL);
|
||||
height = heightSmall;
|
||||
tt9.onCreateInputView();
|
||||
main.requestPreventEdgeToEdge();
|
||||
vibration.vibrate();
|
||||
} else if (settings.isMainLayoutSmall()) {
|
||||
settings.setMainViewLayout(SettingsStore.LAYOUT_NUMPAD);
|
||||
height = (int) Math.max(Math.max(heightNumpad * 0.6, heightSmall * 1.1), height + delta);
|
||||
tt9.onCreateInputView();
|
||||
main.requestPreventEdgeToEdge();
|
||||
vibration.vibrate();
|
||||
} else {
|
||||
changeHeight(delta, heightSmall, heightNumpad);
|
||||
|
|
@ -159,11 +163,13 @@ public class ResizableMainView extends MainView implements View.OnAttachStateCha
|
|||
settings.setMainViewLayout(SettingsStore.LAYOUT_TRAY);
|
||||
height = heightTray;
|
||||
tt9.onCreateInputView();
|
||||
main.requestPreventEdgeToEdge();
|
||||
vibration.vibrate();
|
||||
} else if (!changeHeight(delta, heightSmall, heightNumpad)) {
|
||||
settings.setMainViewLayout(SettingsStore.LAYOUT_SMALL);
|
||||
height = heightSmall;
|
||||
tt9.onCreateInputView();
|
||||
main.requestPreventEdgeToEdge();
|
||||
vibration.vibrate();
|
||||
}
|
||||
}
|
||||
|
|
@ -184,17 +190,12 @@ public class ResizableMainView extends MainView implements View.OnAttachStateCha
|
|||
}
|
||||
|
||||
height = Math.min(height, maxHeight);
|
||||
|
||||
ViewGroup.LayoutParams params = main.getView().getLayoutParams();
|
||||
if (params == null) {
|
||||
return false;
|
||||
if (main.setHeight(height)) {
|
||||
this.height = height;
|
||||
return true;
|
||||
}
|
||||
|
||||
params.height = height;
|
||||
main.getView().setLayoutParams(params);
|
||||
this.height = height;
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private void fitMain() {
|
||||
|
|
|
|||
|
|
@ -1,19 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
style="@style/TTheme.Numpad.FullScreenAlignmentContainer"
|
||||
android:id="@+id/numpad_container">
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
style="@style/TTheme.FullScreenContainer"
|
||||
android:id="@+id/full_screen_container">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
style="@style/TTheme.Numpad.FullScreenContainer"
|
||||
android:id="@+id/numpad_width_constraint_wrapper">
|
||||
|
||||
<LinearLayout
|
||||
style="@style/TTheme.Numpad"
|
||||
android:id="@+id/linearLayout"
|
||||
tools:ignore="MissingConstraints"> <!-- the constraints are set in the styles -->
|
||||
<LinearLayout style="@style/TTheme.FullScreenContainer.SideBumper" android:id="@+id/numpad_bumper_left" />
|
||||
|
||||
<LinearLayout style="@style/TTheme.Numpad" android:id="@+id/numpad_container">
|
||||
<View style="@style/TTheme.Keyboard.TopSeparator" />
|
||||
<include layout="@layout/panel_numpad_status_bar" />
|
||||
|
||||
|
|
@ -28,7 +20,8 @@
|
|||
<include layout="@layout/panel_numpad_text_editing" />
|
||||
<include layout="@layout/panel_numpad_right" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout style="@style/TTheme.FullScreenContainer.SideBumper" android:id="@+id/numpad_bumper_right" />
|
||||
|
||||
</LinearLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</LinearLayout>
|
||||
|
|
|
|||
|
|
@ -139,29 +139,26 @@
|
|||
Numpad
|
||||
*******************************************-->
|
||||
|
||||
<!-- Full screen containers -->
|
||||
<style name="TTheme.Numpad.FullScreenAlignmentContainer" parent="">
|
||||
<style name="TTheme.FullScreenContainer" parent="">
|
||||
<item name="android:layout_width">match_parent</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:gravity">center_horizontal</item>
|
||||
<item name="android:layoutDirection">ltr</item>
|
||||
<item name="android:orientation">horizontal</item>
|
||||
</style>
|
||||
|
||||
<style name="TTheme.Numpad.FullScreenContainer" parent="">
|
||||
<item name="android:layout_width">match_parent</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:maxWidth">@dimen/numpad_max_width</item>
|
||||
<item name="layout_constraintStart_toStartOf">parent</item>
|
||||
<item name="layout_constraintTop_toTopOf">parent</item>
|
||||
<style name="TTheme.FullScreenContainer.SideBumper" parent="">
|
||||
<item name="android:layout_height">1dp</item>
|
||||
<item name="android:layout_width">0dp</item>
|
||||
<item name="android:layout_weight">0</item>
|
||||
<item name="android:layoutDirection">ltr</item>
|
||||
<item name="android:orientation">horizontal</item>
|
||||
</style>
|
||||
|
||||
<!-- The keyboard itself -->
|
||||
<style name="TTheme.Numpad" parent="TTheme.Keyboard">
|
||||
<item name="layout_constraintEnd_toEndOf">parent</item>
|
||||
<item name="layout_constraintStart_toStartOf">parent</item>
|
||||
<item name="layout_constraintTop_toTopOf">parent</item>
|
||||
<item name="android:layoutDirection">ltr</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:layout_width">0dp</item>
|
||||
<item name="android:layout_weight">100</item>
|
||||
<item name="android:orientation">vertical</item>
|
||||
<item name="android:paddingBottom">@dimen/numpad_keys_spacing_bottom</item>
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue