EditText does not trigger changes when back is pressed

半腔热情 提交于 2019-11-29 17:12:53

I had the same problem in an application which i wrote some time ago. It is discontiuned now but that's not your question xD.

In fact there is no option to track such a operation, but i've found a great (more or less) solution to add such a functionality. It's quite simple in theory but it's a "hack" too i think.

So what you will need is a custom linear layout which contains your application, or a special region. After that you have to add it a listener. And this will work only in portrait mode.

So here to the code: (i'm sorry but i can't remember the source)

The custom layout:

LinearLayoutThatDetactsSoftwarekeyboard.java (that's the original name of the layout xD)

package com.tundem.people.Layout;

import android.app.Activity;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.widget.LinearLayout;

/*
 * LinearLayoutThatDetectsSoftKeyboard - a variant of LinearLayout that can detect when 
 * the soft keyboard is shown and hidden (something Android can't tell you, weirdly). 
 */

public class LinearLayoutThatDetectSoftkeyboard extends LinearLayout {

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

    public interface Listener {
        public void onSoftKeyboardShown(boolean isShowing);
    }

    private Listener listener;

    public void setListener(Listener listener) {
        this.listener = listener;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int height = MeasureSpec.getSize(heightMeasureSpec);
        Activity activity = (Activity) getContext();
        Rect rect = new Rect();
        activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
        int statusBarHeight = rect.top;
        int screenHeight = activity.getWindowManager().getDefaultDisplay().getHeight();
        int diff = (screenHeight - statusBarHeight) - height;
        if (listener != null) {
            listener.onSoftKeyboardShown(diff > 128); // assume all soft
                                                        // keyboards are at
                                                        // least 128 pixels high
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

}

And how you add the listener:

final LinearLayoutThatDetectSoftkeyboard lltodetectsoftkeyboard = (LinearLayoutThatDetectSoftkeyboard) findViewById(R.id.LinearLayout_SoftKeyboard);
    lltodetectsoftkeyboard.setListener(new Listener() {

        public void onSoftKeyboardShown(boolean isShowing) {
            if (actMode == MODE_SMS && isShowing) {
                findViewById(R.id.LinearLayout_bottomnavigationbar).setVisibility(View.GONE);
            } else {
                findViewById(R.id.LinearLayout_bottomnavigationbar).setVisibility(View.VISIBLE);
            }
        }
    });

The LinearLayout adds a Listener which will be called each time the layoutheight changes by at least 128 pixels. It's a trick and it won't work with keyboards that are smaller than 128 pixels (but i think each keyboard has such a height) If the LayoutHeight has Changed you will get notified if it's showing now or not.

I hope my answer was useful. Perhaps you find the real source here on StackOverFlow again. I won't steal someones genius so. Credits goes to the unknown person ;)

This is the modified version of @mikepenz's answer, since it didn't work on Android 8 with windowSoftInputMode="adjustPan" mode.

The language is kotlin. Use this view as root view and set the keyboardListener:

class KeyboardAwareConstraintLayout(context: Context?, attrs: AttributeSet?) : ConstraintLayout(context, attrs)
{

  var keyboardListener: KeyboardListener? = null

  constructor(context: Context?) : this(context, null)


  override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int)
  {
    val rect = Rect()
    getWindowVisibleDisplayFrame(rect)
    val statusBarHeight = rect.top
    val keyboardHeight = rootView.height - (rect.bottom - rect.top) - statusBarHeight
    // R.dimen.keyboard_min_height has set to 120dp, 
    // as a reasonable minimum height of a soft keyboard
    val minKeyboardHeight = resources.getDimensionPixelSize(R.dimen.keyboard_min_height)

    keyboardListener?.onKeyboardShown(keyboardHeight > minKeyboardHeight)

    super.onMeasure(widthMeasureSpec, heightMeasureSpec)
  }
}

interface KeyboardListener
{
  fun onKeyboardShown (shown: Boolean)
}

You can override the onBackPressed in your activity (pseudo-code - be warned):

@Override
public void onBackPressed() {
    if(userHasChangedAnything) {
        revertChanges();
    } else {
        super.onBackPressed();
    }
}

With the new information of the code being in a fragment, I would suggest adding a key listener to the text box. This code hasn't been tested, but should work.

((EditText) findViewById(R.id.button)).setOnKeyListener(new OnKeyListener() { 
    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
         if ((keyCode == KeyEvent.KEYCODE_BACK)) {
              Log.d(this.getClass().getName(), "back button pressed");
              return true;
         }
         return false;
    }
})

Excuse me if this is not relevant but I once had this problem and forgot that I had added an OnKeyListener that caught the on back pressed for my dialogFragment. I rewrote the listener as follows. The Top condition was added to solve the problem.

getDialog().setOnKeyListener(new DialogInterface.OnKeyListener() {
    @Override
    public boolean onKey(DialogInterface dialogInterface, int i, KeyEvent keyEvent) {
        if(keyEvent.getKeyCode() == KeyEvent.KEYCODE_DEL) {
            return false;
        }
        if(keyEvent.getAction() == KeyEvent.ACTION_DOWN && keyEvent.getKeyCode() == KeyEvent.KEYCODE_BACK) {
            if(iYoutubePickerDialog != null) {
                iYoutubePickerDialog.closeYoutubeDialog(getDialog());
            }
        }
        return true;
    }
});
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!