探究Android中ListView復(fù)用導(dǎo)致布局錯(cuò)亂的解決方案
首先來說一下具體的需求是什么樣的:

需求如圖所示,這里面有ABCD四個(gè)選項(xiàng)的題目,當(dāng)點(diǎn)擊A選項(xiàng),如果A是正確的答案,則變成對(duì)勾的圖案,如果是錯(cuò)誤答案,則變成錯(cuò)誤的圖案,這里當(dāng)時(shí)在寫的時(shí)候覺得很簡單,只要是在點(diǎn)擊的時(shí)候判斷我點(diǎn)擊的選項(xiàng)與正確答案是否一樣,是一樣就將圖片換成正確的樣式,如果不一樣就換成錯(cuò)誤的樣式,于是我便寫了下面的代碼(只貼出了核心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<ConvertModel> list;
private Context mContext;
public ConvertViewAdapter(Context context, List<ConvertModel> 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) {
//清楚之前的狀態(tài)
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;
}
}
寫完這段代碼信心滿滿,覺得沒問題了,但是在手機(jī)上一運(yùn)行,發(fā)現(xiàn)出問題了,效果如下:

是的,由于listview的布局復(fù)用機(jī)制,導(dǎo)致下面沒有選擇的條目也因?yàn)閺?fù)用而選擇了選項(xiàng)
其實(shí)解決的方法很簡單,就是將這個(gè)選中的條目與該條目對(duì)應(yīng)的model相關(guān)聯(lián)起來,具體怎么做呢,下面來仔細(xì)的分析分析,
首先在創(chuàng)建model的時(shí)候添加一個(gè)默認(rèn)的字段,這個(gè)字段就是你選擇的選項(xiàng),當(dāng)然初始值是沒有的,在getView中對(duì)布局進(jìn)行初始化的時(shí)候,就去判斷這個(gè)字段是否有值,并且值為多少,如果有值,就去判斷值為正確還是為錯(cuò)誤,為正確則替換成正確的圖片,如果為錯(cuò)誤,則替換成錯(cuò)誤的圖片,如果沒有值,則顯示原始的ABCD四種初始化圖片,這樣,問題就迎刃而解了
下面貼出完整的代碼,其實(shí)就跟上面的代碼是差不多的,只不過在對(duì)model中添加的那個(gè)字段進(jìn)行了一些復(fù)制與判斷
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<ConvertModel> list;
private Context mContext;
public ConvertViewAdapter(Context context, List<ConvertModel> 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);
<span style="color:#cc0000;">if (TextUtils.isEmpty(module.check)) {
clearSelectState(mViewHolder);
} else {
judgeSelect(mViewHolder, getCheckTextView(mViewHolder, module.check), module.check, module.rightOption, position);
}</span>
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) {
<span style="color:#cc0000;">module.check = "A";</span>
judgeSelect(mViewHolder, mViewHolder.tvSelectA, "A", select, position);
}
});
mViewHolder.tvSelectB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
<span style="color:#cc0000;">module.check = "B";</span>
judgeSelect(mViewHolder, mViewHolder.tvSelectB, "B", select, position);
}
});
mViewHolder.tvSelectC.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
<span style="color:#cc0000;">module.check = "C";
</span> judgeSelect(mViewHolder, mViewHolder.tvSelectC, "C", select, position);
}
});
mViewHolder.tvSelectD.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
<span style="color:#cc0000;">module.check = "D";</span>
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) {
//清楚之前的狀態(tài)
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;
}
<span style="color:#cc0000;">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;
}</span>
class ViewHolder {
TextView tvTitle;
TextView tvSelectA;
TextView tvSelectB;
TextView tvSelectC;
TextView tvSelectD;
}
}
其中標(biāo)紅的就是新添的代碼,加上這些后,問題就解決了,來看一下解決后的代碼運(yùn)行情況:

總結(jié):
最后來總結(jié)一下這個(gè)問題的解決思路吧:
首先就是需要在該填充器對(duì)應(yīng)的實(shí)體類中添加一個(gè)選中的(check)字段,在進(jìn)行g(shù)etview操作中,去根據(jù)這個(gè)check字段來進(jìn)行相應(yīng)的操作,如過有值,則設(shè)置成對(duì)應(yīng)的樣式,如果沒有值,則設(shè)置成沒有值得樣式,當(dāng)然,在用戶點(diǎn)擊的時(shí)候,要及時(shí)的對(duì)該字段進(jìn)行賦值,類似的,像Listview中有checkbox也可以采用同樣的方法來進(jìn)行解決。
以上所述是小編給大家介紹的探究Android中ListView復(fù)用導(dǎo)致布局錯(cuò)亂的解決方案,希望對(duì)大家有所幫助,如果大家有任何疑問請給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
Android實(shí)現(xiàn)Listview異步加載網(wǎng)絡(luò)圖片并動(dòng)態(tài)更新的方法
這篇文章主要介紹了Android實(shí)現(xiàn)Listview異步加載網(wǎng)絡(luò)圖片并動(dòng)態(tài)更新的方法,結(jié)合實(shí)例形式詳細(xì)分析了ListView異步加載數(shù)據(jù)的操作步驟與具體實(shí)現(xiàn)技巧,需要的朋友可以參考下2016-08-08
Android布局自定義Shap圓形ImageView可以單獨(dú)設(shè)置背景與圖片
這篇文章主要介紹了Android布局自定義Shap圓形ImageView可以單獨(dú)設(shè)置背景與圖片 的相關(guān)資料,需要的朋友可以參考下2016-01-01
flutter?Bloc?實(shí)現(xiàn)原理示例解析
這篇文章主要為大家介紹了flutter?Bloc實(shí)現(xiàn)原理示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11
Android使用第三方庫實(shí)現(xiàn)日期選擇器
這篇文章主要為大家詳細(xì)介紹了Android使用第三方庫實(shí)現(xiàn)日期選擇器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-10-10
Android編程簡單實(shí)現(xiàn)雷達(dá)掃描效果
這篇文章主要介紹了Android編程簡單實(shí)現(xiàn)雷達(dá)掃描效果,涉及Android圖形繪制及顯示的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-10-10
Android 中出現(xiàn)java.net.BindException: bind failed: EADDRINUSE 問
這篇文章主要介紹了Android 中出現(xiàn)java.net.BindException: bind failed: EADDRINUSE 問題解決辦法的相關(guān)資料,需要的朋友可以參考下2017-04-04
Android開發(fā)中多進(jìn)程共享數(shù)據(jù)簡析
這篇文章主要為大家簡單分析Android開發(fā)中多進(jìn)程共享數(shù)據(jù),怎么做才能讓這兩邊共享數(shù)據(jù),感興趣的小伙伴們可以參考一下2016-04-04

