Android 에서 ListView 재 활용 으로 인 한 레이아웃 착란 해결 방안 탐구

먼저 구체 적 인 수요 가 어떤 지 말씀 드 리 겠 습 니 다.

요 구 는 그림 에서 보 듯 이 이 안에 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: [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 과 연결 시 키 는 것 입 니 다.구체 적 으로 어떻게 하 는 지 아래 에 자세히 분석 하고 분석 하 겠 습 니 다.
먼저 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: [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; 
} 
}
그 중에서 빨간색 으로 표 시 된 것 은 새로 추 가 된 코드 입 니 다.이런 것들 을 더 하면 문제 가 해결 되 었 습 니 다.해결 후의 코드 운행 상황 을 살 펴 보 겠 습 니 다.

요약:
마지막 으로 이 문제 의 해결 방향 을 정리 합 시다.
우선 이 충전기 에 대응 하 는 실체 클래스 에 선택 한(check)필드 를 추가 해 야 합 니 다.getview 작업 을 할 때 이 check 필드 에 따라 해당 하 는 작업 을 해 야 합 니 다.값 이 있 으 면 해당 하 는 스타일 로 설정 하고 값 이 없 으 면 가치 있 는 스타일 로 설정 해 야 합 니 다.물론 사용자 가 클릭 할 때 이 필드 에 값 을 부여 해 야 합 니 다.비슷 한 것 은 Listview 에 checkbox 가 있 는 것 처럼 똑 같은 방법 으로 해결 할 수 있 습 니 다.
위 에서 말 한 것 은 안 드 로 이 드 에서 ListView 의 재 활용 으로 인해 구조 가 어 지 러 워 지 는 해결 방안 을 탐구 하 는 것 입 니 다.여러분 에 게 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 메 시 지 를 남 겨 주세요.편집장 님 은 신속하게 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!

좋은 웹페이지 즐겨찾기