Using custom simpleCursorAdapter
Asked Answered
T

2

5

I am trying to access a list-activity using custom adapter.I have tried it directly without using any custom adapter it was working good but because I want to add more functions in list-view I want to implement a custom adapter.Now I have tried it but I am getting an empty list-view with no data visible. List-Activity

public class MainActivity extends ListActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0";

         String[] projection = {
                    MediaStore.Audio.Media._ID,
                    MediaStore.Audio.Media.ARTIST,
                    MediaStore.Audio.Media.TITLE,
                    MediaStore.Audio.Media.DATA,
                    MediaStore.Audio.Media.DISPLAY_NAME,
                    MediaStore.Audio.Media.DURATION,

            };
            //query 

            musiccursor = this.managedQuery(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,projection,selection,null,sortOrder);
            music_column_index = musiccursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);


            int a[]= new int[]{R.id.TitleSong,R.id.Artist};


            Custom_Adapter adapter = new Custom_Adapter(this,R.layout.music_items, musiccursor, new String[]{MediaStore.Audio.Media.TITLE,MediaStore.Audio.Media.ARTIST} ,a);

            this.setAdapter(adapter);

            }
    }

Custom-Adapter

    public class Custom_Adapter extends SimpleCursorAdapter {


    private Context mContext;
    private Context appContext;
    private int layout;
    private Cursor cr;
    private final LayoutInflater inflater;

    public Custom_Adapter(Context context,int layout, Cursor c,String[] from,int[] to) {
        super(context,layout,c,from,to);
        this.layout=layout;
        this.mContext = context;
        this.inflater=LayoutInflater.from(context);
        this.cr=c;
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        // TODO Auto-generated method stub
        super.bindView(view, context, cursor);
     view=inflater.inflate(layout, null, false);
        TextView titleS=(TextView)view.findViewById(R.id.TitleSong);
        TextView artistS=(TextView)view.findViewById(R.id.Artist);
        int Title_index;
        int Artist_index;
        cursor.moveToFirst();
        while(cursor.isLast()){

            Title_index=cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME);
            Artist_index=cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST);
            titleS.setText(cursor.getString(Title_index));
            artistS.setText(cursor.getString(Artist_index));
            cr.moveToNext();
            }

    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub

        return convertView;
    }
}
Telethermometer answered 17/7, 2013 at 19:51 Comment(0)
C
13

When extending a cursor adapter you should override the methods bindView and newView. The bindView method is used to bind all data to a given view such as setting the text on a TextView. The newView method is used to inflate a new view and return it, you don't bind any data to the view at this point. Most adapters use the getView function but when extending a cursor adapter you should use bindView and newView.

    public class Custom_Adapter extends SimpleCursorAdapter {

            private Context mContext;
            private Context appContext;
            private int layout;
            private Cursor cr;
            private final LayoutInflater inflater;

            public Custom_Adapter(Context context,int layout, Cursor c,String[] from,int[] to) {
                super(context,layout,c,from,to);
                this.layout=layout;
                this.mContext = context;
                this.inflater=LayoutInflater.from(context);
                this.cr=c;
            }

            @Override
            public View newView (Context context, Cursor cursor, ViewGroup parent) {
                    return inflater.inflate(layout, null);
            }

            @Override
            public void bindView(View view, Context context, Cursor cursor) {
                super.bindView(view, context, cursor);
                TextView titleS=(TextView)view.findViewById(R.id.TitleSong);
                TextView artistS=(TextView)view.findViewById(R.id.Artist);

                int Title_index=cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME);
                int Artist_index=cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST);

                titleS.setText(cursor.getString(Title_index));
                artistS.setText(cursor.getString(Artist_index));

            }

    }
Concentrated answered 17/7, 2013 at 20:8 Comment(8)
I am able to get data in list view but only first row data is appearing in all rows.Check my updated question.Telethermometer
I'm a bit confused what you changed but you should switch to the two methods I mentioned above. Either way I think the problem you are experiencing is you're not moving the cursor index. You should call cr.moveToPosition(position) before you pull data out of the cursor. Switch the the newView bindView methods to reduce the need to inflate new views as you're not checking if convertView is null and reusing it.Concentrated
You are also printing the index of the columns not the actual data stored in the cursor.Concentrated
I have edited question but I am getting a listview with no text written but when I am clicking on them I am able to play songs.Telethermometer
Sometimes I feel that stackoverflow is part of the official Android documentation...Isthmian
@Override public View newView(Context ctx, Cursor cursor, ViewGroup parent) { return inflater.inflate(layout, parent, false); } worked better for me.Empyreal
That is a good idea, supplying the parent allows it to use the layout parameters during inflation.Concentrated
You have not specify the layout view,how can you find view by those specified widget ids?Tegan
C
1

you better write these lines of code in your customadapter getview function. It work for me and will work for you, it's simple.

if (convertView == null) {
    music_column_index = myCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME);
    myCursor.moveToPosition(position);
    id = myCursor.getString(music_column_index);
    music_column_index = myCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE);
    myCursor.moveToPosition(position);
    id += " Size(KB):" + myCursor.getString(music_column_index);
    Log.d("TAG", "id::" + id);
    tv.setText(id);
} else
    tv = (TextView) convertView;
    return tv;
}
Cryosurgery answered 22/4, 2014 at 6:37 Comment(1)
Mmm, I can't see how clean this solution isEmpyreal

© 2022 - 2024 — McMap. All rights reserved.