标签:android getview 自定义baseview 单选 莫智勋
最近因为一个项目的原因需要自定义一个BaseAdapter实现ListVIew单选打勾的功能,虽然听起来很简单,我在网上也 看过一些例子,似乎是实现了,但往往存在一些漏洞。往往漏洞如下
1、网上例子item较少,item增多时漏洞出现,忽略了BaseAdapter中getView()方法中convertView重用的问题
2、忽略了BaseAdapter中getView()方法并不是一下子加载完所有item,上下拖动listview时item会重新加载,getview会重新被调用,所以上下拖动的时候漏洞出 现
3、破坏了getview()方法中的convertView重用的优点,选择每次加载,都重新new一个convertView,虽然实现了,却大大降低了性能
综合以上,你会发现,自定义一个合理的BaseAdapter以及重写getView()方法是实现本功能的关键所在
我们先来看看getView方法有什么奥秘
看看getVIew()方法的参数列表
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方法是合理的、高效的
以下是我实现该功能的核心代码
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>
<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,请评论留下邮箱
ListView 自定义BaseAdapter实现单选打勾(无漏洞)
标签:android getview 自定义baseview 单选 莫智勋
原文地址:http://blog.csdn.net/u010571316/article/details/44802669