多EditTexts焦点问题 [英] Focus issue with multiple EditTexts

查看:183
本文介绍了多EditTexts焦点问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个的EditText 秒的活动。我打电话了 requestFocus的第二的EditText 字段,因为默认情况下,焦点转移到第一个。重点似乎是在第二个字段(第二个得到高亮边框),但如果我们试着输入使用的文字出现在第一个硬件键盘的任何字符的EditText 控制。任何想法,为什么会是这样吗?

I have an activity with two EditTexts. I am calling the requestFocus on the second EditText field since by default the focus goes to the first one. The focus appears to be in the second field (the second one gets the highlighted border), but if we try to enter any characters using the hardware keyboard the text appears in the first EditText control. Any ideas why it would be happening?

推荐答案

这是很难说这是否是你的问题,但它不是不可能的。

It's hard to tell whether this was your problem, but it's not unlikely.

TL; DR:不要调用重点变化的如 requestFocus的方法()从里面 onFocusChanged()通话。

TL;DR: Never call focus-changing methods like requestFocus() from inside a onFocusChanged() call.

问题在于<一href="https://github.com/android/platform_frameworks_base/blob/c420ce34ba177cd959cbb9432e9597d377e6cee6/core/java/android/view/ViewGroup.java#L610"><$c$c>ViewGroup.requestChildFocus(),其中包含这样的:

The issue lies in ViewGroup.requestChildFocus(), which contains this:

// We had a previous notion of who had focus. Clear it.
if (mFocused != child) {
    if (mFocused != null) {
        mFocused.unFocus();
    }

    mFocused = child;
}

在私人领域 mFocused A店的ViewGroup当前具有焦点,如果任何一个子视图。

Inside the private field mFocused a ViewGroup stores the child view that currently has focus, if any.

假设你有一个的ViewGroup VG ,其中包含三个可聚焦视图(如EditTexts) A B C

Say you have a ViewGroup VG that contains three focusable views (e.g. EditTexts) A, B, and C.

您已经添加了一个 OnFocusChangeListener A 的(或许不是直接的,而是介于内部嵌套)调用 B.requestFocus() A 失去焦点。

You have added an OnFocusChangeListener to A that (maybe not directly, but somewhere nested inside) calls B.requestFocus() when A loses focus.

现在想象 A 具有焦点,并在用户点击 C ,引起 A 可失去的, C 来获得焦点。因为 VG.mFocused 目前 A VG.requestChildFocus(C以上的部分, C)然后转换到这一点:

Now imagine that A has focus, and the user taps on C, causing A to lose and C to gain focus. Because VG.mFocused is currently A, the above part of VG.requestChildFocus(C, C) then translates to this:

if (A != C) {
    if (A != null) {
        A.unFocus();          // <-- (1)
    }

    mFocused = C;             // <-- (3)
}

A.unFocus()在这里所做的两个重要的事情:

A.unFocus() does two important things here:

  1. 这标志着 A 为没有重点了。

它要求你的焦点变化监听器。

It calls your focus change listener.

在该侦听器,你现在叫 B.requestFocus()。这将导致 B 标记为有重点,然后调用 VG.requestChildFocus(B,B)。因为我们仍然深深的电话我已经打上内(1),价值 mFocused 仍是 A ,因而这种内心的召唤看起来是这样的:

In that listener, you now call B.requestFocus(). This causes B to be marked as having focus, and then calls VG.requestChildFocus(B, B). Because we're still deep inside the call I've marked with (1), the value of mFocused is still A, and thus this inner call looks like this:

if (A != B) {
    if (A != null) {
        A.unFocus();
    }

    mFocused = B;             // <-- (2)
}

这时候,在调用 A.unFocus()并没有做任何事情,因为 A 已经是标记为未聚焦(否则我们会在这里有一个无限循环)。此外,没有任何反应的标记 C 作为重点不突出,这是的视图实际上的具有焦点现在。

This time, the call to A.unFocus() doesn't do anything, because A is already marked as unfocused (otherwise we'd have an infinite recursion here). Also, nothing happens that marks C as unfocused, which is the view that actually has focus right now.

现在谈到(2),这台 mFocused B 。经过一些更多的东西,我们终于从调用返回的(1),并且在这样(3)的值对 mFocused 现在设置为 C 覆盖previous变化

Now comes (2), which sets mFocused to B. After some more stuff, we finally return from the call at (1), and thus at (3) the value of mFocused is now set to C, overwriting the previous change.

所以,现在我们结束了一个incosistent状态。 B C 都认为他们有重点, VG 认为 C 来成为焦点的孩子。

So now we end up with an incosistent state. B and C both think they have focus, VG considers C to be the focused child.

在特定的,关键presses结束在 C ,它是用户不可能将焦点切换回 ,因为 B 认为它已经集中,因此不会做重点要求任何东西;最重要的是,它的没有的通话 VG.requestChildFocus

In particular, keypresses end up in C, and it is impossible for the user to switch focus back to B, because B thinks it already has focus and thus doesn't do anything on focus requests; most importantly, it does not call VG.requestChildFocus.

推论:你也应该不依赖于 hasFocus结果()电话,而一个 OnFocusChanged 处理程序中,因为重点信息是调用内部不一致的时间。

Corollary: You also shouldn't rely on results from hasFocus() calls while inside an OnFocusChanged handler, because the focus information is inconsistent while inside that call.

这篇关于多EditTexts焦点问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆