专注收集记录技术开发学习笔记、技术难点、解决方案
网站信息搜索 >> 请输入关键词:
您当前的位置: 首页 > Android

Android中Adapter中edittext,checkbox记住状态解决方案(1)

发布时间:2010-05-30 02:51:41 文章来源:www.iduyao.cn 采编人员:星星草
Android中Adapter中edittext,checkbox记住状态解决方案(一)



一、问题原因

我们都知道Android中的adapter的view是用了重用机制的,简单地说就是当屏幕中的item占满屏幕以后,我们滑动listview的时候,第一个item退出屏幕,最后一个item进入屏幕

View getView(final int position, View convertView, ViewGroup parent)
这个时候,getview中convertview就不为空了,它的值就是第一个item的view,我们一般都会通过ViewHolder来缓存item,就不用重复findid了,直接就可以使用缓存的控件了。

这个缓存机制就是导致问题出现的根本原因。可能有人就说了,只要不用convertview来缓存不就能解决问题了么。对于这样的解决方案,我只能说,能使用这种方案的都是用屁股在思考问题!

二、问题解决

1.上面有两个问题,分别是editText和checkBox,我们先从简单的来,checkbox只需要考虑两种状态就行了,所以就先解决checkBox

首先用enum来标记下选中和未选中这两种状态

	public enum Type {
		Checked, UnCheck;
	}
接着在构造方法里面模拟数据,我这里用typeList来保存checkbox的状态,默认都不选中。
private List<CartBean> list;
private List<Type> typeList = new ArrayList<Type>();
public CartAdapter(Context context, List<CartBean> list) {
		this.list = list;
		this.context = context;
		initData();
	}

	private void initData() {
		for (CartBean cartBean : list) {
			Type type = Type.UnCheck;
			typeList.add(type);
		}
接下来,
        mHolder.cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {

			@Override
			public void onCheckedChanged(CompoundButton buttonView,
					boolean isChecked) {
				if (isChecked) {
					typeList.set(position, Type.Checked);
				} else {
					typeList.set(position, Type.UnCheck);
				}
			}

		});

	if (typeList.get(position) == Type.Checked) {
			mHolder.cb.setChecked(true);
		} else if (typeList.get(position) == Type.UnCheck) {
			mHolder.cb.setChecked(false);
		} else {
			mHolder.cb.setChecked(false);
		}
我是先给checkbox注册了监听,当checkbox状态变化的时候,我也相应的改变typeList中对应位置的状态,随后是根据我typeList中存储的状态来设置checkbox是否选中,这样问题就可以解决了。不过有一点需要强调一下,如果把监听的代码放到设置checkbox状态的代码之后的话,仍然会 出现checkbox状态丢失的问题。这是为什么?文章开头有说过viewholder会缓存item,所以如果监听写在后面的话,当初始化checkBox属性时,由于可能改变其状态,导致调用了onCheckedChange()方法,而这个监听器是在上一次初始化的时候添加的,那么position就是上一次的,不是本次的position,从而导致typeList中的状态错了。

我就举个例子吧,譬如说我选中了第一个item的checkbox,屏幕能显示10个item,当滑动item的时候,第十一个出来,它重用的第一个item的view,checkbox也是第一个的,监听也是第一个的。那么系统在执行这段代码的时候

if (typeList.get(position) == Type.Checked) {
			mHolder.cb.setChecked(true);
		} else if (typeList.get(position) == Type.UnCheck) {
			mHolder.cb.setChecked(false);
		} else {
			mHolder.cb.setChecked(false);
		}

就得把这个checkbox的状态从选中改成未选中的状态,这样就会触发监听事件

	public void onCheckedChanged(CompoundButton buttonView,
					boolean isChecked) {
				if (isChecked) {
					typeList.set(position, Type.Checked);
				} else {
					<strong>typeList.set(position, Type.UnCheck);</strong>
				}
			}
根据这段代码就会把position为0的位置的checkbox的状态设为uncheck。这样一来,当我们滑回去,第一个item重新进入屏幕的时候,我们会发现item的状态丢了,又变成未选中了。

所以为了避免这个问题,每次都必须先注册监听,再根据typelist中存储的状态来设置item是否选中。


checkbox的问题解决了,接下来就是editText的了,这个有点麻烦,大家看我文章开头的图片,我不仅要保存edittext里面的值,还要保证在操作加、减button的时候,操作的edittext对象是正确的,最后还有焦点问题。


2.先说说焦点问题,就是在listview中我们点击editText会发现,软键盘是弹出来了,光标也移到EditText上面了但是,不管输入什么editText里面都不显示!对于这个,我们可以在Activity里面这么配置

android:windowSoftInputMode="adjustPan",这个就是设置输入法的弹出模式,不挤压布局,输入法会覆盖在布局之上,同时editText也会获得焦点。其实之前editText不能输入也是因为没有焦点的缘故,这样就可以解决问题了。也不需要自己动态的获取editText的焦点了。

这个时候edittext能够输入内容了,接下来就是保存内容和button能操作对位的edittext。

我的做法是把edittext这个对象保存在list中,这样的做法不是很好,因为edittext不能序列化存储,我们没法把它持久化存储,这就造成这个对象容易丢。我们都知道系统在横竖屏切换的时候,Activity会重启或者在应用长时间处于后台的时候,系统会把Activity给清掉,等用户回到应用的时候会再重启Activity,如果我们无法存储状态的话,从用户体验上来说就不是很好。或许可以把这个list放在application中静态存储,就和项目中管理所有Activity的list一样。

还没有说完,下篇文章会有demo。


Android中Adapter中edittext,checkbox记住状态解决方案(二)





友情提示:
信息收集于互联网,如果您发现错误或造成侵权,请及时通知本站更正或删除,具体联系方式见页面底部联系我们,谢谢。

其他相似内容:

热门推荐: