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;

 }

}

  

时间: 2024-10-12 13:15:39

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

【Android进阶】关于ListView中item与控件抢夺焦点的那些事

在开发中,listview可以说是我们使用最频繁的控件之一了,但是关于listview的各种问题也是很多.当我们使用自定义布局的Listview的时候,如果在item的布局文件里面存在Button或者是CheckBox等控件以及其子类控件的时候,经常会碰到各种控件的点击事件冲突的情况,那么我们如何来处理Listview中这种控件之间焦点冲突的情况呢? 我们以item存在一个Button控件为例 首先,加入我们不设置任何关于焦点的属性,比如focus等,代码如下 @Override public

listView中的button控件获取索引

1.在listitem中初始化button的时候,给该button添加一个setTag方法,将此时的索引值传进去,然后在button的onclick事件中调用view的getTag方法,即可将listitem的索引读出来,代码如下: tagButton.setTag(position); 此处的tagButton就是定义的button,Position是view里边的位置. 2.初始化button的时候通过setTag方法传入一个item的索引值 private OnClickListener 

Android: ListView的使用(列表控件)

当程序中有大量的数据需要展示时,就需要用到 ListView 啦.ListView 允许用户通过手指上下滑动的方式将屏幕外的数据滚动到屏幕内,同时屏幕上原有的数据则会滚动出屏幕. 1.基本性质 (1)由于数组中的数据无法直接传递给ListView,我们需要借助适配器(Adapter)来完成.(2)Adapter有多种,需要根据ListView不同的使用情况选择不同的适配器.主要有两种ArrayAdapter / SimpleAdapter ListView的关键操作是制作一个符合要求的Adapt

DevExpress XtraReports 入门六 控件以程序方式创建一个 交叉表 报表

原文:DevExpress XtraReports 入门六 控件以程序方式创建一个 交叉表 报表 本文只是为了帮助初次接触或是需要DevExpress XtraReports报表的人群使用的,为了帮助更多的人不会像我这样浪费时间才写的这篇文章,高手不想的看请路过 本文内容来DevExpress XtraReports帮助文档,如看过类似的请略过. 废话少说 开始正事 在继续本示例之前,要把所有 必需的程序集 添加到项目的 引用 列表中,并且把一个按钮拖放到窗体上. 然后,以下列方式接管此按钮的

五种情况下会刷新控件状态(刷新所有子FWinControls的显示)——从DFM读取数据时、新增加子控件时、重新创建当前控件的句柄时、设置父控件时、显示状态被改变时

五种情况下会刷新控件状态(刷新控件状态才能刷新所有子FWinControls的显示): 在TWinControls.PaintControls中,对所有FWinControls只是重绘了边框,而没有整个重绘这些FWinControl子控件.那么什么时候才整个重绘全部FWinControls呢?这时候,就不是一个单纯的WM_PAINT来解决控件重绘的问题了,而是这个TWinControl.UpdateShowing函数: procedure TWinControl.UpdateShowing; v

RecyclerView,ListView,GridView等UI控件使用及其优化和图片错位--&gt;

--------------------------------图片错位问题--------------------------------------- 法一: 1:先将图片预设为本地一个占位图片.(重要!很多错位情况在于复用了其他位置的图片缓存,而当前图片迟迟加载不出来,导致当前图片错位.所以解决之道是先用本地占位图片,快速刷新当前图片.等加载完毕之后,就可以替换掉占位图片了.); 2:通过ImageView.setTag,把url记录在图片内部; 3:把url放进一个请求队列,(这是避免图

UIAutomator中滚动ListView获得目标TextView控件对象的经验点滴

当创建一个UiScrollable对象时,如果指定的参数是new UiSelector().scrollable(true),那么会出现以下问题 当可滚动控件(比如ListView)不满一页不需要滚动时,创建的UiSrollable对象返回值是为空的. 所以以下代码是错误的: //Find out the new added note entry UiScrollable noteList = new UiScrollable( new UiSelector().scrollable(true)

ListView(1)控件架构与ArrayAdapter详解

ListView是Android开发中比较常用的一个组件,它以列表的形式展示信息,并能根据信息的长度自适应显示.比如说我们手机里的通讯录就用到了ListView显示联系人信息.在大量的场合下,我们都需要使用这个控件.虽然在Android 5.0时代,RecyclerView在很多地方都在逐渐取代ListView,但ListView的使用范围依然非常的广泛.我们也不能跳过ListView直接去学习RecyclerView,对ListView的透彻理解是十分有必要的. 首先来看ListView在Vi

listView中的button控件获取item的索引

在listview中的listitem设置事件响应,如果listitem中有button控件,这时候listitem就不会捕获到点击事件,而默认的是listitem中的button会捕获点击事件.那么如果点击listitem中的button怎么才能这个button是在哪一个item中呢,换句话说,就是点击listitem中的button怎么获取该listitem的索引?得到了这个索引的话,item里边的值就相对容易了. 通过如下方法可以实现: 1.在listitem中初始化button的时候,给