昨天在ListView Item上添加ImageButton时,发现item点击没响应,上网查找时发现有的文章认为不能使用simpleAdapter为ListView的item添加按钮响应事件,有的则认为simpleAdapter可以。下面一起解决这两个问题:
1.亲测可以分别使用simpleAdapter和baseAdapter为ListView的Item添加按钮响应事件。
(1)使用simpleAdapter为listView的item添加按钮响应事件
MainActivity.java
package com.example.arrayadapter; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ListView; import android.widget.Toast; /** * 继承simpleAdapter实现listView每个Item上面的按钮添加事件 * */ public class MainActivity extends Activity { private ListView lv ; //声明一个列表 /* 显示ListView的两种方法: * 1)在activity对应的布局里声明ListView控件,使用findViewById初始listView对象,最后listView.setAdapter显示listVIew * 2)直接初始化ListVIew = new ListView(this),setAdapter后,通过setContentView(listView)把listView显示出来 */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lv = (ListView)findViewById(R.id.listview) ; // lv = new ListView(this) ; //String[]的img 要和int[]的img名称一致 MySimpleAdapter adapter = new MySimpleAdapter(this,getData(),R.layout.item, new String[]{"view1","view2","img","imageButton"}, new int[]{R.id.view1,R.id.view2,R.id.img,R.id.imageButton}) ; lv.setAdapter(adapter) ; // setContentView(lv) ; //添加监听器 lv.setOnItemClickListener(new OnItemClickListener(){ @Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { // TODO Auto-generated method stub Toast.makeText(MainActivity.this, "点击的是ListView的item:"+arg2, Toast.LENGTH_LONG).show() ; } }) ; } private ArrayList<Map<String,Object>> getData() { ArrayList<Map<String,Object>> data = new ArrayList<Map<String,Object>>() ; Map<String,Object> item ; item = new HashMap<String,Object>() ; item.put("view1", "张三") ; item.put("view2", "23") ; item.put("img", R.drawable.ic_launcher) ; item.put("imageButton", R.drawable.ic_launcher) ; data.add(item) ; item = new HashMap<String,Object>() ; item.put("view1", "李四") ; item.put("view2", "20") ; item.put("img", R.drawable.ic_launcher) ; item.put("imageButton", R.drawable.ic_launcher) ; data.add(item) ; return data ; } @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; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } }MySimpleAdapter.java
package com.example.arrayadapter; import java.util.List; import java.util.Map; import android.content.Context; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.ImageButton; import android.widget.SimpleAdapter; import android.widget.Toast; public class MySimpleAdapter extends SimpleAdapter { Context context ; public MySimpleAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to) { super(context, data, resource, from, to); this.context = context ; // TODO Auto-generated constructor stub } /* (non-Javadoc) * @see android.widget.SimpleAdapter#getView(int, android.view.View, android.view.ViewGroup) */ @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub View view= super.getView(position, convertView, parent); ImageButton btn=(ImageButton) view.findViewById(R.id.imageButton); btn.setTag(position); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Toast.makeText(getApplicationContext(), "点击的是ImageButton"+v.getTag(), 1).show(); } }); return view; } protected Context getApplicationContext() { // TODO Auto-generated method stub return context; } }activity_main.xml
<LinearLayout 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="com.example.arrayadapter.MainActivity" > <!-- 点击ListView item空白地方没响应的原因:ListView的layout_width设置为“wrap_content”,应该为fill_parent或match_parent --> <ListView android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="fill_parent" > </ListView> </LinearLayout>item.xml
<?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:descendantFocusability="blocksDescendants" android:orientation="horizontal" > <ImageView android:id="@+id/img" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_launcher" /> <LinearLayout android:layout_width="174dp" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical" > <TextView android:id="@+id/view1" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="view1" /> <TextView android:id="@+id/view2" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="view2" /> </LinearLayout> <ImageButton android:id="@+id/imageButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="true" android:focusable="false" android:gravity="right" android:src="@drawable/ic_launcher" /> </LinearLayout>
(2)使用baseAdapter为listView的item添加按钮响应事件
MainActivity.java
package com.example.listviewdemo; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.Toast; import android.widget.AdapterView.OnItemClickListener; /** * @author Devel_000 *使用baseAdapter为listView的item添加按钮响应事件 */ public class MainActivity extends Activity { private ListView lv ; //声明一个列表 ArrayList<Map<String,Object>> listData ; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lv = (ListView)findViewById(R.id.listview) ; listData = getData() ; MyAdapter myAdapter = new MyAdapter(this,listData) ; lv.setAdapter(myAdapter) ; //添加监听器 lv.setOnItemClickListener(new OnItemClickListener(){ @Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { // TODO Auto-generated method stub Toast.makeText(MainActivity.this, "点击的是ListView的item:"+arg2, Toast.LENGTH_LONG).show() ; } }) ; } //Item的内容 private ArrayList<Map<String,Object>> getData() { ArrayList<Map<String,Object>> data = new ArrayList<Map<String,Object>>() ; Map<String,Object> item ; item = new HashMap<String,Object>() ; item.put("view1", "张三") ; item.put("view2", "23") ; item.put("img", R.drawable.ic_launcher) ; item.put("imageButton", R.drawable.ic_launcher) ; data.add(item) ; item = new HashMap<String,Object>() ; item.put("view1", "李四") ; item.put("view2", "20") ; item.put("img", R.drawable.ic_launcher) ; item.put("imageButton", R.drawable.ic_launcher) ; data.add(item) ; return data ; } @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; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } }MyAdapter.java
package com.example.listviewdemo; import java.util.ArrayList; import java.util.Map; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; public class MyAdapter extends BaseAdapter { private LayoutInflater mInflater ; private ArrayList<Map<String,Object>> listData ; private Context context ; public MyAdapter(Context context,ArrayList<Map<String,Object>> listData) { mInflater = LayoutInflater.from(context) ; this.listData = listData ; this.context = context ; } @Override public int getCount() { // TODO Auto-generated method stub return listData.size() ; } @Override public Object getItem(int arg0) { // TODO Auto-generated method stub return null; } @Override public long getItemId(int arg0) { // TODO Auto-generated method stub return 0; } //这里arg0被定义为final是java语法规范(Cannot refer to a non-final variable arg0 inside an inner class defined in a different method) @Override public View getView(final int arg0, View arg1, ViewGroup arg2) { // TODO Auto-generated method stub ViewHolder holder = null ; if(arg1 == null) { holder = new ViewHolder() ; arg1 = mInflater.inflate(R.layout.item, null); //需要为每个控件指定内容,如指定textView的显示文字(这就是引用的listData作用) holder.imageButton = (ImageButton)arg1.findViewById(R.id.imageButton) ; holder.imageView = (ImageView)arg1.findViewById(R.id.img) ; holder.textView1 = (TextView)arg1.findViewById(R.id.view1) ; holder.textView1.setText(listData.get(arg0).get("view1").toString()) ; holder.textView2 = (TextView)arg1.findViewById(R.id.view2) ; holder.textView2.setText(listData.get(arg0).get("view2").toString()) ; arg1.setTag(holder) ; } else { holder = (ViewHolder)arg1.getTag(); } holder.imageButton.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { // TODO Auto-generated method stub Toast.makeText(getApplicationContext(), "点击的是ImageButton "+arg0, 1).show(); }}); return arg1; } protected Context getApplicationContext() { // TODO Auto-generated method stub return context; } public class ViewHolder { public ImageView imageView ; public TextView textView1 ; public TextView textView2 ; public ImageButton imageButton ; } }activity_main.xml
<LinearLayout 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="com.example.arrayadapter.MainActivity" > <!-- 点击ListView item空白地方没响应的原因:ListView的layout_width设置为“wrap_content”,应该为fill_parent或match_parent --> <ListView android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="fill_parent" > </ListView> </LinearLayout>item.xml
<?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:descendantFocusability="blocksDescendants" android:orientation="horizontal" > <ImageView android:id="@+id/img" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_launcher" /> <LinearLayout android:layout_width="174dp" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical" > <TextView android:id="@+id/view1" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="view1" /> <TextView android:id="@+id/view2" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="view2" /> </LinearLayout> <ImageButton android:id="@+id/imageButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="true" android:focusable="false" android:gravity="right" android:src="@drawable/ic_launcher" /> </LinearLayout>
运行截图:
在此过程中可能会遇到的问题(上述代码是可正常运行的,没有问题的):
1.为listView添加button等控件时,点击item没响应:
解决方法:在ListView的Item的xml文件中添加如下属性:
1)整个xml文件的根元素如LinearLayout中添加属性android:descendantFocusability="blocksDescendants"
2)被点击的控件如ImageButton中添加属性android:focusable="false"和android:clickable="true"
2.点击listView item中的空白地方没响应:
解决方法:在含ListView的布局中将listView的layout_width设置为fill_parent或match_parent,而不是“wrap_content”
仅供参考