这次做的是一个简单的通讯录,有两个页面,第一个页面呈现联系人,第二个页面是显示联系人的详细信息。
先上两张效果图:
可以进行的操作大家可以下载来试一下,功能不是很多,但是对于入门Android的童鞋来说还是比较有意思的。
下面讲一下技术要点:
对于ListView来说,他的布局是很简单的:
<ListView
android:id="@+id/lv"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
要注意的是这个id是一定要是设的,因为后面需要在.java文件中填充数据。
在.java文件中获得这个ListView之后,使用Adapter为这个ListView填充数据,常用的Adapter有ArrayAdapter,SimpleAdapter,随着ListView中内容的丰富,以上两种Adapter已经很难满足需要,因此现在一般使用自定义的Adapter来填充数据。
在这个应用中,我是用了自定义的Adapter以及SimpleAdapter。
对于SimpleAdapter,,创建SimpleAdapter需要5个参数,第一个参数依然是Context,就不多说了,下面介绍余下的4个参数:
第2个参数:该参数应该是一个List<? Extends Map<String, ?>>类型的集合对象,该集合中每个Map<String, ?>对象生成一个列表项。
第3个参数:该参数指定一个界面布局的ID。该界面布局指定每一个列表项的样式。
第4个参数:该参数应该是一个String[]类型的参数,该参数决定提取Map<String, ?>对象中哪些key对应的value来生成列表项。
第5个参数:该参数应该是一个int[]类型的参数,该参数决定填充哪些组件。
public void More_process() {
String[] op = {"编辑联系人", "分享联系人", "加入黑名单", "删除联系人"};
// 使用SimpleAdapter填充数据
List<Map<String, Object>> mapList = new ArrayList<>();
for (int i = 0; i < op.length; i++) {
Map<String, Object> temp = new LinkedHashMap<>();
temp.put("op", op[i]);
mapList.add(temp);
}
SimpleAdapter simpleAdapter = new SimpleAdapter(this, mapList, R.layout.more,
new String[]{"op"}, new int[]{R.id.more_to_do});
item_list.setAdapter(simpleAdapter);
}
这一个Adapter我用来填充联系人详情页面中的下面的一些东西。
对于listView的长按和点击事件的处理这里就不多说了,这里实现的功能是点击之后跳转到联系人详情页面,长按会弹出对话框提示是否删除这个联系人。
需要注意的是长按的事件处理是有返回值的,默认是false,但是这样的话是不能区分长按和点击的,在我测试的过程中体现出来就是长按之后会弹出对话框,但是也实现了单击的跳转功能,改成true之后就正常了。
下面主要介绍一下自定义的Adapter,直接上代码:
public class MyAdapter extends BaseAdapter {
private Context context;
private List<Information> list;
public MyAdapter(Context context, List<Information> list) {
this.context = context;
this.list = list;
}
@Override
// 获取数据项列表的长度,也就是一共有多少个数据项
public int getCount() {
if (list == null) return 0;
else return list.size();
}
@Override
// 获得某一个数据项
public Object getItem(int i) {
if (list == null) return null;
else return list.get(i);
}
@Override
// 获得数据项的布局样式,
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
// 新声明一个View变量和ViewHolder变量
View convertView;
ViewHolder viewHolder;
// 当View为空时才加载布局,并且创建一个ViewHolder,获得布局中的两个控件
if (view == null) {
// 通过inflate方法加载布局,context这个参数需要使用这个adapter的Activity传入
convertView = LayoutInflater.from(context).inflate(R.layout.item, null);
viewHolder = new ViewHolder();
viewHolder.first_name = (TextView) convertView.findViewById(R.id.first_name);
viewHolder.name = (TextView) convertView.findViewById(R.id.name);
// setTag方法是将处理好的viewHolder放入view中
convertView.setTag(viewHolder);
} else { // 否则,让convertView等于view, 然后从中取出ViewHolder即可
convertView = view;
viewHolder = (ViewHolder) convertView.getTag();
}
// 从ViewHolder中取出对象,然后负责给他们
viewHolder.first_name.setText(list.get(i).getFirst_name());
viewHolder.name.setText(list.get(i).getName());
return convertView;
}
private class ViewHolder {
public TextView first_name;
public TextView name;
}
}
自定义的Adapter需要提供一个数据列表才能填充数据,一般是一个List类型,在这里我是创建了一个information类,然后将List<Information>传入Adapter中作为数据的列表。
注意这个Information类,因为点击联系人页面之后,跳转的联系人详情页面中不出bug的话是要显示详情的,这些详情哪里来呢,当然是从main_activity中传过去啦!所以为了在两个activity之间传递信息,使用bundle来实现。这个Information类就需要实现serializable.
传递和接收是这样的:
Intent intent = new Intent(MainActivity.this, Particulars.class);
Bundle bundle = new Bundle();
bundle.putSerializable("information", list.get(i));
intent.putExtras(bundle);
startActivity(intent);
Information information = (Information) this.getIntent().getSerializableExtra("information");
有兴趣的童鞋可以下载源码来玩一下: