마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

몇일째 헤매서 질문올립니다.

0 추천
죽겟네요ㅠㅠ

먼저 커스텀리스트뷰를 사용하고있습니다.

리스트뷰의 특정항목을  터치한후 다운받으면

해당항목의 텍스트뷰에 진행률이 텍스트뷰로 퍼센트로 표시됩니다.

현재  선택된 셀의 텍스트뷰를  별도의 클래스에 저장해두엇다가 asynctask 호출시 파라미터로 넘기어어

asyntask에서 해당 텍스트뷰에 접근하여 퍼센트수치를 asynctask의 onprogress. .를 통하여 ui업데이트 하게금 처리하였습니다.

일단 퍼센트 표시는 잘되는데 문제가 스크롤을 하면 해당 퍼센트를 보여주는 텍스트뷰의 위치가 엉뚱한데 표시가됩니다.

텍스트뷰 객체 자체를 특정 클래스에 저장해두엇다가 그걸 asynctask에 넘기고 텍스트변경작업을하는게 잘못된 방식인가요?

스크롤하면 자꾸 이상한데로 가잇어서요ㅠㅠ

잠도안오네요ㅠㅠ

살려주세요
익명사용자 님이 2014년 8월 13일 질문
2014년 8월 13일 수정

2개의 답변

+1 추천
스크롤하면 위치가 엉망이되는건 이미 알려진 사실이구요..

그건 원조님이 말씀하신대로 리스트뷰는 재사용을 하기때문에 뷰의 위치값이 뒤죽박죽이 되는건 어쩔수없습니다.

getView에서 레이아웃 안의 view를 넘겨버리면 업데이트야 될수있겠지만 순서가 보장되는건 아니니깐 그렇게하시면 안되구요.

layout 안의 view를 컨트롤할려면 layout 자체를 새로 새로고침해주는수밖에 없습니다.

 

예를들어서, 전역으로 ArrayList나 배열을 하나 선언해주시구요.

ArrayList<Integer> progress;

 

listview의 아이템 갯수만큼 add를 해줍니다.

for(리스트갯수){progress.add(0);} //갯수초기화

 

그다음에 getView에는 textview.setText(progress.get(position)+"%"); 을 해서 arrayList의 position값에 맞는 텍스트를 갖다 붙입니다.

 

그런다음 AsyncTask에서 원하는 textview의 position값을 arrayList에서만 변경시켜줍니다.

progress.set(position, 10);

 

그다음 listviewAdapter.notifiyDataSetChange인가 뭔가 해주면 리스트뷰가 새로 갱신이 됩니다.

물론 이작업은 UI Thread에서해야되구요.(ASyncTask의 onUpdate인가 뭔가에서)

 

그러면 textView에서는 새로 변경된 arrayList의 값을 적용하겠죠

View자체를 컨트롤하려고하지마시고 안에 변수값만 변경시켜서 새로고침한다고 생각하시면됩니다.
기초개발자 (24,060 포인트) 님이 2014년 8월 13일 답변
위에 말씀하신대로면 AsyncTask에는 현재 사용되는 리스트뷰의 Adapter를 파라미터로 받아서 Adapter로 notifyDataSetChange해야된다는 말씀이신가요?
현재 리스트뷰에는 리스트마다 이미지가 있는데요
notifyDataSetChange를 하면 모든 뷰가 다 다시 그려져서 문제가 발생하지는 않나요?
그래서 개별적인 뷰를 컨트롤 하려 했던건데 제가 접근방법이 잘못됫엇나보네요 ㅠㅠ
맞아요.
그래서 제가 새로고침하는수밖에 없다라고 적어놨는데, 어짜피 라인수가 많이 늘어난다고해도 결국 리스트뷰는 화면에 보이는 양만큼만 로드를 하고 안보이면 메모리에서 삭제를 하거든요.
그래서 아무리 많은 양의 리스트가 있다고해도 메모리에 로드되는 양은 화면의 양에 한하기때문에 부하가 걸리진않을거에요.

추가 : 아뇨 아답터를 파라미터로 받으라는게아니라, listview건 adpater건 arraylist건 모두 전역으로 설정이 되어있어야죠.
아 아답터랑 리스트뷰가 모두 전역이어야하나요?
listview나 adapter나 어디서 호출되고 재사용될지모르는데 전역으로 설정하는게 좋죠.
한번 해보고 오겠습니다!
0 추천
리스트뷰는 각각의 아이템 마다 뷰를 생성해서 사용하지 않습니다.

화면에 보여질 정도만 뷰를 생성하고

나머지는 뷰를 돌려가며 재사용합니다.

 

예를 들어 화면에 아이템의 최대 5개가 보여진다면 뷰를 5개를 생성합니다.

그리고 사용자가 스크롤하여 1번째 뷰가 사라지고 6번째 뷰가 나오게 된다면

사라진 1번째 뷰를 재사용하여 6번째 뷰의 위치에 다시 보여지게 되는 것입니다.

 

그래서 아답터의 getView 메소드에서 view 가 null인지 아닌지 체크하여 재사용하는 뷰인지 최초에 생성되는 뷰인지 체크합니다.

그리고 뷰의 내용을 초기화 하여 각 포지션에 맞는 데이터를 넣어 줘야 합니다.

 

뷰를 별도의 클래스에 저장하여 퍼센트 값을 설정해 주신다고 했는데

뷰를 재사용할 경우 뒤섞이게 되어 문제가 있습니다.

뷰에 setTag로 현재 포지션 값을 저장하여 포지션을 체크하여 퍼센트 값을 설정해 주셔야 합니다.
원조안드로이드 (58,190 포인트) 님이 2014년 8월 13일 답변
getView에서 position값을 체크하여 퍼센트를 표시한다고 하셨는데
퍼센테이지가 계속 올라가야되기때문에
textView가 계속 ui변경이 이루어져야 해서
다운로드시 사용하는 AsyncTask 객체로 TextView를 넘겼습니다.
이 방법밖엔 생각이 나지 않았는데
다른 방법으로 textView를 지속적으로 업데이트 할 수 있나요?
퍼센테이지를 표시해야되서 AsyncTask의 onProgress 값을 받아서 세팅해야되는데 방안이 딱히 생각나지 않습니다.
AsyncTask에서 뷰를 직접 컨트롤하려고 하면 꼬일 수 밖에 없습니다.
ListAdapter에 퍼센트와 인덱스 정보를 넘긴 후 ListAdapter의 getView에서 처리하게 바꾸세요.
퍼센트 값이 계속 바뀔텐데 apdater에 계속적으로 넘겨야 하나요?
잘 이해가 되질 않네요 ㅠㅠ
미궁에 빠진것 같습니다.
혹시 샘플 소스 같은게 있다면 부탁드려도 될까요?
넘 답답하네요 물어볼 사수도 없고 난감 ㅠㅠ
...