Skip to content

Commit ba29c7f

Browse files
committed
Support Android 15 in simple pop-ups
1 parent bd2983f commit ba29c7f

File tree

3 files changed

+106
-71
lines changed

3 files changed

+106
-71
lines changed

app/src/main/java/org/thunderdog/challegram/navigation/OptionsLayout.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@
1818
import android.graphics.Canvas;
1919
import android.graphics.ColorFilter;
2020
import android.graphics.PixelFormat;
21+
import android.graphics.Rect;
2122
import android.graphics.drawable.Drawable;
2223
import android.text.TextUtils;
2324
import android.util.TypedValue;
2425
import android.view.Gravity;
2526
import android.view.MotionEvent;
2627
import android.view.View;
2728
import android.view.ViewGroup;
29+
import android.widget.FrameLayout;
2830
import android.widget.LinearLayout;
2931
import android.widget.TextView;
3032

@@ -48,12 +50,13 @@
4850
import org.thunderdog.challegram.util.text.TextEntity;
4951
import org.thunderdog.challegram.widget.CustomTextView;
5052
import org.thunderdog.challegram.widget.EmojiTextView;
53+
import org.thunderdog.challegram.widget.RootFrameLayout;
5154

5255
import me.vkryl.android.ViewUtils;
5356
import me.vkryl.android.animator.Animated;
5457
import me.vkryl.core.StringUtils;
5558

56-
public class OptionsLayout extends LinearLayout implements Animated {
59+
public class OptionsLayout extends LinearLayout implements Animated, RootFrameLayout.MarginModifier {
5760
private final CustomTextView textView;
5861
private final CustomTextView headerView;
5962
private final ViewController<?> parent;
@@ -114,6 +117,12 @@ public int getOpacity () {
114117
}
115118
}
116119

120+
@Override
121+
public void onApplyMarginInsets (View child, FrameLayout.LayoutParams params, Rect legacyInsets, Rect insets, Rect insetsWithoutIme) {
122+
Views.setMargins(params, insets.left, 0, insets.right, 0);
123+
Views.setPaddingBottom(this, insetsWithoutIme.bottom);
124+
}
125+
117126
@Override
118127
protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {
119128
super.onMeasure(widthMeasureSpec, heightMeasureSpec);

app/src/main/java/org/thunderdog/challegram/navigation/ViewController.java

Lines changed: 92 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import android.view.WindowManager;
4545
import android.view.animation.Interpolator;
4646
import android.widget.Button;
47+
import android.widget.FrameLayout;
4748
import android.widget.LinearLayout;
4849
import android.widget.TextView;
4950

@@ -112,12 +113,14 @@
112113
import org.thunderdog.challegram.util.text.TextEntity;
113114
import org.thunderdog.challegram.v.HeaderEditText;
114115
import org.thunderdog.challegram.widget.CustomTextView;
116+
import org.thunderdog.challegram.widget.FillingDecoration;
115117
import org.thunderdog.challegram.widget.ForceTouchView;
116118
import org.thunderdog.challegram.widget.InfiniteRecyclerView;
117119
import org.thunderdog.challegram.widget.MaterialEditText;
118120
import org.thunderdog.challegram.widget.MaterialEditTextGroup;
119121
import org.thunderdog.challegram.widget.NoScrollTextView;
120122
import org.thunderdog.challegram.widget.PopupLayout;
123+
import org.thunderdog.challegram.widget.RootFrameLayout;
121124
import org.thunderdog.challegram.widget.SeparatorView;
122125
import org.thunderdog.challegram.widget.ShadowView;
123126
import org.thunderdog.challegram.widget.TimerView;
@@ -1905,6 +1908,43 @@ public final void showSettings (final @IdRes int id, ListItem[] rawItems, final
19051908
showSettings(new SettingsWrapBuilder(id).setRawItems(rawItems).setIntDelegate(delegate).setAllowResize(allowResize));
19061909
}
19071910

1911+
private static class SettingsWrapLayout extends FrameLayoutFix implements RootFrameLayout.MarginModifier {
1912+
public SettingsWrapLayout (@NonNull Context context) {
1913+
super(context);
1914+
}
1915+
1916+
@Override
1917+
public void onApplyMarginInsets (View child, LayoutParams params, Rect legacyInsets, Rect insets, Rect insetsWithoutIme) {
1918+
Views.setMargins(params, insets.left, insets.top, insets.right, 0);
1919+
setBottomInset(insetsWithoutIme.bottom);
1920+
}
1921+
1922+
private int bottomInset;
1923+
1924+
private void setBottomInset (int extraBottomInsetWithoutIme) {
1925+
if (this.bottomInset != extraBottomInsetWithoutIme) {
1926+
this.bottomInset = extraBottomInsetWithoutIme;
1927+
if (footerView != null) {
1928+
footerView.setLayoutParams(FrameLayoutFix.newParams(ViewGroup.LayoutParams.MATCH_PARENT, Screen.dp(56f) + extraBottomInsetWithoutIme, Gravity.BOTTOM));
1929+
Views.setPaddingBottom(footerView, extraBottomInsetWithoutIme);
1930+
}
1931+
Views.applyBottomInset(recyclerView, footerView == null ? extraBottomInsetWithoutIme : 0);
1932+
Views.setBottomMargin(shadowView, Screen.dp(56f) + extraBottomInsetWithoutIme);
1933+
}
1934+
}
1935+
1936+
private RecyclerView recyclerView;
1937+
private FrameLayout footerView;
1938+
private SeparatorView shadowView;
1939+
1940+
private void setBottomInsetTargets (RecyclerView recyclerView, FrameLayout footerView, SeparatorView shadowView, int inset) {
1941+
this.recyclerView = recyclerView;
1942+
this.footerView = footerView;
1943+
this.shadowView = shadowView;
1944+
this.bottomInset = inset;
1945+
}
1946+
}
1947+
19081948
@SuppressWarnings("deprecation")
19091949
public final @Nullable SettingsWrap showSettings (final SettingsWrapBuilder b) {
19101950
if (isStackLocked()) {
@@ -1938,8 +1978,8 @@ public final void showSettings (final @IdRes int id, ListItem[] rawItems, final
19381978
Collections.addAll(items, b.rawItems);
19391979
}
19401980

1941-
final FrameLayoutFix popupView = new FrameLayoutFix(context);
1942-
popupView.setLayoutParams(FrameLayoutFix.newParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
1981+
final SettingsWrapLayout settingsLayout = new SettingsWrapLayout(context);
1982+
settingsLayout.setLayoutParams(FrameLayoutFix.newParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
19431983

19441984
final SettingsWrap settings = new SettingsWrap();
19451985

@@ -1973,6 +2013,36 @@ protected void onMeasure (int widthSpec, int heightSpec) {
19732013
}
19742014
}
19752015
};
2016+
recyclerView.addItemDecoration(new RecyclerView.ItemDecoration() {
2017+
@Override
2018+
public void onDraw (@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
2019+
super.onDraw(c, parent, state);
2020+
2021+
LinearLayoutManager manager = (LinearLayoutManager) parent.getLayoutManager();
2022+
2023+
int maxBottom = -1;
2024+
boolean hasBottom = false;
2025+
for (int i = 0; i < manager.getChildCount(); i++) {
2026+
View view = manager.getChildAt(i);
2027+
if (view != null) {
2028+
int bottom = manager.getDecoratedBottom(view);
2029+
if (hasBottom) {
2030+
maxBottom = Math.max(bottom, maxBottom);
2031+
} else {
2032+
maxBottom = bottom;
2033+
}
2034+
hasBottom = true;
2035+
}
2036+
}
2037+
2038+
if (hasBottom) {
2039+
int height = parent.getMeasuredHeight();
2040+
if (height > maxBottom) {
2041+
c.drawRect(0, maxBottom, parent.getMeasuredWidth(), height, Paints.fillingPaint(Theme.fillingColor()));
2042+
}
2043+
}
2044+
}
2045+
});
19762046
settings.recyclerView = recyclerView;
19772047
if (b.allowResize) {
19782048
recyclerView.addItemDecoration(new RecyclerView.ItemDecoration() {
@@ -1994,7 +2064,7 @@ public void getItemOffsets (@NonNull Rect outRect, @NonNull View view, @NonNull
19942064
if (firstPosition == 0) {
19952065
View view = manager.findViewByPosition(0);
19962066
if (view != null) {
1997-
return Math.min(Screen.currentHeight(), Math.min(popupView.getMeasuredHeight() - view.getTop(), settings.adapter.measureHeight(-1)) + Screen.dp(56f) + (Screen.needsKeyboardPadding(context) ? Screen.getNavigationBarFrameHeight() : 0));
2067+
return Math.min(Screen.currentHeight(), Math.min(settingsLayout.getMeasuredHeight() - view.getTop(), settings.adapter.measureHeight(-1)) + Screen.dp(56f) + extraBottomInsetWithoutIme);
19982068
}
19992069
}
20002070
return Screen.currentHeight();
@@ -2005,6 +2075,7 @@ public void getItemOffsets (@NonNull Rect outRect, @NonNull View view, @NonNull
20052075
}
20062076
popupLayout.addStatusBar();
20072077
popupLayout.setDismissListener(b.dismissListener);
2078+
popupLayout.setNeedFullScreen(true);
20082079

20092080
final View.OnClickListener onClickListener = v -> {
20102081
final int viewId = v.getId();
@@ -2085,7 +2156,8 @@ public boolean onTouchEvent (MotionEvent event) {
20852156
}
20862157
};
20872158
ViewSupport.setThemedBackground(footerView, ColorId.filling, this);
2088-
footerView.setLayoutParams(FrameLayoutFix.newParams(ViewGroup.LayoutParams.MATCH_PARENT, Screen.dp(56f), Gravity.BOTTOM));
2159+
footerView.setLayoutParams(FrameLayoutFix.newParams(ViewGroup.LayoutParams.MATCH_PARENT, Screen.dp(56f) + extraBottomInsetWithoutIme, Gravity.BOTTOM));
2160+
Views.setPaddingBottom(footerView, extraBottomInsetWithoutIme);
20892161

20902162
for (int i = 0; i < 2; i++) {
20912163
TextView button = new NoScrollTextView(context);
@@ -2119,77 +2191,41 @@ public boolean onTouchEvent (MotionEvent event) {
21192191
}
21202192

21212193
FrameLayoutFix.LayoutParams params = FrameLayoutFix.newParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.BOTTOM);
2122-
params.bottomMargin = footerView != null ? Screen.dp(56f) : 0;
2194+
params.bottomMargin = footerView != null ? Screen.dp(56f) + extraBottomInsetWithoutIme : 0;
21232195

2196+
Views.applyBottomInset(recyclerView, footerView == null ? extraBottomInsetWithoutIme : 0);
21242197
recyclerView.setAdapter(settings.adapter);
21252198
recyclerView.setLayoutParams(params);
2199+
addThemeInvalidateListener(recyclerView);
21262200

2127-
popupView.addView(recyclerView);
2201+
SeparatorView shadowView = null;
2202+
2203+
settingsLayout.addView(recyclerView);
21282204
if (footerView != null) {
2129-
popupView.addView(footerView);
2205+
settingsLayout.addView(footerView);
21302206
}
21312207

2132-
SeparatorView shadowView = null;
2133-
21342208
if (footerView != null) {
21352209
params = FrameLayoutFix.newParams(ViewGroup.LayoutParams.MATCH_PARENT, Screen.dp(1f), Gravity.BOTTOM);
2136-
params.bottomMargin = Screen.dp(56f);
2210+
params.bottomMargin = Screen.dp(56f) + extraBottomInsetWithoutIme;
21372211
shadowView = SeparatorView.simpleSeparator(context, params, true);
21382212
shadowView.setAlignBottom();
21392213
addThemeInvalidateListener(shadowView);
2140-
popupView.addView(shadowView);
2214+
settingsLayout.addView(shadowView);
21412215
}
21422216

2143-
int popupAdditionalHeight = 0;
2144-
2145-
if (Screen.needsKeyboardPadding(context)) {
2146-
popupAdditionalHeight = Screen.getNavigationBarFrameHeight();
2147-
2148-
View dummyView = new View(context);
2149-
dummyView.setBackgroundColor(Theme.getColor(ColorId.filling));
2150-
addThemeBackgroundColorListener(dummyView, ColorId.filling);
2151-
2152-
FrameLayoutFix.LayoutParams modifiedParams = (FrameLayoutFix.LayoutParams) recyclerView.getLayoutParams();
2153-
modifiedParams.bottomMargin += popupAdditionalHeight;
2154-
recyclerView.setLayoutParams(modifiedParams);
2155-
2156-
if (footerView != null) {
2157-
modifiedParams = (FrameLayoutFix.LayoutParams) footerView.getLayoutParams();
2158-
modifiedParams.bottomMargin += popupAdditionalHeight;
2159-
footerView.setLayoutParams(modifiedParams);
2160-
}
2161-
2162-
if (shadowView != null) {
2163-
modifiedParams = (FrameLayoutFix.LayoutParams) shadowView.getLayoutParams();
2164-
modifiedParams.bottomMargin += popupAdditionalHeight;
2165-
shadowView.setLayoutParams(modifiedParams);
2166-
}
2167-
2168-
modifiedParams = FrameLayoutFix.newParams(ViewGroup.LayoutParams.MATCH_PARENT, popupAdditionalHeight, Gravity.BOTTOM);
2169-
dummyView.setLayoutParams(modifiedParams);
2170-
2171-
modifiedParams = FrameLayoutFix.newParams(ViewGroup.LayoutParams.MATCH_PARENT, Screen.dp(1f), Gravity.BOTTOM);
2172-
modifiedParams.bottomMargin = popupAdditionalHeight;
2173-
2174-
SeparatorView bottomShadowView = SeparatorView.simpleSeparator(context, modifiedParams, true);
2175-
bottomShadowView.setAlignBottom();
2176-
addThemeInvalidateListener(bottomShadowView);
2177-
popupView.addView(bottomShadowView);
2178-
2179-
popupView.addView(dummyView);
2180-
popupLayout.setNeedFullScreen(true);
2181-
}
2217+
settingsLayout.setBottomInsetTargets(recyclerView, footerView, shadowView, extraBottomInset);
21822218

21832219
final int height = settings.adapter.measureHeight(-1);
2184-
final int desiredHeight = height + (footerView != null ? Screen.dp(56f) : 0) + popupAdditionalHeight;
2220+
final int desiredHeight = height + (footerView != null ? Screen.dp(56f) : 0) + extraBottomInsetWithoutIme;
21852221
final int popupHeight = Math.min(Screen.currentHeight(), desiredHeight);
21862222

21872223
if (desiredHeight > Screen.currentActualHeight() && checkedIndex != -1) {
21882224
int viewHeight = SettingHolder.measureHeightForType(items.get(checkedIndex).getViewType());
21892225
((LinearLayoutManager) recyclerView.getLayoutManager()).scrollToPositionWithOffset(checkedIndex, (Screen.currentActualHeight() - Screen.dp(56f)) / 2 - viewHeight / 2);
21902226
}
21912227
popupLayout.addThemeListeners(this);
2192-
popupLayout.showSimplePopupView(popupView, Math.min(Screen.currentHeight() / 2 + Screen.dp(56f), popupHeight));
2228+
popupLayout.showSimplePopupView(settingsLayout, Math.min(Screen.currentHeight() / 2 + Screen.dp(56f), popupHeight));
21932229

21942230
onCreatePopupLayout(popupLayout);
21952231
return settings;
@@ -2509,11 +2545,11 @@ public final PopupLayout showOptions (Options options, final OptionDelegate dele
25092545
}
25102546

25112547
final PopupLayout popupLayout = new PopupLayout(context);
2512-
int popupAdditionalHeight;
25132548

25142549
popupLayout.setTag(this);
25152550
popupLayout.init(true);
25162551
popupLayout.setDismissOtherPopUps(!options.ignoreOtherPopUps);
2552+
popupLayout.setNeedFullScreen(true);
25172553

25182554
if (delegate != null) {
25192555
popupLayout.setDisableCancelOnTouchDown(delegate.disableCancelOnTouchdown());
@@ -2528,14 +2564,6 @@ public final PopupLayout showOptions (Options options, final OptionDelegate dele
25282564
optionsWrap.setInfo(this, tdlib(), options.info, false);
25292565
optionsWrap.setLayoutParams(FrameLayoutFix.newParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.BOTTOM));
25302566

2531-
if (Screen.needsKeyboardPadding(context)) {
2532-
popupAdditionalHeight = Screen.getNavigationBarFrameHeight();
2533-
optionsWrap.setPadding(0, 0, 0, popupAdditionalHeight);
2534-
popupLayout.setNeedFullScreen(true);
2535-
} else {
2536-
popupAdditionalHeight = 0;
2537-
}
2538-
25392567
ShadowView shadowView = new ShadowView(context);
25402568
shadowView.setSimpleTopShadow(true);
25412569
optionsWrap.addView(shadowView, 0);
@@ -2557,7 +2585,7 @@ public final PopupLayout showOptions (Options options, final OptionDelegate dele
25572585
}
25582586
};
25592587
}
2560-
int totalHeight = shadowView.getLayoutParams().height + optionsWrap.getTextHeight() + popupAdditionalHeight;
2588+
int totalHeight = shadowView.getLayoutParams().height + optionsWrap.getTextHeight() + extraBottomInsetWithoutIme;
25612589
int index = 0;
25622590
for (OptionItem item : options.items) {
25632591
if (item == OptionItem.SEPARATOR) {
@@ -2604,6 +2632,7 @@ public final PopupLayout showPopup (CharSequence title, boolean isTitle, @NonNul
26042632
final PopupLayout popupLayout = new PopupLayout(context);
26052633
popupLayout.setTag(this);
26062634
popupLayout.init(true);
2635+
popupLayout.setNeedFullScreen(true);
26072636

26082637
int totalHeight = 0;
26092638

@@ -2619,13 +2648,7 @@ public final PopupLayout showPopup (CharSequence title, boolean isTitle, @NonNul
26192648
totalHeight += shadowView.getLayoutParams().height;
26202649

26212650
totalHeight += popUpBuilder.onBuildPopUp(popupLayout, optionsWrap);
2622-
2623-
if (Screen.needsKeyboardPadding(context)) {
2624-
int additionalHeight = Screen.getNavigationBarFrameHeight();
2625-
totalHeight += additionalHeight;
2626-
optionsWrap.setPadding(0, 0, 0, additionalHeight);
2627-
popupLayout.setNeedFullScreen(true);
2628-
}
2651+
totalHeight += extraBottomInsetWithoutIme;
26292652

26302653
popupLayout.showSimplePopupView(optionsWrap, totalHeight);
26312654
onCreatePopupLayout(popupLayout);

app/src/main/java/org/thunderdog/challegram/tool/Screen.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ public static int getNavigationBarHeight () {
254254

255255
private static int navigationBarFrameHeight;
256256

257+
@Deprecated
257258
public static int getNavigationBarFrameHeight () {
258259
if (navigationBarFrameHeight != 0) {
259260
return navigationBarFrameHeight;
@@ -265,15 +266,17 @@ public static int getNavigationBarFrameHeight () {
265266
return navigationBarFrameHeight;
266267
}
267268

269+
@Deprecated
268270
public static int getNavigationBarFrameDifference () {
269271
return Screen.getNavigationBarFrameHeight() - Screen.getNavigationBarHeight();
270272
}
271273

274+
@Deprecated
272275
public static boolean needsKeyboardPadding (BaseActivity context) {
273276
return context.isKeyboardVisible() && isGesturalNavigationEnabled() && getNavigationBarHeight() > 0;
274277
}
275278

276-
public static boolean isGesturalNavigationEnabled () {
279+
private static boolean isGesturalNavigationEnabled () {
277280
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
278281
return false;
279282
}

0 commit comments

Comments
 (0)