일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- kiss원칙
- 개발자
- 시험공부
- 테스팅원리
- 정처기
- 정처기준비
- 균일비용탐색
- 정의
- 언덕오르기탐색
- 공부하는직장인
- 프로그래밍언어패러다임
- 프로그래밍패러다임
- 모바일앱프로그래밍
- 방통대
- 린개발론
- 프로그래밍
- 검증테스팅
- 소프트웨어테스트
- 정보처리산업기사
- 결함테스팅
- 소프트웨어공학
- 린소프트웨어개발론
- 컴퓨터과학과
- 수제비
- A* 알고리즘
- 한국방송통신대학교
- 비전공자
- 정보처리기사
- 결함테스팅검증테스팅차이
- 컴퓨터과학개론
- Today
- Total
우와테크
android Studio 안드로이드 스튜디오 listView 에 item 선택할 때 일정 간격으로 다중 선택되는 버그 + ViewHolder 패턴 기초 본문
android Studio 안드로이드 스튜디오 listView 에 item 선택할 때 일정 간격으로 다중 선택되는 버그 + ViewHolder 패턴 기초
uwaTech 2022. 8. 17. 16:47글을 안쓰고 넘어갈 수 없는
세상 안생아(안드로이드 + 신생아 수준 개발자)에겐 다소 충격적인
디자인 패턴에 대해 얘기 할까한다.
혼자 안드로이드 개발을 시작했는가?
실적 프로젝트 없이 내가 개발하는 이 프로젝트가 바로 실적이 되는가.
책보고 ListView도 만들었고 구글보고 Adapter와 Activity를 구분 짓는 아키텍처도 구현했는가?
그런데 그 구현된 ListView에서 선택해서 일괄수정하거나 선택해서 일괄삭제하는 기능을 넣고 싶은데
하나 선택하면 먼가 일정한 간격을 두고 다중 선택되는가?
바로 당신은 ViewHolder를 쓰지 않았기 때문이다.나다. 내가 쓰지 않았다.
ViewHolder는 Listview를 포함한 RecyclerView, GridView 등을 구현할 때 사용되는 Adapter에서 정의한다.
슈퍼에 하리보젤리가 진열되어 있는게 ListView라 한다면
Adapter가............. 하리보젤리 하나봉지
ViewHolder가....... 하리보젤리 작은봉지
슈퍼에 마이구미가 진열되어 있는게 ListView라 한다면
Adapter가 ............ 마이구미 한봉지
마이구미는 뜯으면 작은 봉지가 없다.....
Adapter를 작성하는 순서에 ViewHolder를 녹여보겠다. 얍!
1. 생성자
2. BaseAdapter 상속 받기 위한 override 4가지 - getCount / getItem / getItemId / getView
3. ViewHolder class 작성하기 - ViewHolder에 넣을 UI 컴퍼넌트 선언하기
4. (getView에서..) ViewHolder로 UI 컴퍼넌트 감싸기 - 이미 저장된 뷰(convertView)가 있을때 / 없을 때 구분
5. ViewHolder 묶기.
6. 묶어둔 ViewHolder에서 컴퍼넌트 꾸미기.
7. DB에서 불러온 데이터 붙혀넣기
public class RAdapter extends BaseAdapter {
public final List<RVO> rVO = new ArrayList<>();
//1. 생성자
public RAdapter(List<RListResponse> vo) {
if (null == vo) return;
this.addItems(vo);
}
/**
* 2. BaseAdapter 상속 받기 위한 override 4가지 - getCount / getItem / getItemId / getView
*/
//Adapter에 사용되는 데이터의 개수를 리턴. : 필수 구현
@Override
public int getCount() {
if (rVO == null) return 0;
return rVO.size();
}
/**
* 2. BaseAdapter 상속 받기 위한 override 4가지 - getCount / getItem / getItemId / getView
*/
//지정한 위치(position)에 있는 데이터 리턴 : 필수 구현
@Override
public Object getItem(int position) {
return rVO.get(position);
}
/**
* 2. BaseAdapter 상속 받기 위한 override 4가지 - getCount / getItem / getItemId / getView
*/
// 지정한 위치(position)에 있는 데이터와 관계된 아이템(row)의 ID를 리턴. : 필수 구현
@Override
public long getItemId(int position) {
return position;
}
/**
* 2. BaseAdapter 상속 받기 위한 override 4가지 - getCount / getItem / getItemId / getView
* position : 리턴 할 자식 뷰의 위치
* convertView : 메소드 호출 시 position에 위치하고 이미 저장된 자식 뷰 ( if == null 자식뷰 생성 )
* parent : 리턴할 부모 뷰, 어댑터 뷰
*/
// position에 위치한 데이터를 화면에 출력하는데 사용될 View를 리턴. : 필수 구현
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
//4. ViewHolder로 UI 컴퍼넌트 감싸기 - 이미 저장된 뷰(convertView)가 있을때 / 없을 때 구분
ViewHolder viewHolder;
//4.1 이미 저장된 뷰(convertView)가 없을 때
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.layout_list, parent, false);
viewHolder = new ViewHolder(); //4.0.viewHolder 생성
viewHolder.list = (LinearLayout) view.findViewById(R.id.list);
viewHolder.text1 = (TextView) view.findViewById(R.id.text1);
viewHolder.text2 = (TextView) view.findViewById(R.id.text2);
viewHolder.text3 = (TextView) view.findViewById(R.id.text3);
view.setTag(viewHolder); //5. ViewHolder 묶기.
} else {//4.2 이미 저장된 뷰(convertView)가 있을때 / 없을 때
viewHolder = (ViewHolder) view.getTag();
}
Log.d("하리보", position + "번째 작은 봉지 확인 : " + viewHolder);
RVO vo = (RVO) getItem(position);
//6. 묶어둔 ViewHolder에서 컴퍼넌트 꾸미기.
if (vo != null) {
viewHolder.text1.setText(vo.getData1());
viewHolder.text2.setText(vo.getData2());
viewHolder.text3.setText(vo.getData3());
viewHolder.list.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View clickView) {
//중략
}
});
viewHolder.list.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View clickView) {
//중략
}
});
}
return view;
}
/**
* 7. DB에서 불러온 데이터 붙혀넣기
*/
public void addItems(@NonNull List<RListResponse> rList) {
for (int i = 0; i < rList.size(); i++) {
RVO vo = new RVO();
vo.setData1(rList.get(i).data1);
vo.setData2(rList.get(i).data2);
vo.setData3(rList.get(i).data3);
rVO.add(vo);
}
}
/**
* list에서 해당 항목 지우기
*/
public void removeItem(int position) {
rVO.remove(position);
}
/**
* 3. ViewHolder class 작성하기 - ViewHolder에 넣을 UI 컴퍼넌트 선언하기
*/
public class ViewHolder {
LinearLayout list;
TextView text1;
TextView text2;
TextView text3;
}
}