How to avoid "jumpy" issue when interacting with soft keyboard visibility
Currently, we have an app with the following requirements
- Must use
android:windowSoftInputMode="adjustPan"
- Use
ViewCompat.setWindowInsetsAnimationCallback
andViewCompat.setOnApplyWindowInsetsListener
to interact with soft keyboard visibility with smooth animation.
Here is our code, when interacting with soft keyboard visibility. It works pretty well in the case, when our EditText
is not scrollable.
The animation went pretty well, when keyboard is showing and hiding.
MainActivity.java
public class MainActivity extends AppCompatActivity {
EditText editText;
LinearLayout toolbar;
FrameLayout keyboardView;
private int systemBarsHeight = 0;
private int keyboardHeightWhenVisible = 0;
private boolean keyboardVisible = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = findViewById(R.id.edit_text);
toolbar = findViewById(R.id.toolbar);
keyboardView = findViewById(R.id.keyboard_view);
final View rootView = getWindow().getDecorView().getRootView();
ViewCompat.setOnApplyWindowInsetsListener(rootView, (v, insets) -> {
boolean imeVisible = insets.isVisible(WindowInsetsCompat.Type.ime());
systemBarsHeight = insets.getInsets(WindowInsetsCompat.Type.systemBars()).bottom;
keyboardVisible = imeVisible;
if (keyboardVisible) {
keyboardHeightWhenVisible = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom;
}
// https://stackoverflow.com/questions/75325095/how-to-use-windowinsetscompat-correctly-to-listen-to-keyboard-height-change-in-a
return ViewCompat.onApplyWindowInsets(v, insets);
});
WindowInsetsAnimationCompat.Callback callback = new WindowInsetsAnimationCompat.Callback(
WindowInsetsAnimationCompat.Callback.DISPATCH_MODE_STOP
) {
@NonNull
@Override
public WindowInsetsCompat onProgress(@NonNull WindowInsetsCompat insets, @NonNull List<WindowInsetsAnimationCompat> runningAnimations) {
// Find an IME animation.
WindowInsetsAnimationCompat imeAnimation = null;
for (WindowInsetsAnimationCompat animation : runningAnimations) {
if ((animation.getTypeMask() & WindowInsetsCompat.Type.ime()) != 0) {
imeAnimation = animation;
break;
}
}
if (imeAnimation != null) {
int keyboardViewHeight;
if (keyboardVisible) {
keyboardViewHeight = (int) (keyboardHeightWhenVisible * imeAnimation.getInterpolatedFraction()) - systemBarsHeight;
} else {
keyboardViewHeight = (int) (keyboardHeightWhenVisible * (1.0-imeAnimation.getInterpolatedFraction())) - systemBarsHeight;
}
keyboardViewHeight = Math.max(0, keyboardViewHeight);
ViewGroup.LayoutParams params = keyboardView.getLayoutParams();
params.height = keyboardViewHeight;
keyboardView.setLayoutParams(params);
Log.i("CHEOK", "keyboardVisible = " + keyboardVisible + ", keyboardViewHeight = " + keyboardViewHeight);
}
return insets;
}
};
ViewCompat.setWindowInsetsAnimationCallback(rootView, callback);
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<EditText
android:id="@+id/edit_text"
android:padding="16dp"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="top" />
<LinearLayout
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="48dp"
android:orientation="horizontal"
android:background="#ffff00" />
<FrameLayout
android:id="@+id/keyboard_view"
android:background="#ff0000"
android:layout_width="match_parent"
android:layout_height="0dp" />
</LinearLayout>
Here is the outcome.
When EditText is not scrollable
However, our app becomes "jumpy", when the content of EditText
is scrollable.
When EditText is scrollable, our app becomes "jumpy"
Does anyone know what is the root cause of this problem, and how we can resolve such?
A demo to demonstrate such an issue, can be downloaded from https://github.com/yccheok/programming-issue/tree/main/jumpy
Thank you.
Comments
Post a Comment