最近尝试做了个listview的多选demo,网上看其他人的例子感觉不是很难,自己动手做了下,各种细节问题,没那么简单啊。既然做了,简单写个笔记记录下。
练手demo,命名笔记乱,不要介意哦。
主界面布局activity_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:id=\"@+id/rootView\" 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=\"com.example.listchecked.MainActivity\" > <ListView android:id=\"@+id/listView1\" android:layout_width=\"match_parent\" android:layout_height=\"wrap_content\" android:layout_marginBottom=\"50dp\" > </ListView> <LinearLayout android:id=\"@+id/button_group\" android:layout_width=\"match_parent\" android:layout_height=\"wrap_content\" android:layout_alignLeft=\"@+id/listView1\" android:layout_alignParentBottom=\"true\" android:orientation=\"vertical\" > <Button android:id=\"@+id/del\" android:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\" android:text=\"删除\" /> </LinearLayout> </RelativeLayout>
列表item的布局
<?xml version=\"1.0\" encoding=\"utf-8\"?>
<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"
android:layout_width=\"match_parent\"
android:layout_height=\"match_parent\"
android:orientation=\"horizontal\"
android:descendantFocusability=\"blocksDescendants\" >
<!--注意上面这个属性,很关键,不加会导致list无法响应OnItemClickListener中的事件-->
<RelativeLayout
android:layout_width=\"match_parent\"
android:layout_height=\"match_parent\"
android:layout_weight=\"1\"
>
<CheckBox
android:id=\"@+id/checkBox1\"
android:layout_width=\"wrap_content\"
android:layout_height=\"wrap_content\"
android:clickable=\"false\"
android:focusable=\"false\" />
<ImageView
android:id=\"@+id/imageView1\"
android:layout_width=\"match_parent\"
android:layout_height=\"match_parent\"
android:scaleType=\"fitCenter\"
android:src=\"@drawable/ic_launcher\" />
</RelativeLayout>
<LinearLayout
android:layout_width=\"match_parent\"
android:layout_height=\"match_parent\"
android:layout_weight=\"1\"
android:gravity=\"center\"
android:orientation=\"vertical\" >
<TextView
android:id=\"@+id/title\"
android:layout_width=\"match_parent\"
android:layout_height=\"wrap_content\"
android:text=\"Title\"
android:textSize=\"20sp\" />
<TextView
android:id=\"@+id/teacher\"
android:layout_width=\"match_parent\"
android:layout_height=\"wrap_content\"
android:text=\"Teacher\" />
<TextView
android:id=\"@+id/time\"
android:layout_width=\"match_parent\"
android:layout_height=\"wrap_content\"
android:text=\"Time\" />
<TextView
android:id=\"@+id/peopleNum\"
android:layout_width=\"match_parent\"
android:layout_height=\"wrap_content\"
android:text=\"peopleNum\"
/>
</LinearLayout>
</LinearLayout>
这个item的布局就被在细节上坑了一次,item中添加button,checkbox,imageButton等时,会导致只响应这些控件的事件,item整体的事件就不会响应了,刚开始没有加那条属性,勾选checkbox后,点删除没有反应。这问题要发现也有点难度,之前见大神们推荐过分析布局的工具hierarchyviewer,这个工具,个人感觉和前端开发中的F12类似啊,很方便,可以看到每个布局的情况。也是好奇,点开一看,整个item的布局,从父布局,到子布局,只要checkbox可以接受click,其他全部是false,这就是问题所在了,后来百度了一下,即如上结论。
解决办法就是添加Android:descendantFocusability=”blocksDescendants” 到list的item的布局里,添加以后,发现checkbox还是可以被单独点击,不响应list的点击选中事件,很是奇怪,看其他人的例子中就没有这种现象。最后只能设置checkbox不能被点击 android:clickable=”false” 布局问题解决了,下面是java类的源码:
首先是bean类,ItemBean.java
package com.example.listchecked;
public class ItemBean {
private int imgRes;
private String title,teacher,time;
private int peopleNum,id;
private boolean isChecked;
private boolean isShow;
public boolean isShow() {
return isShow;
}
public void setShow(boolean isShow) {
this.isShow = isShow;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public boolean isChecked() {
return isChecked;
}
public void setChecked(boolean isChecked) {
this.isChecked = isChecked;
}
public int getImgRes() {
return imgRes;
}
public void setImgRes(int img) {
this.imgRes = img;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getTeacher() {
return teacher;
}
public void setTeacher(String teacher) {
this.teacher = teacher;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public int getPeopleNum() {
return peopleNum;
}
public void setPeopleNum(int peopleNum) {
this.peopleNum = peopleNum;
}
}
自定义的Adapter,MyListAdapter.java
package com.example.listchecked;
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.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView;
import android.widget.TextView;
public class MyListAdapter extends BaseAdapter
{
private LayoutInflater inflater;
private List<ItemBean> items;
private ItemBean item;
private OnShowItemClickListener onShowItemClickListener;
public MyListAdapter(List<ItemBean> list,Context context)
{
items=list;
inflater=LayoutInflater.from(context);
}
@Override
public int getCount() {
// TODO 自动生成的方法存根
return items.size();
}
@Override
public Object getItem(int position) {
// TODO 自动生成的方法存根
return items.get(position);
}
@Override
public long getItemId(int position) {
// TODO 自动生成的方法存根
return items.get(position).getId();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO 自动生成的方法存根
ViewHolder holder;//使用ViewHolder,大神说能提升性能
if(convertView==null)
{
holder=new ViewHolder();
convertView=inflater.inflate(R.layout.item_view, null);
holder.img=(ImageView) convertView.findViewById(R.id.imageView1);
holder.cb=(CheckBox) convertView.findViewById(R.id.checkBox1);
holder.title=(TextView)convertView.findViewById(R.id.title);
holder.teacher=(TextView) convertView.findViewById(R.id.teacher);
holder.time=(TextView) convertView.findViewById(R.id.time);
holder.poeple=(TextView)convertView.findViewById(R.id.peopleNum);
convertView.setTag(holder);
}else
{
holder=(ViewHolder) convertView.getTag();
}
item=items.get(position);
if(item.isShow())
{
holder.cb.setVisibility(View.VISIBLE);
}
else
{
holder.cb.setVisibility(View.GONE);
}
holder.img.setImageResource(item.getImgRes());
holder.title.setText(item.getTitle());
holder.teacher.setText(\"主讲:\"+item.getTeacher());
holder.time.setText(\"课时:\"+item.getTime()+\"讲\");
holder.poeple.setText(\"学习人数:\"+item.getPeopleNum());
holder.cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked)
{
item.setChecked(true);
}
else
{
item.setChecked(false);
}
//回调方法,讲item加入已选择的
onShowItemClickListener.onShowItemClick(item);
}
});
//监听后设置选择状态
holder.cb.setChecked(item.isChecked());
return convertView;
}
static class ViewHolder
{
ImageView img;
CheckBox cb;
TextView title,teacher,time,poeple;
}
public interface OnShowItemClickListener {
public void onShowItemClick(ItemBean bean);
}
public void setOnShowItemClickListener(OnShowItemClickListener onShowItemClickListener) {
this.onShowItemClickListener = onShowItemClickListener;
}
}
最后是MainActivity.java
package com.example.listchecked;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.Toast;
import com.example.listchecked.MyListAdapter.OnShowItemClickListener;
public class MainActivity extends Activity implements OnShowItemClickListener {
private ListView listView;
private List<ItemBean> dataList,selectedList;
private MyListAdapter myAdapter;
private RelativeLayout rootView;
private LinearLayout menuView;
private LinearLayout openView;
private static boolean isShow;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
isShow=false;
setContentView(R.layout.activity_main);
Button delbtn=(Button) findViewById(R.id.del);
rootView=(RelativeLayout) findViewById(R.id.rootView);
menuView=(LinearLayout) findViewById(R.id.button_group);
listView=(ListView) findViewById(R.id.listView1);
dataList=new ArrayList<ItemBean>();
selectedList=new ArrayList<ItemBean>();
for(int i=0;i<10;i++)
{
ItemBean item=new ItemBean();
item.setId(i);
item.setImgRes(R.drawable.ic_launcher);
item.setTitle(\"第\"+item.getId()+\"个\");
item.setTeacher(\"杨老师\");
item.setTime(\"34\");
item.setPeopleNum(i+1*100);
item.setChecked(false);
item.setShow(isShow);
dataList.add(item);
}
myAdapter=new MyListAdapter(dataList, this);
myAdapter.setOnShowItemClickListener(MainActivity.this);
listView.setAdapter(myAdapter);
delbtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO 自动生成的方法存根
showMenu();
isShow=true;
selectedList.clear();
for(ItemBean item:dataList)
{
item.setShow(isShow);
}
myAdapter.notifyDataSetChanged();
}
});
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// TODO 自动生成的方法存根
if (isShow) {
ItemBean item = dataList.get(position);
boolean isChecked = item.isChecked();
if (isChecked) {
item.setChecked(false);
} else {
item.setChecked(true);
}
myAdapter.notifyDataSetChanged();
Log.d(\"select\",selectedList.size()+\"\");
}
}
});
}
//显示选择删除等的菜单
private void showMenu()
{
RelativeLayout.LayoutParams lp=new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
openView=(LinearLayout) inflater.inflate(R.layout.delmenu_layout, null);
rootView.removeView(menuView);
rootView.addView(openView,lp);
final Button sBtn=(Button) openView.findViewById(R.id.selectAll);
Button dBtn=(Button) openView.findViewById(R.id.del_button);
Button cBtn= (Button) openView.findViewById(R.id.cancel_button);
sBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO 自动生成的方法存根
if (\"全选\".equals(sBtn.getText().toString())) {
for (ItemBean bean : dataList) {
if (!bean.isChecked()) {
bean.setChecked(true);
if (!selectedList.contains(bean)) {
selectedList.add(bean);
}
}
}
myAdapter.notifyDataSetChanged();
sBtn.setText(\"反选\");
} else if (\"反选\".equals(sBtn.getText().toString())) {
for (ItemBean bean : dataList) {
bean.setChecked(false);
if (!selectedList.contains(bean)) {
selectedList.remove(bean);
}
}
myAdapter.notifyDataSetChanged();
sBtn.setText(\"全选\");
}
}
});
dBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO 自动生成的方法存根
if (selectedList!=null && selectedList.size()>0) {
dataList.removeAll(selectedList);
myAdapter.notifyDataSetChanged();
selectedList.clear();
} else {
Toast.makeText(MainActivity.this, \"请选择条目\", Toast.LENGTH_SHORT).show();
}
}
});
cBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO 自动生成的方法存根
if (isShow) {
selectedList.clear();
for (ItemBean bean : dataList) {
bean.setChecked(false);
bean.setShow(false);
}
myAdapter.notifyDataSetChanged();
isShow = false;
restoreView();
}
}
});
}
@Override
public void onShowItemClick(ItemBean bean) {
// TODO 自动生成的方法存根
if (bean.isChecked() && !selectedList.contains(bean)) {
selectedList.add(bean);
} else if (!bean.isChecked() && selectedList.contains(bean)) {
selectedList.remove(bean);
}
}
private void restoreView()
{
rootView.addView(menuView);
if(openView!=null)
{
rootView.removeView(openView);
openView=null;
}
}
}
最后还有那个小菜单的布局,还是放上吧
<?xml version=\"1.0\" encoding=\"utf-8\"?> <LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\" android:layout_width=\"match_parent\" android:layout_height=\"match_parent\" android:orientation=\"horizontal\" > <Button android:id=\"@+id/selectAll\" android:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\" android:layout_weight=\"1\" android:text=\"全选\" /> <Button android:id=\"@+id/del_button\" android:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\" android:layout_weight=\"1\" android:text=\"删除\" /> <Button android:id=\"@+id/cancel_button\" android:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\" android:layout_weight=\"1\" android:text=\"取消\" /> </LinearLayout>
全部代码都放上了,如果不想复制粘贴,GitHub地址:https://github.com/2767321434/ListChecked
以上就是本文的全部内容,希望对大家学习Android软件编程有所帮助。
本文地址:https://www.stayed.cn/item/1631
转载请注明出处。
本站部分内容来源于网络,如侵犯到您的权益,请 联系我