您好我在查看器中遇到一些问题,并且想知道是否有人可以提供帮助。
我有一个SQLite数据库很好,我将小缩略图图像存储为blob。我知道blob正在保存,因为我能够在我的应用程序的另一个区域中检索它们。
现在,我正在尝试使用ViewBinder将数据库中的图像绑定到我的自定义列表视图。 (您可以将其视为联系人管理器的布局,其中我有一个名称和数字列表以及相应的图像。)
我尝试了一些不同的方法,包括使用一个简单的游标适配器,从我的研究看来,创建我自己的视图绑定器似乎是这样做的方法。代码没有错误但是在运行时我得到了ClassCastException。
以下是我的主要列表活动
中的代码 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);
和我的自定义视图绑定器
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)
我的视图活页夹中的第14行是
ImageView image = (ImageView) view;
任何人都可以帮助我理解为什么这会产生一个classCastExeption,因为传递给我的视图绑定器的视图是
ImageView image = (ImageView) findViewById(R.id.list_item_image);
非常感谢任何想法。
答案 0 :(得分:1)
当一个简单的游标适配器试图构建一个视图时,它会检查一个视图绑定器是否可用。如果是这样,它将首先调用setViewValue而不管正在渲染的视图类型。基于此函数返回的值,setViewText或setViewImage调用。在大多数情况下,第一个映射来自SQLiteAdapter.KEY_NAME => R.id.list_item_name,我想它是一个textView.So当它试图渲染时,一个视图绑定器是可用的,所以它在你的视图中用textView.But调用,你既不检查传递的视图类型也不检查coloumn index.U只是将它转换为imageView.So只有ClassCastException来。
答案 1 :(得分:1)
在创建适配器时传递的ViewBinder
(适配器构造函数)数组中声明的每个视图都会调用to
。现在你没有传递ImageView
(通过它的id),因此不会为ViewBinder
调用ImageView
,只会使用ids {{来调用视图1}},R.id.list_item_name
和R.id.list_item_phone
。这就是你得到R.id.list_item_companyname
的原因,因为你错误地认为传递给ClassCastException
的视图是ViewBinder
(这是你犯的另一个错误,因为你没有看到传递给ImageView
的视图的ID,以查看当前哪个视图设置为使用来自ViewBinder
的数据进行绑定。
要解决此问题,您需要让适配器知道您还希望该行中的Cursor
得到绑定(请注意额外的列和ID):
ImageView
然后更改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
此:
@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来设置数据。