开发者

Custom SimpleCursorAdapter with multiple row views

I am new to programming with java and android. So my project has been a huge learning experience. I am using a cursorloader that retrieves data from a database and then assign that data to the custom adapter. What I am trying to do is take that data and based on what that data is, assign it to a certain row layout.

There will be around 6-12 different layouts. The data contains different types of devices, e.g. light, dimmer, thermostat, etc. Each type of device is associated with a category number. A light would have a category of 3 and a dimmer a category number of 2. I want to check that category and depending on the number, assign it to a certain row layout. How would one go about doing this? I am trying to create a custom simplecursoradapter. This is what I have so far, however it crashes.

public class DeviceAdapter extends SimpleCursorAdapter {
    private LayoutInflater mInflater;
    private ViewHolder holder;
    private LightViewHolder lightholder;
    private TempViewHolder tempholder;

    public DeviceAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
        super(context, layout, c, from, to);
        this.mInflater = LayoutInflater.from(context);
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {

        if (cursor.getString(4).equals("17")) {;
            tempholder = (TempViewHolder)view.getTag();
            tempholder.name.setText(cursor.getString(1));
            tempholder.temp.setText(cursor.getString(10));
            tempholder.tempImage.setImageResource(R.drawable.thermometer);
        } else if (cursor.getString(4).equals("3")) {
            lightholder = (LightViewHolder)view.getTag();
            lightholder.name.setText(cursor.getString(1));
            lightholder.status.setText(cursor.getString(10));
            lightholder.lightImage.setImageResource(R.drawable.light_on);
        } else {
            holder = (ViewHolder)view.getTag();
            holder.name.setText(cursor.getString(1));
            holder.status.setText(cursor.getString(2));
        }
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        if (cursor.getString(4).equals("17")) {
            View view = mInflater.inflate(R.layout.temperature_device_list_item, null); 
            tempholder = new TempViewHolder();
            tempholder.name = (TextView)view.findViewById(R.id.devicename);
            tempholder.temp = (TextView)view.findViewById(R.id.temp);
            tempholder.tempImage = (ImageView)view.findViewById(R.id.tempImage);
            view.setTag(tempholder);
            return view;
        } else if (cursor.getString(4).equals("3")) {
            View view = mInflater.inflate(R.layout.light_list_item, null); 
            lightholder = new LightViewHolder();
            lightholder.name = (TextView)view.findViewById(R.id.devicename);
            lightholder.status = (TextView)view.findViewById(R.id.status);
            lightholder.lightImage = (ImageView)view.findViewById(R.id.deviceImage);
            view.setTag(lightholder);
            return view;
        } else {
            View view = mInflater.inflate(R.layout.device_list_item, null); 
            holder = new ViewHolder();
            holder.name = (TextView)view.findViewById(R.id.devicename);
            holder.status = (TextView)view.findViewById(R.id.status);
            view.setTag(holder);
            return view;
        }
    }


    private static class LightViewHolder {
        TextView name;
        TextView status;
        ImageView lightImage;
    }

    private static class TempViewHolder {
        TextView name;
        TextView temp;
        ImageView tempImage;
    }

    private static class ViewHolder {
        TextView name;
        TextView status;
    }

}

Does this look right? bare in mind I am new to all of this and it has been hard trying to find some good examples. Most code examples are calling getView and I read that you should use bindView and newView.

My application has a fragment of rooms and a fragment that contains the list of devices. The crash happens when I click one room, the list will display the devices. If I go and click a different room, the application will crash and I get the following:

08-17 03:41:07.033: ERROR/AndroidRuntime(7210): FATAL EXCEPTION: main
08-17 03:41:07.033: ERROR/AndroidRuntime(7210): java.lang.ClassCastException: com.garrettpower.powerha.listadapters.listview.DeviceAdapter$LightViewHolder cannot be cast to com.garrettpower.powerha.listadapters.listview.DeviceAdapter$ViewHolder
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at com.garrettpower.powerha.listadapters.listview.DeviceAdapter.bindView(DeviceAdapter.java:42)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at android.widget.CursorAdapter.getView(CursorAdapter.java:251)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at android.widget.AbsListView.obtainView(AbsListView.java:1949)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at android.widget.ListView.makeAndAddView(ListView.java:1756)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at android.widget.ListView.fillSpecific(ListView.java:1302)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at android.widget.ListView.layoutChildren(ListView.java:1587)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at android.widget.AbsListView.onLayout(AbsListView.java:1800)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at android.view.View.layout(View.java:9588)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at android.view.ViewGroup.layout(ViewGroup.java:3877)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at android.widget.RelativeLayout.onLayout(RelativeLayout.java:912)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at android.view.View.layout(View.java:9588)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at android.view.ViewGroup.layout(ViewGroup.java:3877)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at android.widget.RelativeLayout.onLayout(RelativeLayout.java:912)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at android.view.View.layout(View.java:9588)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at android.view.ViewGroup.layout(ViewGroup.java:3877)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at android.widget.RelativeLayout.onLayout(RelativeLayout.java:912)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at android.view.View.layout(View.java:9588)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at android.view.ViewGroup.layout(ViewGroup.java:3877)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at android.widget.RelativeLayout.onLayout(RelativeLayout.java:912)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at android.view.View.layout(View.java:9588)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at android.view.ViewGroup.layout(ViewGroup.java:3877)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at android.widget.FrameLayout.onLayout(FrameLayout.java:400)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at android.view.View.layout(View.java:9588)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at android.view.ViewGroup.layout(ViewGroup.java:3877)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1542)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1403)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at android.widget.LinearLayout.onLayout(LinearLayout.java:1314)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at android.view.View.layout(View.java:9588)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at android.view.ViewGroup.layout(ViewGroup.java:3877)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at android.widget.FrameLayout.onLayout(FrameLayout.java:400)
08-17 03:41:07开发者_StackOverflow中文版.033: ERROR/AndroidRuntime(7210):     at android.view.View.layout(View.java:9588)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at android.view.ViewGroup.layout(ViewGroup.java:3877)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at android.view.ViewRoot.performTraversals(ViewRoot.java:1288)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at android.view.ViewRoot.handleMessage(ViewRoot.java:2046)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at android.os.Handler.dispatchMessage(Handler.java:99)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at android.os.Looper.loop(Looper.java:132)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at android.app.ActivityThread.main(ActivityThread.java:4123)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at java.lang.reflect.Method.invokeNative(Native Method)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at java.lang.reflect.Method.invoke(Method.java:491)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
08-17 03:41:07.033: ERROR/AndroidRuntime(7210):     at dalvik.system.NativeStart.main(Native Method)


I know this is pretty old but in case anyone comes across this from Google or something.

The problem was that bindView tried to cast a TempViewHolder to a ViewHolder -- both of these are custom inner classes defined in the adapter, and because they are different they cannot be cast from one to the other.

It's important to never assume a ListView is giving you the same view type in the convertView as the one you need.

At least that's what the stack trace shows. There may be other problems but fixing that would reveal the next issue.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜