带checkbox的ListView实现—数据与渲染完全分离的传统实现方式
2015-08-21 11:58
489 查看
目录(?)[+]
一activity_mainxml
二ListItem布局check_list_itemxml
三ViewHolderListItem对应的视图类
四DataHolderListItem对应的数据类
五ListitemAdapter
六 MainActivity
前言:这几天在公司跟着他们写代码才发现,公司有那么多的牛人,个个都很厉害,在他们的帮助下,自己提升的很快,性格又极好的一帮人,真的很招人喜欢。这篇文章使用传统的实现方法来实现带CheckBox的ListView的实现,下一篇写写一个牛人教我的,如何使用重写布局控件来实现带CheckBox的ListView的。
DropBox老总回到母校在毕业生典礼的一段话送给大家:大学里植入的一个错误理念就是“先准备好”虽然学习仍然占据首要位置,不过最快的学习方式还是去实践,如果你拥有梦想,你有一生的时间去学习和准备,而你所要做的就是马上实施。诚实地说,我从来没有准备好。
相关文章:
1、《带checkbox的ListView实现(一)——数据与渲染完全分离的传统实现方式》
2、《带checkbox的ListView实现(二)——自定义Checkable控件的实现方法》
3、《带checkbox的ListView实现(三)——CheckableImageView的实现方法》
先给大家看看实现的效果:
在ListView中,我们一般为了在实现Adapter时,是ListItem渲染与其中的数据完全分离的,可能初学者对数据分离不太清楚,后面我会慢慢讲解。先看主布局(activity_main.xml)
<FrameLayout 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" > <ListView android:id="@+id/list" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="100dp" android:dividerHeight="1px" android:scrollbars="none" /> <Button android:id="@+id/all_sel" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="50dip" android:layout_gravity="bottom" android:text="全选" /> <Button android:id="@+id/all_unsel" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:text="全部取消"/> </FrameLayout>
布局没有特别之处,一个LIstView,两个button,没什么特别注意的地方,下面看看单个Item的布局
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="68dp"> <CheckBox android:id="@+id/checkbox" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="right|center_vertical" android:clickable="false" android:focusable="false" /> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginBottom="17dp" android:layout_marginTop="17dp" android:orientation="vertical"> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="16sp" /> <TextView android:id="@+id/subtitle" android:textSize="12sp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> </FrameLayout>
这个布局就是这样的,左边是一个垂直布局的LinearLayout,一个主标题,一个副标题;右边是一个CheckBox;
但这里有个地方要注意:CheckBox一定要添加两个属性:
[html]view plaincopyprint?
android:clickable="false"
android:focusable="false"
首先将CheckBox设置为不可点击,这样就不会造成ListView无法捕捉当前CheckBox状态的尴尬局面,如果不理解,把这个参数删除,看看代码运行效果就清楚了。另外要把Checbox的获取焦点的属性取消,不然ListView是无法点击的,因为焦点都在CheckBox那了。(坑爹玩意)
上面我们给出了ListItem的布局,下面看看这个Item对应的数据;
public class ViewHolder{ public TextView mTitle; public TextView mSubTitile; public CheckBox mCheckBox; };
这里的三个控件完全对应布局里的三个控件。
package com.harvic.trylistviewcheckboxdata; public class DataHolder{ public String titleStr; public String subTitleStr; public boolean checked; public DataHolder(String title,String subTitle,boolean check){ titleStr = title; subTitleStr = subTitle; checked=check; } }
这里有三个变量,分别对应三个控件所就显示的数据:titleStr对应主标题文字,subTitleStr对应副标题文字,checked对应checkbox是否选中状态。下面就是有点艰难的部分了,ListitemAdapter的生成。
[java]view plaincopyprint?
package com.harvic.trylistviewcheckboxdata; import java.util.List; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.CheckBox; import android.widget.TextView; public class ListitemAdapter extends BaseAdapter { private List<DataHolder> mList; private Context mContext; private LayoutInflater mInflater; public ListitemAdapter(Context context,List<DataHolder> list){ mList = list; mContext = context; mInflater = LayoutInflater.from(context); } @Override public int getCount() { // TODO Auto-generated method stub return mList.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return mList.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @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 = mInflater.inflate(R.layout.check_list_item, null); holder.mTitle = (TextView)convertView.findViewById(R.id.title); holder.mSubTitile = (TextView)convertView.findViewById(R.id.subtitle); holder.mCheckBox = (CheckBox)convertView.findViewById(R.id.checkbox); convertView.setTag(holder); }else { holder = (ViewHolder)convertView.getTag(); } holder.mTitle.setText((String)mList.get(position).titleStr); holder.mSubTitile.setText((String)mList.get(position).subTitleStr); holder.mCheckBox.setChecked(mList.get(position).checked); return convertView; } }
首先看构造函数:
[java]view plaincopyprint?
public ListitemAdapter(Context context,List<DataHolder> list){ mList = list; mContext = context; mInflater = LayoutInflater.from(context); }
传进来一个Context,一个DataHolder的数组;这个数组就是我们的Adapter要显示的所有数据,我们就要根据这个数组的内容,一行行显示数据。
下面我们看显示数据部分:
[java]view plaincopyprint?
public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub ViewHolder holder = null; if (convertView == null) { holder=new ViewHolder(); convertView = mInflater.inflate(R.layout.check_list_item, null); holder.mTitle = (TextView)convertView.findViewById(R.id.title); holder.mSubTitile = (TextView)convertView.findViewById(R.id.subtitle); holder.mCheckBox = (CheckBox)convertView.findViewById(R.id.checkbox); convertView.setTag(holder); }else { holder = (ViewHolder)convertView.getTag(); } holder.mTitle.setText((String)mList.get(position).titleStr); holder.mSubTitile.setText((String)mList.get(position).subTitleStr); holder.mCheckBox.setChecked(mList.get(position).checked); return convertView; }
至于为什么要判断ConvertView是否为空以及setTag()和getTag()的问题,看这篇文章:《BaseAdapter——convertView回收机制与动态控件响应》
在getview函数中的如果这个ConvertView是新建的,那么就会通过获取R.layout.check_list_item中的控件,并与ViewHolder中的变量绑定;
[java]view plaincopyprint?
holder=new ViewHolder();
convertView = mInflater.inflate(R.layout.check_list_item, null);
holder.mTitle = (TextView)convertView.findViewById(R.id.title);
holder.mSubTitile = (TextView)convertView.findViewById(R.id.subtitle);
holder.mCheckBox = (CheckBox)convertView.findViewById(R.id.checkbox);
convertView.setTag(holder);
至于回收来的ConvertView是已经绑定好了的,所以就不必重新生成ViewHolder,不懂的话看上面的《BaseAdapter——convertView回收机制与动态控件响应》
然后根据当前这个<DataHolder> list中的数据来显示当前Item的数据;
[java]view plaincopyprint?
holder.mTitle.setText((String)mList.get(position).titleStr);
holder.mSubTitile.setText((String)mList.get(position).subTitleStr);
holder.mCheckBox.setChecked(mList.get(position).checked);
[java]view plaincopyprint?
package com.harvic.trylistviewcheckboxdata; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.AdapterView.OnItemClickListener; import android.widget.AdapterView; import android.widget.Button; import android.widget.ListView; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //初始化数据 final List<DataHolder> dataList = new ArrayList<DataHolder>(); for (int i = 0; i < 10; i++) { dataList.add(new DataHolder("harvic的blog------" + i, "harvic", false)); } //构造Adapter final ListitemAdapter adapter = new ListitemAdapter(MainActivity.this,dataList); //设置adapter final ListView listView = (ListView) findViewById(R.id.list); listView.setAdapter(adapter); listView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // TODO Auto-generated method stub boolean checked = dataList.get(position).checked; if (!checked) { dataList.get(position).checked = true; }else { dataList.get(position).checked = false; } adapter.notifyDataSetChanged(); } }); //全选按钮按钮设置 Button all_sel = (Button) findViewById(R.id.all_sel); Button all_unsel = (Button) findViewById(R.id.all_unsel); all_sel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub for (int i = 0; i < dataList.size(); i++) { dataList.get(i).checked=true; } adapter.notifyDataSetChanged(); } }); //全部取消的设置 all_unsel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub for (int i = 0; i < dataList.size(); i++) { dataList.get(i).checked=false; } adapter.notifyDataSetChanged(); } }); } }
首先是要构造我们要显示数据,下面这段代码:
[java]view plaincopyprint?
//初始化数据 final List<DataHolder> dataList = new ArrayList<DataHolder>(); for (int i = 0; i < 10; i++) { dataList.add(new DataHolder("harvic的blog------" + i, "harvic", false)); }
然后把构造的List<DataHolder> dataList传入ListitemAdapter的构造函数,构造Adapter,并设置到ListView中
[java]view plaincopyprint?
//构造Adapter final ListitemAdapter adapter = new ListitemAdapter(MainActivity.this,dataList); //设置adapter final ListView listView = (ListView) findViewById(R.id.list); listView.setAdapter(adapter);
虽然我们已经为listview设置了adapter,此时已经能显示我们传进去的所有数据,但还没有办法响应我们的点击事件,所有要对ListView设置onItemClickListener
[java]view plaincopyprint?
//设置ListItem点击监听函数 listView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // TODO Auto-generated method stub boolean checked = dataList.get(position).checked; if (!checked) { dataList.get(position).checked = true; }else { dataList.get(position).checked = false; } adapter.notifyDataSetChanged(); } });
当用户点击某一项时,先看当前项是选中状态还是未选中状态,如果已经选中则取消,如果没选中就选中它。最后通过adapter.notifyDataSetChanged();通知ListView显示数据已经改变,让界面根据最新数据重绘。
到这里,对于数据的显示和单击事件的响应都已经讲完了,下面就讲讲全选和全部取消按钮的实现。
[java]view plaincopyprint?
//全选按钮按钮设置
Button all_sel = (Button) findViewById(R.id.all_sel);
Button all_unsel = (Button) findViewById(R.id.all_unsel);
all_sel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
for (int i = 0; i < dataList.size(); i++) {
dataList.get(i).checked=true;
}
adapter.notifyDataSetChanged();
}
});
当用户点击全选按钮时,对datalist中的所有checked数据进行轮询,将所有的checked都设为true,在listItemAdapter根据datalist中的checked字段进行显示时,自然就全部呈现选中状态。
同理,在全部取消的按钮实现时就是把dataList中表示所有Item 的checkbox选中与否状态的checked字段置为false;代码如下:
[java]view plaincopyprint?
//全部取消的设置 all_unsel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub for (int i = 0; i < dataList.size(); i++) { dataList.get(i).checked=false; } adapter.notifyDataSetChanged(); } });
至此,整篇文章就讲完了,以前也写过几篇有关ListView的文章,当时觉得写的还挺好的,可到现在一看,完全不行,自己都不愿意再看,晦涩难懂,也可能是当时的技术不到家吧,有时间我可能会把有关ListView入门的一些东东讲给大家听,这里不再列以前的几篇文章了。
源码地址:http://download.csdn.net/detail/harvic880925/8081811
请大家尊重原创者版权,转载请标明出处:http://blog.csdn.net/harvic880925/article/details/40458213
谢谢!
一activity_mainxml
二ListItem布局check_list_itemxml
三ViewHolderListItem对应的视图类
四DataHolderListItem对应的数据类
五ListitemAdapter
六 MainActivity
前言:这几天在公司跟着他们写代码才发现,公司有那么多的牛人,个个都很厉害,在他们的帮助下,自己提升的很快,性格又极好的一帮人,真的很招人喜欢。这篇文章使用传统的实现方法来实现带CheckBox的ListView的实现,下一篇写写一个牛人教我的,如何使用重写布局控件来实现带CheckBox的ListView的。
DropBox老总回到母校在毕业生典礼的一段话送给大家:大学里植入的一个错误理念就是“先准备好”虽然学习仍然占据首要位置,不过最快的学习方式还是去实践,如果你拥有梦想,你有一生的时间去学习和准备,而你所要做的就是马上实施。诚实地说,我从来没有准备好。
相关文章:
1、《带checkbox的ListView实现(一)——数据与渲染完全分离的传统实现方式》
2、《带checkbox的ListView实现(二)——自定义Checkable控件的实现方法》
3、《带checkbox的ListView实现(三)——CheckableImageView的实现方法》
先给大家看看实现的效果:
在ListView中,我们一般为了在实现Adapter时,是ListItem渲染与其中的数据完全分离的,可能初学者对数据分离不太清楚,后面我会慢慢讲解。先看主布局(activity_main.xml)
一、activity_main.xml
[html]view plaincopyprint?<FrameLayout 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" > <ListView android:id="@+id/list" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="100dp" android:dividerHeight="1px" android:scrollbars="none" /> <Button android:id="@+id/all_sel" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="50dip" android:layout_gravity="bottom" android:text="全选" /> <Button android:id="@+id/all_unsel" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:text="全部取消"/> </FrameLayout>
<FrameLayout 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" > <ListView android:id="@+id/list" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="100dp" android:dividerHeight="1px" android:scrollbars="none" /> <Button android:id="@+id/all_sel" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="50dip" android:layout_gravity="bottom" android:text="全选" /> <Button android:id="@+id/all_unsel" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:text="全部取消"/> </FrameLayout>
布局没有特别之处,一个LIstView,两个button,没什么特别注意的地方,下面看看单个Item的布局
二、ListItem布局(check_list_item.xml)
[html]view plaincopyprint?<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="68dp"> <CheckBox android:id="@+id/checkbox" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="right|center_vertical" android:clickable="false" android:focusable="false" /> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginBottom="17dp" android:layout_marginTop="17dp" android:orientation="vertical"> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="16sp" /> <TextView android:id="@+id/subtitle" android:textSize="12sp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> </FrameLayout>
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="68dp"> <CheckBox android:id="@+id/checkbox" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="right|center_vertical" android:clickable="false" android:focusable="false" /> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginBottom="17dp" android:layout_marginTop="17dp" android:orientation="vertical"> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="16sp" /> <TextView android:id="@+id/subtitle" android:textSize="12sp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> </FrameLayout>
这个布局就是这样的,左边是一个垂直布局的LinearLayout,一个主标题,一个副标题;右边是一个CheckBox;
但这里有个地方要注意:CheckBox一定要添加两个属性:
[html]view plaincopyprint?
android:clickable="false"
android:focusable="false"
android:clickable="false" android:focusable="false"
首先将CheckBox设置为不可点击,这样就不会造成ListView无法捕捉当前CheckBox状态的尴尬局面,如果不理解,把这个参数删除,看看代码运行效果就清楚了。另外要把Checbox的获取焦点的属性取消,不然ListView是无法点击的,因为焦点都在CheckBox那了。(坑爹玩意)
上面我们给出了ListItem的布局,下面看看这个Item对应的数据;
三、ViewHolder——ListItem对应的视图类
[java]view plaincopyprint?public class ViewHolder{ public TextView mTitle; public TextView mSubTitile; public CheckBox mCheckBox; };
public class ViewHolder{ public TextView mTitle; public TextView mSubTitile; public CheckBox mCheckBox; };
这里的三个控件完全对应布局里的三个控件。
四、DataHolder——ListItem对应的数据类
[java]view plaincopyprint?package com.harvic.trylistviewcheckboxdata; public class DataHolder{ public String titleStr; public String subTitleStr; public boolean checked; public DataHolder(String title,String subTitle,boolean check){ titleStr = title; subTitleStr = subTitle; checked=check; } }
package com.harvic.trylistviewcheckboxdata; public class DataHolder{ public String titleStr; public String subTitleStr; public boolean checked; public DataHolder(String title,String subTitle,boolean check){ titleStr = title; subTitleStr = subTitle; checked=check; } }
这里有三个变量,分别对应三个控件所就显示的数据:titleStr对应主标题文字,subTitleStr对应副标题文字,checked对应checkbox是否选中状态。下面就是有点艰难的部分了,ListitemAdapter的生成。
五、ListitemAdapter
先给出完整代码,然后再细讲:看不懂的话,往下看;[java]view plaincopyprint?
package com.harvic.trylistviewcheckboxdata; import java.util.List; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.CheckBox; import android.widget.TextView; public class ListitemAdapter extends BaseAdapter { private List<DataHolder> mList; private Context mContext; private LayoutInflater mInflater; public ListitemAdapter(Context context,List<DataHolder> list){ mList = list; mContext = context; mInflater = LayoutInflater.from(context); } @Override public int getCount() { // TODO Auto-generated method stub return mList.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return mList.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @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 = mInflater.inflate(R.layout.check_list_item, null); holder.mTitle = (TextView)convertView.findViewById(R.id.title); holder.mSubTitile = (TextView)convertView.findViewById(R.id.subtitle); holder.mCheckBox = (CheckBox)convertView.findViewById(R.id.checkbox); convertView.setTag(holder); }else { holder = (ViewHolder)convertView.getTag(); } holder.mTitle.setText((String)mList.get(position).titleStr); holder.mSubTitile.setText((String)mList.get(position).subTitleStr); holder.mCheckBox.setChecked(mList.get(position).checked); return convertView; } }
package com.harvic.trylistviewcheckboxdata; import java.util.List; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.CheckBox; import android.widget.TextView; public class ListitemAdapter extends BaseAdapter { private List<DataHolder> mList; private Context mContext; private LayoutInflater mInflater; public ListitemAdapter(Context context,List<DataHolder> list){ mList = list; mContext = context; mInflater = LayoutInflater.from(context); } @Override public int getCount() { // TODO Auto-generated method stub return mList.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return mList.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @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 = mInflater.inflate(R.layout.check_list_item, null); holder.mTitle = (TextView)convertView.findViewById(R.id.title); holder.mSubTitile = (TextView)convertView.findViewById(R.id.subtitle); holder.mCheckBox = (CheckBox)convertView.findViewById(R.id.checkbox); convertView.setTag(holder); }else { holder = (ViewHolder)convertView.getTag(); } holder.mTitle.setText((String)mList.get(position).titleStr); holder.mSubTitile.setText((String)mList.get(position).subTitleStr); holder.mCheckBox.setChecked(mList.get(position).checked); return convertView; } }
首先看构造函数:
[java]view plaincopyprint?
public ListitemAdapter(Context context,List<DataHolder> list){ mList = list; mContext = context; mInflater = LayoutInflater.from(context); }
public ListitemAdapter(Context context,List<DataHolder> list){ mList = list; mContext = context; mInflater = LayoutInflater.from(context); }
传进来一个Context,一个DataHolder的数组;这个数组就是我们的Adapter要显示的所有数据,我们就要根据这个数组的内容,一行行显示数据。
下面我们看显示数据部分:
[java]view plaincopyprint?
public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub ViewHolder holder = null; if (convertView == null) { holder=new ViewHolder(); convertView = mInflater.inflate(R.layout.check_list_item, null); holder.mTitle = (TextView)convertView.findViewById(R.id.title); holder.mSubTitile = (TextView)convertView.findViewById(R.id.subtitle); holder.mCheckBox = (CheckBox)convertView.findViewById(R.id.checkbox); convertView.setTag(holder); }else { holder = (ViewHolder)convertView.getTag(); } holder.mTitle.setText((String)mList.get(position).titleStr); holder.mSubTitile.setText((String)mList.get(position).subTitleStr); holder.mCheckBox.setChecked(mList.get(position).checked); return convertView; }
public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub ViewHolder holder = null; if (convertView == null) { holder=new ViewHolder(); convertView = mInflater.inflate(R.layout.check_list_item, null); holder.mTitle = (TextView)convertView.findViewById(R.id.title); holder.mSubTitile = (TextView)convertView.findViewById(R.id.subtitle); holder.mCheckBox = (CheckBox)convertView.findViewById(R.id.checkbox); convertView.setTag(holder); }else { holder = (ViewHolder)convertView.getTag(); } holder.mTitle.setText((String)mList.get(position).titleStr); holder.mSubTitile.setText((String)mList.get(position).subTitleStr); holder.mCheckBox.setChecked(mList.get(position).checked); return convertView; }
至于为什么要判断ConvertView是否为空以及setTag()和getTag()的问题,看这篇文章:《BaseAdapter——convertView回收机制与动态控件响应》
在getview函数中的如果这个ConvertView是新建的,那么就会通过获取R.layout.check_list_item中的控件,并与ViewHolder中的变量绑定;
[java]view plaincopyprint?
holder=new ViewHolder();
convertView = mInflater.inflate(R.layout.check_list_item, null);
holder.mTitle = (TextView)convertView.findViewById(R.id.title);
holder.mSubTitile = (TextView)convertView.findViewById(R.id.subtitle);
holder.mCheckBox = (CheckBox)convertView.findViewById(R.id.checkbox);
convertView.setTag(holder);
holder=new ViewHolder(); convertView = mInflater.inflate(R.layout.check_list_item, null); holder.mTitle = (TextView)convertView.findViewById(R.id.title); holder.mSubTitile = (TextView)convertView.findViewById(R.id.subtitle); holder.mCheckBox = (CheckBox)convertView.findViewById(R.id.checkbox); convertView.setTag(holder);
至于回收来的ConvertView是已经绑定好了的,所以就不必重新生成ViewHolder,不懂的话看上面的《BaseAdapter——convertView回收机制与动态控件响应》
然后根据当前这个<DataHolder> list中的数据来显示当前Item的数据;
[java]view plaincopyprint?
holder.mTitle.setText((String)mList.get(position).titleStr);
holder.mSubTitile.setText((String)mList.get(position).subTitleStr);
holder.mCheckBox.setChecked(mList.get(position).checked);
holder.mTitle.setText((String)mList.get(position).titleStr); holder.mSubTitile.setText((String)mList.get(position).subTitleStr); holder.mCheckBox.setChecked(mList.get(position).checked);
六、 MainActivity
同样,先给出全部代码,然后逐步讲解:[java]view plaincopyprint?
package com.harvic.trylistviewcheckboxdata; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.AdapterView.OnItemClickListener; import android.widget.AdapterView; import android.widget.Button; import android.widget.ListView; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //初始化数据 final List<DataHolder> dataList = new ArrayList<DataHolder>(); for (int i = 0; i < 10; i++) { dataList.add(new DataHolder("harvic的blog------" + i, "harvic", false)); } //构造Adapter final ListitemAdapter adapter = new ListitemAdapter(MainActivity.this,dataList); //设置adapter final ListView listView = (ListView) findViewById(R.id.list); listView.setAdapter(adapter); listView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // TODO Auto-generated method stub boolean checked = dataList.get(position).checked; if (!checked) { dataList.get(position).checked = true; }else { dataList.get(position).checked = false; } adapter.notifyDataSetChanged(); } }); //全选按钮按钮设置 Button all_sel = (Button) findViewById(R.id.all_sel); Button all_unsel = (Button) findViewById(R.id.all_unsel); all_sel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub for (int i = 0; i < dataList.size(); i++) { dataList.get(i).checked=true; } adapter.notifyDataSetChanged(); } }); //全部取消的设置 all_unsel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub for (int i = 0; i < dataList.size(); i++) { dataList.get(i).checked=false; } adapter.notifyDataSetChanged(); } }); } }
package com.harvic.trylistviewcheckboxdata; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.AdapterView.OnItemClickListener; import android.widget.AdapterView; import android.widget.Button; import android.widget.ListView; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //初始化数据 final List<DataHolder> dataList = new ArrayList<DataHolder>(); for (int i = 0; i < 10; i++) { dataList.add(new DataHolder("harvic的blog------" + i, "harvic", false)); } //构造Adapter final ListitemAdapter adapter = new ListitemAdapter(MainActivity.this,dataList); //设置adapter final ListView listView = (ListView) findViewById(R.id.list); listView.setAdapter(adapter); listView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // TODO Auto-generated method stub boolean checked = dataList.get(position).checked; if (!checked) { dataList.get(position).checked = true; }else { dataList.get(position).checked = false; } adapter.notifyDataSetChanged(); } }); //全选按钮按钮设置 Button all_sel = (Button) findViewById(R.id.all_sel); Button all_unsel = (Button) findViewById(R.id.all_unsel); all_sel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub for (int i = 0; i < dataList.size(); i++) { dataList.get(i).checked=true; } adapter.notifyDataSetChanged(); } }); //全部取消的设置 all_unsel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub for (int i = 0; i < dataList.size(); i++) { dataList.get(i).checked=false; } adapter.notifyDataSetChanged(); } }); } }
首先是要构造我们要显示数据,下面这段代码:
[java]view plaincopyprint?
//初始化数据 final List<DataHolder> dataList = new ArrayList<DataHolder>(); for (int i = 0; i < 10; i++) { dataList.add(new DataHolder("harvic的blog------" + i, "harvic", false)); }
//初始化数据 final List<DataHolder> dataList = new ArrayList<DataHolder>(); for (int i = 0; i < 10; i++) { dataList.add(new DataHolder("harvic的blog------" + i, "harvic", false)); }
然后把构造的List<DataHolder> dataList传入ListitemAdapter的构造函数,构造Adapter,并设置到ListView中
[java]view plaincopyprint?
//构造Adapter final ListitemAdapter adapter = new ListitemAdapter(MainActivity.this,dataList); //设置adapter final ListView listView = (ListView) findViewById(R.id.list); listView.setAdapter(adapter);
//构造Adapter final ListitemAdapter adapter = new ListitemAdapter(MainActivity.this,dataList); //设置adapter final ListView listView = (ListView) findViewById(R.id.list); listView.setAdapter(adapter);
虽然我们已经为listview设置了adapter,此时已经能显示我们传进去的所有数据,但还没有办法响应我们的点击事件,所有要对ListView设置onItemClickListener
[java]view plaincopyprint?
//设置ListItem点击监听函数 listView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // TODO Auto-generated method stub boolean checked = dataList.get(position).checked; if (!checked) { dataList.get(position).checked = true; }else { dataList.get(position).checked = false; } adapter.notifyDataSetChanged(); } });
//设置ListItem点击监听函数 listView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // TODO Auto-generated method stub boolean checked = dataList.get(position).checked; if (!checked) { dataList.get(position).checked = true; }else { dataList.get(position).checked = false; } adapter.notifyDataSetChanged(); } });
当用户点击某一项时,先看当前项是选中状态还是未选中状态,如果已经选中则取消,如果没选中就选中它。最后通过adapter.notifyDataSetChanged();通知ListView显示数据已经改变,让界面根据最新数据重绘。
到这里,对于数据的显示和单击事件的响应都已经讲完了,下面就讲讲全选和全部取消按钮的实现。
[java]view plaincopyprint?
//全选按钮按钮设置
Button all_sel = (Button) findViewById(R.id.all_sel);
Button all_unsel = (Button) findViewById(R.id.all_unsel);
all_sel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
for (int i = 0; i < dataList.size(); i++) {
dataList.get(i).checked=true;
}
adapter.notifyDataSetChanged();
}
});
//全选按钮按钮设置 Button all_sel = (Button) findViewById(R.id.all_sel); Button all_unsel = (Button) findViewById(R.id.all_unsel); all_sel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub for (int i = 0; i < dataList.size(); i++) { dataList.get(i).checked=true; } adapter.notifyDataSetChanged(); } });
当用户点击全选按钮时,对datalist中的所有checked数据进行轮询,将所有的checked都设为true,在listItemAdapter根据datalist中的checked字段进行显示时,自然就全部呈现选中状态。
同理,在全部取消的按钮实现时就是把dataList中表示所有Item 的checkbox选中与否状态的checked字段置为false;代码如下:
[java]view plaincopyprint?
//全部取消的设置 all_unsel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub for (int i = 0; i < dataList.size(); i++) { dataList.get(i).checked=false; } adapter.notifyDataSetChanged(); } });
//全部取消的设置 all_unsel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub for (int i = 0; i < dataList.size(); i++) { dataList.get(i).checked=false; } adapter.notifyDataSetChanged(); } });
至此,整篇文章就讲完了,以前也写过几篇有关ListView的文章,当时觉得写的还挺好的,可到现在一看,完全不行,自己都不愿意再看,晦涩难懂,也可能是当时的技术不到家吧,有时间我可能会把有关ListView入门的一些东东讲给大家听,这里不再列以前的几篇文章了。
源码地址:http://download.csdn.net/detail/harvic880925/8081811
请大家尊重原创者版权,转载请标明出处:http://blog.csdn.net/harvic880925/article/details/40458213
谢谢!
相关文章推荐
- hadoop Unhealthy Nodes问题解决
- Android 实现个性的ViewPager切换动画 实战PageTransformer(兼容Android3.0以下)
- Sublime Text3安装插件方法详解
- 玩转Bootstrap(基础) -- (5.下拉菜单)
- mac系统mysql配置环境变量(转)
- Material Design Lite,简洁惊艳的前端工具箱。
- Eclipse中Outline里各种图标的含义
- pdf格式的电子如何转换成html
- 用户与内核交互--netlink
- 百度网页分享js代码
- 用选择法对10个整数按从小到大排序(数组)
- 学习笔记之SQl语句-插入对象的值
- LoadRunner11学习记录一
- html5获取地理位置信息
- 什么是领域驱动设计(Domain Driven Design)?
- AngularJS自定义Echarts标签 — 折线图Line
- gridx的使用
- Android推送服务——百度云推送
- 关于Repository模式
- Android中自定义checkbox样式