web-dev-qa-db-ja.com

onClickイベントがトリガーされない| Android

1つのアクティビティと1つのレイアウトを持つ非常に単純なテストアプリケーションを作成しました。 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>

このアプリケーションを実行し、2番目のeditTextをクリックしてから最初のアプリケーションに戻ると、onClickはトリガーされません。前後に選択を続けると、onClickがまったくトリガーされません。この基本的な機能が必要ですが、機能させる方法を考えることができませんでした。アイデア?

通知

APIレベル16の物理デバイスとAPIレベル8エミュレータで推奨されるすべての方法を試しましたが、同じ問題が発生します。

明確化

いつ editText1がフォーカスされてクリックされると、onClickメソッドが起動します。 editText2がフォーカスされ、次にeditText1がクリックされると、それはしない発火します。大問題。

50
EGHDK

概要、ユーザーがUIコンポーネントを操作すると、さまざまなリスナーがトップダウンの順序で呼び出されます。優先度の高いリスナーの1つが「イベントを消費する」場合、低いリスナーは呼び出されません

あなたの場合、これらの3つのリスナーは順番に呼び出されます:

  1. OnTouchListener
  2. OnFocusChangeListener
  3. OnClickListener

ユーザーが初めてEditTextにタッチすると、ユーザーが入力できるようにフォーカスを受け取ります。 アクションはここで消費されます。したがって、優先度の低いOnClickListenerは呼び出されません。連続してタッチするたびにフォーカスは変更されないため、これらのイベントはOnClickListenerにトリクルダウンします。

ボタン(および他のそのようなコンポーネント)はタッチイベントからフォーカスを受け取らないため、OnClickListenerが毎回呼び出されます。

基本的に、3つの選択肢があります:

  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を入力できるようにフォーカスを変更します。

  2. OnClickListenerとともにOnFocusChangeListenerを実装します。

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

    このリスナーは、フォーカスが変更されたときに最初のタッチイベントをキャッチし、OnClickListenerは他のすべてのイベントをキャッチします。

  3. (これはここでは有効な答えではありませんが、知っておくと良いでしょう。)XMLでfocusable属性をfalseに設定します。

    _Android:focusable="false"
    _

    OnClickListenerは、クリックされるたびに毎回起動します。しかし、ユーザーはテキストを入力できなくなるため、EditTextは役に立たなくなります...

注:

getApplicationContext() はメモリリークを引き起こす可能性があります。絶対に必要な場合を除き、使用することは避けてください。代わりにv.getContext()を安全に使用できます。

お役に立てば幸いです!

182
Sam

編集テキストをクリック可能にします。XMLAndroid:clickable="true"またはコード内

ed1.setClickable(true);

それから

ed1.setOnClickListener(new OnClickListener() {

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

私はおそらくパーティーには遅すぎますが、ここでは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"

これが機能しない場合は、親ビューにも適用してみてください。

2
Irshu
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>
0
Yash

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が最初に適切に機能します。

0
Andrei Lupsa

これが私に起こったときに一度これを理解するために私を取りました。 ImageButtonsetOnClickListenerを含むonClickは起動しないようで、実際にxmlレイアウトの別の要素の下にあることに気づいたので、これを有効にしました。

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

これに:

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

imageButtonが親レイアウトに後で追加され、最上位になり、毎回機能するようになったため、突然ImageButtonが他のレイアウトと重なりませんでした。幸運、基本的なものが突然動作しなくなったように見えるときはいつも楽しい

0
ColossalChris

日付ピッカーを操作する最も簡単な方法です。

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


});
0
Hasan Masud