1、ListView
ListView主要用来进行数据列表,支持动态加入数据,支持自动滚屏。
如果想为ListView加入数据,也要使用Adapter来完成,根据不同的情况,需要加入以下几种Adapter
1) ArrayAdapter:每行显示一条文本数据,可以使用这种Adapter。
2) SimpleAdapter:每行显示多条文本数据,可以使用这种Adapter完成。
3) 自定义Adapter:行中存在要显示的图片,使用这种Adapter
1.1、ArrayAdapter
使用时与Spinner类似,直接通过ArrayAdapter就可以将数据显示到界面中。
public class MainActivity extends Activity {
private ListView list;
private ArrayAdapter<String> adapter;
private List<String> allValues = new ArrayList<String>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 设置默认使用的布局文件
setContentView(R.layout.activity_main);
// 初始化一些数据,假设是查询出来的
for (int i = 0; i < 50; i++) {
allValues.add("新添加的数据 " + i);
}
// 取得组件
list = (ListView) findViewById(R.id.list);
// Adapter
adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, allValues);
list.setAdapter(adapter);
}
}
1.2、SimpleAdapter
在使用这种一行多条数据的Adapter时,首先需要先完成布局的设置,这里的布局指的是每一行的布局样式。
在layout目录下,建立一个布局文件。<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="5"
android:orientation="vertical" >
<TextView
android:id="@+id/line_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#20b2aa"
android:textSize="14sp" />
<TextView
android:id="@+id/line_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#aaaaaa"
android:textSize="10sp" />
<TextView
android:id="@+id/line_area"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#aaaaaa"
android:textSize="10sp" />
</LinearLayout>
<TextView
android:id="@+id/line_price"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textColor="#ff6600"
android:textSize="12sp" />
</LinearLayout>
然后可以在Java程序中建立Adapter并加入数据。
之前数据是用List<String>保存的,现在要改为List<Map<String,Object>>格式,每一行通过Map设置多条数据
public class MainActivity extends Activity {
private ListView list;
private SimpleAdapter adapter;
private List<Map<String, Object>> allValues = new ArrayList<Map<String, Object>>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 设置默认使用的布局文件
setContentView(R.layout.activity_main);
// 初始化一些数据,假设是查询出来的
for (int i = 0; i < 50; i++) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("title", "商品名称 " + i);
map.put("time", "全新 " + i + " 小时前发布");
map.put("area", "江苏 南通");
map.put("price", i * 20 + "元");
allValues.add(map);
}
// 取得组件
list = (ListView) findViewById(R.id.list);
// Adapter
adapter = new SimpleAdapter(this, allValues, R.layout.my_simple_item,
new String[] { "title", "time", "area", "price" }, new int[] {
R.id.line_title, R.id.line_time, R.id.line_area,
R.id.line_price });
list.setAdapter(adapter);
}
}
1.3、自定义Adapter
如果行中出现要显示的图片,必须要通过自定义Adapter 来完成
使用这个Adapter同样也要先完成界面的行的设计
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/listbg"
android:orientation="horizontal"
android:paddingBottom="5dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:paddingTop="5dp" >
<TextView
android:id="@+id/line_img"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="4"
android:orientation="vertical" >
<TextView
android:id="@+id/line_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#000000"
android:textSize="14sp" />
<TextView
android:id="@+id/line_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#bbbbbb"
android:textSize="10sp" />
</LinearLayout>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.75" />
</LinearLayout>
自己建立一个Adapter类,并继承BaseAdapter类,同时覆写里面的方法,动态创建每一行的组件。
public class GameAdapter extends BaseAdapter {
private Context ctx;
private List<Map<String, Object>> allValues;
public GameAdapter(Context ctx, List<Map<String, Object>> allValues) {
this.ctx = ctx;
this.allValues = allValues;
}
@Override
public int getCount() {
return allValues.size();
}
@Override
public Object getItem(int position) {
return allValues.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
/**
* 返回某一行的界面内容 convertView是为了提高性能准备的重用的行组件, 如果当前行之前没有建立过,则该值为null,需要自行建立.
* 如果之前已经建立了足够的行组件,则这里convertView有内容,只需要将里面的数据修改了即可.
*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// 判断是否需要建立当前行的组件
if (convertView == null) {
// 建立新的组件, 需要动态读取xml自动建立组件
convertView = LayoutInflater.from(ctx).inflate(
R.layout.my_adapter_item, null);
}
// 设置组件中的数据
// 分别取得要设置数据的TextView
TextView imgText = (TextView) convertView.findViewById(R.id.line_img);
TextView titleText = (TextView) convertView
.findViewById(R.id.line_title);
TextView timeText = (TextView) convertView.findViewById(R.id.line_time);
// 设置数据
Map<String, Object> map = allValues.get(position);
titleText.setText(map.get("title").toString());
timeText.setText(map.get("time").toString());
// 设置图片
imgText.setBackgroundResource((Integer) map.get("img"));
return convertView;
}
}
在Activity中使用自定义的Adapter
public class MainActivity extends Activity {
private ListView list;
private GameAdapter adapter;
private List<Map<String, Object>> allValues = new ArrayList<Map<String, Object>>();
// 所有图片的数组
private int[] allImgs = { R.drawable.close_dir, R.drawable.image_file,
R.drawable.mp3_file, R.drawable.mp4_file, R.drawable.open_dir,
R.drawable.txt_file };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 设置默认使用的布局文件
setContentView(R.layout.activity_main);
Random r = new Random();
// 初始化一些数据,假设是查询出来的
for (int i = 0; i < 50; i++) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("title", "游戏名称 " + i);
map.put("time", "2014-3-25 动作");
map.put("img", allImgs[r.nextInt(allImgs.length)]);
allValues.add(map);
}
// 取得组件
list = (ListView) findViewById(R.id.list);
// Adapter
adapter = new GameAdapter(this, allValues);
list.setAdapter(adapter);
}
}
建立一个Globals类,在里面计算总屏幕宽度和高度。根据总屏幕高度,来动态改变数据的行高。
public class Globals {
public static int SCREEN_WIDTH;
public static int SCREEN_HEIGHT;
public static void init(Activity a) {
// 初始化屏幕的宽度和高度
SCREEN_WIDTH = a.getWindowManager().getDefaultDisplay().getWidth();
SCREEN_HEIGHT = a.getWindowManager().getDefaultDisplay().getHeight();
}
}
在Activity中调用这个初始化操作。
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Globals.init(this);
修改Adapter中的getView方法,设置行的高度。
public View getView(int position, View convertView, ViewGroup parent) {
// 判断是否需要建立当前行的组件
if (convertView == null) {
// 建立新的组件, 需要动态读取xml自动建立组件
convertView = LayoutInflater.from(ctx).inflate(
R.layout.my_adapter_item, null);
// 设置高度
convertView.setLayoutParams(new LayoutParams(
LayoutParams.MATCH_PARENT, Globals.SCREEN_HEIGHT / 9));
}
// 设置组件中的数据
// 分别取得要设置数据的TextView
TextView imgText = (TextView) convertView.findViewById(R.id.line_img);
// 设置图片组件的高度
imgText.getLayoutParams().height = Globals.SCREEN_HEIGHT / 9;
2、ListView常用事件
常用的监听有以下几种:
1) 点击某一项的监听:OnItemClickListener
list.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// arg2表示当前点的行号,根据这个值,可以取得当前行的数据
Map<String, Object> map = allValues.get(arg2);
Toast.makeText(MainActivity.this,
"当前所点击的是: " + map.get("title"), Toast.LENGTH_SHORT)
.show();
}
});
2) 长按事件:OnItemLongClickListener
list.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
Toast.makeText(MainActivity.this,
"删除: " + arg2, Toast.LENGTH_SHORT)
.show();
return false;
}
});
3) 滑动事件:OnScrollListener
可以监听屏幕的滑动状态和滑动位置。
list.setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) {
System.out.println("当前是空闲状态........ ------- ");
} else if (scrollState == OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
System.out.println("触屏滚动状态......------");
} else if (scrollState == OnScrollListener.SCROLL_STATE_FLING) {
System.out.println("惯性滚动状态......------");
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
System.out.println("当前的显示项: " + firstVisibleItem + " + "
+ visibleItemCount + " --> " + totalItemCount
+ " ------ ");
}
});