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

아래 몇일 헤멨다고 질문 올렸었습니다.

0 추천

기초개발자님 원조안드로이드님의 도움으로 진전이 있었습니다.

먼저 감사의 인사 드립니다.

일단 위치가 뒤죽박죽 되지 않는 문제점은 잡았습니다.

 일단 프로그래스 수치를 가지고 잇는 리스트가 있고,

getView에서는 이 리스트에 접근하여 해당 포지션의 수치를 가져와 텍스트뷰에 진행률을 seText하는

방식으로 처리하였습니다.

그리고 AsyncTask쪽에서는 직접 TextView를 수정하지 않고

adapter의 notifydatasetchanged를 통하여 새로고침을 실시하였습니다.

그런데 문제가 생겼습니다.

퍼센테이지가 오르면서 계속된 notifydatasetchenged로 인하여 계속 뷰가 그려지니

기존에 이미지뷰에 그려져있던 각 셀의 이미지들이 계속 재로딩되는 현상이 발생하고 있습니다.

계속 새로고침이 되어 뷰를 다시그리다보니 가만히 있음에도 불구하고 이미지를 다시 로딩하니

임시로딩이미지처리한것이 보였다가 다시 이미지가 표시되었다가

깜빡거리는 듯한 현상이 발생하고 있습니다.

아...산넘어 산이군요.ㅠㅠ

일단 소스코드를 첨부해보겠습니다.

 

어댑터 부분입니다.

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
final ViewHolder viewHolder;
 
if(convertView == null) {
viewHolder = new ViewHolder();
convertView = mLayoutInflater.inflate(mLayout, parent, false);
viewHolder.thumImageView = (ImageView)convertView.findViewById(R.id.youtube_contents_thum);
viewHolder.titleTextView = (TextView)convertView.findViewById(R.id.youtube_contents_title);
viewHolder.percentTextView = (TextView)convertView.findViewById(R.id.youtube_contents_percent);
convertView.setTag(viewHolder);
}else {
viewHolder = (ViewHolder)convertView.getTag();
viewHolder.thumImageView.setImageResource(R.drawable.intro);
}
final YouTubeVideoDataInfo youTubeVideoDataInfo = mYoutubeArrayList.get(position);
String thumNailImageURL = youTubeVideoDataInfo.getThum();
String title = youTubeVideoDataInfo.getTitle();
ImageView thumNailImageView = viewHolder.thumImageView;
final TextView titleTextView = viewHolder.titleTextView;
final TextView percentTextView = viewHolder.percentTextView;
mImageLoader.displayImage(thumNailImageURL, thumNailImageView, mDisplayImageOptions);
titleTextView.setText(title);
 
//해당 셀이 셀렉트가 되어 있는지 확인 후 색상 세팅
if(youTubeVideoDataInfo.isChecked()) {
titleTextView.setBackgroundColor(Color.MAGENTA);
 
}else {
titleTextView.setBackgroundColor(Color.WHITE);
}
 
if(youTubeVideoDataInfo.isPercentFalg()) {
percentTextView.setText("" + youTubeVideoDataInfo.getPercent());
}else {
percentTextView.setText(youTubeVideoDataInfo.getCheckedText());
}
 
//AsyncTask 부분입니다.
 
@Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
int value = values[0];
 
if(youTubeVideoDataInfo != null && youTubeVideoDataInfo.isPercentFalg() == false) {
         youTubeVideoDataInfo.setPercentFalg(true);
}else if(youTubeVideoDataInfo.isPercentFalg()) {
         youTubeVideoDataInfo.setPercent(value);
         YoutubeList.mYoutubeGridViewApdater.notifyDataSetChanged();
}
 
}
 

 

갸아악 (21,260 포인트) 님이 2014년 8월 13일 질문

1개의 답변

+4 추천
 
채택된 답변

많이 고민하시는 것 같아 자세히 답변답니다.

progress 처럼 빈번히 갱신되는 데이터를 아답터 뷰에서 갱신할 때 notifyDataSetChanged를 계속 호출하게되면

화면에 보이는 셀 전체를 getView()를 통해 다시 호출하기 때문에 굉장한 낭비가 됩니다.

따라서 핵심은 현재 화면에 보이고 있는 셀일경우 뷰 자체에서 갱신하도록 하되,

아답터에 progress 데이터는 계속 업데이트 하고 있다가 스크롤 등으로 getView()가 호출되었을 때는

아답터의 데이터를 바탕으로 다시 progress를 셋팅하도록 해야합니다.

간단한 pseudo 코드로 표현하자면

public void updateListRow(int position, int newprogres){
    int first = mListView.getFirstVisiblePosition();
    int last = mListView.getLastVisiblePosition();
    if (position >= first && position <= last) {
        View row = mListView.getChildAt(position - first);
        ProgressBar progressBar = 
             (ProgressBar) row.findViewById(R.xx.xx);
        progressBar.setProgress(newprogress);
    } 
    아답터의 progress 데이터를 newprogress로 갱신
}

이런식으로 컨트롤러에서 뷰를 직접 업데이트 시키고, 아답터의 getView에서는  가지고 있는 progress데이터로

언제든 다시 그리면 자기 position의 프로그래스값을 다시 셋팅할 수 있도록 해주어야 합니다.

b22n (22,940 포인트) 님이 2014년 8월 13일 답변
갸아악님이 2014년 8월 13일 채택됨
자세한 답글 진심으로 감사드립니다.
정말 한줄기의 빛이 보이는군요.
그런데 지금 많은 혼란이 온 상태라 점점 더 헷갈리는데요.
현재 구조가
Activity class, Adapter class, AsyncTask class
이렇게 세개의 구조로 되어있습니다.
진행률에 대한 수치는 AsyncTask가 가지고 있습니다.
위에 말씀해주신 코드는 위의 세곳중 어느곳에 위치해야되는것인가요?
위에 말씀하신 코드가 프로그래스를 업데이트 하는 코드인건가요?
수수께끼야 진짜ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ
그러니깐 b22n님의 말씀은, 님이 처음한것처럼 ASyncTask의 onUpdate에서 progressbar를 넘겨받아서 계속 업데이트를 해주구요..
getVIew에서는 제가 적어놓은 arraylist의 해당 포지션값의 progress를 적용시키면 된다라는 말씀이시네요.

제가 말씀드린건 notifydatachange를 매번하면 리소스낭비가 심하니 progressbar만 적용시키고,
리스트뷰를 드래그하면 다시 순서가꼬이니 제가말씀드린대로 셋팅을 하면, 드래그안할때는 해당 progressbar만 업데이트되고 드래그를 하면 arrayList의 값을 가져오니 순서가꼬일일도없을거같네요.

즉 , ASynctask의 onUpdate에 저 코드를 넣으시구요(저코드를 넣으면 실시간 업데이트는 되는데 드래그시 순서는 보장안됨)
getView에는 ArrayList의 position값을 셋팅하면될거같네요.(드래그시에 순서보장됨)
아까 제가말씀드린 notifyDataSetChange는 빼는게 맞을거같네요.

명쾌하게 답변해주신듯..
...