ListView列表视图是Android开发中最重要的组件之一,基本每一个APP都会用到ListView,不过现在Google推出一个新的组件,RecycleView,我们后面会介绍到。我们可以用ListView绘制出非常漂亮的列表。使用ListView绘制列表需要三个重要的元素:ListView、数据适配器Adapter、数据。ListView就是列表控件,数据就不用说了,下面我们介绍一下什么是Adapter?
我们首先看一下官方是怎么对Adapter定义的:
An Adapter object acts as a bridge between an AdapterView and the underlying data for that view. The Adapter provides access to the data items. The Adapter is also responsible for making a View for each item in the data set.
简单翻译就是:Adapter对象是View和底层数据之间的桥梁,适配器给数据项提供访问接口,适配器还负责做一个视图中的每一项数据集。
Android提供德适配器有:ArrayAdapter, BaseAdapter, CursorAdapter, HeaderViewListAdapter, ListAdapter, ResourceCursorAdapter, SimpleAdapter, SimpleCursorAdapter, SpinnerAdapter, ThemedSpinnerAdapter, WrapperListAdapter。我们常用的有:ArrayAdapter、BaseAdapter、SimpleAdapter、SimpleCursorAdapter。
下面我们实现一个简单的例子,体会一下ListView和Adapter的结合:
ArrayAdapter,Activity代码:
private ListView lv_array_adapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_arrayadapter);
lv_array_adapter = (ListView) findViewById(R.id.lv_array_adapter);
final String[] names = getResources().getStringArray(R.array.adapter_name);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, names);
lv_array_adapter.setAdapter(adapter);
lv_array_adapter.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Toast.makeText(getApplicationContext(), "点击的是:" + names[i], Toast.LENGTH_SHORT).show();
}
});
}
布局代码比较简单,直接在布局中添加一个ListView组件。初始化中三个参数分别是:Context上下文对象,每一个Item的View,数据。
BaseAdapter:
Activity代码:
private ListView lv_base_adapter;
private MYBaseAdapter adapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_baseadapter);
lv_base_adapter= (ListView) findViewById(R.id.lv_base_adapter);
final String[] datas=getResources().getStringArray(R.array.adapter_name);
adapter=new MYBaseAdapter(this,datas);
lv_base_adapter.setAdapter(adapter);
lv_base_adapter.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Toast.makeText(getApplicationContext(),"点击的是:"+datas[i],Toast.LENGTH_SHORT).show();
}
});
}
自定义适配器代码:
package com.example.listviewdemo.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import com.example.listviewdemo.R;
/**
* Created by Devin on 2016/7/7.
*/
public class MYBaseAdapter extends BaseAdapter {
String[] datas;
private Context context;
public MYBaseAdapter(Context context, String[] datas) {
this.datas = datas;
this.context = context;
}
@Override
public int getCount() {
return datas.length;
}
@Override
public Object getItem(int i) {
return i;
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder viewHolder;
if (view == null) {
view = LayoutInflater.from(context).inflate(R.layout.item_base_adapter, null);
viewHolder = new ViewHolder();
viewHolder.tv_base_adapter = (TextView) view.findViewById(R.id.tv_base_adapter);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
viewHolder.tv_base_adapter.setText(datas[i]);
return view;
}
static class ViewHolder {
TextView tv_base_adapter;
}
}
BaseAdapter是一个抽象类,继承于它就必须要实现四个方法:getCount()、getItem(int i)、getItemId(int i)、getView(int i, View view, ViewGroup viewGroup)。在这个四个方法中,getCount()是用来得到列表的长度,如果返回是0,那么列表就不显示item;getItem(int i)是用来得到item、getItemId(int i)是用来得到每一个item的标识;getView(int i, View view, ViewGroup viewGroup)用来绘制View。这里就简单的介绍而已。
simpleAdapter:
Activity代码:
package com.example.listviewdemo.activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;
import com.example.listviewdemo.R;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by Devin on 2016/7/7.
*/
public class SimpleAdapterActivity extends AppCompatActivity {
private ListView lv_simple_adapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_simpleadapter);
lv_simple_adapter = (ListView) findViewById(R.id.lv_simple_adapter);
final String[] names = getResources().getStringArray(R.array.adapter_name);
final String[] says = getResources().getStringArray(R.array.name_says);
List<Map<String, Object>> mapList = new ArrayList<>();
for (int i = 0; i < names.length; i++) {
Map<String, Object> itemMap = new HashMap<>();
itemMap.put("names", names[i]);
itemMap.put("says", says[i]);
mapList.add(itemMap);
}
SimpleAdapter adapter = new SimpleAdapter(getApplicationContext(), mapList, R.layout.item_simple_adapter, new String[]{"names", "says"}, new int[]{R.id.tv_name, R.id.tv_says});
lv_simple_adapter.setAdapter(adapter);
lv_simple_adapter.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Toast.makeText(getApplicationContext(), names[i] + "说了:" + says[i], Toast.LENGTH_SHORT).show();
}
});
}
}
初始化的五个参数中,第一个是上下文对象,第二个是数据,第三个是Item的布局文件,第四个是数据的key,第五个是数据放置对应组件的id。
SimpleCursorAdapter:
Activity代码:
package com.example.listviewdemo.activity;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.support.annotation.Nullable;
import android.support.v4.widget.SimpleCursorAdapter;
import android.support.v7.app.AppCompatActivity;
import android.widget.ListView;
import com.example.listviewdemo.R;
/**
* Created by Devin on 2016/7/7.
*/
public class SimpleCursorAdapterActivity extends AppCompatActivity {
private ListView lv_simple_cursor_adapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_simplecursoradapter);
lv_simple_cursor_adapter = (ListView) findViewById(R.id.lv_simple_cursor_adapter);
Cursor cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
SimpleCursorAdapter adapter=new SimpleCursorAdapter(this,R.layout.item_simple_cursor,cursor,new String[]{ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,ContactsContract.CommonDataKinds.Phone.NUMBER},new int[]{R.id.tv_con_name,R.id.tv_phone});
lv_simple_cursor_adapter.setAdapter(adapter);
}
}
比较简单,就不描述了。下面是实现的效果图:
这里只介绍简单的使用ListView和Adapter,下一节我们会介绍ListView的适配优化和其他问题。
猛戳下载源码
最后附上ListView的国内镜像API和Adapter的国内镜像API