ListView 自定义BaseAdapter实现单选打勾(无漏洞)

最近因为一个项目的原因需要自定义一个BaseAdapter实现ListVIew单选打勾的功能,虽然听起来很简单,我在网上也 看过一些例子,似乎是实现了,但往往存在一些漏洞。往往漏洞如下

1、网上例子item较少,item增多时漏洞出现,忽略了BaseAdapter中getView()方法中convertView重用的问题

2、忽略了BaseAdapter中getView()方法并不是一下子加载完所有item,上下拖动listview时item会重新加载,getview会重新被调用,所以上下拖动的时候漏洞出 现

3、破坏了getview()方法中的convertView重用的优点,选择每次加载,都重新new一个convertView,虽然实现了,却大大降低了性能

综合以上,你会发现,自定义一个合理的BaseAdapter以及重写getView()方法是实现本功能的关键所在

我们先来看看getView方法有什么奥秘

看看getVIew()方法的参数列表

public
View getView (int position, View convertView, ViewGroup parent)

先来解析下参数:position表示第position个item;

convertView表示一个item布局,也就是一个item的句柄

parent表示使用这个Adapter的ListView

对于getVIew的重用和优化功能,在这里我就不详细说明,因为网上这部分的博客说的很多,而且说得还不错

假如你的手机一次性能显示10个item,那么,在第一次加载的时候,这10个item调用getVIew方法的时候,传入的参数中 convertView都是null

但当你向下拖动listview,第11个item显示而第1个item离开的时候,此时getVIew方法的调用传入的参数中 convertView就是第1个item的 convertView,这就是 convertView的重用,我们可以通过 convertView访问item的各个控件,修改控件的text、图片等,就变成了第11个显示的item

假如item里面有一个TextView,写着当前item是第几个,那第1个item的TextVIew就写着第一,当第11个item调用getVIew的传入的 是第1个item的convertView,通过 convertView获取的TextView其实是第1个item的TextView,我们只要将 TextView的text改成第十一

上下拖动listview,只会有10个 convertView实例存在,getVIew()会被反复调用,存在着

1——11——21

2——12——22

3——13——23

。。。。。

10——20——30

这么一个 convertView的对应关系

可参考博客http://blog.csdn.net/kaixinbingju/article/details/8650249

按照上面这个说法设计getVIew方法是合理的、高效的

有了上面的叙述,那实现 ListView 自定义BaseAdapter实现单选打勾 功能就有了理论基础

以下是我实现该功能的核心代码

ListVitw里面item的布局文件listitem_place.xml

<span style="font-size:14px;"><?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="60dp"
    android:background="@drawable/greywhite" >

    <LinearLayout
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:layout_margin="7dp"
        android:orientation="vertical">

        <TextView
            android:id="@+id/place_name"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:textColor="@drawable/black"
            android:singleLine="true"
            android:ellipsize="end"
            android:textSize="14sp"
            />
        <TextView
            android:id="@+id/place_adress"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:textColor="@drawable/darkgrey"
            android:singleLine="true"
            android:ellipsize="end"
            android:textSize="12sp"
            android:layout_marginRight="40dp"
            />
    </LinearLayout>

	<ImageView
	    android:id="@+id/place_select"
	    android:layout_height="25dp"
	    android:layout_width="25dp"
	    android:layout_alignParentRight="true"
	    android:layout_marginRight="10dp"
	    android:layout_centerVertical="true"

	    />

</RelativeLayout></span>

自定义的BaseAdapter,关键

<pre name="code" class="java"><span style="font-size:14px;">package com.vr.souhuodong.UI.Adapter;

import java.util.List;

import android.R.integer;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.baidu.mapapi.search.core.PoiInfo;
import com.vr.souhuodong.R;

public class PlaceListAdapter extends BaseAdapter {

	List<PoiInfo> mList;
	LayoutInflater mInflater;
	int notifyTip ;

	private class MyViewHolder {
		TextView placeName;
		TextView placeAddree;
		ImageView placeSelected;
	}

	public PlaceListAdapter(LayoutInflater mInflater , List<PoiInfo> mList) {
		super();
		this.mList = mList;
		this.mInflater = mInflater;
		notifyTip = -1 ;
	}

	/**
	 * 设置第几个item被选择,很关键
	 * @param notifyTip
	 */
<span style="color:#ff0000;">	public void setNotifyTip(int notifyTip) {
		this.notifyTip = notifyTip;
	}</span>

	@Override
	public int getCount() {
		// TODO Auto-generated method stub
		return mList.size();
	}

	@Override
	public Object getItem(int position) {
		// TODO Auto-generated method stub
		return mList.get(position);
	}

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

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		// TODO Auto-generated method stub
		MyViewHolder holder;
		if (convertView == null) {
			System.out.println("----aa-");
			convertView = mInflater.inflate(com.vr.souhuodong.R.layout.listitem_place, parent, false);
		    holder = new MyViewHolder();
			holder.placeName = (TextView) convertView
					.findViewById(com.vr.souhuodong.R.id.place_name);
			holder.placeAddree = (TextView) convertView
					.findViewById(com.vr.souhuodong.R.id.place_adress);
			holder.placeSelected = (ImageView) convertView
					.findViewById(com.vr.souhuodong.R.id.place_select);
			holder.placeName.setText(mList.get(position).name);
			holder.placeAddree.setText(mList.get(position).address);
			holder.placeSelected.setBackgroundResource(R.drawable.greywhite);
			convertView.setTag(holder);
		} else {
			holder = (MyViewHolder) convertView.getTag();
		}
		holder.placeName.setText(mList.get(position).name);
		holder.placeAddree.setText(mList.get(position).address);
		<span style="color:#ff0000;">//根据重新加载的时候第position条item是否是当前所选择的,选择加载不同的图片,图片是打勾图片
		if(notifyTip == position ){
			holder.placeSelected.setBackgroundResource(R.drawable.ic_select);//打勾图片
		}
		else {
			holder.placeSelected.setBackgroundResource(R.drawable.greywhite);//未打勾图片
		}</span>

		return convertView;
	}

}
</span>

ListView的OnitemClickListenr监听器的Onlick()回调函数

<span style="font-size:14px;">		@Override
		public void onItemClick(AdapterView<?> parent, View view, int position,
				long id) {
			// TODO Auto-generated method stub

			<span style="color:#ff0000;">// 通知是适配器第position个item被选择了
			mAdapter.setNotifyTip(position);

			// 选中项打勾
			mSelectImg.setBackgroundResource(R.drawable.greywhite);
			mSelectImg = (ImageView) view.findViewById(R.id.place_select);
			mSelectImg.setBackgroundResource(R.drawable.ic_select);
</span>
		}</span>

红色为关键

以上就是全部内容,如果有什么疑问可以评论回复,如果希望完整demo,请评论留下邮箱

时间: 2024-08-01 10:45:08

ListView 自定义BaseAdapter实现单选打勾(无漏洞)的相关文章

ListView 自己定义BaseAdapter实现单选打勾(无漏洞)

(假设须要完整demo,请评论留下邮箱) (眼下源代码已经不发送.假设须要源代码,加qq316701116.不喜勿扰) 近期由于一个项目的原因须要自己定义一个BaseAdapter实现ListVIew单选打勾的功能,尽管听起来非常easy,我在网上也 看过一些样例,似乎是实现了,但往往存在一些漏洞.往往漏洞例如以下 1.网上样例item较少,item增多时漏洞出现,忽略了BaseAdapter中getView()方法中convertView重用的问题 2.忽略了BaseAdapter中getVi

android开发最常用例子整理----(3)自定义ListView(自定义BaseAdapter实现)

在上一个教程中,我们使用SimpleAdapter实现自定义ListView,但是有一点不方便的是,如果要对每一个ListView的item选项进行不同的样式设置,就很麻烦,因为SimpleAdapter使用的是统一的风格样式.如果要实现不同item使用不同的风格样式,那么就要通过集成BaseAdapter来实现. 一.Activity MainActivity.java源码: public class MainActivity extends Activity { @Override prot

android ListView 自定义 BaseAdapter

先上效果图 由上面的效果图可以看出:页面中的LISTVIEW的每一项,都是由两个TEXTVIEW组成,初始化的时候,只显示第一个TEXTVIEW,在这里我们成为标题,而内容部分的setVisible属性为"GONE".为Ite添加onClick监听器,在每次点击的时候,显示内容部分,这里需要调用BaseAdapter的notifyDataSetChanged()进行刷新显示. 代码部分: 1 class MyLayout extends LinearLayout { 2 3 priva

Android在listview添加checkbox实现单选多选操作问题

android根据View的不同状态更换不同的背景http://www.eoeandroid.com/thread-198029-1-1.html android 模仿朋友网推出的菜单效果[改进版]http://www.eoeandroid.com/thread-198019-1-1.html 让服务器iis支持.apk文件下载的设置方法http://www.eoeandroid.com/thread-198033-1-1.html 在 android 某些开发需求当中,有时候需要在listve

Android在listview添加checkbox实现单选多选操作问题(转)

转自:http://yangshen998.iteye.com/blog/1310183 在Android某些开发需求当中,有时候需要在listveiw中加入checkbox实现单选,多选操作.表面上看上去只是改变checkbox那么简单,然而实际开发中,实现起来并不是那么得心应手.尤其当listview比较多(比如屏幕最多只能显示10个item,但总共有12个item,也就是说listview的item数大于屏幕能够显示的item数)滑动屏幕的时候,由于适配器中getview()会重复使用被移

Android学习笔记-构建一个可复用的自定义BaseAdapter

转载自http://www.runoob.com/w3cnote/android-tutorial-customer-baseadapter.html   作者:coder-pig 本节引言: 如题,本节给大家带来的是构建一个可复用的自定义BaseAdapter,我们每每涉及到ListView GridView等其他的Adapter控件,都需要自己另外写一个BaseAdapter类,这样显得非常麻烦, 又比如,我们想在一个界面显示两个ListView的话,我们也是需要些两个BaseAdapter

WPF自定义控件与样式(7)-列表控件DataGrid与ListView自定义样式

一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: DataGrid自定义样式: ListView自定义样式: 二.DataGrid自定义样式 DataGrid是常用的数据列表显示控件,先看看实现的效果(动态图,有点大): DataGrid控件样式结构包括以下几个部分: 列头header样式 调整列头宽度的列分割线样式 行样式 行头调整高度样式 行头部样式

Android基础入门教程——2.4.7 构建一个可复用的自定义BaseAdapter

Android基础入门教程--2.4.7 构建一个可复用的自定义BaseAdapter 标签(空格分隔): Android基础入门教程 本节引言: 如题,本节给大家带来的是构建一个可复用的自定义BaseAdapter,我们每每涉及到ListView GridView等其他的Adapter控件,都需要自己另外写一个BaseAdapter类,这样显得非常麻烦, 又比如,我们想在一个界面显示两个ListView的话,我们也是需要些两个BaseAdapter- 这,程序员都是喜欢偷懒的哈,这节我们就来写

[Android] Android RecycleView和ListView 自定义Adapter封装类

在网上查看了很多对应 Android RecycleView和ListView 自定义Adapter封装类 的文章,主要存在几个问题: 一).网上代码一大抄,复制来复制去,大部分都运行不起来,或者 格式错乱 二).剩下的那些能运行起来的,将Adapter类.ViewHolder类,放在不同文件里,导致文件多.杂 于是总结这两个单独的Custom***ViewAdapter 类,以方便调用! 一.RecycleView Adapter自定义封装类 CustomRecyclerViewAdapter