4

I'm getting a problem in a UI form that I'm building in Android. In that form I have some edit text in which the user has to touch them to open a dialog fragment. In the dialog fragment, user can set a value and then, this value is shown on the edittext touched. The problem is the following: when user close the dialog fragment and the edittext touched gets focus, if the user press the back button to go out, the onBackPressed() method is not being called.

I must clarify that the edittexts that open a dialog fragment doesn't show keyboard because the user can't write on them. I don't want to use textviews.

Here I show you part of the layout:

<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        ....

        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/text_input_when"
            android:layout_marginTop="30dp">

            <EditText
                android:hint="@string/meeting_when"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/edit_text_when"
                android:textSize="18sp"
                android:inputType="text|date"
                android:textIsSelectable="true"
                android:focusable="true"
                android:drawableLeft="@drawable/ic_black_18dp"
                android:drawableStart="@drawable/ic_black_18dp"
                android:drawablePadding="10dp"
                android:onClick="onEditTextWhenClicked"
                android:nextFocusForward="@+id/edit_text_time"/>

        </android.support.design.widget.TextInputLayout>

        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/text_input_time"
            android:layout_marginTop="30dp">

            <EditText
                android:hint="@string/meeting_time"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/edit_text_time"
                android:textSize="18sp"
                android:inputType="time"
                android:textIsSelectable="true"
                android:nextFocusForward="@+id/edit_text_place"
                android:focusable="true"
                android:drawableLeft="@drawable/ic__black_18dp"
                android:drawableStart="@drawable/ic__black_18dp"
                android:drawablePadding="10dp"
                android:onClick="onEditTextTimeClicked" />

        </android.support.design.widget.TextInputLayout>
....
....
</LinearLayout>

enter image description here

So, for example, if the user touch the "when" edit text, a datepicker dialog is open:

enter image description here

when the user set the date, the dialog fragment is closed and the value is setted on the edit text

enter image description here

And now, if the user press the back button, it doesn't work.

In the activity I have

@Override
public void onBackPressed(){

    if ( !areAllFieldEmpty() ) {

        showAlertCloseDialog();
    }else
        super.onBackPressed();

}

But these method it doesn't be called. . I don't have any idea about how to solve it. Please help me. If you need more information, let me know it. Thanks.

AlphaDeveloper
  • 539
  • 8
  • 23
  • Still `super.onBackPressed()` is acting to clear the focus from the edit text. Try to `edittext.clearFocus(); super.onBackPressed()`. – zed Feb 20 '17 at 19:07
  • I used that but this causes that the focus go to another control instead of go to the following. That brokes the form's flow. – AlphaDeveloper Feb 20 '17 at 19:13
  • See this: http://stackoverflow.com/questions/6117967/how-to-remove-focus-without-setting-focus-to-another-control – zed Feb 20 '17 at 19:14
  • Yes, that question could be a solution but if you could tested, when clear the focus, no one has a focus so the user has to decide which control use. That causes a lack of navigation circuit in a form. Something I consider important in a design. Maybe I am incorrect but I think it is necessary to have a navigation order from one control to another. – AlphaDeveloper Feb 20 '17 at 19:21
  • Well other hacks would be to 1- pop your backstack on your own or finish activity on back pressed 2- handle focus request on your own and focus clear. – zed Feb 20 '17 at 19:23

1 Answers1

1

Register a callback in your fragment to be invoked when a hardware key is pressed in your view:

if (mLayout != null) {
    mLayout.setFocusableInTouchMode(true);
}
mLayout.setOnKeyListener(new View.OnKeyListener() {
    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            getActivity().onBackPressed();
            return true;
        }
        return false;
    }
});

If it's the back key, go back and consume the event returning true, return false otherwise.

If you have troubles with back and the keyboard override onKeyPreIme() extending your EditText:

@Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        // User has pressed Back key. So hide the keyboard
        InputMethodManager mgr = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
        mgr.hideSoftInputFromWindow(this.getWindowToken(), 0);
        // Hide your view as you do it in your activity
    } else if (keyCode == KeyEvent.KEYCODE_MENU) {
        // Eat the event
        return true;
    }
    return false;
}
Community
  • 1
  • 1
albodelu
  • 7,931
  • 7
  • 41
  • 84
  • 1
    Thanks, you really helped me a lot!. The only thing is that I had to add a filter in the onKeyPreIme method to avoid it execute twice ( if ( event.getAction() == KeyEvent.ACTION_DOWN) ) – AlphaDeveloper Feb 20 '17 at 23:55
  • It's also a good moment to add flags to customize behavior of your custom `EditText`. I found this issue at work and one already created that didn't cover my case, so I created another with three flags with get/setters: `isShowingKeyboard()`, `isConsumingEvent()` and another to disable it so it was reusable in other scenarios. – albodelu Feb 21 '17 at 00:17
  • For example, replacing `return true` by `ìsConsumingEvent()`, or adding `isKeepingFocus()` and `setKeepingFocus()` methods, and `if (!isKeepingFocus()) { this.clearFocus();}` after hide the keyboard, but you don't like this one :). Thanks, feel free to fix the response or add a full `CustomEditText` sample for future readers :) – albodelu Feb 21 '17 at 04:58
  • Sorry for the late of my answer. Thanks for your suggestion. I'm agree about add flags to the custom edittext. In relation to the clearFocus(), that was the simple solution but as I said before I want to give to the user a simple navigation flow and If I use that method, the following component is not going to have the focus. Using the custom edittext solved my problem. – AlphaDeveloper Mar 01 '17 at 10:42