Android之ListView详解(二)
三、SimpleAdapter
SimpleAdapter可以自定义拓展listview。
使用simpleAdapter的数据用一般都是HashMap构成的List,list的每一节对应ListView的每一行。HashMap的每个键值数据映射到布局文件中对应id的组件上。因为系统没有对应的布局文件可用,我们可以自己定义一个布局vlist.xml。下面做适配,new一个SimpleAdapter参数一次是:this,布局文件,HashMap的 title 和 info,img。布局文件的组件id,title,info,img。布局文件的各组件分别映射到HashMap的各元素上,完成适配。
-
<?xml version="1.0" encoding="utf-8"?>
-
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-
android:orientation="horizontal" android:layout_width="fill_parent"
-
android:layout_height="fill_parent">
-
<ImageView android:id="@+id/img"
-
android:layout_width="wrap_content"
-
android:layout_height="wrap_content"
-
android:layout_margin="5px"/>
-
-
<LinearLayout android:orientation="vertical"
-
android:layout_width="wrap_content"
-
android:layout_height="wrap_content">
-
-
<TextView android:id="@+id/title"
-
android:layout_width="wrap_content"
-
android:layout_height="wrap_content"
-
android:textSize="22px" />
-
<TextView android:id="@+id/info"
-
android:layout_width="wrap_content"
-
android:layout_height="wrap_content"
-
android:textSize="13px" />
-
</LinearLayout>
-
</LinearLayout>
布局文件
-
public class MainActivity extends ListActivity {
-
-
@Override
-
public void onCreate(Bundle savedInstanceState) {
-
super.onCreate(savedInstanceState);
-
-
SimpleAdapter adapter = new SimpleAdapter(this, getData(),
-
R.layout.activity_main,
-
new String[] { "title", "info", "img" }, new int[] {
-
R.id.title, R.id.info, R.id.img });
-
setListAdapter(adapter);
-
}
-
-
private List<Map<String, Object>> getData() {
-
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
-
-
Map<String, Object> map = new HashMap<String, Object>();
-
map.put("title", "1");
-
map.put("info", " 1 ");
-
map.put("img", R.drawable.ic_launcher);
-
list.add(map);
-
-
map = new HashMap<String, Object>();
-
map.put("title", "2");
-
map.put("info", " 2 ");
-
map.put("img", R.drawable.ic_launcher);
-
list.add(map);
-
-
map = new HashMap<String, Object>();
-
map.put("title", "3");
-
map.put("info", " 3 ");
-
map.put("img", R.drawable.ic_launcher);
-
list.add(map);
-
-
return list;
-
}
-
}
显示效果如图
*使用simpleadapter我们可以显示许多自定义的复杂视图,但是按钮是无法在simpleadapter中使用的。
四、BaseAdapter
BaseAdapter是一个公共基类适配器,直接提供相关控件的数据提供。
-
<SPAN style="FONT-SIZE: 14px"><?xml version="1.0" encoding="utf-8"?>
-
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-
android:layout_width="fill_parent"
-
android:layout_height="fill_parent"
-
android:orientation="horizontal" >
-
-
<ImageView
-
android:id="@+id/img"
-
android:layout_width="wrap_content"
-
android:layout_height="wrap_content"
-
android:layout_margin="5px" />
-
-
<LinearLayout
-
android:layout_width="wrap_content"
-
android:layout_height="wrap_content"
-
android:orientation="vertical" >
-
-
<TextView
-
android:id="@+id/title"
-
android:layout_width="wrap_content"
-
android:layout_height="wrap_content"
-
android:textSize="22px" />
-
-
<TextView
-
android:id="@+id/info"
-
android:layout_width="wrap_content"
-
android:layout_height="wrap_content"
-
android:textSize="13px" />
-
</LinearLayout>
-
-
<Button
-
android:id="@+id/view_btn"
-
android:layout_width="wrap_content"
-
android:layout_height="wrap_content"
-
android:layout_gravity="bottom|right"
-
android:text="btn" />
-
-
</LinearLayout></SPAN>
布局文件
-
<SPAN style="FONT-SIZE: 14px">public class MainActivity extends ListActivity {
-
//通过一个list去映射数据显示在listview中
-
private List<Map<String, Object>> mData;
-
-
@Override
-
public void onCreate(Bundle savedInstanceState) {
-
super.onCreate(savedInstanceState);
-
mData = getData();
-
MyAdapter adapter = new MyAdapter(this);
-
setListAdapter(adapter);
-
}
-
-
private List<Map<String, Object>> getData() {
-
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
-
-
Map<String, Object> map = new HashMap<String, Object>();
-
map.put("title", "1");
-
map.put("info", " 1 ");
-
map.put("img", R.drawable.ic_launcher);
-
list.add(map);
-
-
map = new HashMap<String, Object>();
-
map.put("title", "2");
-
map.put("info", " 2 ");
-
map.put("img", R.drawable.ic_launcher);
-
list.add(map);
-
-
map = new HashMap<String, Object>();
-
map.put("title", "3");
-
map.put("info", " 3 ");
-
map.put("img", R.drawable.ic_launcher);
-
list.add(map);
-
-
return list;
-
}
-
-
// ListView 中某项被选中后的逻辑
-
@Override
-
protected void onListItemClick(ListView l, View v, int position, long id) {
-
-
Log.v("MyListView4-click", (String) mData.get(position).get("title"));
-
}
-
-
/**
-
* listview中点击按键弹出对话框
-
*/
-
public void showInfo() {
-
new AlertDialog.Builder(this).setTitle("Btn listview")
-
.setMessage("123")
-
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
-
public void onClick(DialogInterface dialog, int which) {
-
}
-
}).show();
-
-
}
-
-
public final class ViewHolder {
-
public ImageView img;
-
public TextView title;
-
public TextView info;
-
public Button viewBtn;
-
}
-
-
public class MyAdapter extends BaseAdapter {
-
-
private LayoutInflater mInflater;
-
-
public MyAdapter(Context context) {
-
this.mInflater = LayoutInflater.from(context);
-
}
-
-
public int getCount() {
-
// TODO Auto-generated method stub
-
return mData.size();
-
}
-
-
public Object getItem(int arg0) {
-
// TODO Auto-generated method stub
-
return null;
-
}
-
-
public long getItemId(int arg0) {
-
// TODO Auto-generated method stub
-
return 0;
-
}
-
-
public View getView(int position, View convertView, ViewGroup parent) {
-
-
ViewHolder holder = null;
-
if (convertView == null) {
-
-
holder = new ViewHolder();
-
-
convertView = mInflater.inflate(R.layout.activity_main, null);
-
holder.img = (ImageView) convertView.findViewById(R.id.img);
-
holder.title = (TextView) convertView.findViewById(R.id.title);
-
holder.info = (TextView) convertView.findViewById(R.id.info);
-
holder.viewBtn = (Button) convertView
-
.findViewById(R.id.view_btn);
-
convertView.setTag(holder);
-
-
} else {
-
-
holder = (ViewHolder) convertView.getTag();
-
}
-
-
holder.img.setBackgroundResource((Integer) mData.get(position).get(
-
"img"));
-
holder.title.setText((String) mData.get(position).get("title"));
-
holder.info.setText((String) mData.get(position).get("info"));
-
-
holder.viewBtn.setOnClickListener(new View.OnClickListener() {
-
-
public void onClick(View v) {
-
showInfo();
-
}
-
});
-
-
return convertView;
-
}
-
-
}
-
}</SPAN>
*在程序中使用ViewHolder可以极大的增加程序的效率
下面将对上述代码,做详细的解释,listView在开始绘制的时候,系统首先调用getCount()函数,根据他的返回值得到listView的长度(这也是为什么在开始的第一张图特别的标出列表长度),然后根据这个长度,调用getView()逐一绘制每一行。如果你的getCount()返回值是0的话,列表将不显示同样return 1,就只显示一行。
系统显示列表时,首先实例化一个适配器(这里将实例化自定义的适配器)。当手动完成适配时,必须手动映射数据,这需要重写getView()方法。系统在绘制列表的每一行的时候将调用此方法。getView()有三个参数,position表示将显示的是第几行,covertView是从布局文件中inflate来的布局。我们用LayoutInflater的方法将定义好的vlist2.xml文件提取成View实例用来显示。然后将xml文件中的各个组件实例化(简单的findViewById()方法)。这样便可以将数据对应到各个组件上了。但是按钮为了响应点击事件,需要为它添加点击监听器,这样就能捕获点击事件。至此一个自定义的listView就完成了,现在让我们回过头从新审视这个过程。系统要绘制ListView了,他首先获得要绘制的这个列表的长度,然后开始绘制第一行,怎么绘制呢?调用getView()函数。在这个函数里面首先获得一个View(实际上是一个ViewGroup),然后再实例并设置各个组件,显示之。好了,绘制完这一行了。那 再绘制下一行,直到绘完为止。在实际的运行过程中会发现listView的每一行没有焦点了,这是因为Button抢夺了listView的焦点,只要布局文件中将Button设置为没有焦点就OK了。
运行效果如图
五、本次要讲的是一个listview的进阶效果,主要实现的功能是,单击显示的item时,会显示出一个大图,以突出效果,即抽屉效果的ListView。效果如下所示:
其主要实现思路是:在getView的时候,动态修改布局,将选中的item添加新的View,这样就做到了点击的时候,与其他的item不同的效果。
代码如下:
-
public class MainActivity extends ListActivity {
-
-
DrawListAdapter adapter;
-
int[] imgs={R.drawable.image,R.drawable.packed,R.drawable.paste,R.drawable.text,R.drawable.delete};
-
String[] text={"第一抽屉","第二抽屉","第三抽屉","第四抽屉","第五抽屉"};
-
int currentItem=0;
-
-
@Override
-
public void onCreate(Bundle savedInstanceState) {
-
super.onCreate(savedInstanceState);
-
adapter = new DrawListAdapter(this);
-
//setListAdapter和getListView方法是ListActivity的方法,分别用于设置adapter和获得一个listview
-
this.setListAdapter(adapter);
-
this.getListView().setOnItemClickListener(new OnItemClickListener(){
-
-
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
-
long arg3) {
-
// TODO Auto-generated method stub
-
currentItem=arg2;
-
//notifyDataSetChanged()可以在修改适配器绑定的数组后,不用重新刷新Activity,通知Activity更新ListView
-
adapter.notifyDataSetChanged();
-
}
-
});
-
}
-
-
public class DrawListAdapter extends BaseAdapter{
-
-
Activity activity;
-
LayoutInflater inflater;
-
-
public DrawListAdapter(Activity a){
-
activity=a;
-
inflater=activity.getLayoutInflater();
-
}
-
-
public int getCount() {
-
// TODO Auto-generated method stub
-
return imgs.length;
-
}
-
-
public Object getItem(int arg0) {
-
// TODO Auto-generated method stub
-
return null;
-
}
-
-
public long getItemId(int position) {
-
// TODO Auto-generated method stub
-
return position;
-
}
-
-
public View getView(int position, View convertView, ViewGroup arg2) {
-
// TODO Auto-generated method stub
-
LinearLayout layout=new LinearLayout(activity);
-
layout.setOrientation(LinearLayout.VERTICAL);
-
layout.addView(addTitleView(position));
-
if(currentItem==position){
-
layout.addView(addCustomView(position));
-
}
-
return layout;
-
}
-
-
//获取选中项的内容
-
private View addCustomView(int i) {
-
// TODO Auto-generated method stub
-
View view=new View(activity);
-
ImageView iv=new ImageView(activity);
-
//根据点击的position设置相应要显示的图片
-
switch (i) {
-
case 0:
-
iv.setImageResource(R.drawable.ic_launcher);
-
view=iv;
-
break;
-
case 1:
-
iv.setImageResource(R.drawable.ic_launcher);
-
view=iv;
-
break;
-
case 2:
-
iv.setImageResource(R.drawable.ic_launcher);
-
view=iv;
-
break;
-
case 3:
-
iv.setImageResource(R.drawable.ic_launcher);
-
view=iv;
-
break;
-
case 4:
-
iv.setImageResource(R.drawable.ic_launcher);
-
view=iv;
-
break;
-
}
-
return view;
-
}
-
-
//获取list的标题内容
-
private View addTitleView(int i) {
-
// TODO Auto-generated method stub
-
LinearLayout layout=new LinearLayout(activity);
-
layout.setOrientation(LinearLayout.HORIZONTAL);
-
ImageView iv=new ImageView(activity);
-
iv.setImageResource(imgs[i]);
-
layout.addView(iv,new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT));
-
TextView tv=new TextView(activity);
-
tv.setText(text[i]);
-
layout.addView(tv,new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT));
-
layout.setGravity(Gravity.CENTER);
-
return layout;
-
}
-
-
}
-
}