android布局错,探究Android中ListView复用导致布局错乱的解决方案

首先来说一下具体的需求是什么样的:

5bf8049dabf2ef543ec3e0c2378bf188.png

需求如图所示,这里面有ABCD四个选项的题目,当点击A选项,如果A是正确的答案,则变成对勾的图案,如果是错误答案,则变成错误的图案,这里当时在写的时候觉得很简单,只要是在点击的时候判断我点击的选项与正确答案是否一样,是一样就将图片换成正确的样式,如果不一样就换成错误的样式,于是我便写了下面的代码(只贴出了核心Adapter中的代码)

package com.fizzer.anbangproject_dahuo_test.Adapter;

import android.annotation.TargetApi;

import android.content.Context;

import android.graphics.drawable.Drawable;

import android.os.Build;

import android.text.TextUtils;

import android.view.View;

import android.view.ViewGroup;

import android.widget.BaseAdapter;

import android.widget.TextView;

import com.fizzer.anbangproject_dahuo_test.Model.ConvertModel;

import com.fizzer.anbangproject_dahuo_test.R;

import java.util.List;

/**

* Created by Fizzer on 2016/10/8.

* Email: doraemonmqq@sina.com

*/

public class ConvertViewAdapter extends BaseAdapter {

private List list;

private Context mContext;

public ConvertViewAdapter(Context context, List list) {

mContext = context;

this.list = list;

}

@Override

public int getCount() {

if (list == null) {

return 0;

} else {

return list.size();

}

}

@Override

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

ViewHolder mViewHolder;

if (convertView == null) {

convertView = View.inflate(mContext, R.layout.view_upgradepartnet_topic_layout, null);

mViewHolder = new ViewHolder();

mViewHolder.tvTitle = (TextView) convertView.findViewById(R.id.tvTitle);

mViewHolder.tvSelectA = (TextView) convertView.findViewById(R.id.tvSelectA);

mViewHolder.tvSelectB = (TextView) convertView.findViewById(R.id.tvSelectB);

mViewHolder.tvSelectC = (TextView) convertView.findViewById(R.id.tvSelectC);

mViewHolder.tvSelectD = (TextView) convertView.findViewById(R.id.tvSelectD);

convertView.setTag(mViewHolder);

} else {

mViewHolder = (ViewHolder) convertView.getTag();

}

ConvertModel module = list.get(position);

mViewHolder.tvTitle.setText("Q" + (position + 1) + ":" + module.title);

mViewHolder.tvSelectA.setText(module.optionA);

mViewHolder.tvSelectB.setText(module.optionB);

mViewHolder.tvSelectC.setText(module.optionC);

mViewHolder.tvSelectD.setText(module.optionD);

initListener(mViewHolder, module.rightOption, position, module);

return convertView;

}

@Override

public Object getItem(int position) {

return null;

}

@Override

public long getItemId(int position) {

return 0;

}

private void initListener(final ViewHolder mViewHolder, final String select, final int position, final ConvertModel module) {

mViewHolder.tvSelectA.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

judgeSelect(mViewHolder, mViewHolder.tvSelectA, "A", select, position);

}

});

mViewHolder.tvSelectB.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

judgeSelect(mViewHolder, mViewHolder.tvSelectB, "B", select, position);

}

});

mViewHolder.tvSelectC.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

judgeSelect(mViewHolder, mViewHolder.tvSelectC, "C", select, position);

}

});

mViewHolder.tvSelectD.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

judgeSelect(mViewHolder, mViewHolder.tvSelectD, "D", select, position);

}

});

}

private void clearSelectState(ViewHolder mViewHolder) {

mViewHolder.tvSelectA.setCompoundDrawables(getDrawableResource(R.drawable.ic_select_a), null, null, null);

mViewHolder.tvSelectB.setCompoundDrawables(getDrawableResource(R.drawable.ic_select_b), null, null, null);

mViewHolder.tvSelectC.setCompoundDrawables(getDrawableResource(R.drawable.ic_select_c), null, null, null);

mViewHolder.tvSelectD.setCompoundDrawables(getDrawableResource(R.drawable.ic_select_d), null, null, null);

}

private void judgeSelect(ViewHolder viewHolder, TextView text, String select, String rightSelect, int position) {

//清楚之前的状态

clearSelectState(viewHolder);

if (select.equals(rightSelect)) {

text.setCompoundDrawables(getDrawableResource(R.drawable.ic_select_right), null, null, null);

} else {

text.setCompoundDrawables(getDrawableResource(R.drawable.ic_select_error), null, null, null);

}

}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)

private Drawable getDrawableResource(int res) {

Drawable drawable = mContext.getDrawable(res);

drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());

return drawable;

}

class ViewHolder {

TextView tvTitle;

TextView tvSelectA;

TextView tvSelectB;

TextView tvSelectC;

TextView tvSelectD;

}

}

写完这段代码信心满满,觉得没问题了,但是在手机上一运行,发现出问题了,效果如下:

25594cf312658da7ea8dc8cb8b9baf79.gif

是的,由于listview的布局复用机制,导致下面没有选择的条目也因为复用而选择了选项

其实解决的方法很简单,就是将这个选中的条目与该条目对应的model相关联起来,具体怎么做呢,下面来仔细的分析分析,

首先在创建model的时候添加一个默认的字段,这个字段就是你选择的选项,当然初始值是没有的,在getView中对布局进行初始化的时候,就去判断这个字段是否有值,并且值为多少,如果有值,就去判断值为正确还是为错误,为正确则替换成正确的图片,如果为错误,则替换成错误的图片,如果没有值,则显示原始的ABCD四种初始化图片,这样,问题就迎刃而解了

下面贴出完整的代码,其实就跟上面的代码是差不多的,只不过在对model中添加的那个字段进行了一些复制与判断

package com.fizzer.anbangproject_dahuo_test.Adapter;

import android.annotation.TargetApi;

import android.content.Context;

import android.graphics.drawable.Drawable;

import android.os.Build;

import android.text.TextUtils;

import android.view.View;

import android.view.ViewGroup;

import android.widget.BaseAdapter;

import android.widget.TextView;

import com.fizzer.anbangproject_dahuo_test.Model.ConvertModel;

import com.fizzer.anbangproject_dahuo_test.R;

import java.util.List;

/**

* Created by Fizzer on 2016/10/8.

* Email: doraemonmqq@sina.com

*/

public class ConvertViewAdapter extends BaseAdapter {

private List list;

private Context mContext;

public ConvertViewAdapter(Context context, List list) {

mContext = context;

this.list = list;

}

@Override

public int getCount() {

if (list == null) {

return 0;

} else {

return list.size();

}

}

@Override

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

ViewHolder mViewHolder;

if (convertView == null) {

convertView = View.inflate(mContext, R.layout.view_upgradepartnet_topic_layout, null);

mViewHolder = new ViewHolder();

mViewHolder.tvTitle = (TextView) convertView.findViewById(R.id.tvTitle);

mViewHolder.tvSelectA = (TextView) convertView.findViewById(R.id.tvSelectA);

mViewHolder.tvSelectB = (TextView) convertView.findViewById(R.id.tvSelectB);

mViewHolder.tvSelectC = (TextView) convertView.findViewById(R.id.tvSelectC);

mViewHolder.tvSelectD = (TextView) convertView.findViewById(R.id.tvSelectD);

convertView.setTag(mViewHolder);

} else {

mViewHolder = (ViewHolder) convertView.getTag();

}

ConvertModel module = list.get(position);

mViewHolder.tvTitle.setText("Q" + (position + 1) + ":" + module.title);

mViewHolder.tvSelectA.setText(module.optionA);

mViewHolder.tvSelectB.setText(module.optionB);

mViewHolder.tvSelectC.setText(module.optionC);

mViewHolder.tvSelectD.setText(module.optionD);

initListener(mViewHolder, module.rightOption, position, module);

if (TextUtils.isEmpty(module.check)) {

clearSelectState(mViewHolder);

} else {

judgeSelect(mViewHolder, getCheckTextView(mViewHolder, module.check), module.check, module.rightOption, position);

}

return convertView;

}

@Override

public Object getItem(int position) {

return null;

}

@Override

public long getItemId(int position) {

return 0;

}

private void initListener(final ViewHolder mViewHolder, final String select, final int position, final ConvertModel module) {

mViewHolder.tvSelectA.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

module.check = "A";

judgeSelect(mViewHolder, mViewHolder.tvSelectA, "A", select, position);

}

});

mViewHolder.tvSelectB.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

module.check = "B";

judgeSelect(mViewHolder, mViewHolder.tvSelectB, "B", select, position);

}

});

mViewHolder.tvSelectC.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

module.check = "C";

judgeSelect(mViewHolder, mViewHolder.tvSelectC, "C", select, position);

}

});

mViewHolder.tvSelectD.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

module.check = "D";

judgeSelect(mViewHolder, mViewHolder.tvSelectD, "D", select, position);

}

});

}

private void clearSelectState(ViewHolder mViewHolder) {

mViewHolder.tvSelectA.setCompoundDrawables(getDrawableResource(R.drawable.ic_select_a), null, null, null);

mViewHolder.tvSelectB.setCompoundDrawables(getDrawableResource(R.drawable.ic_select_b), null, null, null);

mViewHolder.tvSelectC.setCompoundDrawables(getDrawableResource(R.drawable.ic_select_c), null, null, null);

mViewHolder.tvSelectD.setCompoundDrawables(getDrawableResource(R.drawable.ic_select_d), null, null, null);

}

private void judgeSelect(ViewHolder viewHolder, TextView text, String select, String rightSelect, int position) {

//清楚之前的状态

clearSelectState(viewHolder);

if (select.equals(rightSelect)) {

text.setCompoundDrawables(getDrawableResource(R.drawable.ic_select_right), null, null, null);

} else {

text.setCompoundDrawables(getDrawableResource(R.drawable.ic_select_error), null, null, null);

}

}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)

private Drawable getDrawableResource(int res) {

Drawable drawable = mContext.getDrawable(res);

drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());

return drawable;

}

private TextView getCheckTextView(ViewHolder mViewHolder, String rightSelect) {

if ("A".equals(rightSelect)) {

return mViewHolder.tvSelectA;

} else if ("B".equals(rightSelect)) {

return mViewHolder.tvSelectB;

} else if ("C".equals(rightSelect)) {

return mViewHolder.tvSelectC;

} else if ("D".equals(rightSelect)) {

return mViewHolder.tvSelectD;

}

return null;

}

class ViewHolder {

TextView tvTitle;

TextView tvSelectA;

TextView tvSelectB;

TextView tvSelectC;

TextView tvSelectD;

}

}

其中标红的就是新添的代码,加上这些后,问题就解决了,来看一下解决后的代码运行情况:

ac457a1120bc2f3967528a6c88c69113.gif

总结:

最后来总结一下这个问题的解决思路吧:

首先就是需要在该填充器对应的实体类中添加一个选中的(check)字段,在进行getview操作中,去根据这个check字段来进行相应的操作,如过有值,则设置成对应的样式,如果没有值,则设置成没有值得样式,当然,在用户点击的时候,要及时的对该字段进行赋值,类似的,像Listview中有checkbox也可以采用同样的方法来进行解决。

以上所述是小编给大家介绍的探究Android中ListView复用导致布局错乱的解决方案,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值