GetView Vs. BindView in a custom CursorAdapter?
Asked Answered
P

3

53

So, I'm watching this video http://www.youtube.com/watch?v=N6YdwzAvwOA and Romain Guy is showing how to make more efficient UI adapter code using the getView() method. Does this apply to CursorAdapters as well? I'm currently using bindView() and newView() for my custom cursor adapters. Should I be using getView instead?

Phonology answered 20/8, 2010 at 21:39 Comment(0)
C
72

CursorAdapter has an implementation of getView() that delegates to newView() and bindView(), in such a way as enforces the row recycling pattern. Hence, you do not need to do anything special with a CursorAdapter for row recycling if you are overriding newView() and bindView().

Chrestomathy answered 20/8, 2010 at 21:51 Comment(12)
How would I apply the ViewHolder pattern? Would I split it between newView() and bindView() ?Phonology
@Scienceprodigy: In newView(), you would create the ViewHolder for the row and associate it with setTag(). In bindView(), you would retrieve the ViewHolder via getTag().Chrestomathy
Thanks, that works. I'm having a bit of trouble with the recycling of the views though, because I have list items that have a header that is GONE by default, which I use to display dated sections. Everything shows up fine until I fling the list up or down, then there's headers showing up where they shouldn't be.Phonology
@Scienceprodigy: If you have 2+ types of rows, you need to override getViewTypeCount() and getItemViewType().Chrestomathy
@ComonsWare: I did that. But getItemViewType is always called after getView. The result is that getViews gets a wrong convertView when the viewtype changes. Any idea?Teasel
@Christian13467: I really recommend that you open a new question rather than commenting on an 18-month-old answer. That being said, if you are saying that you are changing the view type of a position, that's unlikely to work well without forcing a full reload of the AdapterView.Chrestomathy
What do you suggest when there's need to know item's view position in adapterview, for example in gridview or listview? getView provides position as method's argument so we can handle views based on that also. For example, if I want third element to be blank/empty element or if I have some kind of logic which is responsible for determination of view's content.Tinfoil
It really helped me, i had a similar issue with a SimpleCursorAdapter, understanding this i could write a switch implementation affordable for my app, THANKS!!!Monochromat
how to use notifyDataSetChanged() in this wayMande
If CursorAdapter recycles rows, does that mean we don't need to implement the ViewHolder pattern?Richers
@IgorGanapolsky: The ViewHolder pattern, should you choose to use it, is relevant for all adapters. ArrayAdapter also recycles rows, for example.Chrestomathy
@Chrestomathy Is this question related to my question?Kosey
H
19
/**
     * @see android.widget.ListAdapter#getView(int, View, ViewGroup)
     */
    public View getView(int position, View convertView, ViewGroup parent) {
        if (!mDataValid) {
            throw new IllegalStateException("this should only be called when the cursor is valid");
        }
        if (!mCursor.moveToPosition(position)) {
            throw new IllegalStateException("couldn't move cursor to position " + position);
        }
        View v;
        if (convertView == null) {
            v = newView(mContext, mCursor, parent);
        } else {
            v = convertView;
        }
        bindView(v, mContext, mCursor);
        return v;
    }

This CursorAdapter source code, clearly cursorAdapter work more.

Headship answered 16/7, 2012 at 14:52 Comment(0)
C
2

The CursorAdapter implementation is different from sub-classing regular adapters like BaseAdapter, you don't need to override getView(), getCount(), getItemId() because that information can be retrieved from the cursor itself.

Given a Cursor, you only need to override two methods to create a CursorAdapter subclass:

bindView() : Given a view, update it to display the data in the provided cursor.

newView() : This gets called to consctruct a new view that goes into the the list.

The CursorAdapter will take care of recycling views (unlike the getView() method on regular Adapter). It doesn't call the newView() each time it needs a new row. If it already has a View(not null), it will directly call the bindView(), this way, the created view is reused. By splitting the creation and population of each view into these two methods, the CursorAdapter achieves view reuse where as, in regular adapters, both these things are done in getView() method.

Casuistry answered 30/4, 2016 at 16:14 Comment(1)
Thank you, very helpful.Sacramentalist

© 2022 - 2024 — McMap. All rights reserved.