Android学习----自定义Adapter实现ListView
前言:
对于ListView而言,自定义的Adapter对于显示复杂的界面有很大的灵活性 。使用自定义的Adapter需要继承BaseAdapter,然后重写getCount(),getView(),getItem,getItemId()4个方法。adapter在绘制listview时是先根据getCount()获得底层数据的个数来判断绘制item的个数,然后通过getView绘制单个item。
ListView实现的效果如下:

详细步骤:
1.新建Activity,在对应的布局文件中放置listview,textview和图片按钮;
2.新建一个布局文件,布局文件中包含图片,两个textview,一个checkbox
3.自定义MyAdapter继承BaseAdapter重写4个方法;
4.给listview绑定适配器,给按钮添加点击事件。
具体实现:
布局文件:(item.xml)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" > <ImageView
android:id="@+id/img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" /> <TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toRightOf="@+id/img"
android:textSize="20sp"
android:text="" /> <TextView
android:id="@+id/info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/img"
android:layout_toRightOf="@+id/img"
android:textSize="12sp"
android:text="" />
<!--注意checkBox中focusable="false",如果不设置的话,listview的item点击事件没有用,因为item此时不能获取焦点-->
<CheckBox
android:id="@+id/cb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:focusable="false" android:text="" /> </RelativeLayout>
layout_main.xml
<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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" > <TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_toLeftOf="@id/title"
android:text="@string/title" /> <ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/imageButton1" >
</ListView> <ImageButton
android:id="@+id/imageButton1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignRight="@+id/listView1"
android:visibility="invisible"
android:src="@drawable/delete" /> </RelativeLayout>
java代码:
public class MainActivity extends Activity {
ListView listview;
//list中存储listview的每一行的内容,每一行的内容存储在map中,根据键可以取出对应的值
List<Map<String,Object>> list;
ImageButton imgbtn;
//positions中保存的是当前选中的所有元素
List<Map<String,Object>> positions=new ArrayList<Map<String,Object>>();
MyAdapter adapter=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listview=(ListView) findViewById(R.id.listView1);
imgbtn=(ImageButton) findViewById(R.id.imageButton1);
list=getData();
adapter =new MyAdapter(this,list);
listview.setAdapter(adapter);
listview.setOnItemClickListener(cl);
/*
* 根据选中的内容,删除listview中的显示
* positions中存放的是当前所有的选中项,每次删除完毕之后,应该把它清空,不然下次删除的时候
* 它还有数据,此时会出现问题。
* 删除完毕之后调用adapteradapter.notifyDataSetChanged(); 刷新view
*/
imgbtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(), "delete", Toast.LENGTH_SHORT).show();
//list.remove(int location)不能在for循环中使用
for(int i=0;i<positions.size();i++){
list.remove(positions.get(i));
}
//每一次删除完之后,把当前positions的元素删除
Iterator<Map<String,Object>> iterator=positions.iterator();
while(iterator.hasNext()){
iterator.next();
iterator.remove();
}
adapter.notifyDataSetChanged();
//删除之后设置按钮不显示
imgbtn.setVisibility(View.INVISIBLE);
}
});
}
//点击时确定当前选中的checkBox
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
/*
* 设置item的点击事件
*/
OnItemClickListener cl=new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), (String)list.get(position).get("title"), Toast.LENGTH_SHORT).show();
}
};
/*
* 提供音乐列表中的数据,包括每行数据中的歌手图片,歌曲名称,歌曲简介
*/
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("title", "真的爱你");
map.put("info", "无法可修饰的一对手,带出温暖永远在背后");
map.put("img", R.drawable.huangjiaju);
list.add(map);
map=new HashMap<String,Object>();
map.put("title", "一生有你");
map.put("info", "多少人曾爱慕你年轻时的容颜");
map.put("img", R.drawable.shuimunianhua);
list.add(map);
map=new HashMap<String,Object>();
map.put("title", "Moves Like Jagger");
map.put("info", "Just you shoot for the stars,If it feels right");
map.put("img", R.drawable.maroon5);
list.add(map);
return list;
}
//创建一个ViewHolder类,每个类对象包含ListView的Item的所有控件元素
private final class ViewHolder{
public ImageView img;
public TextView title;
public TextView info;
public CheckBox cb;
}
//自定义adapter继承自BaseAdapter,实现两个方法
/*
*
*/
class MyAdapter extends BaseAdapter{
private LayoutInflater inflater;
private List<Map<String,Object>> list;
/*
* 三种方式获取XML布局文件
* 1.LayoutInflater inflater=LayoutInflater.from(context);
* 2.LayoutInflater inflater=getLayoutInflater();
* 3.LayoutInflater inflater=(LayoutInflater) context.getSystemService(LAYOUT_INFLATER_SERVICE);
*/
public MyAdapter(Context context,List<Map<String,Object>> list){
inflater=LayoutInflater.from(context);
this.list=list;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}
/*
* (non-Javadoc)
* holder里面放置每个item的所有控件
* 当convertview为空时,说明之前没有创建过这个Item,实例化一个新的view,通过setTag方法把holder放在convertView中
* 当convertview不为空时,此时可以直接从convertView取出,使用getTag
* @see android.widget.Adapter#getView(int, android.view.View, android.view.ViewGroup)
*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder holder=null;
if(convertView==null){
holder=new ViewHolder();
convertView=inflater.inflate(R.layout.item, null);
holder.img=(ImageView) convertView.findViewById(R.id.img);
holder.title=(TextView) convertView.findViewById(R.id.title);
holder.info=(TextView) convertView.findViewById(R.id.info);
holder.cb=(CheckBox) convertView.findViewById(R.id.cb);
convertView.setTag(holder);
}else{
holder=(ViewHolder) convertView.getTag();
}
holder.img.setBackgroundResource((Integer) list.get(position).get("img"));
holder.title.setText((CharSequence) list.get(position).get("title"));
holder.info.setText((CharSequence) list.get(position).get("info"));
holder.cb.setOnCheckedChangeListener(new checkedChangeListener(position));
holder.cb.setChecked(false);//特别说明:把它全部设为false,是因为每次删除完之后会出现下一个界面上显示为选中但是不能删除,只有先取消再点击才有效,这应该是界面的绘制问题(猜测)
return convertView;
}
/*
* MyAdapter中的内部类实现了OnCheckedChangeListener接口,
* 提供一个构造函数,此处的构造函数的作用是传递了一个position参数,
* 可以与getView中的position关联起来,也可以在类内部的onCheckedChanged方法中使用。
* onCheckedChanged方法是在checkBox的状态改变时被调用的,为了删除按钮的点击事件中
* 能够获取到当前选中的所有项,所以每当选中一项,就把当前项放在一个list列表中,这样
* 在删除按钮处理点击事件时,就可以轻松完成。
* 一个小小的效果:有选中项时删除按钮显示,否则按钮消失。
* 实现:按钮初始状态为不可见,每当选中一项则设为可见,每当取消一项,判断是否还有选中,
* 若没有选中项,设为不可见
*/
class checkedChangeListener implements OnCheckedChangeListener{
int position;
public checkedChangeListener(int position){
this.position=position;
}
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
/*
* 当某一个checkbox被选中时,先显示点击了当前item,然后把当前元素作为对象加入positions列表当中
* 设置删除按钮为可见
*/
if(isChecked){
imgbtn.setVisibility(View.VISIBLE);
Toast.makeText(getApplicationContext(), "点击了"+(String)list.get(position).get("title"),Toast.LENGTH_SHORT).show();
positions.add(list.get(position));
}else{
/*
* 当该项被取消时,先显示取消了此项,然后把当前项从列表中删除,
* 每次删除完之后,判断是否还有选中项,如果没有选中项,设置删除按钮不可见
*/
Toast.makeText(getApplicationContext(), "取消了"+(String)list.get(position).get("title"),Toast.LENGTH_SHORT).show();
positions.remove(list.get(position));
//判断当前是否有选中项,若没有,隐藏删除按钮
if(positions.size()==0){
imgbtn.setVisibility(View.INVISIBLE);
}
}
}
}
/*
* 此处没有用到下面两个方法,故不作说明
* (non-Javadoc)
* @see android.widget.Adapter#getItem(int)
*/
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
}
}
代码均已测试,无明显bug。因本人水平有限,出错之处在所难免,欢迎指正。
Android学习----自定义Adapter实现ListView的更多相关文章
- 【转】Android之自定义Adapter的ListView
http://www.cnblogs.com/topcoderliu/archive/2011/05/07/2039862.html 在开发中,我们经常使用到ListView这个控件.Android的 ...
- Android之自定义Adapter的ListView
ListView的创建,一般要具备两大元素: 1)数据集,即要映射的字符串.图片信息之类. 2)适配器,实现把要映射的字符串.图片信息映射成视图(如Textview.Image等组件),再添加到Lis ...
- 【转】Android自定义Adapter的ListView的思路及代码
原文网址:http://www.jb51.net/article/37236.htm Android自定义Adapter的ListView的思路及代码,需要的朋友可以参考一下 在开发中,我们经常使 ...
- 关于自定义Adapter实现ListView的使用
以下为使用BaseAdapter作扩展,自定义Adapter来使用ListView控件: 需要注意以下的几点: 1.自定义Adapter时,需要特别注意Adapter类中getView()方法覆盖,注 ...
- android学习--视图列表(ListView和ListActivity)
说明: 视图列表(ListView和ListActivity)与AutoComplete.Spinner类似,它们都须要一个供显示的列表项,能够须要借助于内容Adapter提供显示列表项 创建List ...
- [转]Android自定义Adapter的ListView的思路及代码
本文转自:http://www.jb51.net/article/37236.htm 在开发中,我们经常使用到ListView这个控件.Android的API也提供了许多创建ListView适配器的快 ...
- Android 自定义Adapter 但listview 只显示第一条数据
<ScrollView android:layout_width="fill_parent" android:layout_height="wrap_content ...
- Android学习笔记(20)————利用ListView制作带竖线的多彩表格
http://blog.csdn.net/conowen/article/details/7421805 /********************************************** ...
- Android学习笔记-Adapter基础讲解
本节引言 从本节开始我们要讲的UI控件都是跟Adapter(适配器)打交道的,了解并学会使用这个Adapter很重要, Adapter是用来帮助填充数据的中间桥梁,简单点说就是:将各种数据以合适的形式 ...
随机推荐
- 关于org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.atguigu.crud.dao.DepartmentMapper.insertSelective的错误
今天我在使用mybatis逆向工程的时候,由于一个疏忽字打错了..结果花了一早上才把错误找全..广大小伙伴们一定要小心啊(能复制粘贴就别手打) 关于org.apache.ibatis.binding. ...
- CORS(cross-origin-resource-sharing)跨源资源共享
其实就是跨域请求.我们知道XHR只能访问同一个域中的资源,这是浏览器的安全策略所限制,但是开发中合理的跨域请求是必须的.CORS是W3的一个工作草案,基本思想就是:使用自定义的HTTP头部让浏览器与服 ...
- django setting文件那些事
1.设置语言.时区 2.设置新建的用户表作为默认用户表 3.利用apps文件夹收纳app 新建python package apps,然后把app放在该文件夹下 然后setting中添加如下代码: 4 ...
- linux下 GUI 数码相册项目 持续更新中
GITHUB: https://github.com/nejidev/digital_photo_album 本项目,是部分参考别人的项目,是全新从0编写的.算法实现和别人肯定是不同的,github ...
- Logback,SLF4J,Log4J2。了解它们并学习如何使用。(翻译)
背景 如果您正在或在任何Java项目上工作,则可能已记录了一些debug,error或info语句以进行调试或跟踪.通过将库记录到磁盘或其他某种介质上的文件中来写这些语句. 日志记录是任何项目的关键方 ...
- js实现字符串逆向输出的4种方式
一.第一种方式(利用charAt()这个函数实现) 代码如下: var str="你好世界!!!!"; var str1="";//这里创建一个空字符串用来拼接 ...
- guava限流器RateLimiter原理及源码分析
前言 RateLimiter是基于令牌桶算法实现的一个多线程限流器,它可以将请求均匀的进行处理,当然他并不是一个分布式限流器,只是对单机进行限流.它可以应用在定时拉取接口数据, 预防单机过大流量使用. ...
- react 新创建项目
1,先创建一个文件夹用于存放项目 2,运行cmd,路径选择到你创建的文件夹内 3, npm install -g create-react-app create-react-app ...
- 【Python】2.13学习笔记 数学函数和随机函数
我死了,今天看课看过头了,忘了发作业,被典明批评 而且化学作业还是瞎搞的,直接就发了 我觉得我已经提前死亡了,现在不死亡,开学也会的 函数 挺容易的,有很多语言之间重合的部分 注意 在使用某些数学函数 ...
- 2016 Multi-University Training Contest 1 T4
http://acm.hdu.edu.cn/showproblem.php?pid=5726 求不修改区间gcd可以用线段树或者倍增. 求l-n的我们注意观察gcd(al,al+1,... ...