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

커스텀 arrayAdapter를 이용해 spinner에 이미지 표현할 때 몇몇 이미지 안보이는 증상

0 추천
커스텀 ArrayAdapter를 사용하여 Spinner에 이미지를 표시하는 데 안 보일 때가 있습니다.

코드는 아래와 같습니다.

 

public class AppInfo implements Serializable {
    public byte[] imgData;
    public  String AppName;
    public String PackageName;
 
 
}
 
public class custom_adapter extends ArrayAdapter {
    public ArrayList<AppInfo> m_list;
 
 
    private PackageManager pm;
 
    ALPHA_COMPARATOR _comparator;
 
 
    public custom_adapter(Context context, int textViewResourceId) {
        super(context, textViewResourceId);
        pm = context.getPackageManager();
        m_list=new ArrayList<AppInfo>();
        _comparator = new ALPHA_COMPARATOR(context);
    }
    public custom_adapter(Context context, int textViewResourceId, String[] objects) {
        super(context, textViewResourceId, objects);
        pm = context.getPackageManager();
        m_list=new ArrayList<AppInfo>();
        _comparator = new ALPHA_COMPARATOR(context);
    }
 
......
 
 
 
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        return getCustomView(position, convertView, parent);
    }
 
    @Override
    public View getDropDownView(int position, View convertView, ViewGroup parent) {
        return getCustomView(position, convertView, parent);
    }
 
    public View getCustomView(int position, View convertView, ViewGroup parent)
    {
        final Context context = parent.getContext();
       
        ImageView img=null;
        TextView text=null;
        Holder holder=null;
 
       if ( convertView == null ) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
           convertView = inflater.inflate(R.layout.custom_item, parent, false);
 
           img = (ImageView) convertView.findViewById(R.id.list_image);
           text = (TextView) convertView.findViewById(R.id.text);
 
 
           holder = new Holder();
           holder.iv=img;
           holder.tv=text;
           convertView.setTag(holder);
       }
       else
       {
           holder=(Holder)convertView.getTag();
           img=holder.iv;
           text=holder.tv;
       }
 
img.setImageBitmap(BitmapFactory.decodeByteArray(m_list.get(position).imgData, 0, m_list.get(position).imgData.length));
text.setText(m_list.get(position).AppName);
 
        return convertView;
    }
 
setImageBitmap 때문에 느려서 일꺼라는 분들도 계셔서 cache를 써 보아도 같은 증상입니다.
피카소 라이브러리 써 보시라는 분도 계셨는데 안되네요...

꼭 처음 드돕다운의 모든 아이템은 다 표시되고 그 다음 첫 아이템은 항상 표시되지 않습니다
또 표시 됐던 것도 스크롤 하다 다시 돌아가 보면 안보일 때가 있고 다시 내렸다 돌아가면 다시 표시 될 때도 있습니다.

하지만 convertView가 null일  때만 하지 않고 항상

LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
           convertView = inflater.inflate(R.layout.custom_item, parent, false);
 
위 함수를 호출해서 converView를 갱신해서 사용하면 이미지는 잘 보이는데 대신 스크롤을 많이 하면 메모리 사용이 계속 증가 하다가 OutOfMemory가 발생합니다.
 
convertView의 null 처리 부분이 잘 된것 맞나요?
 
고수님들의 가르침을 부탁드립니다.
궁금이5 (740 포인트) 님이 2015년 3월 14일 질문

1개의 답변

0 추천
그냥 Bitmap으로 사용하시면 파워스크롤(?) 확 스크롤 다운하고 그러면 outofmememory 발생하죠

bitmap 사용하다보면 이런 문제들 많이 겪는데, 저도 리스트뷰에 이미지를 bitmap으로 표기하다가 이 문제로 걍 포기하고 말았쬬. bitmap.recycle()로 메모리에서 제거하고 이런것도 안먹히고 물론 먹히겠지만, 이걸 일일이 list 보여주는 activitiy에다가 설정해버리면 어디부분에서 제거되어야 하고 하는것을 정확하게 알아야하죠. 안그러면 recycle된 이미지를 다시 사용하려고 한다고 하면서 뭐라뭐라 에러 나오죠.

 

전 그래서 그냥 android:largeHeap="true"였나? 이걸로 해결했지만 이것도 임시방편이지 나중을 위해서라면 방법이 필요합니다.

님 adapter 코드는 문제될게 없어보이고, 단순히 image를 bitmap으로 바꾸면서 메모리를 많이 잡아먹는 것이 문제입니다.

그냥 비트맵을 사용하지마세요. imageview로 setdrawable 이 함수였나? 이걸로 그냥 해버리시징
Djleeee (13,180 포인트) 님이 2015년 3월 16일 답변
답변 감사합니다.
에초에 그 방법도 사용해 봤었는데, 메모리를 훨씬 많이 먹었구요, 똑같이 이미지가 표시 안 될 때가 있더군요.
마찬가지로 convertView를 null처리 하지 않고, 항상 새로 받아서 사용하면 이미지는 표시되는데, 똑같이 OutOfMemory가 발생하더군요.

파워스크롤(?) 을 하면 훨씬 반응 성은 좋았습니다.
앵 다시보니, custom하게 리스트 작성하셨는데,
getCustomView는 왜 만드신거죠??
그냥 getView에 저 넣으시면 됐을텐데
참고로 convertview==null 이부분은 상관 없다고 봅니다.
널이면 새로 만드는것이니
...