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

ListView ViewHolder 패턴시 에러 문제입니다.

0 추천

현재 ListView에 데이터를 ViewHolder 패턴을 이용해서 구현하였습니다.

 

또한 ListView item 내에 TextView의 클릭 이벤트를 감지하여

ViewHolder를 제어하기 위해서 ArrayList<ViewHolder>를 생성하였습니다.

 

그렇게해서 converView==null 일 때 ArrayList에 add를 하는데요.

 

다음은 getView 코드입니다.

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {

        final ViewHolder holder;

        if(convertView == null){
            convertView = mInflater.inflate(R.layout.row_coupon_list, null);

            holder = new ViewHolder();

            Log.i("size", String.valueOf(position));
            holder.rlcontent = (RelativeLayout) convertView.findViewById(R.id.row_coupon_rl_content);
            holder.txtname = (TextView) convertView.findViewById(R.id.row_coupon_tv_name);
            holder.txtenddate = (TextView) convertView.findViewById(R.id.row_coupon_tv_enddt);
            holder.txtstore = (TextView) convertView.findViewById(R.id.row_coupon_tv_store);
            holder.txtdiscount = (TextView) convertView.findViewById(R.id.row_coupon_tv_discount);
            holder.txtuse = (TextView) convertView.findViewById(R.id.row_coupon_tv_use);
            holder.ivimage = (ImageView) convertView.findViewById(R.id.row_coupon_iv_image);

            holder.rlbarcode = (RelativeLayout) convertView.findViewById(R.id.row_coupon_rl_barcode);
            holder.ivbarcode = (ImageView) convertView.findViewById(R.id.row_coupon_iv_barcode);
//            holder.txtbarcode = (TextView) convertView.findViewById(R.id.row_coupon_tv_barcode);

            mHolderList.add(holder);

            convertView.setTag(mHolderList.get(position));
        } else {
            Log.i("size2", String.valueOf(position));
            mHolderList.set(position, (ViewHolder) convertView.getTag());
//            holder = (ViewHolder) convertView.getTag();
        }

        mHolderList.get(position).txtname.setText(mCouponList.get(position).getName());
        mHolderList.get(position).txtenddate.setText(mCouponList.get(position).getEnd_dt() + "까지");
        mHolderList.get(position).txtstore.setText(mCouponList.get(position).getStore_summary());
        if(mCouponList.get(position).getType() == 1) {
            mHolderList.get(position).txtdiscount.setText(String.valueOf(mCouponList.get(position).getDiscount()) + "%");
        } else if(mCouponList.get(position).getType() == 2) {
            mHolderList.get(position).txtdiscount.setText("-" + String.valueOf(mCouponList.get(position).getDiscount()) + "원");
        }
        if(mCouponList.get(position).getImage() != null)
            ImageLoader.getInstance().displayImage(mCouponList.get(position).getImage().getUrl(), mHolderList.get(position).ivimage, options);

        mHolderList.get(position).txtuse.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.i("position", String.valueOf(position));
                try {
                    // 해당 포지션의 바코드 정보를 가져온다.
                    Barcode barcode = new CouponUseTask(mContext).execute(mCouponList.get(position).getCoupon_id()).get();

                    // 바코드가 있으면 바코드를 보여줌
                    if (barcode != null) {
                        mCouponList.get(position).setBarcode(barcode);
                        ImageLoader.getInstance().displayImage(mCouponList.get(position).getBarcode().getBarcode_image().getUrl(), mHolderList.get(position).ivbarcode, options);
                        mHolderList.get(position).rlbarcode.setVisibility(View.VISIBLE);
                        mHolderList.get(position).rlcontent.setVisibility(View.GONE);
                    }

                    // 클릭된 포지션 외에 전환
                    for(int i = 0; i < mHolderList.size(); i++) {
                        if(i == position)
                            continue;
                        else {
                            mHolderList.get(i).rlbarcode.setVisibility(View.GONE);
                            mHolderList.get(i).rlcontent.setVisibility(View.VISIBLE);
                        }
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        return convertView;
    }

 

문제점)

 - ListView를 드래깅하여 내려가다가 새로운 아이템이 생성될 때(예를들면 position 7번째의 아이템이 생성될 때) 

if(converView == null) 로 분기되어 ArrayList에 add를 해야하는데, 이 시점에 

else 구문을 타면서 add 받지 못한 position의 값이 set되려고 합니다. 그래서 어플이 강제종료 되버리는 현상이 발생합니다.

 

해결책이 있을까요? 혹은 다른 방법이 있는지 궁금합니다...

taejun (7,240 포인트) 님이 2015년 6월 4일 질문

답변 달기

· 글에 소스 코드 보기 좋게 넣는 법
· 질문에 대해 추가적인 질문이나 의견이 있으면 답변이 아니라 댓글로 달아주시기 바랍니다.
표시할 이름 (옵션):
개인정보: 당신의 이메일은 이 알림을 보내는데만 사용됩니다.
스팸 차단 검사:
스팸 검사를 다시 받지 않으려면 로그인하거나 혹은 가입 하세요.
...