listview用ViewHolder存储控件,避免多次创建寻找空间资源,PopupWindow的使用。

1、listview写Adapater时候在getview里,用局部定义的view加载的xml后调用findviewbyid(),在oncreate()里调用findviewById时候由于activity往往没有加载listview要加载的Item.xml因此找到的其实为null,从而导致错误。

2、popupwindow为类成员时候,在oncreate里只能定义一个”空“的popuwindow,即用new PopupWindow(),经测试在oncreate()方法里给popupWindow设置属性都是无效的。并且oncreate()里面不能显示popupwindow,否则报错。

3、在listview的一个item里存在Button、checkbox或者自己在getview()覆写方法里定义了item里的一个view的监听事件时候,如果再setOnItemClickListener,很可能导致局部view个item抢焦点,而item点击事件失效,经测试下面的demo在真机上失效,模拟器上可用。后修改 为都监听局部view了。

4、Listview的getview时候每次都得创建item时候有三种方法,1直接创建。2将view存入到convertview参数里;3、为了提高效率可以定义Viewholder将view保存在里面,然后调用setTag(),下次创建item的时候直接用getTag()获取view,设定值,来提高效率;具体方法见代码。

下面看code:

 main_xml:

<RelativeLayout xmlns:andro
    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.deomhouxuan.MainActivity$PlaceholderFragment" >

    <RelativeLayout
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:
        >
    <EditText
        android:
        android:layout_width="200dp"
        android:layout_height="wrap_content"
			 />
    <ImageButton 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:background="@drawable/down_arrow"
        android:onClick="imbOnClick"
        android:
        />
</RelativeLayout>


</RelativeLayout>

 item_xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:andro
    android:layout_width="200dp"
    android:layout_height="match_parent"
    >
    <ImageView 
         android:contentDescription="@string/app_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/user"
        android:
		android:layout_margin="5dp"
        />
	<TextView 
	    android:layout_width="wrap_content"
	    android:layout_height="wrap_content"
	    android:
		android:layout_centerHorizontal="true"
		android:layout_centerVertical="true"
	    />
	<ImageView 
	    android:contentDescription="@string/app_name"
	    android:layout_width="wrap_content"
	    android:layout_height="wrap_content"
	    android:
	    android:background="@drawable/delete"
		android:layout_centerVertical="true"
		android:layout_alignParentRight="true"
	    />
</RelativeLayout>

activity

package com.example.deomhouxuan;
import java.util.ArrayList;
import android.app.Activity;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.TextView;

public class MainActivity extends Activity {

	private EditText ed;
	private ArrayList<String> data;
	public ListView list;
	public PopupWindow popu;
	MylistAdapter adapter;
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initview();
        
        
    }
    public void initview()
    {
    	ed=(EditText) findViewById(R.id.ed_t);
    	data=new ArrayList<String>();
    	for(int x=0;x<10;x++)
    		data.add(String.valueOf(1234123+x));
    	
    	list=new ListView(this);
    	popu=new PopupWindow();
    	adapter=new MylistAdapter();
    	list.setAdapter(adapter);
//	   System.out.println(popu==null);

    }

    public void  imbOnClick(View v) 
   {	
    	//经实验发现:popupwindow除了在主线程内new出一个空对象外,其他的一切 属性设定都是无效的
    	popu.setWidth(ed.getWidth());
  	   popu.setHeight(200);
  	   //设置listview的item之间的线为0;
  	   list.setDividerHeight(0);
  	   popu.setContentView(list);
	   if(popu.isShowing())
	   {
		   popu.dismiss();
	   }
	   else
		   popu.showAsDropDown(ed);
	   //下面2句是让popup的背后也获取焦点,点击后面时候popup隐藏
	    popu.setBackgroundDrawable(new BitmapDrawable());
	    popu.setFocusable(true);
	    
	    //在这里设置点击事件时候,由于listitem里的delete跟item争抢角点导致item在模拟器上可以,真机上失效,
	    //因此为了避免,在getview里定义了监听事件
//	    list.setFocusable(true);
//    	list.setOnItemClickListener(new OnItemClickListener() {
//			@Override
//			public void onItemClick(AdapterView<?> parent, View view,
//					int position, long id) {
//				ed.setText(data.get(position));
//				
//				System.out.println(popu==null);				
//			}
//		});
    	
   }
    
 class MylistAdapter extends BaseAdapter
   {

	@Override
	public int getCount() {
		return data.size();
	}

	@Override
	public Object getItem(int position) {
		
		return null;
	}

	@Override
	public long getItemId(int position) {
		// TODO Auto-generated method stub
		return position;
	}

	@Override
	public View getView(final int position, View convertView, ViewGroup parent) 
	{
		//	最慢的方法,每次创建view,再返回
//		View v=getLayoutInflater().inflate(R.layout.item, null);
//		TextView tv=(TextView) v.findViewById(R.id.text_v);
//		tv.setText(data.get(position));
//		return v;
		
//		//一般的方法,将view存入convertView,下次直接取
//		if(convertView==null)
//		{
//			convertView=getLayoutInflater().inflate(R.layout.item, null);
//			TextView tv=(TextView) convertView.findViewById(R.id.text_v);
//			tv.setText(data.get(position));
//		}
//		else
//		{
//			((TextView)convertView.findViewById(R.id.text_v)).setText(data.get(position));
//		}
//		return convertView;
		
		//最快的方法
		ViewHolder viewholder;
		if(convertView==null)
		{
			convertView=getLayoutInflater().inflate(R.layout.item, null);
			TextView tv=(TextView) convertView.findViewById(R.id.text_v);
			viewholder=new ViewHolder();
			viewholder.tv=tv;
			viewholder.delete=(ImageView) convertView.findViewById(R.id.delete);
			convertView.setTag(viewholder);
		}
		else
		{
			viewholder=(ViewHolder) convertView.getTag();
		}
		
		
		viewholder.tv.setText(data.get(position));
		
		//添加点击删除的事件
		viewholder.delete.setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View v) {
				data.remove(position);
				adapter.notifyDataSetChanged();
			}
		}
);
		//添加点击data的事件
		viewholder.tv.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				ed.setText(data.get(position));
				popu.dismiss();
			}
		});
		return convertView;
	}
   }
 //静态的VieHolder类存储view对象
 static class ViewHolder
 {
	 TextView tv;
	 ImageView delete;
	 
 }
   
}