Подтвердить что ты не робот

Событие onClick не запускается | Android

Я сделал очень простое тестовое приложение с одним действием и одним макетом. 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 и моем эмуляторе уровня 8, но у меня такая же проблема.

Разъяснение

Когда editText1 фокусируется и нажимается, то срабатывает метод onClick. Если editText2 фокусируется, а затем editText1 щелкнут, он не стреляет. Большая проблема.

4b9b3361

Ответ 1

Обзор, когда пользователь взаимодействует с любым компонентом пользовательского интерфейса, различные слушатели вызывают в порядке сверху вниз. Если один из слушателей с более высоким приоритетом "потребляет событие", тогда нижние слушатели не будут вызываться.

В вашем случае эти три слушателя вызываются в порядке:

  • OnTouchListener
  • OnFocusChangeListener
  • OnClickListener

В первый раз, когда пользователь касается EditText, он получает фокус, чтобы пользователь мог ввести его. Действие расходуется здесь. Поэтому нижний приоритет OnClickListener не вызывается. Каждое последующее касание не изменяет фокус, поэтому эти события просачиваются в OnClickListener.

Кнопки (и другие такие компоненты) не получают фокуса от события касания, поэтому каждый раз вызывается OnClickListener.

В принципе, у вас есть три варианта:

  • Внедрить 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.

  • Внедрите OnFocusChangeListener вместе с OnClickListener:

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

    Этот слушатель ловит первое событие касания, когда фокус изменяется, когда ваш OnClickListener ловит каждое другое событие.

  • (Здесь недействительный ответ, но это хороший трюк.) Установите для настраиваемого атрибута false в свой XML:

    android:focusable="false"
    

    Теперь OnClickListener будет стрелять каждый раз при нажатии. Но это делает EditText бесполезным, поскольку пользователь больше не может вводить текст...

Примечание:

getApplicationContext() может создавать утечки памяти. Хорошая привычка состоит в том, чтобы избежать использования, если это абсолютно необходимо. Вы можете безопасно использовать v.getContext().

Надеюсь, что это поможет!

Ответ 2

сделать редактируемый текст кликабельным.. В XML android:clickable="true"  или в коде

ed1.setClickable(true);

то do

ed1.setOnClickListener(new OnClickListener() {

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

Ответ 3

Возможно, я слишком поздно опоздал на вечеринку, но вот код, который исправлен, устраняет проблему с неотображаемым 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;
    }
});

Ответ 4

Это происходит потому, что первое нажатие фокусируется на виде. Следующее нажатие вызывает щелчок.

Если вы надуваете представление динамически, сделайте это:

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

Если это не работает, попробуйте применить его и к родительскому представлению.

Ответ 5

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>

Ответ 6

Понадобился минутку, чтобы понять это однажды, когда это случилось со мной. Мой ImageButton с setOnClickListener и onClick, похоже, не срабатывал, а затем я понял, что это действительно под другим элементом моего макета xml, поэтому я обернулся:

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

в это:

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

и внезапно ImageButton не перекрывался с другим макетом, так как теперь он был добавлен позже в родительский макет и теперь был сверху и работает каждый раз. Удачи, всегда весело, когда основные вещи внезапно перестают работать.

Ответ 7

Избегайте использования 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 будет функционировать должным образом в первый раз.

Ответ 8

Это самый простой способ работы со сборщиком даты.

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


});

Ответ 9

попробуйте следующее:

public class MainActivity extends Activity implements OnClickListener {
 //rest of your code
}