从头学android_ListView的使用
来源:互联网 发布:linux全局翻墙教程 编辑:程序博客网 时间:2024/06/05 04:36
需求
当界面上需要有多个条目需要显示的时候,而且条目数量不定,在xml文件中定义控件就无能为力了,这种情况下可以使用ListView,用来显示多个结构相同的条目,比如新闻客户端,应用市场app列表中,每个条目都是由相同的结构构成的,条目总数目来自于数据库,编程时未知。
步骤
首先定义一个Listview控件,找到它,设置它的适配器。
1. 定义控件
在布局文件中定义一个ListView控件,加上id方便获取,给予适当的宽高。
2. 设置Adapter
这里常用的Adapter有三种,BaseAdapter,SimpleAdapter,ArrayAdapter。其中:
baseAdapter是一个抽象类,需要继承并实现抽象方法才能使用,封装较浅,最为灵活
SimpleAdapter是BaseAdapter的子类,能通过自定义布局作为每个条目的结构来显示。
ArrayAdapter也是BaseAdapter的子类,封装度很高,能够很简单的使用,但是只能用来显示单项文本。
使用 BaseAdapter
写一个Adapter继承BaseAdapter,实现四个方法
class MyAdapter extends BaseAdapter { //有系统调用,用来获知模型层有多少条数据 @Override public int getCount() { return plist.size(); } @Override public Object getItem(int position) { return plist.get(position); } @Override public long getItemId(int position) { return position; } //由系统调用 返回的view对象就会作为listView的一个条目显示在屏幕上 @Override public View getView(int position, View convertView, ViewGroup parent) { View view; //convertView就是已经缓存好的View对象,应尽量使用已经缓存的对象,节约内存 if (convertView == null) { //获取条目的布局文件,将布局文件填充成view对象 view = View.inflate(MainActivity.this, R.layout.personlayout, null); } else { view = convertView; } //获取布局文件里面的控件 TextView tv_name = (TextView) view.findViewById(R.id.tv_name); TextView tv_phone = (TextView) view.findViewById(R.id.tv_phone); TextView tv_salary = (TextView) view.findViewById(R.id.tv_salary);<pre name="code" class="java"> //设置文本
Person person = plist.get(position); tv_name.setText(person.getName()); tv_phone.setText(person.getPhone()); tv_salary.setText(person.getSalary() + "");//如果参数是字符串,则设置字符串为文本值,如果参数是整数,则以整数为id去查找相应的资源 return view; } }
使用viewHolder;
还有一个性能优化的空间就是,每次从id中找控件,每次都是相同的id,得到相同的控件。使用viewholeder可以减少findviewbyId的次数,可以提高运行速度。
定义一个类,将控件作为其成员存在,在第一次调用getview的时候,实例化这个类,将所有findviewbyid得到的控件存入该实例,再将实例作为一个Tag保存在View中,这样,之后调用的都是缓存后的ConvertView,它的Tag肯定就是这个实例了,然后直接就可以使用这个实例的成员作为控件进行设置了。
public View getView(int position, View convertView, ViewGroup parent) { News news = newses.get(position); View view; MyViewHolder mhoder; if (convertView == null) { mhoder = new MyViewHolder(); view = View.inflate(MainActivity.this, R.layout.newslayout, null); mhoder.tv_title = (TextView) view.findViewById(R.id.tv_title); mhoder.tv_detail = (TextView) view.findViewById(R.id.tv_detail); mhoder.tv_comment = (TextView) view.findViewById(R.id.tv_comment); mhoder.imageView = (SmartImageView) view.findViewById(R.id.imageview); view.setTag(mhoder); } else { view = convertView; mhoder = (MyViewHolder) view.getTag();//这样的话,不管convertview是否为空,都能保证mholder是有值的。 } mhoder.imageView.setImageUrl(news.getImagePath()); mhoder.tv_title.setText(news.getTitle()); mhoder.tv_detail.setText(news.getDetail()); mhoder.tv_comment.setText(news.getComment()); return view; } class MyViewHolder{ private TextView tv_title; private TextView tv_detail; private TextView tv_comment; private SmartImageView imageView; }设置Adapter
if (lv != null) lv.setAdapter(new MyAdapter());结果
使用SimpleAdapter
SimpleAdapter不是抽象类,直接new就可以使用
if (lv != null) lv.setAdapter(new SimpleAdapter(MainActivity.this, data, R.layout.personlayout, new String[]{"name","phone","salary"},//data中map的key new int[]{R.id.tv_name, R.id.tv_phone, R.id.tv_salary}));//将map中的数据放到哪里去构造函数参数: arg0 Context,arg1 List<Map<String,Object>>, arg2 int, arg3 String[], arg4 int[]
其中 arg1 (data) 是一个List,泛型是Map,map的泛型是<String,?>,每一个map可以理解为一个一个条目的数据,整个list就是所有的条目的数据,而map中的每一个键值对就是每一个条目中的一个部分的标志和值。
其中arg2是描述每一个条目的布局结构的布局文件的资源id。
arg3 是一个字符串数组,与Map<String,?>中的key String。
arg4 是一个int数组,描述的是将Map中Key所对应的value设置给哪些控件,如果对应的是ImageView,那么arg3中的value应该是图片的资源Id
如:
for (Person person:plist ) { Map<String, Object> map = new HashMap<>(); map.put("name", person.getName()); map.put("phone", person.getPhone()); map.put("salary", person.getSalary()); data.add(map); }因为这里不过就是将BaseAdapter做了封装,使用的布局和数据都是一样的,所以运行结果和BaseAdapter是一样的
使用ArrayAdapter
ArrayAdapter封装度极高,只能将字符串数组作为data
if (lv!=null) lv.setAdapter(new ArrayAdapter<String>(MainActivity.this,R.layout.personlayout,R.id.tv_name,new String[]{"zhangsan","lisi"}))
可以看到定义的条目布局中只能有一个根据数据变动,应为它只能接收一个字符串数组作为data,但是使用起来也非常简单。
总结
Listview可以用来显示多条目的数据,作用就相当于JavaWeb MVC框架中的jsp。Adapter就相当于Servlet(Controller),是控制显示的。
三种Adapter各有不同,使用BaseAdapter的话,各种方法需要自己实现,如使用ConvertView来节约内存(不用的话后果很严重)等。而其他两个都已经实现好了,直接用就可以。最简单的实现就要用ArrayAdapter,需要显示特定结构的条目就需要使用SimpleAdapter,如果都不能满足,才应该考虑使用BaseAdapter。
- 从头学android_ListView的使用
- 从头学android_ViewPager的使用
- 从头学android_alertDialog的使用
- 从头学android_LocationManager的使用
- Android_Listview中使用线程实现分页延迟加载的功能
- android_ListView的操作
- Android_ListView的用法
- android_Listview
- Android_ListView
- Android_ListView
- Android_ListView
- Android_ListView控件_使用注意事项
- 出来混总要还的,从头学printf
- hibernate从头学,hibernate的配置
- Android_Listview中使用线程实现无限加载更多项目的功能
- 24、从头学Android之多媒体--使用MediaPlayer播放音频
- 25、从头学Android之多媒体--使用SoundPool播放音频
- 26、从头学Android之多媒体--使用MediaRecorder录制音频
- Android Sqlite的基本用法
- Python函数
- 括号匹配
- CS231n 卷积神经网络与计算机视觉 10 卷积神经网络学了些什么?
- 51NOD 1010 只包含因子2 3 5的数(二分 + 预处理)
- 从头学android_ListView的使用
- Android MVP架构简单封装
- TOEFL writing——6 vocabulary words
- 尺取法 poj3061
- 新领域的快速成长
- 负载均衡的那些算法们
- Hive 查询优化总结
- 关于日志分类的一些思考
- [转] maven-compiler-plugin 插件版本信息错误提示的解决方法