按下后退时,EditText不会触发更改

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了按下后退时,EditText不会触发更改相关的知识,希望对你有一定的参考价值。

在带有购物车的应用程序中,我提供了通过EditText更改项目数量的选项,该文本仅允许数字输入。 一切正常,除非用户更改字段然后按后退键以隐藏软键盘。在这种情况下,该字段显示更改的值,但我不知道如何检测此更改并对其作出反应。等待切换到另一个活动不是一种选择。 当用户使用“完成”按钮确认时,我可以使用“OnEditorActionListener”处理此问题。但是后退键呢?

更新: 事实证明,当使用后退键关闭软键盘时,编辑字段上的onKeyDown / onBackPressed和OnKeyListener都不会触发。

答案

我在一段时间前写的应用程序中遇到了同样的问题。它现在已经不在了,但这不是你的问题xD。

事实上,没有选项来跟踪这样的操作,但我发现了一个很棒的(或多或少)解决方案来添加这样的功能。它在理论上非常简单,但我认为它也是“黑客”。

因此,您需要的是一个自定义线性布局,其中包含您的应用程序或特殊区域。之后你必须添加一个监听器。这只适用于纵向模式。

所以这里的代码:(对不起,但我不记得来源)

自定义布局:

LinearLayoutThatDetactsSoftwarekeyboard.java(这是布局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);
    }

}

以及如何添加监听器:

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);
            }
        }
    });

LinearLayout添加了一个Listener,每次layoutheight改变至少128个像素时都会调用它。这是一个技巧,它不适用于小于128像素的键盘(但我认为每个键盘都有这样的高度)如果LayoutHeight已更改,您将收到通知,如果它现在显示。

我希望我的回答很有用。也许您再次在StackOverFlow上找到真正的源代码。我不会这样偷走某人的天才。积分归于未知的人;)

另一答案

这是@ mikepenz的答案的修改版本,因为它在带有windowSoftInputMode =“adjustPan”模式的Android 8上不起作用。

语言是kotlin。将此视图用作根视图并设置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)
}
另一答案

您可以覆盖活动中的onBackPressed(伪代码 - 警告):

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

由于代码的新信息在片段中,我建议在文本框中添加一个键监听器。此代码尚未经过测试,但应该可以使用。

((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;
    }
})
另一答案

对不起,如果这不相关,但我曾经遇到过这个问题而忘记了我已经添加了一个OnKeyListener,它抓住了我的dialogFragment按下了。我重写了听众如下。添加了Top条件来解决问题。

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;
    }
});

以上是关于按下后退时,EditText不会触发更改的主要内容,如果未能解决你的问题,请参考以下文章

应用程序在主要活动中关闭onBackPressed

Android:按下后退按钮时提示用户保存更改

Android:为EditText打开键盘时处理后退按钮单击

检测后退按钮但不关闭对话框片段

按下后退按钮时正在重新创建 Listview 片段

如何在按下单个片段的手动后退按钮时返回上一个片段?