본문 바로가기

ANDROID

Viewholder 사용하기

보통 C/C++와같은 Native 언어에서 필드로 하여, 직접적으로 접근하는 것은 좋은 코드이긴 하나 안드로이드에서는 그렇지 않습니다.



객체에 접근하는 것은 지역 변수에 접근하는 것 보다 매우. 확실히  더 느립니다. 



그러기에 객체에 접근하는걸 Cache화 해야하는데.. 이런기능은 이미 제작되어있습니다..



그런데 별로 설명해주는곳이 없더군요.. 그건 ViewHolder라는 것을 사용하면 됩니다.



이름 그대로 View를 홀더에 꼽는다. 혹은 View에 홀더를 꼽아서 꺼내기 편하게 한다..



 즉. 참조하기 빠르게 미리 꼽아둔다는 겁니다.



제가 사용한 ViewHolder를 보며 예를 들어보겠습니다.


import java.util.ArrayList;

import android.content.Context;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
 
class ViewHolder
{
    ImageView ivThumbnail;
    TextView tvScreenName;
    TextView tvCreatedAt;
    TextView tvText;
}

public class CustomAdapter extends ArrayAdapter<TweetInfo>
{
    private Context mContext;
    private int mResource;
    private ArrayList<TweetInfo> mList;
    private LayoutInflater mInflater;
    public CustomAdapter(Context context, int layoutResource, ArrayList<TweetInfo> objects)
    {
        super(context, layoutResource, objects);
        this.mContext = context;
        this.mResource = layoutResource;
        this.mList = objects;
        this.mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        ViewHolder holder = null;
        TweetInfo tweet = mList.get(position);
 
        if(convertView == null)
        {
            convertView = View.inflate(mContext, R.layout.lst_view_row, null);                
            holder = new ViewHolder();
            holder.ivThumbnail = (ImageView) convertView.findViewById(R.id.list_view_row_profile_thumbnail);
            holder.tvScreenName = (TextView) convertView.findViewById(R.id.list_view_row_user_screen_name);
            holder.tvCreatedAt = (TextView) convertView.findViewById(R.id.list_view_row_create_at);
            holder.tvText = (TextView) convertView.findViewById(R.id.list_view_row_text);
            convertView.setTag(holder);
        }else{
            holder = (ViewHolder)convertView.getTag();
        }
        
        if (tweet != null) 
        {
            holder.tvScreenName.setText(tweet.getFrom_user());
            holder.tvCreatedAt.setText(tweet.getCreated_at());
            holder.tvText.setText(tweet.getText());
        }
        
  
        return convertView;
    }
}

간단하게 보면


아직 convertView가 캐시화(뷰홀더)에 저장이 안되어있으면, 새롭게 ViewHolder를 선언해 그곳에 꼽아(?) 보관해 줍니다.

다음에 사용할때 바로 멤버로 엑세스가 가능하게끔 접근성을 높여줍니다.


이렇게 사용하고 나면 많은 양의 Row가 잇어도 Listview는 힘들어 하지 않을겁니다.




저의 설명이 매우 부실하기 때문에 [여기][여기]를 참조해주시면 더욱 좋습니다. :)