简体   繁体   中英

Android: DrawerLayout with EditText after keyboard dismissed closes app when pressing back

We have a NavigationDrawer (using DrawerLayout) which slides in from the right, this drawer has an EditText.

Normally the drawer would close when the back button is pressed.

However when we enter text into the EditText and dismiss the soft keyboard using the done button or the back button, and then press the back button again to dismiss the Drawer it just closes the underlying fragment/activity - which in our case closes the app.

Has anyone else come across this issue?

Layout

<?xml version="1.0" encoding="utf-8"?>
<!-- A DrawerLayout is intended to be used as the top-level content view using match_parent for both width and height to consume the full space available. -->
<com.example.CustomDrawerLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    <!-- As the main content view, the view below consumes the entire
    space available using match_parent in both dimensions. -->
    <FrameLayout android:id="@+id/main_fragment_container"
                 android:layout_weight="1"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"/>

    <LinearLayout
            android:id="@+id/left_drawer"
            android:layout_width="280dp"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            android:choiceMode="singleChoice"
            android:clickable="true"
            android:dividerHeight="2dp">
        <fragment
                android:id="@+id/global_nav_fragment"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                class="com.example.GlobalNavFragment"
                tools:layout="@layout/fragment_global_nav_v3"/>
    </LinearLayout>

    <LinearLayout
            android:id="@+id/right_drawer"
            android:layout_width="280dp"
            android:layout_height="match_parent"
            android:layout_gravity="end"
            android:choiceMode="singleChoice"
            android:dividerHeight="2dp">

        <FrameLayout
                android:id="@+id/search_form_fragment"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                tools:layout="@layout/fragment_search_form_v3"/>
    </LinearLayout>

</com.example.CustomDrawerLayout>

EditText

<EditText 
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight=".90"
    android:id="@+id/option_value"
    android:layout_gravity="center_vertical"
    android:paddingLeft="10dp"
    android:paddingRight="10dp"
    android:minWidth="30dp"
    android:ellipsize="end"
    android:singleLine="true"
    android:textColor="@color/white"
    android:textSize="@dimen/search_form_text"
    android:editable="true"
    android:background="@null"
    android:inputType="text"
    android:textColorHint="@color/any_option"
    android:imeOptions="actionDone"
    android:focusable="true"/>

CustomDrawerLayout

public class CustomDrawerLayout extends DrawerLayout {

private BackButtonManager backButtonManager;
private float xDistance, yDistance, lastX, lastY, firstX;


public ATDrawerLayout(Context context) {
    super(context);
}

public ATDrawerLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public ATDrawerLayout(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    if(isPeeking()) {
        return false;
    }

    switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            xDistance = yDistance = 0f;
            lastX = ev.getX();
            lastY = ev.getY();
            firstX = ev.getX();
            break;
        case MotionEvent.ACTION_MOVE:
            final float curX = ev.getX();
            final float curY = ev.getY();
            xDistance += Math.abs(curX - lastX);
            yDistance += Math.abs(curY - lastY);
            lastX = curX;
            lastY = curY;
            if(isScrollingVertically() || isOpenAndSwipingRightToLeft()) {
                return false;
            }
    }

    return super.onInterceptTouchEvent(ev);
}

private boolean isPeeking() {
    return isDrawerVisible(GravityCompat.END) && !isDrawerOpen(GravityCompat.END);
}

private boolean isScrollingVertically() {
    return yDistance > xDistance;
}

private boolean isOpenAndSwipingRightToLeft() {
    return isDrawerOpen(GravityCompat.END) && firstX > lastX;
}

public void setBackButtonManager(BackButtonManager manager) {
    this.backButtonManager = manager;
}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    return keyCode == KeyEvent.KEYCODE_BACK && backButtonManager.hasListeners() || super.onKeyDown(keyCode, event);
}

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
    //This is to allow the override of back button behaviour
    return keyCode == KeyEvent.KEYCODE_BACK && backButtonManager.back() || super.onKeyUp(keyCode, event);
}

I came across a similar issue. Some of my fragments open keyboards and when I open my custom drawer, the app will go back/close instead of closing the keyboard.

I realized what was going on: The drawer lost focus because the keyboard was maintaining it!

When you close the keyboard, request focus for the drawer layout:

InputMethodManager inputManager = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
                if(inputManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(),0)){
                    drawerLayout.requestFocus();
                }

I came across a similar issue. Some of my fragments open keyboards and when I open my custom drawer, the app will go back/close instead of closing the keyboard.

I realized what was going on: The drawer lost focus because the keyboard was maintaining it!

When you close the keyboard, request focus for the drawer layout:

 actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.drawer_open, R.string.drawer_close)
        {


            @Override
            public void onDrawerClosed(View drawerView) {
                // Code here will be triggered once the drawer closes as we don't want anything to happen so we leave this blank
                super.onDrawerClosed(drawerView);
            }

            @Override
            public void onDrawerOpened(View drawerView) {
                // Code here will be triggered once the drawer open as we don't want anything to happen so we leave this blank
                super.onDrawerOpened(drawerView);
                InputMethodManager inputManager = (InputMethodManager) DrawerActivityExpandable.this.getSystemService(Context.INPUT_METHOD_SERVICE);
                if(inputManager.hideSoftInputFromWindow(DrawerActivityExpandable.this.getCurrentFocus().getWindowToken(),0)){
                    drawer.requestFocus();
                }

            }
        };

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM