Adapter的简单学习应用
初步记录方便自己回忆怎么用
主要针对具体实现类ArrayAdapter,SimpleAdapter,以及抽象类BaseAdapter。
一ArrayAdapter
支持泛型操作,最为简单,只能展示一行字。数据类型数组,集合。
针对ListView展示数据都是分三步走。
a.ListVeiw 用来展示列表的View。(layout中构建一个布局,添加ListView)
b.适配器 用来把数据映射到ListView上的中介。(Adapter适配器)
c.数据 具体的将被映射的字符串,图片,或者基本组件。(数据以及数据填充的组件)
在活动中也是有三步。
构建Adapter,加载ListView要展示的View,将adapter添加到listview中去。
1.构建一个布局文件,展示listview
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/array_list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
在线性 布局中添加一个ListView。
2要映射的组件例如要把26个字母分行展示。
使用TextView装载。
直接构建一个TextView或者android内置了很多简单的组件,可以直接通过
android.R.layout.simple_expandable_list_item_1调用(此处就是一个简单的TextView)
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/list_adapter"
android:textSize="30dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
然后开始三步走。
1构建ArrayAdapter,通过构造器创建实例注意构造器参数的含义
2listview添加布局文件
3listview添加adapter
举个例子
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>( ArrayListDemo.this, android.R.layout.simple_list_item_1, adapterData);
数据类型是String,第一个参数上下文。这里就是本Activity,第二个参数装载展示数据的控件,此处是android自带的TextView。也可以自己构建。自己构建那此处就是R.layout.布局文件名。第三个参数,数据。
具体实现如下
public class DataActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.datalist);
//造数据
String[] testData = {"A","b","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S"};
List<String> arraylist = new ArrayList<String>();
arraylist.add("a");arraylist.add("b");
arraylist.add("c");arraylist.add("d");
arraylist.add("e");arraylist.add("f");
arraylist.add("g");arraylist.add("h");
arraylist.add("i");arraylist.add("j");
arraylist.add("k");arraylist.add("l");
arraylist.add("m");arraylist.add("n");
//ArrayAdapter adapter = new ArrayAdapter(DataActivity.this,R.layout.array_adapter,testData);
1 ArrayAdapter adapter = new ArrayAdapter(DataActivity.this,R.layout.array_adapter,arraylist);
2 ListView listView = findViewById(R.id.list_adapter);
3 listView.setAdapter(adapter);
}
数组或者集合都可以。所以我造了两个数据集。
主要步骤如1,2,3
二SimpleAdapter
SimpleAdapter继承BaseAdapter。具有一定灵活性。
例如此处模拟展示每行展示一个图片加一个文字。
同理Activity中分三步走即可。
实现案例
1构建一个ListView布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/list_data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
2构建一个布局文件,里面放置一个ImageView以及一个TextView。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/base_image"
android:textSize="30dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/_base_text"
android:textSize="30dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
3在Activity中实现三步走
public class SimpleAdapterActivity extends AppCompatActivity {
private List<Map<String,Object>> dataList ;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.datalist);
1 SimpleAdapter simpleAdapter = new SimpleAdapter(SimpleAdapterActivity.this,getData(),R.layout.simple_adapter,
new String[]{"image","theme"},
new int[]{R.id.image1,R.id.text1});
2 ListView listView = findViewById(R.id.list_data);
3 listView.setAdapter(simpleAdapter);
}
private List<Map<String, Object>> getData() {
dataList = new ArrayList<>();
for(int i = 0; i<20; i++) {
Map map=new HashMap<String, Object>();
map.put("image", R.drawable.logo);
map.put("theme", "慕课网"+i);
dataList.add(map);
}
return dataList;
}
}
主要步骤,1,2,3要理解SimpleAdapter的构造器的参数含义
SimpleAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to)
Context上下文
要展示的数据,基于Map的list。Data里边的每一项都和 ListView里边的每一项对应。Data里边的每一项都是一个Map类型,这个Map类里边包含了ListView每一行需要的数据。
resoirce。布局文件。可以自定义也可以自定义。此处自定的simple_adapter.xml。里面构建了一个ImageView和一个TextView。
form 上面list中map的key(构建时key必须相同,每生成一个map,虽然key一样但随即就添加到list中去了。集合的下标不同,且list的数据可以重复。此处不会造成覆盖。)
to 里面是一个TextView数组。这些 TextView是以id的形式来表示的。例如:Android.R.id.text1,这个text1在layout当中是可以索引的。就是布局文件中的ImageView的id和TextView的id。
举个例子
SimpleAdapter simpleAdapter = new SimpleAdapter(SimpleAdapterActivity.this,getData(),R.layout.simple_adapter,
new String[]{"image","theme"},
new int[]{R.id.image1,R.id.text1});
ListView listView = findViewById(R.id.list_data);
listView.setAdapter(simpleAdapter);
}
具体实现如下
public class SimpleAdapterActivity extends AppCompatActivity {
private List<Map<String,Object>> dataList ;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.datalist);
1 SimpleAdapter simpleAdapter = new SimpleAdapter(SimpleAdapterActivity.this,getData(),R.layout.simple_adapter,
new String[]{"image","theme"},
new int[]{R.id.image1,R.id.text1});
2 ListView listView = findViewById(R.id.list_data);
3 listView.setAdapter(simpleAdapter);
}
private List<Map<String, Object>> getData() {
dataList = new ArrayList<>();
for(int i = 0; i<20; i++) {
Map map=new HashMap<String, Object>();
map.put("image", R.drawable.logo);
map.put("theme", "学习"+i);
dataList.add(map);
}
return dataList;
}
}
注意三步走以及构造器的参数含义
三抽象类BaseAdapter,灵活度最高,需要自己实现抽象方法。
还有各种优化方案。
示例如下同理定义一个ListView布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/list_data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
第二个定义具体承载数据的控件这里定义base_adapter.xml文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/base_image"
android:textSize="30dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/_base_text"
android:textSize="30dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
3定义具体的bean对象
此处想展示每行一个图片加文字。
Bean对象中两个参数,image,跟text(留存一个疑问此处定义整形的image是否是因为R中的id关系)
public class JavaBean {
private int image;
private String title;
public JavaBean(int image, String title) {
this.image = image;
this.title = title;
}
public int getImage() {
return image;
}
public String getTitle() {
return title;
}
}
定义自己的Adapter实现类
public class BeanAdapter extends BaseAdapter {
//数据源
1 private List<JavaBean> bList;
2 //布局装载器对象
private LayoutInflater mInflater;
3 public BeanAdapter(Context context,List<JavaBean> List) {
this.bList=List;
mInflater = LayoutInflater.from(context);
}
@Override
4 public int getCount() {
return bList.size();
}
@Override
5 public Object getItem(int position) {
return bList.get(position);
}
@Override
6 public long getItemId(int position) {
return position;
}
/** @Override
* //这种方式只是实现了,但是效率低下,吃内存,容易造成程序崩溃
7 public View getView(int position, View convertView, ViewGroup parent) {
//将布局文件转换为View对象
View view = mInflater.inflate(R.layout.base_adapter,null);
ImageView imageView = (ImageView) view.findViewById(R.id.base_image);
TextView textView = (TextView) view.findViewById(R.id._base_text);
//获取相应索引bean对象
JavaBean bean = bList.get(position);
imageView.setImageResource(bean.getImage());
textView.setText(bean.getTitle());
return view;
}**/
/*****利用缓存来实现,效率提升,但是每次都需要创建一个view对象,然后通过id找到控件,效率还是可以进一步提升
7 public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.base_adapter,null);
}
//找到item布局文件中对应的控件
ImageView imageView = (ImageView) convertView.findViewById(R.id.base_image);
TextView titleTextView = (TextView) convertView.findViewById(R.id._base_text);
//获取相应索引的ItemBean对象
JavaBean bean = bList.get(position);
//设置控件的对应属性值
imageView.setImageResource(bean.getImage());
titleTextView.setText(bean.getTitle());
return convertView;
}
**/
7 public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
//如果view未被实例化过,缓存池中没有对应的缓存
if (convertView == null) {
viewHolder = new ViewHolder();
// 由于我们只需要将XML转化为View,并不涉及到具体的布局,所以第二个参数通常设置为null
convertView = mInflater.inflate(R.layout.base_adapter, null);
//对viewHolder的属性进行赋值
viewHolder.imageView = (ImageView) convertView.findViewById(R.id.base_image);
viewHolder.title = (TextView) convertView.findViewById(R.id._base_text);
//通过setTag将convertView与viewHolder关联
convertView.setTag(viewHolder);
}else{//如果缓存池中有对应的view缓存,则直接通过getTag取出viewHolder
viewHolder = (ViewHolder) convertView.getTag();
}
// 取出bean对象
JavaBean bean = bList.get(position);
// 设置控件的数据
viewHolder.imageView.setImageResource(bean.getImage());
viewHolder.title.setText(bean.getTitle());
return convertView;
}
// ViewHolder用于缓存控件,三个属性分别对应item布局文件的三个控件
class ViewHolder{
public ImageView imageView;
public TextView title;
public TextView content;
}
}
public int getCount(): 适配器中数据集的数据个数;
public Object getItem(int position): 获取数据集中与索引对应的数据项;
public long getItemId(int position): 获取指定行对应的ID;
public View getView(int position,View convertView,ViewGroup parent): 获取没一行Item的显示内容。
Activity实现如下
public class BaseAdapterActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.datalist);
List<JavaBean> itemBeanList = new ArrayList<>();
for (int i = 0;i < 20; i ++){
itemBeanList.add(new JavaBean(R.mipmap.ic_launcher, "内容" + i));
}
BeanAdapter beanAdapter = new BeanAdapter(this,itemBeanList);
//listview的布局
ListView listView = findViewById(R.id.list_data);
//设置adapter
listView.setAdapter(beanAdapter);
}
}