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

时间:2011-08-02 20:43:07

标签: android android-edittext back

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

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

5 个答案:

答案 0 :(得分:3)

我在一段时间前写的应用程序中遇到了同样的问题。它现在已经废弃,但这不是你的问题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上找到真正的源代码。我不会这样偷走某人的天才。积分归于未知的人;)

答案 1 :(得分:1)

这是@ mikepenz的答案的修改版本,因为它没有使用 windowSoftInputMode =" adjustPan" 使用 Android 8 / strong>模式。

语言 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)
}

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

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

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

答案 4 :(得分:0)

对不起,如果这不相关,但我曾经遇到过这个问题而忘记了我已经添加了一个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;
    }
});