【问题标题】:Android How to keep text in EditText when taping outside?Android 如何在外部点击时将文本保留在 EditText 中?
【发布时间】:2020-03-19 15:52:46
【问题描述】:

当我输入 EditText 并在屏幕的另一部分点击时,EditText 中的文本会消失(就像键盘在关闭/隐藏时一样)。

EditText 是密码输入,当前显示在AlertDialog.Builder

final AlertDialog.Builder passwordInputDialog =  new AlertDialog.Builder(MainActivity.this, R.style.CustomAlertDialog);
TextInputLayout passwordInputLayout           = new TextInputLayout(MainActivity.this);
passwordInputInflater                         = LayoutInflater.from(MainActivity.this).inflate(R.layout.password_input, null);

passwordInputDialog
    .setCustomTitle(passwordInputTextView)
    .setMessage(message)
    .setView(passwordInputLayout)
    .setPositiveButton("OK", onPositiveAlertDialogClick())
    .setNegativeButton("Cancel", onNegativeAlertDialogClick());

final AlertDialog passwordInputShownDialog = passwordInputDialog.show();
final EditText enteredPassword = passwordInputInflater.findViewById(R.id.etPassword);

EditText 附加了一个addTextChangedListener 事件,它可以很好地执行任何其他操作:

enteredPassword.addTextChangedListener(new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) { }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) { }

    @Override
    public void afterTextChanged(Editable enteredText) {
        ...
        enteredPassword.removeTextChangedListener(this);
        enteredPassword.setText(enteredText);
        enteredPassword.setSelection(enteredText.length());
        enteredPassword.addTextChangedListener(this);
    }
});

问题是我做错了什么,或者是“离开输入时”对话框中 EditText 的默认行为。

我该如何做才能“保留”在 EditText 中输入的文本,然后在此之外进行粘贴?


这是我尝试在 afterTextChanged 函数上设置 EditText 的文本时得到的结果:

2019-11-24 20:20:46.795 20941-20954/com.example.map2 I/om.example.map: Background concurrent copying GC freed 135477(4MB) AllocSpace objects, 0(0B) LOS objects, 50% free, 9MB/18MB, paused 79us total 113.470ms
2019-11-24 20:20:54.553 20941-20954/com.example.map2 I/om.example.map: Background concurrent copying GC freed 136023(4MB) AllocSpace objects, 0(0B) LOS objects, 49% free, 10MB/21MB, paused 89us total 128.803ms
2019-11-24 20:21:03.751 20941-20954/com.example.map2 I/om.example.map: Background concurrent copying GC freed 137630(4MB) AllocSpace objects, 0(0B) LOS objects, 50% free, 12MB/25MB, paused 108us total 162.638ms
2019-11-24 20:21:13.794 20941-20954/com.example.map2 I/om.example.map: Background concurrent copying GC freed 137787(4MB) AllocSpace objects, 0(0B) LOS objects, 50% free, 14MB/28MB, paused 110us total 153.423ms
2019-11-24 20:21:24.617 20941-20954/com.example.map2 I/om.example.map: Background concurrent copying GC freed 137118(4MB) AllocSpace objects, 0(0B) LOS objects, 50% free, 16MB/32MB, paused 101us total 181.131ms

它冻结了应用程序,我不得不杀死它。

我理解并意识到我需要的不是那样做。因为我想保存用户在 SharedPreferences 中写入的内容以再次显示它们,这样用户就不必多次键入内容。

【问题讨论】:

    标签: android android-edittext android-alertdialog


    【解决方案1】:

    通过关闭alertDialog,里面的所有数据都会丢失。 您可以通过以下方式阻止关闭 alertDialog:

    passwordInputDialog.setCancelable(false);
    

    或者您可以将最后一个值保存在 alertDialog 中,并通过再次显示将其恢复。 (不推荐)

    【讨论】:

    • 嗨 Siavoosh,感谢您抽出宝贵时间。这以某种方式解决了部分问题,但我仍然能够离开焦点并丢失我输入的内容。
    • 我知道这是我能去的最接近的地方。再次感谢。
    【解决方案2】:

    要回答您的问题,editText 不是消失的那个! 它是对话框,并且由于对话框是承载 editText 的对话框,因此如果这正是您正在做的事情,对话框的 onCancle 也会简单地删除 editText。

    注意:注意下面代码中的cmets。

    第一次观察:

    enteredPassword.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
    
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) { }
    
        @Override
        public void afterTextChanged(Editable enteredText) {
            ...
            enteredPassword.removeTextChangedListener(this); /* why this? when you will still add it back immediately below? */
            enteredPassword.setText(enteredText); /*Change to enteredText.toString() because enteredText is an interface and you need to point to the method toString to get the character array inside it.*/
            enteredPassword.setSelection(enteredText.length()); /*Not sure why you're using this either */
            enteredPassword.addTextChangedListener(this); /*why this? when you're already listening?*/
        }
    });
    

    这可以替代您目前对上面 enterPassword 的了解:

    enteredPassword.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
    
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) { }
    
        @Override
        public void afterTextChanged(Editable enteredText) {
        enteredPassword.setText(enteredText.toString()); /* although this is actually weird! in the sense that enteredPassword already has the text and yet, you're still assigning it texts back to itself, I mean enteredPassword.setText(enteredPassword.getText().toString() is equivalent to enteredText.toString())*/
        }
    });
    

    还有: 既然您说 editText 在对话框中,那么如果 Dialog 实际关闭,那么您不应该看到 editText,好吧,我猜对话框没有关闭,并且在同一个对话框中您正在尝试做其他事情并且当焦点从editText更改为Dialog上的另一个View,那么EditText中用于输入密码的文本不见了?如果是:那么如果您只需要文本,那么您实际上不需要 TextChange 侦听器,只需创建一个变量来存储文本并根据需要使用。

    最后: 我的问题是你特别想做什么?不要害怕问更详尽的问题,你只需要具体。

    【讨论】:

    • 您好,感谢您的宝贵时间。 enteredPassword.removeTextChangedListener 是因为从该函数本身修改 EditText 时,应用程序进入无限循环。无法真正解释如何,我对 Android 和 Java 还很陌生。
    • @sab 我认为您需要花更多时间自上而下地审查您的代码,同时在什么情况下无限循环?在输入editText或?我建议你简单地删除这两行:enteredPassword.removeTextChangedListener();输入密码.addTextChangedListener(this);因为在您放置这些内容时,您已经在聆听,无需删除或重新添加。还有,现在问题解决了吗?如果是,介意发布答案,如果我们的任何答案不匹配。?
    • 对不起鲸鱼,问题仍未解决。我按照 Siavoosh 的建议添加了 passwordInputDialog.setCancelable ,但在将焦点从输入中移开时,我仍然丢失了我输入的内容。
    • @sab 你能打开一个新问题,专门针对你在这方面面临的当前问题,并在此处分享链接,以便我跟进吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-17
    • 1970-01-01
    • 1970-01-01
    • 2015-11-13
    • 2020-05-26
    • 2017-10-15
    相关资源
    最近更新 更多