Jelmer Brands
Jelmer Brands

Reputation: 302

Android use Data Binding Library with CursorAdapter

I want to use the Android Data Binding Library with a ListView populated by a custom CursorAdapter, but I can't figure out how to get it work. I seems such a simple thing to achieve.

This is what I have now:

public class PlayCursorAdapter extends CursorAdapter {
    private List<Play> mPlays;

    PlayCursorAdapter(Context context, Cursor cursor) {
        super(context, cursor, 0);
        mPlays = new ArrayList<>();
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        ListItemPlayBinding binding = ListItemPlayBinding.inflate(LayoutInflater.from(context), parent, false);
        Play play = new Play();
        binding.setPlay(play);
        mPlays.add(play);
        return binding.getRoot();
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        int timeIndex = cursor.getColumnIndexOrThrow(PlayEntry.COLUMN_TIME);
        ...

        long time = cursor.getLong(timeIndex);
        ...

        Play play = mPlays.get(cursor.getPosition());

        play.setTime(time);
        ...
    }
}

Current behaviour:
When I run this code and I scroll down in the list I get a IndexOutOfBoundsException on the mPlays list.

Desired behaviour:
I want to populate a ListView with data from a ContentProvider using the Data Binding Library and a CursorAdapter. Is it even possible to use the Data Binding Library with a CursorAdapter? Or do you recommend to always use a RecyclerView and a RecyclerView.Adapter?

Upvotes: 1

Views: 661

Answers (1)

George Mount
George Mount

Reputation: 20926

You should be able to avoid the problem by eliminating the mPlays list:

public class PlayCursorAdapter extends CursorAdapter {
    PlayCursorAdapter(Context context, Cursor cursor) {
        super(context, cursor, 0);
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        ListItemPlayBinding binding = ListItemPlayBinding.inflate(LayoutInflater.from(context), parent, false);
        Play play = new Play();
        binding.setPlay(play);
        return binding.getRoot();
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        int timeIndex = cursor.getColumnIndexOrThrow(PlayEntry.COLUMN_TIME);
        ...

        long time = cursor.getLong(timeIndex);
        ...
        ListItemPlayBinding binding = DataBindingUtil.getBinding(view);
        Play play = binding.getPlay();

        play.setTime(time);
        ...
    }
}

This assumes you don't just want to instantiate a new Play each time you bindView().

Upvotes: 1

Related Questions