Android ListView 以无序方式显示列表项
Android ListView shows the list items in a dis-ordered manner
列表视图有时会重复前 5 个值,有时会重复 10 个值,但代码不会显示任何错误或警告。另一个问题是,如果我 select 一个 RadioButton 它会更改具有相同 ID(但位置不同)的整个 RadioButtons
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import org.json.JSONObject;
import java.util.ArrayList;
/**
* Created by Anu Martin on 3/1/2016.
*/
public class QuestionAdapter extends BaseAdapter{
ArrayList<JSONObject> arrayList;
LayoutInflater inflater;
Context context;
public static final String KEY_QUESTION_TYPE="type"
,KEY_QUESTION="Q"
,KEY_QESTION_OPTION_YES="OPTYES"
,KEY_QUESTION_OPTION_NO="OPTNO"
,KEY_QUESTION_OPTION1="OPT1"
,KEY_QUESTION_OPTION2="OPT2"
,KEY_QUESTION_OPTION3="OPT3"
,KEY_QUESTION_OPTION4="OPT4"
,KEY_QUESTION_EXPLANATION="EXPL"
,KEY_ARRAY_QUESTION="A";
public static final int QUESTION_TYPE_YESORNO=15
,QUESTION_TYPE_MULTIPLE_CHOICE=20
,QUESTION_TYPE_SHORT_ANSWER=25;
public QuestionAdapter(Context context,ArrayList<JSONObject> arrayList){
this.arrayList=arrayList;
this.context=context;
inflater=LayoutInflater.from(this.context);
}
@Override
public int getCount() {
return arrayList.size();
}
@Override
public Object getItem(int position) {
return arrayList.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Log.e("getView",position+"");
try {
JSONObject jsonObject = this.arrayList.get(position);
Log.d("getView",jsonObject.toString());
int questionType=jsonObject.getInt(KEY_QUESTION_TYPE);
switch (questionType){
case QUESTION_TYPE_YESORNO:{
ViewHolderYesOrNo mViewHolder;
if(convertView==null){
convertView=this.inflater.inflate(R.layout.row_question_yesorno,null);
mViewHolder=new ViewHolderYesOrNo(convertView);
convertView.setTag(mViewHolder);
}else{
mViewHolder=(ViewHolderYesOrNo)convertView.getTag();
}
mViewHolder.question.setText(jsonObject.getString(KEY_QUESTION));
mViewHolder.type.setText(jsonObject.getInt(KEY_QUESTION_TYPE)+"");
if(jsonObject.getString(KEY_QUESTION_EXPLANATION)!=null) {
mViewHolder.explanation.setText(jsonObject.getString(KEY_QUESTION_EXPLANATION));
mViewHolder.explanation.setVisibility(View.VISIBLE);
}
}break;
case QUESTION_TYPE_MULTIPLE_CHOICE:{
final ViewHolderMultipleChoice mViewHolder;
if(convertView==null){
convertView=this.inflater.inflate(R.layout.row_question_multiple_choice,null);
mViewHolder=new ViewHolderMultipleChoice(convertView);
convertView.setTag(mViewHolder);
}else{
mViewHolder=(ViewHolderMultipleChoice)convertView.getTag();
}
mViewHolder.question.setText(jsonObject.getString(KEY_QUESTION));
mViewHolder.type.setText(jsonObject.getInt(KEY_QUESTION_TYPE)+"");
mViewHolder.explanation.setText("");
mViewHolder.option1.setText(jsonObject.getString(KEY_QUESTION_OPTION1));
mViewHolder.option2.setText(jsonObject.getString(KEY_QUESTION_OPTION2));
mViewHolder.option3.setText(jsonObject.getString(KEY_QUESTION_OPTION3));
mViewHolder.option4.setText(jsonObject.getString(KEY_QUESTION_OPTION4));
if(jsonObject.getString(KEY_QUESTION_EXPLANATION)!=null) {
mViewHolder.explanation.setText(jsonObject.getString(KEY_QUESTION_EXPLANATION));
mViewHolder.explanation.setVisibility(View.VISIBLE);
}
}break;
case QUESTION_TYPE_SHORT_ANSWER:{
ViewHolderShortAnswer mViewHolder;
if(convertView==null){
convertView=this.inflater.inflate(R.layout.row_question_short_answer,null);
mViewHolder=new ViewHolderShortAnswer(convertView);
convertView.setTag(mViewHolder);
}else{
mViewHolder=(ViewHolderShortAnswer)convertView.getTag();
}
mViewHolder.question.setText(jsonObject.getString(KEY_QUESTION));
mViewHolder.type.setText(jsonObject.getInt(KEY_QUESTION_TYPE)+"");
if(jsonObject.getString(KEY_QUESTION_EXPLANATION)!=null) {
mViewHolder.explanation.setText(jsonObject.getString(KEY_QUESTION_EXPLANATION));
mViewHolder.explanation.setVisibility(View.VISIBLE);
}
}break;
default:{
if(convertView==null){
convertView=this.inflater.inflate(R.layout.row_question_not_available,null);
}
}
}
}catch (Exception e){
}
return convertView;
}
static class ViewHolderYesOrNo{
public TextView question,type,explanation;
public RadioGroup radioGroup;
public RadioButton yes,no;
public ViewHolderYesOrNo(View view){
question=(TextView) view.findViewById(R.id.rowQuestionYesNo);
type=(TextView)view.findViewById(R.id.rowQuestionType);
explanation=(TextView)view.findViewById(R.id.rowQuestionExplanation);
radioGroup=(RadioGroup)view.findViewById(R.id.rowOptionRadioGroup);
yes=(RadioButton)view.findViewById(R.id.rowOptionYes);
no=(RadioButton)view.findViewById(R.id.rowOptionNo);
}
}
static class ViewHolderMultipleChoice{
public TextView question,type,explanation;
public RadioGroup radioGroup;
public RadioButton option1,option2,option3,option4;
public ViewHolderMultipleChoice(View view){
question=(TextView) view.findViewById(R.id.rowQuestionYesNo);
type=(TextView)view.findViewById(R.id.rowQuestionType);
explanation=(TextView)view.findViewById(R.id.rowQuestionExplanation);
radioGroup=(RadioGroup)view.findViewById(R.id.rowOptionRadioGroup);
option1=(RadioButton)view.findViewById(R.id.rowOptionOne);
option2=(RadioButton)view.findViewById(R.id.rowOptionTwo);
option3=(RadioButton)view.findViewById(R.id.rowOptionThree);
option4=(RadioButton)view.findViewById(R.id.rowOptionFour);
}
}
static class ViewHolderShortAnswer{
public TextView question,type,explanation;
public ViewHolderShortAnswer(View view){
question=(TextView) view.findViewById(R.id.rowQuestionYesNo);
type=(TextView)view.findViewById(R.id.rowQuestionType);
explanation=(TextView)view.findViewById(R.id.rowQuestionExplanation);
}
}
}
感谢您的帮助。
就是这样的地方造成了你所看到的。
if(jsonObject.getString(KEY_QUESTION_EXPLANATION)!=null) {
mViewHolder.explanation.setText(jsonObject.getString(KEY_QUESTION_EXPLANATION));
mViewHolder.explanation.setVisibility(View.VISIBLE);
}
总之,你忘了else块。
无论何时从 viewholder 获取视图,它仍然具有之前设置的所有值。 仅使用 if
部分而不使用 [=13] =]部分,你只改变了一些值,而其他的保持不变。
在这种情况下,当你的 jsonObject 没有 KEY_QUESTION_EXPLANATION 时,它显示最后一项的解释,因此你需要添加
else {
mViewHolder.explanation.serVisibily(View.Invisible);//or Gone
}
编辑:
粗体部分是导致您出现问题的原因。流程是这样的:
- 您的适配器获取视图。一开始,它是空的。
- 您的适配器检查空视图,如果它是空的,它会创建一个新视图并设置一半值(因为另一半已在 xml 中预设)。
- 当您的视图变得不可见(屏幕外)并且需要新视图时,您的适配器将获得视图,该视图不为空。
- 您的适配器设置了一些值,未设置的值保留在之前的视图中。
您可以使用我之前建议的 else
语句轻松解决此问题。
列表视图有时会重复前 5 个值,有时会重复 10 个值,但代码不会显示任何错误或警告。另一个问题是,如果我 select 一个 RadioButton 它会更改具有相同 ID(但位置不同)的整个 RadioButtons
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import org.json.JSONObject;
import java.util.ArrayList;
/**
* Created by Anu Martin on 3/1/2016.
*/
public class QuestionAdapter extends BaseAdapter{
ArrayList<JSONObject> arrayList;
LayoutInflater inflater;
Context context;
public static final String KEY_QUESTION_TYPE="type"
,KEY_QUESTION="Q"
,KEY_QESTION_OPTION_YES="OPTYES"
,KEY_QUESTION_OPTION_NO="OPTNO"
,KEY_QUESTION_OPTION1="OPT1"
,KEY_QUESTION_OPTION2="OPT2"
,KEY_QUESTION_OPTION3="OPT3"
,KEY_QUESTION_OPTION4="OPT4"
,KEY_QUESTION_EXPLANATION="EXPL"
,KEY_ARRAY_QUESTION="A";
public static final int QUESTION_TYPE_YESORNO=15
,QUESTION_TYPE_MULTIPLE_CHOICE=20
,QUESTION_TYPE_SHORT_ANSWER=25;
public QuestionAdapter(Context context,ArrayList<JSONObject> arrayList){
this.arrayList=arrayList;
this.context=context;
inflater=LayoutInflater.from(this.context);
}
@Override
public int getCount() {
return arrayList.size();
}
@Override
public Object getItem(int position) {
return arrayList.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Log.e("getView",position+"");
try {
JSONObject jsonObject = this.arrayList.get(position);
Log.d("getView",jsonObject.toString());
int questionType=jsonObject.getInt(KEY_QUESTION_TYPE);
switch (questionType){
case QUESTION_TYPE_YESORNO:{
ViewHolderYesOrNo mViewHolder;
if(convertView==null){
convertView=this.inflater.inflate(R.layout.row_question_yesorno,null);
mViewHolder=new ViewHolderYesOrNo(convertView);
convertView.setTag(mViewHolder);
}else{
mViewHolder=(ViewHolderYesOrNo)convertView.getTag();
}
mViewHolder.question.setText(jsonObject.getString(KEY_QUESTION));
mViewHolder.type.setText(jsonObject.getInt(KEY_QUESTION_TYPE)+"");
if(jsonObject.getString(KEY_QUESTION_EXPLANATION)!=null) {
mViewHolder.explanation.setText(jsonObject.getString(KEY_QUESTION_EXPLANATION));
mViewHolder.explanation.setVisibility(View.VISIBLE);
}
}break;
case QUESTION_TYPE_MULTIPLE_CHOICE:{
final ViewHolderMultipleChoice mViewHolder;
if(convertView==null){
convertView=this.inflater.inflate(R.layout.row_question_multiple_choice,null);
mViewHolder=new ViewHolderMultipleChoice(convertView);
convertView.setTag(mViewHolder);
}else{
mViewHolder=(ViewHolderMultipleChoice)convertView.getTag();
}
mViewHolder.question.setText(jsonObject.getString(KEY_QUESTION));
mViewHolder.type.setText(jsonObject.getInt(KEY_QUESTION_TYPE)+"");
mViewHolder.explanation.setText("");
mViewHolder.option1.setText(jsonObject.getString(KEY_QUESTION_OPTION1));
mViewHolder.option2.setText(jsonObject.getString(KEY_QUESTION_OPTION2));
mViewHolder.option3.setText(jsonObject.getString(KEY_QUESTION_OPTION3));
mViewHolder.option4.setText(jsonObject.getString(KEY_QUESTION_OPTION4));
if(jsonObject.getString(KEY_QUESTION_EXPLANATION)!=null) {
mViewHolder.explanation.setText(jsonObject.getString(KEY_QUESTION_EXPLANATION));
mViewHolder.explanation.setVisibility(View.VISIBLE);
}
}break;
case QUESTION_TYPE_SHORT_ANSWER:{
ViewHolderShortAnswer mViewHolder;
if(convertView==null){
convertView=this.inflater.inflate(R.layout.row_question_short_answer,null);
mViewHolder=new ViewHolderShortAnswer(convertView);
convertView.setTag(mViewHolder);
}else{
mViewHolder=(ViewHolderShortAnswer)convertView.getTag();
}
mViewHolder.question.setText(jsonObject.getString(KEY_QUESTION));
mViewHolder.type.setText(jsonObject.getInt(KEY_QUESTION_TYPE)+"");
if(jsonObject.getString(KEY_QUESTION_EXPLANATION)!=null) {
mViewHolder.explanation.setText(jsonObject.getString(KEY_QUESTION_EXPLANATION));
mViewHolder.explanation.setVisibility(View.VISIBLE);
}
}break;
default:{
if(convertView==null){
convertView=this.inflater.inflate(R.layout.row_question_not_available,null);
}
}
}
}catch (Exception e){
}
return convertView;
}
static class ViewHolderYesOrNo{
public TextView question,type,explanation;
public RadioGroup radioGroup;
public RadioButton yes,no;
public ViewHolderYesOrNo(View view){
question=(TextView) view.findViewById(R.id.rowQuestionYesNo);
type=(TextView)view.findViewById(R.id.rowQuestionType);
explanation=(TextView)view.findViewById(R.id.rowQuestionExplanation);
radioGroup=(RadioGroup)view.findViewById(R.id.rowOptionRadioGroup);
yes=(RadioButton)view.findViewById(R.id.rowOptionYes);
no=(RadioButton)view.findViewById(R.id.rowOptionNo);
}
}
static class ViewHolderMultipleChoice{
public TextView question,type,explanation;
public RadioGroup radioGroup;
public RadioButton option1,option2,option3,option4;
public ViewHolderMultipleChoice(View view){
question=(TextView) view.findViewById(R.id.rowQuestionYesNo);
type=(TextView)view.findViewById(R.id.rowQuestionType);
explanation=(TextView)view.findViewById(R.id.rowQuestionExplanation);
radioGroup=(RadioGroup)view.findViewById(R.id.rowOptionRadioGroup);
option1=(RadioButton)view.findViewById(R.id.rowOptionOne);
option2=(RadioButton)view.findViewById(R.id.rowOptionTwo);
option3=(RadioButton)view.findViewById(R.id.rowOptionThree);
option4=(RadioButton)view.findViewById(R.id.rowOptionFour);
}
}
static class ViewHolderShortAnswer{
public TextView question,type,explanation;
public ViewHolderShortAnswer(View view){
question=(TextView) view.findViewById(R.id.rowQuestionYesNo);
type=(TextView)view.findViewById(R.id.rowQuestionType);
explanation=(TextView)view.findViewById(R.id.rowQuestionExplanation);
}
}
}
感谢您的帮助。
就是这样的地方造成了你所看到的。
if(jsonObject.getString(KEY_QUESTION_EXPLANATION)!=null) { mViewHolder.explanation.setText(jsonObject.getString(KEY_QUESTION_EXPLANATION)); mViewHolder.explanation.setVisibility(View.VISIBLE); }
总之,你忘了else块。
无论何时从 viewholder 获取视图,它仍然具有之前设置的所有值。 仅使用 if
部分而不使用 [=13] =]部分,你只改变了一些值,而其他的保持不变。
在这种情况下,当你的 jsonObject 没有 KEY_QUESTION_EXPLANATION 时,它显示最后一项的解释,因此你需要添加
else {
mViewHolder.explanation.serVisibily(View.Invisible);//or Gone
}
编辑:
粗体部分是导致您出现问题的原因。流程是这样的:
- 您的适配器获取视图。一开始,它是空的。
- 您的适配器检查空视图,如果它是空的,它会创建一个新视图并设置一半值(因为另一半已在 xml 中预设)。
- 当您的视图变得不可见(屏幕外)并且需要新视图时,您的适配器将获得视图,该视图不为空。
- 您的适配器设置了一些值,未设置的值保留在之前的视图中。
您可以使用我之前建议的 else
语句轻松解决此问题。