ListView의 체크박스 정렬 문제 해결
이 섹션 소개:
ListView의 고전적인 문제 중 하나로서, 체크박스를 사용하여 ListView 항목을 사용자 정의하려고 시도한 경우 이 문제는 항목 수가 한 페이지를 초과할 때 발생합니다. 이 문제의 원인과 해결 방법을 분석해 보겠습니다. 이 문제를 해결해보세요!
1 문제의 원인:
이것은 인터넷에서 발견된 ListView getView 메서드 호출 메커니즘에 대한 그림입니다.
위 그림에는 Recycler 항목이 있습니다. 일반적으로 ListView는 표시되는 항목은 메모리에 있으며 해당 항목은 다음 위치에 배치됩니다. 이 Recycler에서는 항목이 처음 로드될 때 현재 페이지의 ConvertView가 NULL입니다. 화면 밖으로 스크롤할 때 이번에는 ConvertView가 비어 있지 않으므로 새 항목은 이 ConvertView를 재사용합니다! 간단한 예제를 작성하고 로그를 따라갈 수 있습니다. 실행 후 로그 다이어그램은 다음과 같습니다.
그림에서 볼 수 있듯이 12번째 위치부터 ConvertView는 더 이상 비어 있지 않습니다. 정확히 무엇을 의미하나요? 모르겠습니다. 소스 코드를 시각적으로 검토해야 합니다... 우리는 이러한 이유로 ConvertView가 여기에 캐시된다는 것을 알고 있습니다. 확인란이 잘못 정렬되었으므로 첫 번째 해결 방법은 이 ConvertView를 재사용하지 않는 것입니다. getView가 이 ConvertView를 null로 설정할 때마다 표시해야 하는 Item의 수가 많다면, 이 방법은 매우 비대해 보일 것입니다. 일반적으로 실제 개발에서는 다음 솔루션을 사용합니다. 현재 항목 CheckBox의 상태를 저장할 항목을 찾고, 선택 여부를 초기화 중에 판단합니다!
2. 해결 방법:
이 체크박스를 HashMap<Integer, Boolean>에 저장할 수 있는 좋은 방법이 많이 있습니다. 각 초기화 중에 위치에 따라 해당 부울 값이 제거되고 확인란 상태가 설정됩니다. 저자의 접근 방식은 판단을 위해 엔터티 클래스에 부울 값을 추가하는 것입니다. 다음은 저자의 프로젝트 중 하나입니다. 추출된 코드는 비교적 간단하므로 몇 초 안에 이해하실 수 있을 거라 믿습니다~
Entity 클래스: Person.java:
private String name;
private String number;
private boolean checkStatus;
public Person(String name, String number) {
super();
this.name = name;
이. number = number;
this.checkStatus = false;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
공개 문자열 getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public boolean getCheckStatus() {
return checkStatus;
}
public void setCheckStatus(boolean checkStatus) {
this.checkStatus = checkStatus;
}
}
구현된 어댑터 클래스: ContactListAdapter.java:
private List<Person>을 구현합니다. mData;
private Context mContext;
public ContactListAdapter(List<Person> data, Context context) {
mData = data;
mContext = context;
}
/ / 정확한 个刷 새로운 방식의 방법
public void changeData(List< ;사람> 데이터) {
mData = data;
notifyDataSetChanged();
}
@Override
public int getCount() {
return mData.size();
}
@Override
public Person getItem(int position) ) {{return mdata.get (position);
}@override
public long getItemid (int position) {
리턴 위치;
}@atriade} public getView (int position, view convertView, viewGroup Parent) {
최종 int 색인 = position;
ViewHolder viewHolder;
if (convertView == null) {
convertView = LayoutInflater.from(mContext).inflate(
R.layout.item_contact, parent, false);
viewHolder = 새 ViewHolder ();
viewHolder.ly = (RelativeLayout) convertView
.findViewById(R.id.lyContactListItem);
viewHolder.txtName = (TextView) convertView
.findViewById(R.id.txtName);
viewHolder.txtNumber = (TextView) convertView
.findView ById(R.id.txtNumber);
viewHolder.cbxStatus = (CheckBox) convertView
. findViewById(R.id.cbxStatus);
convertView.setTag(viewHolder);
viewHolder.cbxStatus.setTag(index);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.cbxStatus. setOnCheckedChangeListener(this);
viewHolder.cbxStatus.setChecked(mData.get(position).getcheckStatus());
viewHolder.txtName.setText(mData.get(index).getName());
viewHolder.txtNumber.setText( mData.get(index).getNumber());
return convertView;
}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
int index =(int)buttonView.getT ag();
만약 ( isChecked)
mData.get(index).setCheckStatus(true);
else
mData.get(index).setCheckStatus(false);
}
비공개 클래스 ViewHolder {
RelativeLayout ly;
TextView txtName;
TextView txtNumber ;
CheckBox cbxStatus;
}
}
아주 간단합니다. 한 가지 더 잊지 마세요. 체크박스 상태를 초기화하는 코드 앞에 체크박스 리스너 메서드를 추가해야 합니다~
이 섹션 소개:
알겠습니다. , 이 섹션에서는 ListView의 전형적인 문제를 설명하겠습니다. ListView의 확인란이 잘못되었습니다. 체크박스 선택 상태를 기록하는 값을 추가한 후 체크박스를 다시 작성하면 문제가 해결됩니다. 이벤트 클릭시 판단을 먼저 해주세요~감사합니다~