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: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.deomhouxuan.MainActivity$PlaceholderFragment" > <RelativeLayout android:layout_width="200dp" android:layout_height="wrap_content" android:id="@+id/QQ" > <EditText android:id="@+id/ed_t" 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:id="@+id/imb" /> </RelativeLayout> </RelativeLayout>
item_xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 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:id="@+id/ima_v" android:layout_margin="5dp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/text_v" 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:id="@+id/delete" 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; } }