AndroidのListView多重化によるレイアウトの乱れを探究するソリューション


まず具体的な需要はどのようなものですか?

需要は図に示すように、この中にABCDの四つのオプションのテーマがあります。Aオプションをクリックすると、Aが正しい答えであれば、チェックのパターンになります。間違った答えであれば、間違いのパターンになります。ここで書いている時はとても簡単だと思います。クリックした時に私が選んだオプションと正しい答えが同じかどうかを判断します。同じように写真を正しい形に変えます。違ったら間違ったスタイルに変えます。そこで下記のコードを書きました。

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: [email protected] 
*/ 
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) { 
//        
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; 
} 
}
このコードを書き終えて自信満々で、大丈夫だと思いましたが、携帯で運転したら、問題が発生しました。効果は以下の通りです。

はい、listviewのレイアウト多重化のため、以下の選択されていない項目も多重化のために選択されました。
実際に解決する方法は簡単です。この選択した項目をその項目に対応するモデルと関連づけて、具体的にどうすればいいですか?以下で詳しく分析します。
まずmodelを作成する時にデフォルトのフィールドを追加します。このフィールドはあなたが選択したオプションです。もちろん初期値はありません。getViewでレイアウトを初期化する時は、このフィールドに値があるかどうかを判断します。そして、値があるなら、正しいか正しくないかを判断します。間違った画像に置き換えると、元のABCDの4種類の初期化画像が表示されます。これで問題は解決されます。
下に完全なコードを貼り付けます。上のコードと同じです。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: [email protected] 
*/ 
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) { 
//        
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; 
} 
}
その中で赤いのが新しく追加されたコードです。これらを加えると問題が解決されます。解決後のコードの運行状況を見てみます。

まとめ:
最後にこの問題の解決策をまとめましょう。
まず、この充填器に対応するエンティティクラスに選択されたフィールドを追加し、getview操作を行う際に、このチェックフィールドによって対応する操作を行います。値があれば、対応するスタイルに設定します。値がなければ、スタイルがないように設定します。もちろん、ユーザーがクリックする時には、該当フィールドを適時に割り当てます。同様に、Listviewにあるcheckboxも同様の方法で解決できます。
以上は、AndroidのListView多重化によるレイアウトの乱れを探究するための解決策を紹介しました。皆さんに何か質問があれば、メッセージをください。ここでも私たちのサイトを応援してくれてありがとうございます。