androidandroid-alertdialogandroid-windowmanager

Full-screen AlertDialog has janky animation when keyboard is shown


Watch the video here to see the problem: https://streamable.com/s0yhrm

Or see it here on a faster device: https://streamable.com/4sshdn

I have an AlertDialog that I've set up to take all the vertical space. The problem is that when the keyboard appears, I get a nasty animation as the AlertDialog resizes to fit above the keyboard. Is there some way to prevent this from happening? Ideally, it should measure the available space above the keyboard before the AlertDialog ever displays.


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/enter_address_alert_dialog_root_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="4dp">

    <TextView
        android:id="@+id/title_textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="6dp"
        android:paddingLeft="12dp"
        android:paddingTop="6dp"
        android:paddingBottom="4dp"
        android:text="Delivery address"
        android:textSize="14dp"
        android:textStyle="bold" />

    <ImageView
        android:id="@+id/network_error_imageView"
        android:layout_alignParentRight="true"
        android:src="@drawable/cloud_off_36dp"
        app:tint="@color/colorError"
        android:visibility="gone"
        tools:visibility="visible"
        android:layout_alignTop="@id/title_textView"
        android:layout_alignBottom="@id/title_textView"
        android:layout_marginRight="12dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <LinearLayout
        android:id="@+id/top_LinearLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"
        android:layout_below="@id/title_textView"
        android:background="@drawable/autocomplete_list_item_background"
        android:elevation="2dp"
        android:paddingLeft="8dp"
        android:paddingTop="2dp"
        android:paddingRight="8dp"
        android:paddingBottom="12dp">

        <RelativeLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="3"
            android:gravity="bottom">

            <EditText
                android:id="@+id/address_editText"
                style="@style/MyEditTextStyle"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Street address"
                android:imeOptions="actionNext"
                android:maxLength="100"
                android:maxLines="4"
                android:importantForAutofill="no"
                android:paddingLeft="4dp"
                android:paddingTop="8dp"
                android:paddingRight="32dp"
                android:selectAllOnFocus="true"
                android:textSize="@dimen/address_alert_dialog_text_size" />

            <ImageButton
                android:id="@+id/clear_button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:layout_centerVertical="true"
                android:paddingTop="4dp"
                android:paddingLeft="4dp"
                android:paddingRight="4dp"
                android:paddingBottom="0dp"
                android:background="?selectableItemBackgroundBorderless"
                android:src="@drawable/ic_close_24dp" />

        </RelativeLayout>

        <EditText
            android:id="@+id/enter_address_unit_number_alert_dialog_edit_text"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"
            android:layout_marginLeft="16dp"
            android:layout_weight="0.8"
            android:gravity="center"
            android:imeOptions="actionDone"
            android:hint="Unit #"
            android:importantForAutofill="no"
            android:inputType="textPostalAddress|textCapWords|text"
            android:maxLength="30"
            android:paddingTop="6dp"
            android:selectAllOnFocus="true"
            android:textSize="@dimen/address_alert_dialog_text_size" />

    </LinearLayout>

    <ScrollView
        android:id="@+id/scrollView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_above="@id/map_button"
        android:layout_below="@id/top_LinearLayout">

        <!--Single parent to ScrollView-->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <TextView
                android:id="@+id/no_store_address_enter_address_alert_dialog_text_view"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="18dp"
                android:layout_marginTop="@dimen/address_autocomplete_margin_above_empty_view"
                android:layout_marginRight="18dp"
                android:textSize="@dimen/address_alert_dialog_no_store_address_text_size"
                android:text="You haven't entered a store address. Without this, the app can't locate delivery addresses or calculate driving distances. To fix this, go to Settings and use the 'Store addresses' option."
                android:textColor="#F00"
                android:visibility="gone" />

            <TextView
                android:id="@+id/enter_address_alert_dialog_empty_view"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="18dp"
                android:layout_marginTop="@dimen/address_autocomplete_margin_above_empty_view"
                android:layout_marginRight="18dp"
                android:drawablePadding="6dp"
                android:gravity="center_horizontal"
                android:padding="12dp"
                android:text="Start typing an address above and matching results will show up here"
                android:textSize="@dimen/address_alert_dialog_text_size"
                app:drawableTint="@color/colorAutocompleteEmptyViewIcon"
                app:drawableTopCompat="@drawable/ic_search_white_28dp" />

        </LinearLayout>

    </ScrollView>

    <ListView
        android:id="@+id/enter_address_alert_dialog_list_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@id/map_button"
        android:layout_below="@id/scrollView"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="4dp"
        android:layout_marginRight="8dp"
        android:layout_marginBottom="4dp"
        android:divider="@android:color/transparent"
        android:dividerHeight="-3dp" />

    <TextView
        android:id="@+id/map_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentBottom="true"
        android:layout_marginLeft="16dp"
        android:background="@drawable/toolbar_image_button_ripple"
        android:fontFamily="sans-serif-medium"
        android:padding="8dp"
        android:text="MAP"
        android:textColor="@color/colorAlertDialogButton"
        android:textSize="@dimen/alert_dialog_button_text_size" />

    <TextView
        android:id="@+id/cancel_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_marginRight="15dp"
        android:layout_toLeftOf="@id/submit_button"
        android:background="@drawable/toolbar_image_button_ripple"
        android:fontFamily="sans-serif-medium"
        android:padding="8dp"
        android:text="CANCEL"
        android:textColor="@color/colorAlertDialogButton"
        android:textSize="@dimen/alert_dialog_button_text_size" />

    <TextView
        android:id="@+id/submit_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true"
        android:layout_marginRight="20dp"
        android:background="@drawable/toolbar_image_button_ripple"
        android:fontFamily="sans-serif-medium"
        android:padding="8dp"
        android:text="SUBMIT"
        android:textColor="@color/colorAlertDialogButton"
        android:textSize="@dimen/alert_dialog_button_text_size" />

</RelativeLayout>

Solution

  • I was able to solve this in a satisfactory manner by expanding the AlertDialog's height only once the user starts typing. See video here: https://streamable.com/oj3fbv

           addressEditText.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                }
    
                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {
                }
    
                @Override
                public void afterTextChanged(Editable s) {
                    String inputText = s.toString().toLowerCase().trim();
    
                    if (inputText.length() > 0) {
                        if (inputText.length() == 1) {
                        autocompleteListView.setVisibility(View.VISIBLE);
    
                            RelativeLayout.LayoutParams listViewParams = new RelativeLayout.LayoutParams(
                                    RelativeLayout.LayoutParams.MATCH_PARENT,
                                    RelativeLayout.LayoutParams.MATCH_PARENT);
                            listViewParams.addRule(RelativeLayout.BELOW, topLinearLayout.getId());
                            listViewParams.addRule(RelativeLayout.ABOVE, mapButton.getId());
                            listViewParams.leftMargin = dpToPx(8);
                            listViewParams.rightMargin = dpToPx(8);
                            listViewParams.topMargin = dpToPx(4);
                            listViewParams.bottomMargin = dpToPx(4);
                            autocompleteListView.setLayoutParams(listViewParams);
    
                            RelativeLayout.LayoutParams mapButtonParams = new RelativeLayout.LayoutParams(
                                    RelativeLayout.LayoutParams.MATCH_PARENT,
                                    RelativeLayout.LayoutParams.WRAP_CONTENT);
                            mapButtonParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
                            mapButton.setLayoutParams(mapButtonParams);
                        }
    
                        clearButton.setVisibility(View.VISIBLE);
    
                        if (inputText.length() > 1 && storeAddressEntered) {
                            alertDialogEmptyView.setVisibility(View.GONE);
                            scrollView.setVisibility(View.GONE);
                        }
                    }
                    alertDialogAdapter.getFilter().filter(inputText);
                }
            });
    
    <?xml version="1.0" encoding="utf-8"?>
    
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/enter_address_alert_dialog_root_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingBottom="4dp">
    
        <TextView
            android:id="@+id/title_textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="6dp"
            android:paddingLeft="12dp"
            android:paddingTop="6dp"
            android:paddingBottom="4dp"
            android:text="Delivery address"
            android:textSize="14dp"
            android:textStyle="bold" />
    
        <ImageView
            android:id="@+id/network_error_imageView"
            android:layout_alignParentRight="true"
            android:src="@drawable/cloud_off_36dp"
            app:tint="@color/colorError"
            android:visibility="gone"
            tools:visibility="visible"
            android:layout_alignTop="@id/title_textView"
            android:layout_alignBottom="@id/title_textView"
            android:layout_marginRight="12dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    
        <LinearLayout
            android:id="@+id/top_LinearLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="8dp"
            android:layout_below="@id/title_textView"
            android:background="@drawable/autocomplete_list_item_background"
            android:elevation="2dp"
            android:paddingLeft="8dp"
            android:paddingTop="2dp"
            android:paddingRight="8dp"
            android:paddingBottom="12dp">
    
            <RelativeLayout
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="3"
                android:gravity="bottom">
    
                <EditText
                    android:id="@+id/address_editText"
                    style="@style/MyEditTextStyle"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="Street address"
                    android:imeOptions="actionNext"
                    android:maxLength="100"
                    android:maxLines="4"
                    android:importantForAutofill="no"
                    android:paddingLeft="4dp"
                    android:paddingTop="8dp"
                    android:paddingRight="32dp"
                    android:selectAllOnFocus="true"
                    android:textSize="@dimen/address_alert_dialog_text_size" />
    
                <ImageButton
                    android:id="@+id/clear_button"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentRight="true"
                    android:layout_centerVertical="true"
                    android:paddingTop="4dp"
                    android:paddingLeft="4dp"
                    android:paddingRight="4dp"
                    android:paddingBottom="0dp"
                    android:background="?selectableItemBackgroundBorderless"
                    android:src="@drawable/ic_close_24dp" />
    
            </RelativeLayout>
    
            <EditText
                android:id="@+id/enter_address_unit_number_alert_dialog_edit_text"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_gravity="bottom"
                android:layout_marginLeft="16dp"
                android:layout_weight="0.8"
                android:gravity="center"
                android:imeOptions="actionDone"
                android:hint="Unit #"
                android:importantForAutofill="no"
                android:inputType="textPostalAddress|textCapWords|text"
                android:maxLength="30"
                android:paddingTop="6dp"
                android:selectAllOnFocus="true"
                android:textSize="@dimen/address_alert_dialog_text_size" />
    
        </LinearLayout>
    
        <ScrollView
            android:id="@+id/scrollView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/top_LinearLayout">
    
            <!--Single parent to ScrollView-->
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">
    
                <TextView
                    android:id="@+id/no_store_address_enter_address_alert_dialog_text_view"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="18dp"
                    android:layout_marginTop="@dimen/address_autocomplete_margin_above_empty_view"
                    android:layout_marginRight="18dp"
                    android:textSize="@dimen/address_alert_dialog_no_store_address_text_size"
                    android:text="You haven't entered a store address. Without this, the app can't locate delivery addresses or calculate driving distances. To fix this, go to Settings and use the 'Store addresses' option."
                    android:textColor="#F00"
                    android:visibility="gone" />
    
                <TextView
                    android:id="@+id/enter_address_alert_dialog_empty_view"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="18dp"
                    android:layout_marginRight="18dp"
                    android:drawablePadding="6dp"
                    android:gravity="center_horizontal"
                    android:padding="12dp"
                    android:text="Start typing an address above and matching results will show up here"
                    android:textSize="@dimen/address_alert_dialog_text_size"
                    app:drawableTint="@color/colorAutocompleteEmptyViewIcon"
                    app:drawableTopCompat="@drawable/ic_search_white_28dp" />
    
            </LinearLayout>
    
        </ScrollView>
    
        <ListView
            android:id="@+id/enter_address_alert_dialog_list_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_below="@id/scrollView"
            android:visibility="gone"
            android:layout_marginLeft="8dp"
            android:layout_marginTop="4dp"
            android:layout_marginRight="8dp"
            android:layout_marginBottom="4dp"
            android:divider="@android:color/transparent"
            android:dividerHeight="-3dp" />
    
        <TextView
            android:id="@+id/map_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_below="@id/scrollView"
            android:layout_marginLeft="16dp"
            android:background="@drawable/toolbar_image_button_ripple"
            android:fontFamily="sans-serif-medium"
            android:padding="8dp"
            android:text="MAP"
            android:textColor="@color/colorAlertDialogButton"
            android:textSize="@dimen/alert_dialog_button_text_size" />
    
        <TextView
            android:id="@+id/cancel_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBottom="@id/map_button"
            android:layout_marginRight="15dp"
            android:layout_toLeftOf="@id/submit_button"
            android:background="@drawable/toolbar_image_button_ripple"
            android:fontFamily="sans-serif-medium"
            android:padding="8dp"
            android:text="CANCEL"
            android:textColor="@color/colorAlertDialogButton"
            android:textSize="@dimen/alert_dialog_button_text_size" />
    
        <TextView
            android:id="@+id/submit_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_alignBottom="@id/map_button"
            android:layout_marginRight="20dp"
            android:background="@drawable/toolbar_image_button_ripple"
            android:fontFamily="sans-serif-medium"
            android:padding="8dp"
            android:text="SUBMIT"
            android:textColor="@color/colorAlertDialogButton"
            android:textSize="@dimen/alert_dialog_button_text_size" />
    
    </RelativeLayout>