android onClick事件未触发|安卓

ubby3x7f  于 2022-12-25  发布在  Android
关注(0)|答案(9)|浏览(223)

我制作了一个非常简单的测试应用程序,只有一个活动和一个布局,onClick在第一次按下时没有触发,这是应该的。
活动:

package com.example.mytest;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final EditText ed1 = (EditText) findViewById(R.id.editText1);

        ed1.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

                Toast.makeText(getApplicationContext(), "1", Toast.LENGTH_LONG)
                        .show();

            }

        });
    }

}

布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <EditText
        android:id="@+id/editText1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:ems="10" >

        <requestFocus />
    </EditText>

    <EditText
        android:id="@+id/editText2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/editText1"
        android:ems="10" />

</RelativeLayout>

如果你运行这个应用程序,点击第二个editText,然后回到第一个,它不会触发onClick。你可以继续来回选择,它根本不会触发onClick。我需要这个基本的功能,但还没有能够想到一个方法来让它工作。

通知

我已经在我的API级别16物理设备和API级别8模拟器上尝试了所有推荐的方法,但我得到了同样的问题。

澄清

editText1被聚焦并被点击时,onClick方法会被触发。如果editText2被聚焦,然后editText1被点击,它不会触发。

l7wslrjt

l7wslrjt1#

    • 概述,**当用户与任何UI组件交互时,将按自上而下的顺序调用各种监听程序。如果其中一个较高优先级的监听程序"使用事件",则将不会调用 * 较低优先级的监听程序。

在您的示例中,将按顺序调用这三个侦听器:
1.在线监听器
1.焦点更改监听器
1.点击监听器
用户第一次触摸EditText时,它会获得焦点,以便用户可以键入。* 该操作在此处使用。* 因此,不会调用优先级较低的OnClickListener。每次连续触摸都不会改变焦点,因此这些事件会向下传递到OnClickListener。
按钮(以及其他类似的组件)不会从触摸事件接收焦点,这就是为什么每次都调用OnClickListener。

    • 基本上,**你有三个选择

1.单独实现OnTouchListener:

ed1.setOnTouchListener(new OnTouchListener() {
     @Override
     public boolean onTouch(View v, MotionEvent event) {
         if(MotionEvent.ACTION_UP == event.getAction())
             editTextClicked(); // Instead of your Toast
         return false;
     }
 });

这将在每次点击EditText时执行。注意,侦听器返回false,这允许事件向下传递到内置的OnFocusChangeListener,后者更改焦点,以便用户可以键入EditText。
1.随OnClickListener一起实现OnFocusChangeListener:

ed1.setOnFocusChangeListener(new OnFocusChangeListener() {
     @Override
     public void onFocusChange(View v, boolean hasFocus) {
         if(hasFocus)
             editTextClicked(); // Instead of your Toast
     }
 });

此侦听器在焦点更改时捕获第一个触摸事件,而OnClickListener捕获所有其他事件。
1.(这不是一个有效的答案,但这是一个很好的技巧。)在XML中将focusable属性设置为false

android:focusable="false"

现在OnClickListener将在每次被点击时触发。但是这使得EditText无用,因为用户不能再输入任何文本...

    • 注:**

getApplicationContext()可能会造成内存泄漏。一个好习惯是避免使用它,除非绝对必要。您可以安全地使用v.getContext()代替。

wbrvyc0a

wbrvyc0a2#

我可能来得太晚了,但这里有一段代码,它修复了未调用onClick()的问题:

ed1.setOnTouchListener(new OnTouchListener() {

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP && !v.hasFocus()) {
            // onClick() is not called when the EditText doesn't have focus,
            // onFocusChange() is called instead, which might have a different 
            // meaning. This condition calls onClick() when click was performed
            // but wasn't reported. Condition can be extended for v.isClickable()
            // or v.isEnabled() if needed. Returning false means that everything
            // else behaves as before.
            v.performClick();
        }
        return false;
    }
});
8fq7wneg

8fq7wneg3#

使编辑文本可单击..在XML android:clickable="true"或代码中

ed1.setClickable(true);

那就

ed1.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View v) {
      Toast.makeText(getBaseContext(), "1",Toast.LENGTH_SHORT).show();
    }
  });
w80xi6nr

w80xi6nr4#

发生这种情况是因为第一次点击获得了视图的焦点,下一次点击触发了点击。
如果要动态膨胀视图,请执行以下操作:

android:clickable="true"
android:focusable="false"
android:focusableInTouchMode="false"

如果这样做不起作用,请尝试也将其应用到父视图上。

mi7gmzs6

mi7gmzs65#

这是使用日期选择器最简单的方法。

private DatePickerDialog datePickerDialog;
EditText etJoiningDate;
etJoiningDate=(EditText)findViewById(R.id.etJoiningDate);

etJoiningDate.setOnTouchListener(new View.OnTouchListener() {

    @Override
    public boolean onTouch(View v, MotionEvent event) {

        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:

                final Calendar cldr = Calendar.getInstance();
                int day = cldr.get(Calendar.DAY_OF_MONTH);
                int month = cldr.get(Calendar.MONTH);
                int year = cldr.get(Calendar.YEAR);
                // date picker dialog
                datePickerDialog = new DatePickerDialog(TestActivity.this,
                        new DatePickerDialog.OnDateSetListener() {
                            @Override
                            public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
                                etJoiningDate.setText(dayOfMonth + "/" + (monthOfYear + 1) + "/" + year);
                            }
                        }, year, month, day);
                datePickerDialog.show();

                break;
        }

        return false;
    }

});
dsf9zpds

dsf9zpds6#

public class TestProject extends Activity implements OnClickListener {
TextView txtmsg;
EditText ed1, ed2;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    txtmsg = (TextView) findViewById(R.id.txtmsg);
    ed1 = (EditText) findViewById(R.id.edt1);
    ed2 = (EditText) findViewById(R.id.edt2);

    ed1.setOnClickListener(this);
    ed2.setOnClickListener(this);
}

@Override
public void onClick(View v) {

    if(v==ed1){
        txtmsg.setText("1");
        Toast.makeText(this, "first",Toast.LENGTH_SHORT).show();
    }
    if(v==ed2){
        txtmsg.setText("2");
        Toast.makeText(this, "second",Toast.LENGTH_SHORT).show();
    }

}

}

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <EditText
        android:id="@+id/edt1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:ems="10" />

    <EditText
        android:id="@+id/edt2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/edt1"
        android:layout_marginTop="14dp"
        android:ems="10" />

    <TextView
        android:id="@+id/txtmsg"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignRight="@+id/edt2"
        android:layout_below="@+id/edt2"
        android:layout_marginRight="22dp"
        android:layout_marginTop="160dp"
        android:textAppearance="?android:attr/textAppearanceLarge" />

</RelativeLayout>
g6ll5ycj

g6ll5ycj7#

有一次我花了一分钟才弄明白这个问题,我的ImageButtonsetOnClickListeneronClick似乎没有启动,然后我意识到它实际上在我的xml布局中的另一个元素下面,所以我把它:

<RelativeLayout>
     <ImageButton>
     <LinearLayout></LinearLayout>
 </RelativeLayout>

变成这样:

<RelativeLayout>
     <LinearLayout></LinearLayout>
     <ImageButton>
 </RelativeLayout>

突然间,ImageButton不再与其他布局重叠,因为它现在是稍后添加到父布局中的,现在位于顶部,并且每次都能正常工作。祝你好运,当基本的东西突然停止工作时总是很有趣

n3ipq98p

n3ipq98p8#

避免使用FocusChangeListener,因为当你不需要它的时候(例如,当你进入一个活动的时候),它会表现得不稳定。只需像这样设置一个OnTouchListener沿着你的OnClickListener

@Override
public boolean onTouch(View view, MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            view.requestFocus();
            break;
    }
    return false;
}

这将使EditText第一次获得焦点,并且onClick第一次正常工作。

zvms9eto

zvms9eto9#

简单、可重复使用的Kotlin解决方案

我从两个自定义扩展函数开始:

val MotionEvent.up get() = action == MotionEvent.ACTION_UP

fun MotionEvent.isIn(view: View): Boolean {
    val rect = Rect(view.left, view.top, view.right, view.bottom)
    return rect.contains((view.left + x).toInt(), (view.top + y).toInt())
}

然后听编辑文本上的触摸。这将只在初始ACTION_DOWN事件最初在编辑文本上时触发,并且现在仍然是。

myEdittext.setOnTouchListener { view, motionEvent ->
    if (motionEvent.up && motionEvent.isIn(view)) {
        // Talk your action here
    }
    false
}

相关问题