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

Posted IyangcLove

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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);
		elseviewHolder=(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

 





                     


以上是关于android ListView显示多个类型item 和 item中控件抢夺焦点解决办法的主要内容,如果未能解决你的问题,请参考以下文章

Android中使用ListView实现分页刷新(线程休眠模拟)

Android中使用ListView实现分页刷新(线程休眠模拟)(滑动加载列表)

Android 下载多个文件并在 ListView 中显示进度

android listView,list中有多个值,页面显示两个listView,如何让list中的值在页面中循环显示,谢谢大神…

为啥我的 Android ListView 选择多个项目?

具有多种布局的Android ListView