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;
    }
}
General Grievance
  • 4,555
  • 31
  • 31
  • 45
Himanshu Verma
  • 111
  • 1
  • 3
  • 9

2 Answers2

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));

            }

    }
Bobbake4
  • 24,509
  • 9
  • 59
  • 94
  • I am able to get data in list view but only first row data is appearing in all rows.Check my updated question. – Himanshu Verma Jul 17 '13 at 20:14
  • 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. – Bobbake4 Jul 17 '13 at 20:20
  • You are also printing the index of the columns not the actual data stored in the cursor. – Bobbake4 Jul 17 '13 at 20:22
  • 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. – Himanshu Verma Jul 17 '13 at 20:28
  • 3
    Sometimes I feel that stackoverflow is part of the official Android documentation... – kouretinho Sep 23 '14 at 13:45
  • `@Override public View newView(Context ctx, Cursor cursor, ViewGroup parent) { return inflater.inflate(layout, parent, false); }` worked better for me. – Joaquin Iurchuk Mar 12 '15 at 17:59
  • That is a good idea, supplying the parent allows it to use the layout parameters during inflation. – Bobbake4 Mar 12 '15 at 19:32
  • You have not specify the layout view,how can you find view by those specified widget `ids`? – zionpi Jun 26 '15 at 02:34
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;
}
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
zek
  • 55
  • 1
  • 1
  • 9