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()方法的参数列表

publicViewgetView(int position,ViewconvertView,ViewGroupparent)先来解析下参数: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的对应关系

可参考博客

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

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

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

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

<span style="font-size:14px;"><?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android=""android:layout_width="match_parent"android:layout_height="60dp"android:background="@drawable/greywhite" ><LinearLayoutandroid:layout_height="wrap_content"android:layout_width="wrap_content"android:layout_margin="7dp"android:orientation="vertical"><TextViewandroid: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"/><TextViewandroid: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><ImageViewandroid: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>@Overridepublic int getCount() {// TODO Auto-generated method stubreturn mList.size();}@Overridepublic Object getItem(int position) {// TODO Auto-generated method stubreturn mList.get(position);}@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {// TODO Auto-generated method stubMyViewHolder 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()回调函数

天上永远不会掉馅饼,不要因为贪图一时的快乐而付出惨痛的代价,

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

相关文章:

你感兴趣的文章:

标签云: