Customizing list shown from SimpleCursorAdapter using ViewBinder

主宰稳场 提交于 2019-12-25 10:51:08

问题


I'm building a ListView with either TextViews or ImageViews 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 views 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 ImageViews. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!