CastClassException in benutzerdefinierter Ansicht
-
12-11-2019 - |
Frage
Wenn ich versuche findViewById()
in meiner benutzerdefinierten Ansicht bekomme ich immer eine ClassCastException
.Ich habe so viele Dinge ausprobiert, dass ich mir sicher bin, dass ich den Code jetzt verpfuscht habe!
Um sicherzugehen, dass ich nicht verrückt werde, habe ich die Klassen auf das Nötigste reduziert, um herauszufinden, was los war.
Ich bin neu in der Android-Programmierung und ich bin mir sicher, dass mir etwas Grundlegendes fehlt.
Das ist BaseImageView
eine erweiterte Ansichtsklasse.
package com.company.product.client.android.gui.views;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.view.View;
public class BaseImageView
extends View
{
public BaseImageView(Context context)
{
super(context);
}
@Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
canvas.drawColor(Color.GREEN);
}
}
Das ist LiveImageView
eine Erweiterung des BaseImageView
Klasse.
package com.company.product.client.android.gui.views;
import android.content.Context;
import android.util.AttributeSet;
public class LiveImageView
extends BaseImageView
{
public LiveImageView(Context context, AttributeSet attrs)
{
super(context);
}
}
Hier ist das Layout my_view.xml
.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center">
<View
class="com.company.product.client.android.gui.views.LiveImageView"
android:id="@+id/lvImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Und hier ist das onCreate in meiner Aktivität LiveViewActivity
.
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
try
{
setContentView(R.layout.my_view);
final LiveImageView lvImage = (LiveImageView) findViewById(R.id.lvImage);
}
catch (final Exception e)
{
Log.e(TAG, "onCreate() Exception: " + e.toString());
e.printStackTrace();
}
Schließlich ist dies der Stack-Trace.
02-11 17:25:24.829: ERROR/LiveViewActivity(1942): onCreate() Exception: java.lang.ClassCastException: android.view.View
02-11 17:25:24.839: WARN/System.err(1942): java.lang.ClassCastException: android.view.View
02-11 17:25:24.839: WARN/System.err(1942): at com.company.product.client.android.gui.screen.LiveViewActivity.onCreate(LiveViewActivity.java:26)
02-11 17:25:24.839: WARN/System.err(1942): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
02-11 17:25:24.849: WARN/System.err(1942): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)
02-11 17:25:24.849: WARN/System.err(1942): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
02-11 17:25:24.849: WARN/System.err(1942): at android.app.ActivityThread.access$2200(ActivityThread.java:119)
02-11 17:25:24.849: WARN/System.err(1942): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
02-11 17:25:24.859: WARN/System.err(1942): at android.os.Handler.dispatchMessage(Handler.java:99)
02-11 17:25:24.859: WARN/System.err(1942): at android.os.Looper.loop(Looper.java:123)
02-11 17:25:24.859: WARN/System.err(1942): at android.app.ActivityThread.main(ActivityThread.java:4363)
02-11 17:25:24.869: WARN/System.err(1942): at java.lang.reflect.Method.invokeNative(Native Method)
02-11 17:25:24.869: WARN/System.err(1942): at java.lang.reflect.Method.invoke(Method.java:521)
02-11 17:25:24.869: WARN/System.err(1942): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
02-11 17:25:24.869: WARN/System.err(1942): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
02-11 17:25:24.879: WARN/System.err(1942): at dalvik.system.NativeStart.main(Native Method)
Lösung
Bei Verwendung in Layout-XML-Dateien sollte Ihre benutzerdefinierte Ansicht lauten:
<com.company.product.client.android.gui.views.LiveImageView
android:layout_width="..."
...
/>
Stellen Sie außerdem sicher, dass Sie die anderen beiden Varianten von Konstruktoren für Ansichten definieren:
public BaseImageView(Context, AttributeSet);
public BaseImageView(Context, AttributeSet, int);
Da der Layout-Inflater tatsächlich diese zwei Varianten benötigt, um die Instanz zu erstellen.
Andere Tipps
Ich bin schon einmal darauf gestoßen, benutze einen Kleinbuchstaben <view>
Tag:
<view
class="com.company.product.client.android.gui.views.LiveImageView" ... />
Dies ist von Android-Dokumente punkt 4:
<view
class="com.android.notepad.NoteEditor$MyEditText"
id="@+id/note" ...
Versuchen Sie, Ihre XML-Deklaration zu ändern
<com.company.product.client.android.gui.views.LiveImageView
android:id="@+id/lvImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
Oder es kann an einem Fehler liegen.
Zu behebender Workaround:Weisen Sie der benutzerdefinierten Ansicht in Layout-XML und findViewById () einen neuen 'ID' -Wert zu.