展现大量数据时使用,平时滑动屏幕的时候上下滑动的就是这个玩意。
(1)首先创建一个包含listview的布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<strong><ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView></strong>
</RelativeLayout>
(2)编写代码,为listview中加入数据
public class MainActivity extends Activity {
private String[] data = {"小明","小红","小刚"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1,data);
//无法直接给listview赋值,需要通过适配器来做
//参数一为当前上下文;参数二为ListView子项布局的id;参数3为适配的数据
ListView listView = (ListView)findViewById(R.id.listView);
listView.setAdapter(adapter);
}
}
运行时的图片为:
只是这种文字,太难看了。得弄的生动一些。
(3)比如我们现在希望每一条信息是一个头像加上一个名字。
第一,编写Person类,用于存储用户信息。
public class Person {
private String name;
private int imageId;//android里面的资源都通过一个id来表示
public Person(String name, int imageId){
this.name = name;
this.imageId = imageId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getImageId() {
return imageId;
}
public void setImageId(int imageId) {
this.imageId = imageId;
}
}
第二,为头像和名字设计专门的layout,作为一种最小粒度的布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="@+id/<strong>fruit_image</strong>"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/<strong>fruit_name</strong>"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="10dip" />
</LinearLayout>
第三,要重新设计adapter,用于后续为listView赋值做准备
public class PersonAdapter extends ArrayAdapter<Person> {
private int resourceId;
/**
* 构造函数
* @param context 上下文
* @param resource ListView子项布局id
* @param objects 传递的数据
*/
public PersonAdapter(Context context, int resource, List<Person> objects) {
super(context, resource, objects);
resourceId = resource;
}
public View getView(int position, View convertView, ViewGroup parent){
//该方法在每个子项被滚动到屏幕内的时候会被调用
Person p = getItem(position); //获取当前实例
View view = LayoutInflater.from(getContext()).inflate(resourceId, null);
//为子项加载我们传入的布局
ImageView personImg = (ImageView)view.findViewById(R.id.fruit_image);
TextView personName = (TextView)view.findViewById(R.id.fruit_name);
personImg.setImageResource(p.getImageId());
personName.setText(p.getName());
return view;
}
}
第四,在活动中初始化人员数据,并给listView赋值
public class MainActivity extends Activity {
private List<Person> personList = new ArrayList<Person>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initPerson();//初始化list数据
PersonAdapter adapter = new PersonAdapter(MainActivity.this, R.layout.person_item,personList);
//无法直接给listview赋值,需要通过适配器来做
//参数一为当前上下文;参数二为ListView子项布局的id;参数3为适配的数据
ListView listView = (ListView)findViewById(R.id.listView);
listView.setAdapter(adapter);
}
private void initPerson(){
Person p1 = new Person("小明",R.drawable.a);
Person p2 = new Person("小红",R.drawable.b);
Person p3 = new Person("小刚",R.drawable.c);
personList.add(p3);
personList.add(p2);
personList.add(p1);
}
}
(4)从代码可以看出来,每次有条目滑动到屏幕中的时候都要重新加载一次视图,而且每次都要重新查找组件。那么可以通过简单的方式进行缓存。
public class PersonAdapter extends ArrayAdapter<Person> {
private int resourceId;
/**
* 构造函数
* @param context 上下文
* @param resource ListView子项布局id
* @param objects 传递的数据
*/
public PersonAdapter(Context context, int resource, List<Person> objects) {
super(context, resource, objects);
resourceId = resource;
}
public View getView(int position, View convertView, ViewGroup parent){
//该方法在每个子项被滚动到屏幕内的时候会被调用
Person p = getItem(position); //获取当前实例
View view;
ViewHolder viewHolder;//用于缓存view的组件
if(convertView == null){ //再次滑到屏幕中的时候不用重新加载布局
view = LayoutInflater.from(getContext()).inflate(resourceId, null); //滚动到屏幕中的时候都会重新加载,那么滑动的太快就会遇到瓶颈
viewHolder = new ViewHolder();
viewHolder.personImg =(ImageView)view.findViewById(R.id.fruit_image);
viewHolder.personName=(TextView)view.findViewById(R.id.fruit_name);
view.setTag(viewHolder);
}else{
view = convertView;
viewHolder = (ViewHolder)view.getTag();
}
//为子项加载我们传入的布局
// ImageView personImg = (ImageView)view.findViewById(R.id.fruit_image); //每次都是重新查到该组件,可以缓存下来
// TextView personName = (TextView)view.findViewById(R.id.fruit_name);
// personImg.setImageResource(p.getImageId());
// personName.setText(p.getName());
viewHolder.personImg.setImageResource(p.getImageId());
viewHolder.personName.setText(p.getName());
return view;
}
class ViewHolder{
ImageView personImg;
TextView personName;
}
}
(5)列表选中事件:
listView.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
Person p = personList.get(arg2);
Toast.makeText(MainActivity.this, p.getName(), Toast.LENGTH_SHORT).show();
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
});