问题描述
我编写了一个键盘动画,使控件(任何视图)跟随软键盘的滑入和滑出动画。 在 Android 10 及更低版本中,一切正常。
我从 proandroiddev 上这篇(同时)过时的文章(在 Android 11 之前编写,不幸的是用 Kotlin 编写,它也不太关心已弃用的方法)中获得了这个想法,但翻译成 Java 效果很好 -剩下的唯一问题是 Api30+
在 Android 11 中,当动画结束时,WindowInsetListener
(或 delayedTransition
,我不知道是什么原因导致问题)似乎使偏移量加倍(即添加软键盘第二次到达视图的边界)。
看看这两个 gif 显示的差异(对不起,质量 - 我对视频录制不太了解)。
在两台设备上运行相同的代码。
左侧为 Android 10,右侧为 Android 11
这里是监听器:
class WindowInsetsListener implements View.OnApplyWindowInsetsListener {
private final KeyboardAnimationListener animationListener;
private int prevIoUsOffset = 0;
WindowInsetsListener(KeyboardAnimationListener animationListener) {
this.animationListener = animationListener;
}
@Override
public WindowInsets onApplyWindowInsets(View decorView,WindowInsets insets) {
WindowInsets result = insets;
int offset = insets.getSystemWindowInsetBottom() < insets.getStableInsetBottom() ?
insets.getSystemWindowInsetBottom() :
insets.getSystemWindowInsetBottom() - insets.getStableInsetBottom();
if (offset != prevIoUsOffset && animationListener.animate(decorView,offset)) {
prevIoUsOffset = offset;
result = consumeBottomInset(insets);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
return WindowInsets.CONSUMED;
}
}
return decorView.onApplyWindowInsets(result);
}
private WindowInsets consumeBottomInset(WindowInsets insets) {
Rect insetRect = new Rect(
insets.getSystemWindowInsetLeft(),insets.getSystemWindowInsetTop(),insets.getSystemWindowInsetRight(),Math.min(insets.getSystemWindowInsetBottom(),insets.getStableInsetBottom()));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
Insets newInsets = Insets.of(insetRect);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
return new WindowInsets.Builder().
setInsets(WindowInsets.Type.systemBars(),newInsets).build();
} else {
return new WindowInsets.Builder().
setSystemWindowInsets(newInsets).build();
}
} else {
return insets.replaceSystemWindowInsets(insetRect);
}
}
@Override
public boolean animate(@NonNull View view,int offset) {
ViewGroup group = getGroup(view); // searches the hierarchy up until it finds the group
if (group != null) {
TransitionManager.beginDelayedTransition(group,bounds);
setBottomPadding(view,offset);
return true;
}
return false;
}
protected void setBottomPadding(View view,int offset) {
view.setPadding(
view.getPaddingLeft(),view.getPaddingTop(),view.getPaddingRight(),offset);
}
我试图通过版本尊重所有弃用。尤其是Android的这部分在每个版本中都发生了变化。但是,即使我去掉了 Api 29 和 30 的“新”实现,并且当我使用已弃用的 .replaceSystemWindowInsets
方法时,效果保持不变。
任何人都知道需要在 Api 30+ 中提供的其他标志或其他内容吗?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)