2016/4/5 17:22】
之前写listview其实写了很多次,但好像还是模模糊糊的感觉,直到今天准备写tab的时候被告诉说原理有像的地方,于是我就先来分析整理一下listview好了
先来一种非常自然的理解方式:
ListView其实就是一个View中放入数据呗,于是它的使用原理很可能是这样:
很好理解:
- 先得到数据
- 然后得到layout中的listview对象
- 然后把数据输入到对象中
但其实这里稍微有个实际的问题,就是第三步中,数据是不能直接传入listview中的
这也很好理解,因为
- 数据可能有很多种,各种各样的,肯定需要一种固定格式的数据才行,所以普通数据到这种特殊的固定格式,就需要适配器了
- Listview展示的不止是数据,一条条的List还有布局呢,所以你还需要传入一个布局文件
于是安卓中通过一个通用的适配器类(可以通过它来定制自己的)来实现这两个功能
这一步的变化就像这样:
to
所以实际的原理示意图会是这样:
而更加实际的应用中是这样:
1、定义一个data类
就是一个data unit,可以定义成bean的形式
但之后真正传给adapter的其实是data list,传入一个List,然后到时候listview显示的顺序就是往List添加dataitem的顺序
代码:
public class Zchooseproject {
private String name
;
private String place
;
private int imageId ;
//这是从外面传入数据的方法
public Zchooseproject(String name
,String
place
,
int imageId ) {
this . name
=
name
;
this . place
=
place
;
this . imageId
=
imageId
;
}
//这两个是在外面取数据的方法
public String getName() {
return name ;
}
public String getPlace() {
return place ;
}
public int getImageId() {
return imageId ;
}
}
2、写一个itemlayout
就是普通的Layout,但是它高度是固定的,不能是matchparent(下面的例子里这块搞得有点怪,因为里边使用了wrap_content)
<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、接下来需要创建一个自定义的适配器
这个适配器继承自 ArrayAdapter(是官方适配器的一种),并将泛型指定 为我们的data类。
1. Adapter重写了父类的一组构造函数,用于将上下文、ListView子项布局的 id和数 据都传递进来
2. 另外又重写了 getView()方法,这个方法在每个子项被滚动到屏幕内的时候 会被调用
1. 在 getView方法中,首先通过 getItem()方法得到当前项的 Fruit实例(这个有点怪,不过没事)
2. 然后使用 LayoutInflater来为这个子项加载我们传入的布局
3. 接着调用 View的 findViewById()方法分别 获取到 ImageView和 TextView的实例,并分别调用它们的 setImageResource()和 setText()方 法来设置显示的图片和文字
4. 最后将布局返回,这样我们自定义的适配器就完成了。
代码如下所示:
public class Zchooseprojectadapter extends ArrayAdapter<Zchooseproject> {
private int resourceId ;
public Zchooseprojectadapter(Context context
,
int textViewResourceId ,List<Zchooseproject>
objects
) {
super ( context
,
textViewResourceId
,
objects
);
resourceId =
textViewResourceId
;
}
@Override
public View getView( int position , View
convertView
, ViewGroup
parent
) {
Zchooseproject fruit = getItem(
position
);
// 获取当前项的Fruit实例
View view = LayoutInflater.from(getContext()).inflate( resourceId ,
null );
ImageView fruitImage = (ImageView)
view
.findViewById(R.id.
fruit_image );//获取itemlayout中的控件
TextView fruitName = (TextView)
view
.findViewById(R.id.
fruit_name );
TextView fruitName2 = (TextView)
view
.findViewById(R.id.
place );
fruitImage .setImageResource(
fruit
.getImageId());
fruitName .setText(
fruit
.getName());
fruitName2 .setText(
fruit
.getPlace());
return view ;
}
}
4、OK,在onCreate方法中装配adapter吧!
4.1、初始化data list
private List<Zchooseproject> fruitList
=
new ArrayList<Zchooseproject>();
Zchooseproject apple =
new Zchooseproject( "项目名称"
,
"项目地点 项目信息"
, R.drawable.
icon_project );
fruitList .add(
apple
);
Zchooseproject banana =
new Zchooseproject( "项目名称"
,
"项目地点 项目信息"
, R.drawable.
icon_project );
fruitList .add(
banana
);
Zchooseproject orange =
new Zchooseproject( "项目名称"
,
"项目地点 项目信息"
, R.drawable.
icon_project );
fruitList .add(
orange
);
......
Zchooseproject mango =
new Zchooseproject( "项目名称"
,
"项目地点 项目信息"
, R.drawable.
icon_project );
fruitList .add(
mango
);
4.2、装配adapter
Zchooseprojectadapter adapter =
new Zchooseprojectadapter( this ,R.layout. z_chooseprojectitem , fruitList
);
5、结束!装配ListView
ListView listView = (ListView) findViewById(R.id.
list_view );
listView .setAdapter(
adapter
);
因为贴图的繁琐。。。所以以上图片不完整。。。完整的在这里: