Android列表用法之一:实战简单ListView
2017-04-19 14:37
381 查看
ListView这个列表控件,是我们在开发当中使用频率比较高的一个控件。 既然是使用频率比较高,那么我们就有必要将它的使用方式保存,方便以后直接复制粘贴,把注意力放在架构上面,不用经常做代码搬运工(重复搬运)。 当然Android的API也提供了许多创建ListView适配器的快捷方式。例如ArrayAdapter、SimpleAdapter、SimpleCursorAdapter等。但是在日常的开发当中,我是从来不会使用系统自带的适配器。毕竟一个项目当中,大部分列表Item的高度、容纳的控件数量、控件类型、逻辑处理、事件的处理等等都是不同的,使用系统自带的完全不能胜任。 套用一句俚语:一切不以实际项目为例子的Sample都是耍*流*氓^_^
今天的简单实例为百度地图-收藏夹页面的收藏点列表的仿写(只是列表哟),下面我们先来看看原装正品效果图动画:
怎么样,够简单吧,不过虽然简单,却不能使用系统提供给我们的适配器来做,我们来自定义适配器。
一、纵观全局—-我们先来分析一下页面有哪些元素
1、一个列表(费话,我们就是来做列表的!^_^)。
2、一个餐厅名称、一个收藏时间、一个右箭头。
3、一条分隔线(这一个千万忘不得)。
4、点击Item会有交互颜色变化。
二、技术选型
1、这一步是不可少的哈,因为实现列表,我们有多种方式,ListView可以,RecyclerView也可以,当然硬布局+ScrollView也可以(这一个估计没人这么做)等等。这里,我们使用ListView。没什么原因,就因为今天是ListView的实例。^_^
2、名称和时间肯定使用TextView了。右箭头使用ImageView,由于这个箭头只是一个标识作用,没有集成事件之类的,所以不会选择ImageButton、Button等控件。
3、分隔线,这个就有讲究了。我们仔细观察,这个分隔线是从左到右,横跨整个列表的。实现它的方法,至少有两种:(1)使用Listview自带的divder. (2)写一个View到Item布局当中。
如果这个分隔线不是横跨整个列表,而是有左边距或右边距呢,比如分隔线是和文字以及时间控件左对齐的呢,我们就只能写到Item布局当中了。
4、选择使用Selector。
三、码代码
1、构造数据,模拟好像是在线获取的数据,这里我们封闭一个数据获取的方法即可,所有的数据增删查改等都在此方法内进行。
/** * 数据封装,模拟从网络上获取到的数据 * * @return 返回数据列表 */ private List<RestaurantBean> getDatasFromNetwork() { for (int i = 0; i < Constants.PLACE.length; i++) { RestaurantBean restaurant = new RestaurantBean(); restaurant.setPlace(Constants.PLACE[i]); restaurant.setTime(Constants.TIME[i]); datas.add(restaurant); } //刷新列表,如果是真实的网络数据,则放到请求回调函数当中使用。 //注意如果是在异步线程中,应该怎么使用?它必须在主线程中执行!! listViewSimpleAdapter.notifyDataSetChanged(); return datas; }
以下附方法内使用到的常量:
package oliver.zhantao.oliverproject.constants; /** * 存放常量类 * * Created by ZhanTao on 2017/4/17. */ public class Constants { //地点列表 public static final String PLACE[] = { "德克士(新世幻环球中心店)", "肯德基(九方餐厅)", "第18区海鲜拼盘", "邓家面馆", "锦水缘餐厅", "麦地里(中海店)", "可可豆汤", "临江门火锅店", "若水河鲜", "自贡鸿鹤鲜锅兔", "又见曾毛肚老火锅" }; //时间列表 public static final String TIME[] = { "2017-04-08" , "2017-04-09", "2017-04-10", "2017-04-11", "2017-04-12", "2017-04-13", "2017-04-14" , "2017-04-15", "2017-04-16", "2017-04-17", "2017-04-18" }; }
以下附方法内使用到的实体类:
package oliver.zhantao.oliverproject.listview; import java.io.Serializable; /** * 用于存放保存餐厅的地点和时间的实体类。 * * Created by ZhanTao on 2017/4/17. */ public class RestaurantBean implements Serializable { //地点字段 private String place; //收藏时间字段 private String time; public String getPlace() { return place; } public void setPlace(String place) { this.place = place; } public String getTime() { return time; } public void setTime(String time) { this 4000 .time = time; } }
2、构建一个ListViewSimpleActivity
package oliver.zhantao.oliverproject.listview; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.widget.ListView; import java.util.ArrayList; import java.util.List; import oliver.zhantao.oliverproject.R; import oliver.zhantao.oliverproject.constants.Constants; /** * 实战项目中简单的列表实现,自定义适配器。 * 仿写百度地图当中,收藏夹里面,收藏点的列表实现。 * 一切脱离实战的实例,都是耍流氓。 * <p> * Created by ZhanTao on 2017/4/14. */ public class ListViewSimpleActivity extends AppCompatActivity { private ListView listViewSimple; private ListViewSimpleAdapter listViewSimpleAdapter; private List<RestaurantBean> datas = null; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_listview_simple); datas = new ArrayList<>(); //1、找到布局当中的列表控件 listViewSimple = (ListView) findViewById(R.id.listViewSimple); //2、创建适配器对象, 上下文必须传(非常有用)、数据必须传 listViewSimpleAdapter = new ListViewSimpleAdapter(ListViewSimpleActivity.this, datas); //3、将适配器与listview进行绑定 listViewSimple.setAdapter(listViewSimpleAdapter); //4、构造数据、刷新列表 getDatasFromNetwork(); } }
3、建立activity的布局文件activity_listview_simple
有人可能会疑惑:ConstraintLayout这个是什么布局。你可以将它改为RelativeLayout或LinearLayout,这个布局我会在以后的文章中介绍到。
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="oliver.zhantao.oliverproject.listview.ListViewSimpleActivity"> <ListView android:id="@+id/listViewSimple" android:layout_width="0dp" android:layout_height="0dp" android:listSelector="@drawable/listviewsimple_bg_selector" android:divider="@color/transparent_20" android:dividerHeight="@dimen/px_1" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> </android.support.constraint.ConstraintLayout>
以上布局文件要注意几个要点:
(1)分隔线的粗细:dividerHeight
(2)分隔线的颜色:divider
(3)点击Item后交互变化:listSelector
以下来制作:listviewsimple_bg_selector
颜色值就自己定义:以下color_221E90FF名字当中,221E90FF就是颜色值。
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@color/color_221E90FF" android:state_pressed="true" /> <item android:drawable="@color/transparent" /> </selector>
4、自定义Adapter,按照顺序,得先把优化框架搭上,这个是不能少的。然后再是填数据,附加事件
package oliver.zhantao.oliverproject.listview; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; import java.util.List; import oliver.zhantao.oliverproject.R; /** * 餐厅列表适配器,在这里将数据与控件进行绑定 * <p> * 项目中都是自定义适配器,很少用到系统提供的简易适配器。 * 所以果断抛弃系统的简易适配器,自定义想咋样就咋样,一个字,爽^_^ * <p> * Created by ZhanTao on 2017/4/17. */ public class ListViewSimpleAdapter extends BaseAdapter { private Context mContext; //餐厅列表 private List<RestaurantBean> restaurantList; private LayoutInflater mInflater; public ListViewSimpleAdapter(Context context, List<RestaurantBean> restaurantList) { this.mContext = context; this.restaurantList = restaurantList; mInflater = LayoutInflater.from(context); } @Override public int getCount() { return restaurantList.size(); } @Override public Object getItem(int position) { return position; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; //1、优化框架搭起 if (convertView == null) { convertView = mInflater.inflate(R.layout.activity_listview_simple_item, null); holder = new ViewHolder(); holder.place = (TextView) convertView.findViewById(R.id.resturant_place); holder.time = (TextView) convertView.findViewById(R.id.resturant_time); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } //2、绑定数据到控件 bindViewData(position, convertView, holder); //3、绑定监听事件 bindViewClickListener(position, convertView, holder); return convertView; } class ViewHolder { private TextView place; private TextView time; } /** * 绑定数据到控件,在这里做统一处理,方便数据抽离 * * @param position 列表索引 * @param convertView 每个position对应的itemView * @param holder holder对象 */ private void bindViewData(int position, View convertView, ViewHolder holder) { holder.place.setText(restaurantList.get(position).getPlace()); holder.time.setText("时间:" + restaurantList.get(position).getTime()); } /** * 绑定控件的各种View的事件,在这里做统一处理,比如点击事件,长安事件。 * * @param position 列表索引 * @param convertView 每个position对应的itemView * @param holder holder对象 */ private void bindViewClickListener(int position, View convertView, ViewHolder holder) { } }
5、编写Item布局文件activity_listview_simple_item
资源icon_right_arrow,大家都自己去各种app当中扒。
<?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" android:paddingBottom="@dimen/dp_10" android:paddingTop="@dimen/dp_10"> <ImageView android:id="@+id/img_right_arrow" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginLeft="@dimen/dp_16" android:layout_marginRight="@dimen/dp_16" android:src="@drawable/icon_right_arrow" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginLeft="@dimen/dp_16" android:layout_toLeftOf="@id/img_right_arrow" android:orientation="vertical"> <TextView android:id="@+id/resturant_place" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="@color/color_AA000000" android:textSize="@dimen/dp_14" /> <TextView android:id="@+id/resturant_time" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="@dimen/dp_5" android:textSize="@dimen/dp_12" /> </LinearLayout> </RelativeLayout>
下面我们来看看代码运行后的效果图:
以上,完了。代码贴完就完了。如有问题或好的建议希望大家留言,感激。
作者:Amir
博客:http://blog.csdn.NET/amir_zt/
以上原创,转载请注明出处,谢谢。
http://blog.csdn.net/amir_zt/article/details/70240519
相关文章推荐
- androidSwipeLayout简单用法,仿qq会话列表listview左右滑动
- Android关于ExpandableListView用法的一个简单小例子。仿QQ列表
- Android列表用法之二:实战ListView高级用法
- Android ListView 列表控件的简单使用
- android-ListView的简单用法
- 【Android】浅谈ListView的简单用法
- Android中通过ListView的实现简单新闻列表
- Android开发从入门到放弃(8)使用ListView显示一个简单的列表
- Android 学习笔记之ExpandableListView UI的简单用法
- 【Android成长之路】最常用和最难用的控件——ListView的浅谈(ListView 的简单用法)
- android_listView一些简单用法(动态)
- android:ListView 的简单用法
- Android学习总结(十三) ———— ListView 简单用法
- Android ListView列表控件的简单使用
- Android实战简易教程-第五枪(ListView用法研究)
- Android简易实战教程--第十八话《ListView显示,简单的适配器SimpleAdapter》
- Android——ListView实现简单列表
- Android控件之列表视图ListView与适配器用法
- Android实战简易教程<五>(ListView用法研究)
- Android实战简易教程<十四>(介绍SwipeMenuListView-简单实现类似QQ的滑动删除效果)