2015-05-27 15 views
6

Ich möchte einen OnClick Listener für einen EditText in der Layout-XML von Mai-Aktivität definieren, aber es immer mit einer obskuren Ausnahme fehlschlägt.Android EditText onClick Listener im Layout definiert, scheitert mit obskurer Ausnahme

Das Layout wird mit setContentView() in der onCreate -Methode meiner Tätigkeit injiziert. Ich bin nicht mit einem Fragment hier und ich bin mir bewusst, dass die XML-definierten onClick Listener nicht für Fragmente arbeiten.

Zu Testzwecken habe ich die gleiche Handler-Methode zu einem ImageView hinzugefügt, das sich neben dem EditText befindet. Dort arbeitet der Handler, am EditText schlägt er fehl. Das ist etwas Spezielles des EditText und kein allgemeines Problem einer falsch lokalisierten Handler-Methode.

Dies ist der relevante Teil meiner Layout-Datei:

<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" 
    /> 

Wenn ich auf das Image des zugehörige Verfahren ausgeführt wird, und ein DialogFragment gestartet wird. Wenn ich auf dem EditText ich die folgende Ausnahme erhalten:

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) 

ich zur Zeit auf einem Samsung S4 am Testen (Android 5.0.1) API 21 und AppCompat Bibliothek in Version v7 22.1.0

des Hinzufügen onClick Listener programmgesteuert in der onCreate Methode wäre eine Lösung, aber ich wollte dies vermeiden, da es in einer einzigen onClick Methode mit einer großen switch-Anweisung und die XML-basierte onClick-Handler führt zu einem lesbareren und expliziten Code, die ich bevorzugen.

Did zusätzliche Forschung:

Jetzt kann ich das Fehlerverhalten und das richtige Verhalten reproduzieren (siehe unten). Es scheint, das ist ein Fehler (oder ein Feature) mit appcompat-v7 22.1.0 & 22.1.1 eingeführt.

Ich habe ein neues Projekt mit Android Studio mit Blank Activity erstellt. minSdk 17, targetSdk 21. Added die EditText auf den Rohling Activity wie unten gezeigt und hinzugefügt, um die Handler-Methode zum Activity wie folgt aus:

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

die App gestartet berührte den EditText -> Absturz

Changed my build.gradle aus:

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

zu

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

und Toast wird angezeigt.

Irgendwelche Ideen?

+0

ich den onClick Zuhörer auf der EditText benötigen. Es zu entfernen ist keine Lösung. – Wildsau

Antwort

10

Vielleicht hilft dies anderen, Zeit zu sparen bei der Suche nach einer Lösung. Ich habe ein Problem für appcompat7, das mit dem folgenden Kommentar akzeptiert wurde:

Dies wurde bereits für die nächste Plattform behoben, aber es ist möglicherweise nicht möglich, dies in appcompat zu beheben.

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

So in der Tat ist es ein Fehler/Problem der appcompat und ich werde den onClick Zuhörer zum Hinzufügen programmatisch Rückfall.

+0

Ich bestätige, es ist ein Fehler :) passiert mir gerade jetzt, und die Ausnahme Nachricht ist "keine solche Funktion". Schlechter Google! – eiran

+0

Gut gemacht! Vielen Dank. – Hong

+0

Ich hatte gerade dieses Problem mit 'appcompat-v7: 22.2.0', ging zu dem Link und bemerkte einen Post vor einer Stunde, wo der Status in' FutureRelease' geändert worden war. – hoss

3

Sie müssen die Methode onCreationClicked(View) in Ihrem Activity nicht in Ihrem Fragment definieren. Wenn Sie möchten, dass der Fragment den Klick verarbeitet, müssen Sie die onClick in Ihrem XML entfernen und den Listener programmgesteuert verarbeiten.

+0

Die Layoutdatei ist einer Aktivität zugeordnet, und onCreatíonClicked ist in Activity implementiert. Zu Testzwecken habe ich den gleichen Handler zum ImageView hinzugefügt. Da funktioniert es, aber ich möchte es in EditText und nicht in ImageView haben. Der einzige Punkt, an dem ich hier ein Fragment verwende, ist, dass der "onCreationClicked" -Handler ein DialogFragment startet. – Wildsau

+0

hast du den 'onclick' von 'ImageView' entfernt, wenn du 'onclick' im 'EditText' testest? Vielleicht ist der gleiche Methodenname der PB. –

+0

Warum nicht einfach den EditText in der onCreate() Methode aufblasen und setOnClickListener darauf anwenden? –

0

benutzte ich die folgenden Tipp von # 5 auf Issue 174871:

Änderung: <EditText .../> zu <android.widget.EditText .../>

So hat AppCompat nicht onClick Griff mehr

+1

Ich glaube nicht, dass dies eine Lösung ist. AFAIK bedeutet nur, dass Sie das appcompat EditText-Widget nicht mehr verwenden, indem Sie es durch das "native" Android-Widget ersetzen. Dies bedeutet, dass das Verhalten und das Aussehen davon abhängig ist von der Android-Version, auf die Sie ausgerichtet sind. Appcompat "emuliert" das Verhalten der neueren Android-Version für ältere Versionen, so dass Sie alle "neuen" EditText-Funktionen verlieren (was für Sie in Ordnung sein könnte und einen EditText). – Wildsau