android ListView显示多个类型item 和 item中控件抢夺焦点解决办法

来源:互联网 发布:南宁广电网络 编辑:程序博客网 时间:2024/04/28 19:10

  在android  ListView item条目中 如果添加有ImageView,Button 等会强行获取获取焦点 导致 ListView 本身的监听失效 下面是总结的几个方法 来进行避免此类问题。另外,也简单描述下 ListView 的adapter 显示多个不同类型的item 布局文件 如何使用。先上一下 Demo 界面图片 看看是否是自己需要的,然后具体讲解


 


一.先说item中ImageView ,Button等抢夺焦点的问题 ,解决办法

1.将ListView中的Item布局中的子控件focusable属性设置为false
2.在 adapter 的 getView()方法中设置抢夺焦点的控件setFocusable(false)

3.将强行获取焦点的控件更换成普通控件 ,例如 将Button, ImageView,EditText等换成 TextView 就不会抢夺焦点了

4.设置item的根布局的属性android:descendantFocusability="blocksDescendants"

我们可以发现,其实这三种方法都是为了让Button等控件不能获取焦点,从而使得item可以响应点击事件。

第4种方法使用起来相对方便,因为它是将item布局中的其他所有控件都设置为不能获取焦点。

android:descendantFocusability属性共有三个取值,分别为

beforeDescendants:viewgroup会优先其子类控件而获取到焦点
afterDescendants:viewgroup 只有当其子类控件不需要获取焦点时才获取焦点
blocksDescendants:viewgroup 会覆盖子类控件而直接获得焦点

  设置为   beforeDescendants 时 item的监听和 item内子控件的监听可同时存在。     

Demo 详细代码:

   focus_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:orientation="horizontal" android:descendantFocusability="blocksDescendants"    >    <ImageView         android:id="@+id/focus_iv"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:src="@drawable/ic_launcher"        />    <Button         android:id="@+id/focus_btn"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="founs_Btn"         android:layout_gravity="center"        /></LinearLayout>
  FocusAdapter类文件
  
package com.example.lvproblem;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.Button;import android.widget.ImageView;import android.widget.Toast;public class FocusAdapter extends BaseAdapter {@Overridepublic int getCount() {// TODO Auto-generated method stubreturn 5;}LayoutInflater inflater;Context context;       public FocusAdapter(Context context){       inflater=LayoutInflater.from(context);        this.context=context;       }@Overridepublic Object getItem(int position) {return null;}@Overridepublic long getItemId(int position) {return 0;}    class ViewHolder{    ImageView iv;       Button btn;    }@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder; if(convertView==null){    holder = new ViewHolder();convertView=inflater.inflate(R.layout.focus_xml,null); holder.btn = (Button) convertView.findViewById(R.id.focus_btn); holder.iv = (ImageView) convertView.findViewById(R.id.focus_iv); convertView.setTag(holder);}else{holder=(ViewHolder) convertView.getTag();}holder.btn.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {Toast.makeText(context, "you checked Button", Toast.LENGTH_SHORT).show();}});holder.iv .setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {Toast.makeText(context, "you checked ImageView", Toast.LENGTH_SHORT).show();}});return convertView;}}
在MainActivity中 设置Adapter 就ok了

二.ListView 显示多个不同类型的item  (做新闻界面,消息界面用得到)

我的Demo 中有三种类型 对应三个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:orientation="vertical" >    <ImageView           android:id="@+id/img_img"          android:layout_width="wrap_content"          android:layout_height="wrap_content"                 android:background="@drawable/ic_launcher"           android:layout_gravity="center"        /></LinearLayout>

<?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="vertical" >    <TextView      android:id="@+id/text_text"     android:layout_width="wrap_content"     android:layout_height="wrap_content"          android:text=" in text xml"       android:layout_gravity="center"       android:textSize="20sp"      android:textColor="#ff0000"      /></LinearLayout>

<?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="vertical" >    <ImageView        android:id="@+id/imgtext_img"        android:layout_height="wrap_content"        android:layout_width="wrap_content"         android:background="@drawable/ic_launcher"         />    <TextView        android:id="@+id/imgtext_tv"                android:layout_height="wrap_content"        android:layout_width="wrap_content"        android:text="img and text"         /></LinearLayout>
MoreAdapter适配器文件

package com.example.lvproblem;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.view.ViewDebug.FlagToString;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.TextView;public class MoreAdapter extends BaseAdapter {public final static int FLAG_IMG = 0;public final static int FLAG_TEXT = 1;public final static int FLAG_IMGTEXT = 2;    Context context;    LayoutInflater inflater;public MoreAdapter(Context context){this.context=context;inflater=LayoutInflater.from(context); }//返回数据item 条目数量@Overridepublic int getCount() {return 12;}@Overridepublic Object getItem(int position) {return null;}@Overridepublic long getItemId(int position) {return 0;}@Overridepublic int getViewTypeCount() {return 3;}// 返回需要显示的item是什么类型 根据这个类型去判断@Overridepublic int getItemViewType(int position) {//第一个item类型   只返回一次  if (position == 0) {return FLAG_IMG;} else {return position % 2 + 1;}}class ViewHolder{//纯文本TextView text;//纯图片ImageView img;//文本加图片ImageView img2;TextView text2;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder viewHolder;if (convertView == null) {viewHolder=new ViewHolder();switch (getItemViewType(position)) {case FLAG_IMG:                 convertView=inflater.inflate(R.layout.img_xml, null);                 viewHolder.img=(ImageView) convertView.findViewById(R.id.img_img);                      break;case FLAG_TEXT:convertView=inflater.inflate(R.layout.text_xml, null);viewHolder.text=(TextView)convertView.findViewById(R.id.text_text);break;case FLAG_IMGTEXT:convertView=inflater.inflate(R.layout.imgtext_xml, null);viewHolder.img2=(ImageView) convertView.findViewById(R.id.imgtext_img);viewHolder.text2=(TextView) convertView.findViewById(R.id.imgtext_tv);break;}           convertView.setTag(viewHolder);}else{viewHolder=(ViewHolder) convertView.getTag();}return convertView;}}
我这样设置 纯图片就只会出现在第一个  且只会出现一次!

最后上一个MainActivity 的文件

package com.example.lvproblem;import android.os.Bundle;import android.app.Activity;import android.view.Menu;import android.view.View;import android.view.View.OnClickListener;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.ListView;import android.widget.Toast;public class MainActivity extends Activity implements OnClickListener{private MoreAdapter adapter;private FocusAdapter adapter2;private ListView lv;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);    lv = (ListView) findViewById(R.id.lv);    adapter = new MoreAdapter(this);   adapter2 = new FocusAdapter(this);   findViewById(R.id.btn1).setOnClickListener(this);   findViewById(R.id.btn2).setOnClickListener(this);  }  @Overridepublic void onClick(View v) {       switch (v.getId()) {case R.id.btn1:lv.setAdapter(adapter);break;case R.id.btn2:      lv.setAdapter(adapter2);      lv.setOnItemClickListener(new OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position,long id) {  Toast.makeText( MainActivity.this, "you checked ListView-s item", Toast.LENGTH_LONG).show();}});break;}}}

最后附上Demo源代码 需要的朋友可以去下载看看  哪儿有不好的地方 希望能够提示一下 谢谢;

http://download.csdn.net/detail/yangbo437993234/8449555

 





                     


0 0