android - 查看 Binder 和 ClassCastException

标签 android android-listview android-viewbinder

您好,我在取景器方面遇到了一些问题,想知道是否有人可以提供帮助。

我有一个很好的 SQLite 数据库,并且将小缩略图作为 blob 存储在其中。我知道这些 blob 正在被保存,因为我可以在应用程序的另一个区域中检索它们。

现在,我尝试使用 ViewBinder 将数据库中的图像绑定(bind)到我的自定义 ListView 。 (您可以将其视为联系人管理器的布局,其中我有一个带有相应图像的姓名和号码列表。)

我尝试了几种不同的方法,包括使用简单的光标适配器,从我的研究来看,创建我自己的 View 绑定(bind)器似乎是做到这一点的方法。代码没有错误,但在运行时我收到 ClassCastException。

下面是我的主列表 Activity 的代码

  listViewCards = (ListView) findViewById(android.R.id.list); 
    Cursor cursor = dbhelper.getAllContacts();



    SimpleCursorAdapter myAdapter = new SimpleCursorAdapter(
        getApplicationContext(), 
        R.layout.listview_each_item, 
        cursor, 
        new String[] { SQLiteAdapter.KEY_NAME,SQLiteAdapter.KEY_PHONE, SQLiteAdapter.KEY_COMPANYNAME}, 
        new int[] { R.id.list_item_name,R.id.list_item_phone, R.id.list_item_companyname  },0);

    ImageView image = (ImageView) findViewById(R.id.list_item_image);
    MyViewBinder mvb = new MyViewBinder();
    mvb.setViewValue(image, cursor, cursor.getColumnIndex(SQLiteAdapter.KEY_IMAGE));
    myAdapter.setViewBinder(mvb);
    listViewCards.setAdapter(myAdapter);

以及我的自定义 View Binder

 public class MyViewBinder implements ViewBinder{

@Override
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
    ImageView image = (ImageView) view;
    cursor.moveToFirst();
    byte[] byteArray = cursor.getBlob(columnIndex);
    if(image !=null){
    image.setImageBitmap(BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length));
    return false;
    }
    return true;
}

现在是 logcat

08-14 11:01:15.275: E/AndroidRuntime(2669): FATAL EXCEPTION: main
08-14 11:01:15.275: E/AndroidRuntime(2669): java.lang.ClassCastException: android.widget.TextView cannot be cast to android.widget.ImageView
08-14 11:01:15.275: E/AndroidRuntime(2669):     at          com .example.npacards.MyViewBinder.setViewValue(MyViewBinder.java:14)
08-14 11:01:15.275: E/AndroidRuntime(2669):     at android.widget.SimpleCursorAdapter.bindView(SimpleCursorAdapter.java:146)
08-14 11:01:15.275: E/AndroidRuntime(2669):     at android.widget.CursorAdapter.getView(CursorAdapter.java:250)
08-14 11:01:15.275: E/AndroidRuntime(2669):     at android.widget.AbsListView.obtainView(AbsListView.java:2457)
08-14 11:01:15.275: E/AndroidRuntime(2669):     at android.widget.ListView.measureHeightOfChildren(ListView.java:1250)
08-14 11:01:15.275: E/AndroidRuntime(2669):     at android.widget.ListView.onMeasure(ListView.java:1162)
08-14 11:01:15.275: E/AndroidRuntime(2669):     at android.view.View.measure(View.java:15473)
08-14 11:01:15.275: E/AndroidRuntime(2669):     at android.widget.RelativeLayout.measureChild(RelativeLayout.java:602)
08-14 11:01:15.275: E/AndroidRuntime(2669):     at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:415)

我的 View Binder 中的第 14 行是

    ImageView image = (ImageView) view; 

任何人都可以帮助我理解为什么这会产生 classCastExeption 因为传递到我的 View 绑定(bind)器的 View 是

  ImageView image = (ImageView) findViewById(R.id.list_item_image);

非常感谢任何想法。

最佳答案

对于创建适配器时传递的 to(适配器的构造函数)数组中声明的每个 View ,都会调用 ViewBinder 。现在你没有传递ImageView(通过它的id),所以ViewBinder不会被ImageView调用,它只会得到调用 ID 为 R.id.list_item_nameR.id.list_item_phoneR.id.list_item_companyname 的 View 。这就是为什么你会得到ClassCastException,因为你错误地认为传递给ViewBinder的 View 是ImageView(这是你犯的另一个错误,因为您不会查看传递给 ViewBinder 的 View id 来了解此时设置哪个 View 与来自 Cursor 的数据绑定(bind))。

要解决这个问题,您需要让适配器知道您还希望绑定(bind)行中的 ImageView(注意额外的列和 id):

SimpleCursorAdapter myAdapter = new SimpleCursorAdapter(
        getApplicationContext(), 
        R.layout.listview_each_item, 
        cursor, 
        new String[] { SQLiteAdapter.KEY_NAME,SQLiteAdapter.KEY_PHONE, SQLiteAdapter.KEY_COMPANYNAME, SQLiteAdapter.KEY_IMAGE}, 
        new int[] { R.id.list_item_name,R.id.list_item_phone, R.id.list_item_companyname,  R.id.list_item_image},0);

然后更改 ViewBinder 来处理设置图像,让适配器自行绑定(bind)其他 View :

@Override
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
    if (view.getId() == R.id.list_item_image) { // we have our ImageView so bind the image
        byte[] byteArray = cursor.getBlob(columnIndex);
        ((ImageView)view).setImageBitmap(BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length));
        return true; // return true to let the adapter know that we handled this view on our own
    }
    return false; // return false for any other view so the adapter will bind the data on its own
}

这个:

mvb.setViewValue(image, cursor, cursor.getColumnIndex(SQLiteAdapter.KEY_IMAGE));

不正确。您无需自行调用 setViewValue(),适配器将在 getView() 方法中为每个具有来自 id 的 View 调用它。到数组来设置它们的数据。

关于android - 查看 Binder 和 ClassCastException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18229007/

相关文章:

android - 如何在 Android 中用手指手势交换 Imageview 和 TextView

android - 如何使用 Listview 访问多个 JSONArray?

android - 如何让我的 ListView 项目具有(并保持)不同的背景?

android - ListView 的内容占用大量内存

android - Android 上的 WebView 问题

android - 一个本地容器(.apk),可以将 html 文件作为应用程序加载到设备中

android - 无法使用 Android Paging 库加载下一个数据

android - 在 fragment 中调用 getTag() 时总是返回 null

java - 应用带有 View 的选项卡而不是单独的 Activity

android - 给 ListView 的 TextView 添加标签?