Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EditText expands too slow inside AlertDialog on android

Simplifying a more complex problem.

I have an AlertDialog with this view dialog.xml (I might be wrong and this problem has nothing to do with AlertDialog, but Views in general):

<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:orientation="horizontal">

  // <ImageView 48dp x 48dp/> ImageView for profile photo

  <EditText
    android:layout_width="0dp"
    android:layout_weight="1"
    android:layout_height="wrap_content"
    android:layout_gravity="top"
    android:maxLines="5"
    android:inputType="textMultiLine"
    android:scrollbars="vertical"
    android:scrollHorizontally="false"/>

  // <ImageView 48dp x 48dp> ImageView for a send button.

</LinearLayout>

I need this whole dialog to be on the bottom, right above the keyboard, so that it's similar to how the chat programs have it. I need it as floating dialog, because it's not tied to any one place in the parent view.

I do this (in client code) to achieve that:

dialog.show();  // above dialog
Window window dialog.getWindow();
window.setGravity(Gravity.BOTTOM);
window.setLayout(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);

Now when I type, the edit field correctly expands up to 5 lines (from bottom up). But if I type too fast (press enter to create new lines fast), the dialog expand animation (the height increases downward) is slower than the dialog shifts up animation. This causes for a 1-2 seconds when the dialog appears to be floating in the air, with a little gap between its lower border and the keyboard.

How can I prevent that (eliminate this space in between)? Or make the animation take 0 sec?

To clarify: I do not need to disable animation for dialog popup/dismiss. When the window expands too fast (for example by creating new lines), the window gets shifted up, while the height does not compensate for the shift fast enough leaving a small temporary (1-2sec) gap in between the dialog and keyboard. This might be fundamental problem for floating Views in general (I tried using PopupWindow with the same effect).

Dialog with the gap: Dialog with the gap

Becomes this after 1-2 sec (when the expand animation finally catches up): Dialog with no gap

like image 256
vtlinh Avatar asked Apr 27 '15 23:04

vtlinh


Video Answer


2 Answers

Found the solution on my own after a lot of digging through stack overflow answers with no results.

The idea is to expand the entire dialog first to full screen, but have a transparent overlay view covering empty parts.

The dialog.xml now looks like this:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

  <!-- Transparent view that extends over entire screen and push comment view to the bottom -->
  <View
      android:id="@+id/overlay"
      android:layout_width="match_parent"
      android:layout_height="0dp"
      android:layout_weight="1"
      android:background="@color/transparent"/>

  <LinearLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:layout_alignParentBottom="true"
      android:background="@android:color/white"
      android:orientation="horizontal">

    // <ImageView 48dp x 48dp/> ImageView for profile photo

    <EditText
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:layout_gravity="top"
        android:maxLines="5"
        android:inputType="textMultiLine"
        android:scrollbars="vertical"
        android:scrollHorizontally="false"/>

    // <ImageView 48dp x 48dp> ImageView for a send button.

  </LinearLayout>
</LinearLayout>

And for Java code:

public void showDialog() {
  View content = activity.getLayoutInflater().inflate(R.layout.dialog, null, false);

  // This makes top LinearLayout background transparent, without this, 
  // it will be all white covering fullscreen.
  content.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));        

  Dialog dialog = new AlertDialog.Builder(context)
    .setView(content).create();
  dialog.show(); // needs to be done before window changes
  Window window dialog.getWindow();
  window.setLayout(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
  window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
  window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);

  View overlay = content.findViewById(R.id.overlay);
  overlay.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
      if (dialog.isShowing()) {
        dialog.cancel();
      }
    }
  });
}
like image 200
vtlinh Avatar answered Oct 15 '22 09:10

vtlinh


To remove animation, follow the following steps:

  1. Adds a no_anim.xml to /res/anim, the key is to set duration to 0

    <scale xmlns:android="http://schemas.android.com/apk/res/android"
        android:fromDegrees="0"
        android:toDegrees="360"
        android:pivotX="50%"
        android:pivotY="50%"
        android:duration="0" />
    
  2. Define a custom style using the 0-duration animation:

<style name="NoAnimation">
    <item name="android:windowEnterAnimation">@anim/no_anim</item>
    <item name="android:windowExitAnimation">@anim/no_anim</item>
</style>
  1. Apply the style to your AlertDialog:
dialog.getWindow().getAttributes().windowAnimations = R.style.NoAnimation;
like image 35
Kai Avatar answered Oct 15 '22 10:10

Kai