在Android中如何检测EditText的焦点?

53

我的页面中有多个EditText元素和两个按钮。我希望用户触摸任何一个EditText字段,并单击任何按钮将某个值插入到他们触摸的那个EditText字段中。不允许使用键盘输入。请帮助我完成这个功能。


1
也许你正在寻找View.setOnTouchListener。 - mihail
我想要检测当前获取焦点的EditText视图。 - Eclipse-fan
10个回答

67

你可以使用View.OnFocusChangeListener来检测任何视图(如EditText)是否获得或失去焦点。

for (EditText view : editList){
   view.setOnFocusChangeListener(focusListener);
}
....
private OnFocusChangeListener focusListener = new OnFocusChangeListener() {
    public void onFocusChange(View v, boolean hasFocus) {
        if (hasFocus){
             focusedView = v;
        } else {
             focusedView  = null;
        }
    }
}

这段代码需要放在您的活动或片段或任何您有EditText的地方。....仅表示您可以将其放置在类中的任何其他位置。显然,您需要创建一个包含它们的数组,因此需要editList


你试过这段代码吗?如果其中一个输入框失去焦点,而另一个获得焦点,则监听器将被调用两次。此后,focusedView可能为空吗? - Vasilii Suricov

42

对我来说这个方法可行,它返回一个布尔值。

myEditText.hasFocus()

28

你可以做的一件事是声明一个全局变量evalue,通过使用onTouchListener来确定哪个是最后选定的EditText,然后根据evalue的值,你可以通过按钮点击将文本值设置到EditText中。希望你能理解。

它的代码可能如下所示:

EditText e1,e2;
    Button b1,b2;
    String evalue;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        e1=(EditText)findViewById(R.id.editText1);
        e2=(EditText)findViewById(R.id.editText2);
        b1=(Button)findViewById(R.id.button1);
        b2=(Button)findViewById(R.id.button2);

        e1.setOnTouchListener(new View.OnTouchListener()
        {
            public boolean onTouch(View arg0, MotionEvent arg1)
            {
                evalue="1";
                return false;
            }
        });

        e2.setOnTouchListener(new View.OnTouchListener()
        {
            public boolean onTouch(View arg0, MotionEvent arg1)
            {
                evalue="2";
                return false;
            }
        });
        b1.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View arg0) {
                if(evalue=="1")
                {
                    e1.setText("yes");
                }
                if(evalue=="2")
                {
                    e2.setText("yes");
                }
            }
        });


        b2.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View arg0) {
                if(evalue=="1")
                {
                    e1.setText("No");
                }
                if(evalue=="2")
                {
                    e2.setText("No");
                }
            }
        });

    }

它是一种逻辑性的编码,但不够完美。如果你找到了更好的,请使用它。谢谢。


非常感谢。这完全满足了我的需求。 - Eclipse-fan
5
我认为你已经抓住了重点。还有许多其他答案假定 onFocusChange 是必需的监听器事件,我认为这是因为他们在以 PC/浏览器体验的思维模式下进行考虑。但这似乎是不正确的。触摸设备并不像这样工作。问题在于,当我测试那些其他答案时,即使我触摸了另一个屏幕上的 UI 元素,光标仍然在该字段中“闪烁”。因此,这意味着尽管接触了屏幕上的另一个 UI 元素,但焦点仍然在该字段中。因此,你必须检测其他被触摸到的东西,而不是该字段是否处于焦点状态。+1 - angryITguy
3
//当移动到可编辑字段时,onFocusChange事件将起作用。关键是要尝试理解在具有虚拟键盘的触摸设备上的行为上下文。 - angryITguy
@SrujanBarai--也许这个会有所帮助。 - DSlomer64

10

使用Java 8的Lambda表达式:

EditText editTextTo = findViewById(R.id.editTextTo);

editTextTo.setOnFocusChangeListener((view, b) -> {
    if (view.isFocused()) {
        // Do whatever you want when the EditText is focused 
        // Example:
        editTextFrom.setText("Focused!");
    }
});

请注意,lambda函数内部的视图实际上是EditText的一个实例。


1
终于有人提供了一种优雅、简单且可行的解决方案,代码更少,感谢 @olmedocr。 - Emmanuel Njorodongo

10

这对我有效。

e1 = (EditText) findViewById(R.id.editText1);

e1.setOnFocusChangeListener(new View.OnFocusChangeListener() {
   @Override
   public void onFocusChange(View arg0, boolean hasfocus) {
      if (hasfocus) {
         Log.e("TAG", "e1 focused") 
      } else {
         Log.e("TAG", "e1 not focused") 
      }            
   }
});

8

让你的Fragment实现OnTouchListenerOnFocusChangeListener接口:

public class AttributesFragment extends Fragment 
                       implements OnTouchListener, OnFocusChangeListener {

然后使用以下方式实现:

@Override
public boolean onTouch(View view, MotionEvent event) {
    if (view instanceof EditText) {
        view.setOnFocusChangeListener(this); // User touched edittext
    }
    return false;
}

@Override
public void onFocusChange(View v, boolean hasFocus) {

}

在创建EditText后,不要忘记设置你的监听器。

editText.setOnTouchListener(this);

如果一个EditText框默认情况下被聚焦,但用户尚未更改该字段,则不会触发onFocusChange事件。


1
这是最好的答案。我喜欢你考虑到了那些不是由直接用户交互触发的焦点事件。 - Taslim Oseni

6

我使用Java 8 (lambda表达式)实现了以下操作:

EditText myEditText = findViewById(R.id.editText);

myEditText.setOnFocusChangeListener((view, hasFocus) -> {
      if(hasFocus){
          Log.e("TAG", "myEditext has focus") 
      }else{
          Log.e("TAG", "myEditext has no focus") 
      }
});

5

简单编码:

if(EditText1.isFocused()){
  //EditText1 is focused
}else if(EditText2.isFocused()){
  //EditText2 is focused
}

除非您使用大写字母E命名变量,否则此代码将无法编译。在这种情况下,无论是Kotlin还是Java,Lint都应该崩溃您的构建。此外,已经有一个带有此解决方案的答案。 - milosmns

2
在您的活动或片段中实现OnFocusChangeListener。
edittextNeme= (EditText) findViewById(R.id.edittextNeme);
edittextNeme.setOnFocusChangeListener(this);

您需要通过view.getId()获取视图id来检查哪个视图更改了焦点,并进行相应处理。

@Override
public void onFocusChange(View view, boolean hasfocus) {
    switch(view.getId()){
    case R.id.edittextNeme:
    //Do something
    break;

    ...etc
    }
}

1
val currentFocusView = activity.currentFocus
if (currentFocusView is EditText){
   currentFocusView.appendText("Has Focus!")
}

请阅读如何撰写好的答案?。虽然这个代码块可能回答了OP的问题,但如果您解释一下这段代码与问题中的代码有何不同,您做了哪些更改,为什么要更改以及为什么这样解决问题而不会引入其他问题,那么这个答案将会更加有用。 - Saeed Zhiany

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接