fixed the insets randomly zero on Android 15 for the third time (aka I really hate edge-to-edge)
This commit is contained in:
parent
8885ced4ca
commit
aa3a3de661
4 changed files with 56 additions and 34 deletions
|
|
@ -10,6 +10,8 @@ import android.view.KeyEvent;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import io.github.sspanak.tt9.R;
|
||||||
|
|
||||||
public class DeviceInfo {
|
public class DeviceInfo {
|
||||||
private static Resources resources;
|
private static Resources resources;
|
||||||
|
|
||||||
|
|
@ -24,6 +26,21 @@ public class DeviceInfo {
|
||||||
return getResources(context).getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
|
return getResources(context).getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int getNavigationBarHeight(Context context, boolean isLandscape) {
|
||||||
|
Resources resources = getResources(context);
|
||||||
|
|
||||||
|
// navBarMode = 0: 3-button, 1 = 2-button, 2 = gesture
|
||||||
|
int resourceId = resources.getIdentifier("config_navBarInteractionMode", "integer", "android");
|
||||||
|
int navBarMode = resourceId > 0 ? resources.getInteger(resourceId) : 0;
|
||||||
|
|
||||||
|
int navBarHeight = resources.getDimensionPixelSize(R.dimen.android_navigation_bar_height);
|
||||||
|
if (isLandscape) {
|
||||||
|
return navBarMode == 0 ? 0 : navBarHeight;
|
||||||
|
} else {
|
||||||
|
return navBarHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static int getScreenWidth(Context context) {
|
public static int getScreenWidth(Context context) {
|
||||||
return getResources(context).getDisplayMetrics().widthPixels;
|
return getResources(context).getDisplayMetrics().widthPixels;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,14 @@ import androidx.core.view.WindowInsetsCompat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import io.github.sspanak.tt9.R;
|
import io.github.sspanak.tt9.R;
|
||||||
|
import io.github.sspanak.tt9.hacks.DeviceInfo;
|
||||||
import io.github.sspanak.tt9.ime.TraditionalT9;
|
import io.github.sspanak.tt9.ime.TraditionalT9;
|
||||||
import io.github.sspanak.tt9.ui.main.keys.SoftKey;
|
import io.github.sspanak.tt9.ui.main.keys.SoftKey;
|
||||||
import io.github.sspanak.tt9.util.ThemedContextBuilder;
|
import io.github.sspanak.tt9.util.ThemedContextBuilder;
|
||||||
|
|
||||||
abstract class BaseMainLayout {
|
abstract class BaseMainLayout {
|
||||||
private static ViewGroup.MarginLayoutParams edgeToEdgeMargins = null;
|
protected int e2ePaddingBottomLandscape = -1;
|
||||||
|
protected int e2ePaddingBottomPortrait = -1;
|
||||||
|
|
||||||
protected final TraditionalT9 tt9;
|
protected final TraditionalT9 tt9;
|
||||||
private final int xml;
|
private final int xml;
|
||||||
|
|
@ -76,26 +78,36 @@ abstract class BaseMainLayout {
|
||||||
@RequiresApi(api = Build.VERSION_CODES.VANILLA_ICE_CREAM)
|
@RequiresApi(api = Build.VERSION_CODES.VANILLA_ICE_CREAM)
|
||||||
protected WindowInsets preventEdgeToEdge(@NonNull View v, @NonNull WindowInsets windowInsets) {
|
protected WindowInsets preventEdgeToEdge(@NonNull View v, @NonNull WindowInsets windowInsets) {
|
||||||
Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
|
Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
|
||||||
ViewGroup.MarginLayoutParams marginParams = setMargins(v, insets.right, insets.bottom, insets.left);
|
v.setPadding(insets.left, 0, insets.right, insets.bottom);
|
||||||
if (marginParams != null) {
|
|
||||||
edgeToEdgeMargins = marginParams;
|
// cache the padding for use when the insets are not available
|
||||||
return WindowInsets.CONSUMED;
|
if (e2ePaddingBottomLandscape < 0 || e2ePaddingBottomPortrait < 0) {
|
||||||
|
boolean isLandscape = DeviceInfo.isLandscapeOrientation(view.getContext());
|
||||||
|
if (isLandscape) {
|
||||||
|
e2ePaddingBottomLandscape = insets.bottom;
|
||||||
|
} else {
|
||||||
|
e2ePaddingBottomPortrait = insets.bottom;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return windowInsets;
|
return WindowInsets.CONSUMED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Similar to the above method, but reuses the last known margins. Useful for when the Main View
|
* Similar to the above method, but reuses the last known padding. Useful for when the Main View
|
||||||
* is re-created and it is not yet possible to get the new window insets.
|
* is re-created and it is not yet possible to get the new window insets.
|
||||||
*/
|
*/
|
||||||
public void preventEdgeToEdge() {
|
public void preventEdgeToEdge() {
|
||||||
if (view == null || edgeToEdgeMargins == null || Build.VERSION.SDK_INT < Build.VERSION_CODES.VANILLA_ICE_CREAM) {
|
if (tt9 == null || view == null || Build.VERSION.SDK_INT < Build.VERSION_CODES.VANILLA_ICE_CREAM) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setMargins(view, edgeToEdgeMargins.rightMargin, edgeToEdgeMargins.bottomMargin, edgeToEdgeMargins.leftMargin);
|
boolean isLandscape = DeviceInfo.isLandscapeOrientation(view.getContext());
|
||||||
|
|
||||||
|
int bottomPadding = isLandscape ? e2ePaddingBottomLandscape : e2ePaddingBottomPortrait;
|
||||||
|
bottomPadding = bottomPadding < 0 ? DeviceInfo.getNavigationBarHeight(view.getContext(), isLandscape) : bottomPadding;
|
||||||
|
view.setPadding(view.getPaddingLeft(), 0, view.getPaddingRight(), bottomPadding);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -129,40 +141,30 @@ abstract class BaseMainLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private ViewGroup.MarginLayoutParams setMargins(View v, int right, int bottom, int left) {
|
|
||||||
if (v == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
ViewGroup.MarginLayoutParams layout = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
|
|
||||||
if (layout != null) {
|
|
||||||
layout.rightMargin = right;
|
|
||||||
layout.bottomMargin = bottom;
|
|
||||||
layout.leftMargin = left;
|
|
||||||
v.setLayoutParams(layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
return layout;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int getHeight(boolean forceRecalculate) {
|
int getHeight(boolean forceRecalculate) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
boolean setHeight(int height) {
|
int getKeyboardHeight() {
|
||||||
if (view == null) {
|
View keyboard = view != null ? view.findViewById(R.id.keyboard_container) : null;
|
||||||
|
return keyboard != null ? keyboard.getMeasuredHeight() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
boolean setKeyboardHeight(int height) {
|
||||||
|
View keyboard = view != null ? view.findViewById(R.id.keyboard_container) : null;
|
||||||
|
if (keyboard == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewGroup.LayoutParams params = view.getLayoutParams();
|
ViewGroup.LayoutParams params = keyboard.getLayoutParams();
|
||||||
if (params == null) {
|
if (params == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
params.height = height;
|
params.height = height;
|
||||||
view.setLayoutParams(params);
|
keyboard.setLayoutParams(params);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,8 +63,8 @@ public class ResizableMainView extends MainView implements View.OnAttachStateCha
|
||||||
|
|
||||||
@Override public void onViewDetachedFromWindow(@NonNull View v) {}
|
@Override public void onViewDetachedFromWindow(@NonNull View v) {}
|
||||||
@Override public void onViewAttachedToWindow(@NonNull View v) {
|
@Override public void onViewAttachedToWindow(@NonNull View v) {
|
||||||
setHeight(height, heightSmall, heightNumpad);
|
|
||||||
main.preventEdgeToEdge();
|
main.preventEdgeToEdge();
|
||||||
|
setHeight(height, heightSmall, heightNumpad);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -180,11 +180,12 @@ public class ResizableMainView extends MainView implements View.OnAttachStateCha
|
||||||
|
|
||||||
|
|
||||||
private boolean changeHeight(int delta, int minHeight, int maxHeight) {
|
private boolean changeHeight(int delta, int minHeight, int maxHeight) {
|
||||||
if (main == null || main.getView() == null) {
|
int keyboardHeight = main.getKeyboardHeight();
|
||||||
|
if (keyboardHeight == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return setHeight(main.getView().getMeasuredHeight() + delta, minHeight, maxHeight);
|
return setHeight(keyboardHeight + delta, minHeight, maxHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -194,7 +195,7 @@ public class ResizableMainView extends MainView implements View.OnAttachStateCha
|
||||||
}
|
}
|
||||||
|
|
||||||
height = Math.min(height, maxHeight);
|
height = Math.min(height, maxHeight);
|
||||||
if (main.setHeight(height)) {
|
if (main.setKeyboardHeight(height)) {
|
||||||
this.height = height;
|
this.height = height;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@
|
||||||
to ignore the Android text size scale. We can't allow scaling because it breaks the layout.
|
to ignore the Android text size scale. We can't allow scaling because it breaks the layout.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
<dimen name="android_navigation_bar_height">48dp</dimen>
|
||||||
|
|
||||||
<!-- standard text size for keys -->
|
<!-- standard text size for keys -->
|
||||||
<dimen name="key_text_size">21dp</dimen>
|
<dimen name="key_text_size">21dp</dimen>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue