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

ListView 이벤트 관련 질문입니다.

0 추천

@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();
        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.txtuse.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(mCouponList.get(position).getBarcode() != null) {
                    Toast.makeText(mContext, "position : " + position, Toast.LENGTH_SHORT).show();
                    holder.txtbarcode.setVisibility(View.VISIBLE);
                    holder.rlcontent.setVisibility(View.GONE);

                }
            }
        });
        holder.ivimage = (ImageView) convertView.findViewById(R.id.row_coupon_iv_image);

        holder.txtbarcode = (TextView) convertView.findViewById(R.id.row_coupon_tv_barcode);

        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    holder.txtname.setText(mCouponList.get(position).getName());
    holder.txtenddate.setText(mCouponList.get(position).getEnd_dt() + "까지");
    holder.txtstore.setText(mCouponList.get(position).getStore_summary());
    if(mCouponList.get(position).getType() == 1) {
        holder.txtdiscount.setText(String.valueOf(mCouponList.get(position).getDiscount()) + "%");
    } else if(mCouponList.get(position).getType() == 2) {
        holder.txtdiscount.setText("-" + String.valueOf(mCouponList.get(position).getDiscount()) + "원");
    }

    if(mCouponList.get(position).getStatus() == 1 || mCouponList.get(position).getStatus() == 2) {
        if(mCouponList.get(position).getBarcode() != null) {
            holder.txtbarcode.setText(mCouponList.get(position).getBarcode().getBarcode());
        }
    }

    return convertView;
}

현재 getView 메소드입니다.

 

holder.txtuse.setOnClickListener

에서 TextView에 클릭 리스너를 달아서 해당하는 position의 레이아웃을 변경해주는 작업을 해주고 있습니다.

 

제가 원하는 것은 해당 position은 저렇게 변경을 해주고 다른 position의 레이아웃은 반대로 GONE, VISIBLE 작업을 해주고 싶은데... 클릭 된 다른 position의 레이아웃을 잡을 아이디어가 있을까요...??

 

layout code)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent">

    <RelativeLayout
        android:id="@+id/row_coupon_rl_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/row_coupon_tv_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center_vertical"
            android:text="test"/>

        <RelativeLayout
            android:id="@+id/row_coupon_rl_date_store"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/row_coupon_tv_name">
            <TextView
                android:id="@+id/row_coupon_tv_enddt"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center_vertical"
                android:text="test"/>
            <TextView
                android:id="@+id/row_coupon_tv_store"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="10dp"
                android:layout_toRightOf="@+id/row_coupon_tv_enddt"
                android:gravity="center_vertical"
                android:text="test"/>
        </RelativeLayout>

        <TextView
            android:id="@+id/row_coupon_tv_temp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/row_coupon_rl_date_store"
            android:visibility="gone"
            android:text="test"/>

        <TextView
            android:id="@+id/row_coupon_tv_discount"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/row_coupon_tv_temp"
            android:gravity="center_vertical"
            android:text="50"/>

        <TextView
            android:id="@+id/row_coupon_tv_use"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:layout_below="@+id/row_coupon_tv_discount"
            android:gravity="center_vertical"
            android:background="@drawable/button_blue_outline"
            android:text="사용하기"/>

        <ImageView
            android:id="@+id/row_coupon_iv_image"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/row_coupon_rl_date_store"
            android:src="@drawable/ic_home_coupon"
            android:background="@android:color/transparent"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"/>
    </RelativeLayout>


    <TextView
        android:id="@+id/row_coupon_tv_barcode"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"
        android:visibility="gone"/>
</RelativeLayout>

 

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

1개의 답변

+1 추천
 
채택된 답변
정확히 어떤 것을 하려는지 모르겠습니다만

퍼포먼스 문제가 생길 듯 하네요.

아이템들의 레이아웃을 Visible, Gone하는 것보다는

어댑터의 아이템 리스트를 갱신해주는 것이 좋을 것 같습니다.

 

그리고 위 소스에서

홀더에 새로 텍스트뷰가 들어갈 때에만 클릭리스너를 달아주셨는데

그렇게 하면 리스트 뷰 스크롤 시 클릭리스너가 정상 작동 하지 않을겁니다.

if(convertView == null){

...

}else{

...

}이 끝난 다음에 클릭 리스너를 붙이셔야 할 거에요
파닭칡힌 (1,820 포인트) 님이 2015년 6월 2일 답변
taejun님이 2015년 6월 4일 채택됨
음... 어떤식으로 변경해야된다는 말씀이시져...ㅠㅠ?

지금 position=6 일 때, (7번째 아이템이 생성될 때)
if(converView==null)에 들어가지 않아서 생성이 안되서 인덱스가 꼬이는 것 같아요....ㅠㅠ
getView에서 받아오는 position은
실제로 리스트뷰에 보이는 convertView의 순서이기 때문에

taejun님의 실제 아이템 갯수가 100개여도
리스트뷰에 보이는 아이템이 6개면
position은 0~5까지 밖에 받아오지 않아요.
계속 0~5를 돌려가면서 사용하는거에요

그러니
Viewholder holder;
if(convertView==null){
...
}else{
holder = (ViewHolder)convertView.getTag();
}
하시고
밑에서 사용하는
mHolderList.get(position)대신
holder를 사용하셔야 안꼬여요
네... 그렇다면 7번째 아이템이 보일 때는
if(converView==null) 에 들어가서 뷰홀더가 생성이 되어야 되지 않나요...?
말씀대로 아래와 같이 수정하였는데,

@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();
        }

        holder.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(), holder.ivbarcode, options);
                        holder.rlbarcode.setVisibility(View.VISIBLE);
                        holder.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();
                }
            }
        });

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


        return convertView;
    }

처음 리스트뷰를 내릴 시에는 정상적으로 나타납니다... 하지만
getTag가 잘못불리는지... 위로 다시 올라가면 꼬여버리네요...음....
의심가는 부분은
태그 설정할 때 convertView.setTag(mHolderList.get(position));
이거 밖에 없네요..
convertView.setTag(holder)로 해보세요.

그 외에는 저도 모르겠네요..;
...