Android EditText onClick Listener defined in Layou

2019-04-07 21:43发布

I want to define an onClick Listener for an EditText in the Layout-XML of may activity, but it always fails with an obscure Exception.

The Layout is injected with setContentView()in the onCreate-Method of my activity. I am not using a Fragment here and I am well aware that the XML defined onClick Listener do not work for fragments.

For testing purposes I added the same handler method to an ImageView that is located next to the EditText. There the handler works, on the EditText it fails. So this is something special of the EditText and not a general Problem of a mislocated handler method.

This is the relevant part of my layout file:

<ImageView
     android:layout_gravity="center_horizontal|top"
     android:layout_rowSpan="3"
     android:src="@drawable/ic_action_event"
     android:onClick="onCreationClicked"
     />

<EditText
     android:id="@+id/creation_edit"
     android:focusable="false"
     android:clickable="true"
     android:layout_gravity="fill_horizontal"
     android:hint="@string/enter_creation"
     android:onClick="onCreationClicked"
     style="@style/PickerEditText"
     />

When I click on the ImageView the associated method is executed and a DialogFragment is started. When I click on the EditText I get the following Exception:

    java.lang.IllegalStateException: Could not find a method onCreationClicked(View) in the activity class android.support.v7.internal.widget.TintContextWrapper for onClick handler on view class android.support.v7.widget.AppCompatEditText with id 'creation_edit'
            at android.view.View$1.onClick(View.java:3994)
            at android.view.View.performClick(View.java:4756)
            at android.view.View$PerformClick.run(View.java:19749)
            at android.os.Handler.handleCallback(Handler.java:739)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
     Caused by: java.lang.NoSuchMethodException: onCreationClicked [class android.view.View]
            at java.lang.Class.getMethod(Class.java:664)
            at java.lang.Class.getMethod(Class.java:643)
            at android.view.View$1.onClick(View.java:3987)
            at android.view.View.performClick(View.java:4756)
            at android.view.View$PerformClick.run(View.java:19749)
            at android.os.Handler.handleCallback(Handler.java:739)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

I am currently testing on a Samsung S4 (Android 5.0.1) API 21 and AppCompat Library in Version v7 22.1.0

Adding the onClick Listener programmatically in the onCreate method would be a solution, but I wanted to avoid this, since it results in a single onClick method with a big switch statement and the XML-based onClick-Handler result in a more readable and explicit code which I prefer.

Did additional research:

Now I can reproduce the error behaviour and the correct behavior (see below). It seems this is a bug (or a feature) introduced with appcompat-v7 22.1.0 & 22.1.1.

I created a new fresh project with Android Studio with Blank Activity. minSdk 17, targetSdk 21. Added the EditText to the blank Activity as shown below and added the handler method to the Activity like this:

public void onCreationClicked(View view) {
    Toast.makeText(this,"Event Handled",Toast.LENGTH_LONG).show();
}

Started the App touched the EditText --> Crash

Changed my build.gradle from:

    compile 'com.android.support:appcompat-v7:22.1.1'

to

    compile 'com.android.support:appcompat-v7:22.0.0'

and the Toast is shown.

Any ideas?

3条回答
戒情不戒烟
2楼-- · 2019-04-07 22:22

You need to define the method onCreationClicked(View) in your Activity not in your Fragment. If you want the Fragment to handle the click, you need remove the onClick in your XML and handle the listener programmatically.

查看更多
别忘想泡老子
3楼-- · 2019-04-07 22:24

Maybe this helps others to save time with searching for a solution. I raised an issue for appcompat7 which was accepted with the following comment:

This has already been fixed for the next platform release, but it may not be feasible to fix this in appcompat.

Details: https://code.google.com/p/android/issues/detail?id=174871

So indeed it is a bug / problem of appcompat and I will fallback to adding the onClick listener programmatically.

查看更多
迷人小祖宗
4楼-- · 2019-04-07 22:26

I used the following tip from #5 on Issue 174871:

change : <EditText .../> to <android.widget.EditText .../>

So Appcompat does not handle onClick anymore

查看更多
登录 后发表回答