自定义listview的步骤

时间:2022-07-03 19:44:11

1、定义一个实体类;

public class Fruit {
private String name;
private int imageId;
public Fruit(String name, int imageId) {
this.name = name;
this.imageId = imageId;
}
public String getName() {
return name;
}
public int getImageId() {
return imageId;
}
}

2、新建item.xml,放入控件,这里是listview中每个item的内容;

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="@+id/fruit_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/fruit_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="10dip" />
</LinearLayout>

3、自定义adapter,新建自定义的adapter继承arrayadapter,泛型指定为之前的实体类。构造函数包括上下文、listview的子项布局,还有数据。然后重写getView方法,先通过getitem获取当前实例,然后用LayoutInflater加载布局,调用view的findviewbyid方法与控件联系起来,然后用settext等方法设置内容,返回view

public class FruitAdapter extends ArrayAdapter<Fruit> {
private int resourceId;
public FruitAdapter(Context context, int textViewResourceId,
List<Fruit> objects) {
super(context, textViewResourceId, objects);
resourceId = textViewResourceId;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Fruit fruit = getItem(position); // 获取当前项的Fruit实例
View view = LayoutInflater.from(getContext()).inflate(resourceId, null);
ImageView fruitImage = (ImageView) view.findViewById(R.id.fruit_image);
TextView fruitName = (TextView) view.findViewById(R.id.fruit_name);
fruitImage.setImageResource(fruit.getImageId());
fruitName.setText(fruit.getName());
return view;
}
}

4、在所在的activity中定义一个类型为实体类的List,将对象添加到list中,定义一个adapter对象,构造参数分别是当前活动,子项布局和list对象;定义listview,调用setadapter方法;

public class MainActivity extends Activity {
private List<Fruit> fruitList = new ArrayList<Fruit>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initFruits(); // 初始化水果数据
FruitAdapter adapter = new FruitAdapter(MainActivity.this,
R.layout.fruit_item, fruitList);
ListView listView = (ListView) findViewById(R.id.list_view);
listView.setAdapter(adapter);
}

只要修改item.xml的内容,界面就可以更加复杂。

5、提升运行效率

getview方法中有一个convertview,用来缓存之前加载好的内容,所以可以加一个条件判断如果 convertView 为空,则使用LayoutInflater 去加载布局,如果不为空则直接对 convertView 进行重用。

View view;
if (convertView == null) {
view = LayoutInflater.from(getContext()).inflate(resourceId, null);
} else {
view = convertView;
}

还可以用内部类viewholder,对控件实例进行缓存,当convertView 为空的时候,创建一个 ViewHolder 对象,并将控件的实例都存放在 ViewHolder 里,然后调用 View的 setTag()方法,将 ViewHolder 对象存储在 View 中。当 convertView 不为空的时候则调用View 的 getTag()方法,把 ViewHolder 重新取出。这样所有控件的实例都缓存在了 ViewHolder里,就没有必要每次都通过 findViewById()方法来获取控件实例了。