This article directory
Source code of several important classes
The following is the source code of Android 6.0 version.
/frameworks/base/core/java/android/widget/Adapter.java
Adapter.java
public interface Adapter {
...
int getCount();
Object getItem(int position);
View getView(int position, View convertView, ViewGroup parent);
boolean isEmpty();
...
}
ListAdapter.java
/frameworks/base/core/java/android/widget/ListAdapter.java
public interface ListAdapter extends Adapter {
public boolean areAllItemsEnabled();
boolean isEnabled(int position);
}
BaseAdapter.java
/frameworks/base/core/java/android/widget/BaseAdapter.java
public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter {
private final DataSetObservable mDataSetObservable = new DataSetObservable();
...
public void registerDataSetObserver(DataSetObserver observer) {
mDataSetObservable.registerObserver(observer);
}
public void unregisterDataSetObserver(DataSetObserver observer) {
mDataSetObservable.unregisterObserver(observer);
}
public void notifyDataSetChanged() {
mDataSetObservable.notifyChanged();
}
...
public boolean isEnabled(int position) {
return true;
}
...
public int getViewTypeCount() {
return 1;
}
public boolean isEmpty() {
return getCount() == 0;
}
}
ArrayAdpater.java
/frameworks/base/core/java/android/widget/ArrayAdapter.java
public class ArrayAdapter<T> extends BaseAdapter implements Filterable, ThemedSpinnerAdapter {
private List<T> mObjects;
...
public ArrayAdapter(Context context, @LayoutRes int resource, @NonNull List<T> objects) {
this(context, resource, 0, objects);
}
public ArrayAdapter(Context context, @LayoutRes int resource, @IdRes int textViewResourceId,
@NonNull List<T> objects) {
mContext = context;
mInflater = LayoutInflater.from(context);
mResource = mDropDownResource = resource;
mObjects = objects;
mFieldId = textViewResourceId;
}
public int getCount() {
return mObjects.size();
}
public T getItem(int position) {
return mObjects.get(position);
}
public View getView(int position, View convertView, ViewGroup parent) {
return createViewFromResource(mInflater, position, convertView, parent, mResource);
}
private View createViewFromResource(LayoutInflater inflater, int position, View convertView,
ViewGroup parent, int resource) {
View view;
TextView text;
if (convertView == null) {
view = inflater.inflate(resource, parent, false);
} else {
view = convertView;
}
try {
if (mFieldId == 0) {
// If no custom field is assigned, assume the whole resource is a TextView
text = (TextView) view;
} else {
// Otherwise, find the TextView field within the layout
text = (TextView) view.findViewById(mFieldId);
}
} catch (ClassCastException e) {
Log.e("ArrayAdapter", "You must supply a resource ID for a TextView");
throw new IllegalStateException(
"ArrayAdapter requires the resource ID to be a TextView", e);
}
T item = getItem(position);
if (item instanceof CharSequence) {
text.setText((CharSequence)item);
} else {
text.setText(item.toString());
}
return view;
}
}
The specific use of ArrayAdapter
import java.util.ArrayList;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class Demo13Activity extends Activity {
private ListView lv;
private ArrayList<String> list = new ArrayList<String>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
lv = (ListView)findViewById(R.id.listview);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
this,
android.R.layout.simple_expandable_list_item_1,
getData());
lv.setAdapter(adapter);
}
private ArrayList<String> getData()
{
list.add("180平米的房子");
list.add("一个勤劳漂亮的老婆");
list.add("一辆宝马");
list.add("一个强壮且永不生病的身体");
list.add("一个喜欢的事业");
return list;
}
}
ListView.java
/frameworks/base/core/java/android/widget/ListView.java
public class ListView extends AbsListView {
......
@Override
public void setAdapter(ListAdapter adapter) {
//这里需要的是ListAdapter接口类型的入参
...
}
......
}
object adapter pattern
The three roles of the class adapter pattern:
- Destination Interface(dst: destination target, destination)
- source class (src:source source)
- adapter
ListView is used as a client, and the target interface it needs is the ListAdapter interface.
Source class is DataSource: ArrayList<String>
Adapter is ArrayAdapter
ArrayAdapter accepts the ArrayList object in the constructor and assigns it to private List<T> mObjects;
. The getCount(), getItem(), and getView() methods are implemented through mObject
member variables.
So the adapter pattern in ListView is an object adapter pattern, not a class adapter pattern.
What problem does ArrayAdapter solve or what is its role?
Completed ArrayList<String>
conversion to ListAdapter.
The source data given when using it is that ArrayList<String>
ListView needs ListAdapter, and ArrayAdapter completes ArrayList<String>
the conversion from ListAdapter.
Conclusion: The adapter pattern in ListView is an object adapter pattern, not a class adapter pattern.
This article: Android Design Patterns Series - Adapter Patterns analysis is pretty good, but misleading.