一、基本概念
ListView相信大家一定不陌生,用了安卓手机也有一些时间了,我发现几乎所有的应用都用到了ListView,所以可见ListView是多么重要的一个组件。但是,感觉自己对它的掌握和理解还是差很多,于是根据开发经验以及网上的资料来写一篇文章整理对ListView的理解。
ListView
extends AbsListViewjava.lang.Object | |||||
↳ | android.view.View | ||||
| ↳ | android.view.ViewGroup | |||
| | ↳ | android.widget.AdapterView<T extends android.widget.Adapter> | ||
| | | ↳ | android.widget.AbsListView | |
| | | | ↳ | android.widget.ListView |
Known Direct Subclasses |
ListView是一个显示一个垂直滚动列表中项目的视图,项目来自与此视图相关的ListAdapter。
XML属性:
(4)android:divider 各个项目之间的分隔符,可以用Drawable 或者 color 来表示。
(2)android:dividerHeight divader的高度。
(3)android:entries 对数组资源,的引用用来填充列表,事实上很多人用ArrayAdapter。
还用一个比较重要的方法就是SetAdapter()。当我们实例化一个ListView,然后就调用SetAdapter()方法来进行数据的绑定。其中Adapter一般有以下几种:ArrayAdapter,SimpleAdapter和SimpleCursorAdapter以及BaseAdapter。ArrayAdapter最为简单,只能展示一行字。SimpleAdapter有最好的扩充性,可以自定义出各种效果。SimpleCursorAdapter可以认为是SimpleAdapter对数据库的简单结合,可以方面的把数据库的内容以列表的形式展示出来。
二、实例
①用ListView来显示文本,点击文本进入另一个Activity。
我们用两种方法来实现,一个是用xml属性里的entries,另一个是ArrayAdapter。先用第一种方法,在values文件夹里面新建arrays.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="listtext">
<item>安卓</item>
<item>苹果</item>
<item>WindowsPhone</item>
</string-array>
</resources>
main.xml中添加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"
tools:context=".ListViewDemo" >
<ListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:entries="@array/listtext"//用来在ListView显示的文本
android:layout_height="match_parent" >
</ListView>
</RelativeLayout>
MainActivity.javaa如下:
package com.example.listviewdemo;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.database.DataSetObserver;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
public class ListViewDemo extends Activity {
private ListView listView;
private Intent intent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_view_demo);
listView=(ListView) findViewById(R.id.listview);
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
switch(arg2){
case 0:
intent=new Intent(ListViewDemo.this,OtherActivity.class);
startActivity(intent);
break;
case 1:
intent=new Intent(ListViewDemo.this,OtherActivity.class);
startActivity(intent);
case 2:
intent=new Intent(ListViewDemo.this,OtherActivity.class);
startActivity(intent);
}
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_list_view_demo, menu);
return true;
}
}
另一种方式就是ArrayAdapter:
public class ListViewDemo extends Activity {
private ListView listView;
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_view_demo);
listView=(ListView) findViewById(R.id.listview);
listView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1,getData())); setContentView(listView); } private List<String> getData(){ List<String> data = new ArrayList<String>(); data.add("苹果"); data.add("安卓"); data.add("windowsphone"); return data;
}}
效果如下:
还有可以用SimpleAdapter和SimpleCursorAdapter往列表中添加图片等其他组件。simpleAdapter的扩展性最好,可以定 义各种各样的布局出来,可以放上ImageView(图片),还可以放上Button(按钮),CheckBox(复选框)等等。 SimpleCursorAdapter比SimpleAdapter多了一个可以从数据库查询数据并显示在ListView中。 当然,我们最常用的还是BaseAdapter,可以根据需求来写我们自己的Adapter。下面这个例子就用到了BaseAdapter。 用过安卓的用户都知道,像软件市场,微信对话里面都用到了ListView。比如软件Marcket里面基本上就是一个ListView,每一个item有一个软件,如图:
之前我们在ListView的item里面只是显示文本,这种情况比较适合在设置界面,那Marcket的item是如何实现的呢。无非也就是在item里面显示图片,文本以及按钮。
下面模仿这个效果做一下:
xml文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="@+id/linear1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginLeft="10dp"
>
<ImageView
android:id="@+id/appimg"
android:layout_width="40dp"
android:layout_height="40dp"
/>
</LinearLayout>
<LinearLayout
android:id="@+id/linear2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/linear1"
android:layout_alignParentTop="true"
android:layout_marginLeft="5dp"
android:layout_toRightOf="@id/linear1"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/sublinear1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/appnametext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/weixin"
/>
</LinearLayout>
<LinearLayout
android:id="@+id/sublinear2"
android:layout_marginTop="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<TextView
android:id="@+id/sizetext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/weixinsize"
/>
<ImageView
android:id="@+id/slashimg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:layout_marginRight="3dp"
android:src="@drawable/slash"
/>
<TextView
android:id="@+id/amounttext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/downamount"
/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/linear3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginRight="10dp"
>
<Button
android:id="@+id/dowmbutton"
android:layout_width="wrap_content"
android:layout_height="35dp"
android:layout_marginTop="5dp"
android:text="@string/downapp" />
</LinearLayout>
</RelativeLayout>
Activity代码如下:
package com.example.listviewdemo;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.DataSetObserver;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
public class ListViewDemo extends Activity {
private ListView listView;
private Intent intent;
private List<Map<String, Object>> mData;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_view_demo);
listView = (ListView) findViewById(R.id.listview);
SimpleAdapter simpleAdapter = new SimpleAdapter(this, getData(),
R.layout.item, new String[] { "nametext", "teitext",
"amounttext" }, new int[] { R.id.name_text,
R.id.tel_text, R.id.image });
listView.setAdapter(simpleAdapter);
mData = getData();
MyAdapter adapter = new MyAdapter(this);
listView.setAdapter(adapter);
}
public 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("appnametext", "微信");
map.put("sizetext", "15.2");
map.put("amounttext", "1234323");
map.put("appimg", R.drawable.weixin);
list.add(map);
map = new HashMap<String, Object>();
map.put("appnametext", "手机QQ");
map.put("sizetext", "8.5");
map.put("amounttext", "122073323");
map.put("appimg", R.drawable.qq);
list.add(map);
map = new HashMap<String, Object>();
map.put("appnametext", "手机QQ空间");
map.put("sizetext", "6.3");
map.put("amounttext", "122393");
map.put("appimg", R.drawable.qqko);
list.add(map);
map = new HashMap<String, Object>();
map.put("appnametext", "微博");
map.put("sizetext", "7.7");
map.put("amounttext", "1278323");
map.put("appimg", R.drawable.weib);
list.add(map);
map = new HashMap<String, Object>();
map.put("appnametext", "陌陌");
map.put("sizetext", "6.9");
map.put("amounttext", "1279073");
map.put("appimg", R.drawable.mom);
list.add(map);
map = new HashMap<String, Object>();
map.put("appnametext", "飞信");
map.put("sizetext", "6.9");
map.put("amounttext", "1279073");
map.put("appimg", R.drawable.fei);
list.add(map);
return list;
}
public final class ViewHolder {
public ImageView appimg;
public TextView appnametext;
public TextView sizetext;
public TextView amounttext;
public Button dowmbutton;
}
public class MyAdapter extends BaseAdapter {
private LayoutInflater mInflater;
public MyAdapter(Context context) {
this.mInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return mData.size();
}
@Override
public Object getItem(int arg0) {
return null;
}
@Override
public long getItemId(int arg0) {
return 0;
}
@Override
public View getView(int arg0, View arg1, ViewGroup arg2) {
ViewHolder holder = null;
if (arg1 == null) {
holder = new ViewHolder();
arg1 = mInflater.inflate(R.layout.item1, null);
holder.appimg = (ImageView) arg1.findViewById(R.id.appimg);
holder.appnametext = (TextView) arg1.findViewById(R.id.appnametext);
holder.sizetext = (TextView) arg1.findViewById(R.id.sizetext);
holder.amounttext = (TextView) arg1.findViewById(R.id.amounttext);
holder.dowmbutton = (Button) arg1.findViewById(R.id.dowmbutton);
arg1.setTag(holder);
} else {
holder = (ViewHolder) arg1.getTag();
}
holder.appimg.setBackgroundResource((Integer) mData.get(arg0).get("appimg"));
holder.appnametext.setText((String) mData.get(arg0).get("appnametext"));
holder.sizetext.setText((String) mData.get(arg0).get("sizetext"));
holder.amounttext.setText((String) mData.get(arg0).get("amounttext"));
return arg1;
}
}
}
效果如下:
虽然效果达到了,但是我们这只是一个本地的显示,实际应用中都是从网络上下载然后展示的。流程应该是从数据库中获取数据,然后封装成josn或xml,之后安卓端异步解析并且显示。关于ListView还有很多要说的东西,优化,分页加载,下拉刷新等等。