Last active
July 25, 2023 05:49
-
-
Save JakeWharton/5423616 to your computer and use it in GitHub Desktop.
An adapter base class that uses a new/bind pattern for its views.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Apache 2.0 licensed. | |
import android.content.Context; | |
import android.view.LayoutInflater; | |
import android.view.View; | |
import android.view.ViewGroup; | |
import android.widget.BaseAdapter; | |
/** An implementation of {@link BaseAdapter} which uses the new/bind pattern for its views. */ | |
public abstract class BindableAdapter<T> extends BaseAdapter { | |
private final Context context; | |
private final LayoutInflater inflater; | |
public BindableAdapter(Context context) { | |
this.context = context; | |
this.inflater = LayoutInflater.from(context); | |
} | |
public Context getContext() { | |
return context; | |
} | |
@Override public abstract T getItem(int position); | |
@Override public final View getView(int position, View view, ViewGroup container) { | |
if (view == null) { | |
view = newView(inflater, position, container); | |
if (view == null) { | |
throw new IllegalStateException("newView result must not be null."); | |
} | |
} | |
bindView(getItem(position), position, view); | |
return view; | |
} | |
/** Create a new instance of a view for the specified position. */ | |
public abstract View newView(LayoutInflater inflater, int position, ViewGroup container); | |
/** Bind the data for the specified {@code position} to the view. */ | |
public abstract void bindView(T item, int position, View view); | |
@Override public final View getDropDownView(int position, View view, ViewGroup container) { | |
if (view == null) { | |
view = newDropDownView(inflater, position, container); | |
if (view == null) { | |
throw new IllegalStateException("newDropDownView result must not be null."); | |
} | |
} | |
bindDropDownView(getItem(position), position, view); | |
return view; | |
} | |
/** Create a new instance of a drop-down view for the specified position. */ | |
public View newDropDownView(LayoutInflater inflater, int position, ViewGroup container) { | |
return newView(inflater, position, container); | |
} | |
/** Bind the data for the specified {@code position} to the drop-down view. */ | |
public void bindDropDownView(T item, int position, View view) { | |
bindView(item, position, view); | |
} | |
} |
For the common scenario where there is a single view type the following is slightly more convenient:
https://gist.github.com/ManuelPeinado/5424997
@ManuelPeinado Just ignore the type
argument if you only have one view type.
Take the 50th star :) I've never understood how does the presence of reference to a context in the adapter not make a leak of memory.
@AlexBonel A leak implies that it exists outside of the scope of its intended existence. The component that owns the BaseAdapter
should be the Context
(or owned by something that is the Context
, a Fragment
for example). In which case, the BaseAdapter
can never have the Context
when the Context
is not to be had anymore, specifically because the BaseAdapter
won't exist by that time.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I like to name
convertView
asreusableView
, since that states it purpose a little clearer to me (think that comes from iOS TableView)