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

  在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 {

	@Override
	public int getCount() {
		// TODO Auto-generated method stub
		return 5;
	}
	LayoutInflater inflater;
	Context context;
       public FocusAdapter(Context context){
    	   inflater=LayoutInflater.from(context);
        this.context=context;
       }
	@Override
	public Object getItem(int position) {
		
		return null;
	}

	@Override
	public long getItemId(int position) {
		
		return 0;
	}
    class ViewHolder{
    	ImageView iv;
       Button btn;
    }
	@Override
	public 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() {
			@Override
			public void onClick(View v) {
			Toast.makeText(context, "you checked Button", Toast.LENGTH_SHORT).show();
			}
		});
		holder.iv .setOnClickListener(new OnClickListener() {
			@Override
			public 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 条目数量
	@Override
	public int getCount() {
		return 12;
	}
	@Override
	public Object getItem(int position) {
		return null;
	}

	@Override
	public long getItemId(int position) {
		return 0;
	}

	@Override
	public int getViewTypeCount() {
		return 3;
	}

	// 返回需要显示的item是什么类型 根据这个类型去判断
	@Override
	public 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;
	}
	@Override
	public 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;
	@Override
	protected 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);	  }
	  @Override
	public 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() {
					@Override
					public 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

 





                     


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值