问题
I'm building a ListView
with either TextView
s or ImageView
s based on whether or not the item is a text item or has an image associated with it. I used Customizing list shown from SimpleCursorAdapter using VewBinder and it worked great, up to a point.
I have an SQLite database
containing items that all have a title (some text), but not all of them have an image/video as a resource; so some are pure text items while others are images or videos. For the images and videos I want to load a resource, but when the item is a plain text item, I just want to display the title of the image.
So my XML
contains two elements - a TextView
to display the title of the text items, and an ImageView
to display the resource file (for videos I retrieve the YouTube default image for the video id).
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="6dp"
android:background="@android:color/black"
>
<TextView
android:id="@+id/tv_details_title"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_gravity="center"
android:text="TextView"
android:textColor="@android:color/white"
android:visibility="visible"
android:background="@android:color/holo_blue_bright" />
<ImageView
android:id="@+id/iv_details_resource"
android:layout_width="200dp"
android:layout_height="200dp"
android:adjustViewBounds="true"
android:scaleType="centerInside"
android:layout_gravity="center"
android:src="@drawable/logo"
android:visibility="visible"
android:background="@android:color/holo_green_light" />
</LinearLayout>
I'm not using a Content Provider
because I don't need other apps to ever use my database. I use a SimpleCursorAdapter
and have written a CustomViewBinder
(inner) class to bind my data to my view
s based on whether or not there is a resource associated to the item.
The problem is that the visibility of the ImageView
is always set to GONE
no matter what. So the title of each item is displayed, because that is always bound to the TextView
element, but when there is no resource listed in my database (i.e. "null" is in the record in the resource
field), then the ImageView
also disappears.
Here is the code for my CustomViewBinder
:
private class CustomViewBinder implements ViewBinder{
@Override
public boolean setViewValue(View view, Cursor cursor, int columnIndex){
if(columnIndex == cursor.getColumnIndex(DatabaseHelper.FIELD_RESOURCE)){
Log.d("CustomViewBinder", "columnIndex = " + columnIndex);
//If the column is resource, ten we use custom view.
String resource = cursor.getString(columnIndex);
Log.d("CustomViewBinder", "resource = " + resource);
if(resource.equalsIgnoreCase("null")){
Log.d("CustomViewBinder", "Inside if resource = " + resource);
Log.d("CustomViewBinder", "Set the image view to GONE");
view.setVisibility(View.GONE);
}else{
Log.d("CustomViewBinder", "Inside else resource = " + resource);
columnIndex = cursor.getColumnIndex(DatabaseHelper.FIELD_TITLE);
Log.d("CustomViewBinder", "columnIndex = " + columnIndex);
//If the column is resource, ten we use custom view.
String title = cursor.getString(columnIndex);
Log.d("CustomViewBinder", "title = " + title);
if(!resource.equalsIgnoreCase("null")){
Log.d("CustomViewBinder", "Set the title view to GONE");
view.setVisibility(View.GONE);
}
return true;
}
return true;
}
return false;
}
And then some logs for clarity:
07-26 17:05:36.343: D/CustomViewBinder(9735): columnIndex = 4
07-26 17:05:36.343: D/CustomViewBinder(9735): resource = null
07-26 17:05:36.343: D/CustomViewBinder(9735): Inside if resource = null
07-26 17:05:36.343: D/CustomViewBinder(9735): Set the image view to GONE
07-26 17:05:36.353: D/CustomViewBinder(9735): columnIndex = 4
07-26 17:05:36.353: D/CustomViewBinder(9735): resource = null
07-26 17:05:36.353: D/CustomViewBinder(9735): Inside if resource = null
07-26 17:05:36.353: D/CustomViewBinder(9735): Set the image view to GONE
07-26 17:05:36.363: D/CustomViewBinder(9735): columnIndex = 4
07-26 17:05:36.363: D/CustomViewBinder(9735): resource = null
07-26 17:05:36.363: D/CustomViewBinder(9735): Inside if resource = null
07-26 17:05:36.363: D/CustomViewBinder(9735): Set the image view to GONE
07-26 17:05:53.770: D/CustomViewBinder(9735): columnIndex = 4
07-26 17:05:53.770: D/CustomViewBinder(9735): resource = Notes_Box_2_Notebook_1_006.jpg
07-26 17:05:53.770: D/CustomViewBinder(9735): Inside else resource = Notes_Box_2_Notebook_1_006.jpg
07-26 17:05:53.770: D/CustomViewBinder(9735): columnIndex = 2
07-26 17:05:53.770: D/CustomViewBinder(9735): title = Notebook page - man and wife
07-26 17:05:53.770: D/CustomViewBinder(9735): Set the title view to GONE
07-26 17:05:54.310: D/CustomViewBinder(9735): columnIndex = 4
07-26 17:05:54.310: D/CustomViewBinder(9735): resource = null
07-26 17:05:54.310: D/CustomViewBinder(9735): Inside if resource = null
07-26 17:05:54.310: D/CustomViewBinder(9735): Set the image view to GONE
The problem is that at "Set the title view to GONE
" the "image view
" is still set to GONE
so the image "Notes_Box_2_Notebook_1_006.jpg
" is not displayed - it's title is.
This is becase the "view
" of the CustomViewBinder
seems to always be the ImageView
in my XML
rather than ever being the TextView
.
How do I access "another" view
in the CustomViewBinder
?
回答1:
I used the ViewHolder pattern.
I implemented it by having a Cursor
extended class. In my main activity I get the cursor from my database helper class which queries the database. Then I link my CustomCursorAdapter
to a horizontal listview which holds three items - a TextView
and two ImageView
s. I then have an OnItemClickListener
set to my horizontal listview
. You can then filter on something, but I just updated a main view
above my horizontal listview
(much like in the linked tutorial).
In my CustomCursorAdapter
's getView
function I define a ViewHolder
, move the cursor to the position (from getView's parameters), andt hen do what is done in almost every example of the getView
function, so here it is:
@Override
public View getView(int position, View convertView, ViewGroup parent){
ViewHolder holder = null;
cursor.moveToPosition(position);
if(convertView == null){
convertView = inflater.inflate(R.layout.activity_media_items, null);
holder = new ViewHolder();
holder.textview = (TextView) convertView.findViewById(R.id.tv_details_title);
holder.imageview = (ImageView) convertView.findViewById(R.id.iv_details_resource_image);
holder.imageviewvideo = (ImageView) convertView.findViewById(R.id.iv_details_resource_video);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
//////////////////////////TYPE
type = cursor.getString(cursor.getColumnIndex(DatabaseHelper.FIELD_ITEM_TYPE));
itemId = cursor.getString(cursor.getColumnIndex(DatabaseHelper.FIELD_MEDIA_ITEM_ID));
if(type.equalsIgnoreCase("text")){
//////////////////////////TEXT
String title = cursor.getString(cursor.getColumnIndex(DatabaseHelper.FIELD_TRANSCRIPTION));
title = title.subSequence(0, 150) + "...";
holder.textview.setText(title);
holder.textview.setVisibility(View.VISIBLE);
holder.imageview.setVisibility(View.GONE);
holder.imageviewvideo.setVisibility(View.GONE);
}
if(type.equalsIgnoreCase("image")){
//////////////////////////IMAGE
String imageUri = "assets://";
Log.d(TAG, "URI = " + imageUri + fileName);
ImageLoader.getInstance().displayImage(imageUri+fileName, holder.imageview);
holder.textview.setVisibility(View.GONE);
holder.imageview.setVisibility(View.VISIBLE);
holder.imageviewvideo.setVisibility(View.GONE);
}
if(type.equalsIgnoreCase("video")){
//////////////////////////VIDEO
//get the file name
String fileName = cursor.getString(cursor.getColumnIndex(DatabaseHelper.FIELD_RESOURCE));
//get the image of a youtube video because it's a video
try {
Log.d(TAG,"Want to show video at -> http://img.youtube.com/vi/"+fileName+"/mqdefault.jpg");
ImageLoader.getInstance().displayImage("http://img.youtube.com/vi/"+fileName+"/mqdefault.jpg", holder.imageviewvideo);
} catch(Exception e) {
Log.d("YouTube photo", "Failed to load photo!!! "+e.toString());
}
holder.textview.setVisibility(View.GONE);
holder.imageview.setVisibility(View.GONE);
holder.imageviewvideo.setVisibility(View.VISIBLE);
}
return convertView;
}
来源:https://stackoverflow.com/questions/17885047/customizing-list-shown-from-simplecursoradapter-using-viewbinder