public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
Log.i("test33", "getview call : " + g);
g++;
day = mDayList.get(position);
DayViewHolde dayViewHolder;
if (convertView == null) {
Log.i("test33", "convertView null");
convertView = mLiInflater.inflate(mResource, null);
convertView.setLayoutParams(params);
//뷰홀더 고정
dayViewHolder = new DayViewHolde();
dayViewHolder.calender_rel = (RelativeLayout)convertView.findViewById(R.id.calender_rel);
dayViewHolder.calender_rel_sel = (RelativeLayout)convertView.findViewById(R.id.calender_rel_sel);
dayViewHolder.calender_rel_startbox = (RelativeLayout)convertView.findViewById(R.id.calender_rel_startbox);
dayViewHolder.calender_rel_finishbox = (RelativeLayout)convertView.findViewById(R.id.calender_rel_finishbox);
dayViewHolder.calender_rel_finishbox_botton = (RelativeLayout)convertView.findViewById(R.id.calender_rel_finishbox_botton);
dayViewHolder.calender_photo = (ImageView)convertView.findViewById(R.id.calender_photo);
dayViewHolder.cal_halfcircle = (ImageView)convertView.findViewById(R.id.cal_halfcircle);
dayViewHolder.calender_days = (TextView)convertView.findViewById(R.id.calender_days);
dayViewHolder.calender_finish_count = (TextView)convertView.findViewById(R.id.calender_finish_count);
dayViewHolder.calender_finish_count_botton = (TextView)convertView.findViewById(R.id.calender_finish_count_botton);
dayViewHolder.calender_start_count = (TextView)convertView.findViewById(R.id.calender_start_count);
convertView.setTag(dayViewHolder);
} else {
Log.i("test33", "convertView not null");
dayViewHolder = (DayViewHolde)convertView.getTag();
}
return convertView;
달력을 만들면서 위와 같이 뷰홀더를 적용중입니다.
문제는 없다!... 라고 안심하다가 속도가 워낙 느려서 로그를 찍어보니
겟뷰의 호출횟수 1번에서는 컨버트뷰가 널, 뷰를 파인드하고
2회에서는 컨버트뷰가 널이 아니니까 바로 겟테그를 해서 사용하더군요.
그런데 왜 3회째 루프에서 컨버트뷰가 널이되면서 마지막까지 파인드를 하는걸까요!!
제가 뷰홀더를 잘못써도 한참 잘못쓴것 같은데... 답변 바랍니다.
성능땜에 홀더패턴을 적용하실 텐데.. 최소화 해야하는 getView안에 저렇게나 findViewById를 호출하면 도루묵이됩니다 @.@;;
뷰뿐만 아니라 레이아웃들도 모두 연산을 사용해 연결해주셨는데.. getView의 else문 밑에서 사용하지 않으시면 최대한 빼시고 입출력이 아닌 이벤트를 처리하고 싶으시면 우회해서(xml상에서 클릭리스너를 등록해준다던지....) 해결하시면 좋겠네요.
그리드뷰를 쓰시는 건가요? 스크린에 month단위로 1일부터 말일까지 한화면에 나오는 거라면 convertView가 null인게 당연할 텐데요.. convertView가 null이 아닌 경우는 화면에서 짤리는 부분을 위아래로 스크롤하는 경우가 그렇죠.. 그리고 한 화면에 월단위가 아닌 1단위로 표현하시는 거라면 성능상의 문제로 그리드뷰나 리스트뷰를 사용하지 않으시는게 좋구요...
아무리 홀더패턴을 쓰더라도 위에 로직을 보시면 아시겠지만. . converView 인자가 호출시점에 넘어오는지 아닌지로 분기가 됩니다..
converView의 사용은 infalte 메쏘드의 호출을 줄여 성능향상을 노리는 것이고. . 홀더패턴의 장점은.. findViewById 메쏘드의 호출을 줄여 성능 향상을 꾀하는거죠...
화면에 10개의 그리드뷰 아이템이 표현되고 나머지 20개는 잘려서 스크롤로 볼 수 있다면.. 분명 converView + holder 적용은 장점이 될 수 있습니다..
반면 30개의 그리드 뷰 아이템이 표현되고 짤리는 부분이 없다면.. converView는 30개동안 null이 나올테고 위 패턴이 적용되는 경우가 전혀 없게 되죠.. 오히려 홀더로 인한 메모리만 추가로 잡아먹게 됩니다...
리플에 대한 답은.. getView는 화면에 리스트가 뿌려질때 표현되는 item의 갯수만큼(정확히는 이런저런 이유로 몇 번 더 호출됩니다.) 리스트뷰로 예를들면 0번에서 5번까지 화면에 6개가 나왔고.. 스크롤로 6번(순서로는 7번째)을 보게 되면 0번아이템이 화면 위로 사라지면서 그게 재사용이 되고 convertView의 매개변수로 들어오게 됩니다..
즉 한 화면에 모든 아이템을 다 표현한다면 converView가 재사용될 일이 없습니다 '';




근데 뭔 뷰가 저렇게 많아요? 날짜 한칸에 저렇게 많은 뷰가 필요한가요?
convertView를 AdapterView가 관리하게 되어있는데요... null 이 넘어오는 케이스는
메모리 관리하다보니 줄게 없는 케이스라고 보시면 됩니다.
null이 자꾸 넘어온다면 일종의 메모리 문제라고 보셔도 됩니다.
버거워하는거죠... 재활용을 못하고 자꾸 날리고 필요할때 만드는겁니다.
되도록이면 뷰를 좀 줄여보시는게 좋을 것 같습니다. 한칸에 저렇게 많은 뷰가 필요한지 다시한번 확인해보세요.