首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >视图绑定器与ClassCastException

视图绑定器与ClassCastException
EN

Stack Overflow用户
提问于 2013-08-14 10:15:54
回答 2查看 859关注 0票数 2

嗨,我在查看器上遇到了一些问题,想知道是否有人能帮忙。

我有一个SQLite数据库,这是很好的,并将小缩略图图像存储在它作为小块。我知道blobs正在被保存,因为我能够在我的应用程序的另一个区域中检索它们。

现在,我试图使用ViewBinder将数据库中的图像绑定到我的自定义列表视图。(您可以将其看作是联系人管理器的某种布局,其中我有一个有相应图像的姓名和数字列表。)

我尝试了几种不同的方法,包括使用简单的游标适配器,从我的研究来看,创建自己的视图绑定似乎是实现它的方法。代码没有错误,但是在运行时我得到了一个ClassCastException。

下面是我的主要列表活动的代码

代码语言:javascript
复制
  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);

还有我的定制视图活页夹

代码语言:javascript
复制
 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;
}

现在这只小猫

代码语言:javascript
复制
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)

在我的视图中,绑定程序的第14行是

代码语言:javascript
复制
    ImageView image = (ImageView) view; 

有谁能帮助我理解为什么这会产生一个classCastExeption,因为要传递给我的视图绑定程序的视图是

代码语言:javascript
复制
  ImageView image = (ImageView) findViewById(R.id.list_item_image);

任何想法都是非常感谢的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-08-14 11:08:24

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

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

代码语言:javascript
复制
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以处理设置映像,让适配器自己绑定其他视图:

代码语言:javascript
复制
@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
}

这是:

代码语言:javascript
复制
mvb.setViewValue(image, cursor, cursor.getColumnIndex(SQLiteAdapter.KEY_IMAGE));

是不正确的。如果不单独调用setViewValue(),适配器将在getView()方法中对每个视图调用to数组中的ids来设置它们上的数据。

票数 1
EN

Stack Overflow用户

发布于 2013-08-14 10:55:58

当一个简单的游标适配器试图构建一个视图时,它会检查视图绑定器是否是available.If,因此它首先调用setViewValue,而不管这个函数返回的值的视图类型是rendered.Based,setViewText或setViewImage是called.In ur的情况,第一个映射来自SQLiteAdapter.KEY_NAME => R.id.list_item_name,我认为它在尝试呈现时是一个textView.So,视图绑定器是可用的,因此在视图绑定器中使用textView.But调用它,您既不检查传递的视图类型,也不检查coloumindex.u只需将其转换为imageView.So,只有ClassCastException出现。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18229007

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档