问题
I've just run into an issue when attempting to grab a custom View using findViewById(). The custom view otherwise displays and operates correctly. Unfortunately, I need to be able to change some data it displays at will, so it has to be done.
My XML looks like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.TheProject.TheApp.Chart
android:id="@+id/chart"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
I know sometimes the issue is that people accidentally name the component "View" in the XML instead of their subclass of it.
Inside my Activity's onCreate() method, I have this:
myChart=(Chart)findViewById(R.id.chart); //where myChart is an object of type Chart
That throws a ClassCastException.
I decided to experiment a little and instead changed the line to this to see if I still recieved a ClassCastException:
View chart=(View)findViewById(R.id.chart);
This worked fine, which tells me that findViewById has no trouble giving me a View. But it doesn't want to give me a Chart.
As far as the Chart class goes, it's a really simple subclass of View that appears to otherwise work correctly.
public class Chart extends View{
public Chart(Context context) {
super(context);
init();
}
public Chart(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public Chart(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
/* More stuff below like onDraw, onMeasure, setData, etc. */
}
I'm probably just doing something stupid. Do you guys have any ideas? Thanks for your help!
回答1:
Just out of curiosity, is that xml being used in another layout with an <include>
tag?
I had an issue just like this where we were including another xml layout in a viewflipper with
<include layout="@layout/some_layout.xml">
and findviewbyid
was getting the wrong widgets. I had to wrap the whole external layout in <merge></merge>
tags to allow it to merge correctly into the base layout.
Try changing your layout to this, if it's being included.
<?xml version="1.0" encoding="utf-8"?>
<merge>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.TheProject.TheApp.Chart
android:id="@+id/chart"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
</merge>
edit: check out this link about how merge works
回答2:
It is most probably a bug.
Workaround to fix: Use some new 'id' value for the CustomView in Layout XML and findViewById().
回答3:
findViewById will always return the View object. You will only be able to access methods specified in the view class and none of the methods for your Chart class will be accessbile.
If you need to access any of the chart specific methods or data you will need to cast the view object to Chart.
来源:https://stackoverflow.com/questions/7816182/android-classcastexception-upon-retrieving-custom-view