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

리스트뷰 체크박스 스크롤시...문제입니다.

0 추천

현재 각항목이 잘 출력되고 데이터저장에도 이상이없습니다.

다만 체크박스 클릭후 스크롤시 선택하지않은 체크박스가 체크가되어있고

기존 선택했던 체크박스는 사라지는 현상이 나타납니다.

제 생각에는 체크박스값을 별로 저장을해야될것같은데...

정확히 감이안옵니다.

소스는 아래와 같구요. 참고할수있는사이트나 해결방법좀 제시해주셨으면합니다..

이걸로 한달내내 붙잡고있네요..ㅠㅠ

   public class listdata_3 extends BaseAdapter {
        private Context context;
        private ArrayList<EachList_4> datalist;
        private int layout;
        private LayoutInflater inflater;
        public listdata_3(Context context, int layout,
                          ArrayList<EachList_4> listlist) {
            this.context = context;
            this.layout = layout;
            this.datalist = listlist;
            inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }
        @Override
        public int getCount() {
            return datalist.size();
        }
        @Override
        public Object getItem(int position) {
            return datalist.get(position);
        }
        @Override
        public long getItemId(int position) {
            return position;
        }
        public String getBArtCode(int position) {
            return datalist.get(position).BArtCode;
        }
        public String getBArtNAme(int position) {
            return datalist.get(position).BArtNAme;
        }
        public String getBStanDard(int position) {
            return datalist.get(position).BStanDard;
        }
        public String getBUnit(int position) {
            return datalist.get(position).BUnit;
        }
        public String getBSaleCost(int position) {
            return datalist.get(position).BSaleCost;
        }
        public String getBAMount(int position) {
            return datalist.get(position).BAMount;
        }
        public String getBjAMount(int position) {
            return datalist.get(position).BjAMount;
        }
        @Override
        public View getView(final int position, View convertView, final ViewGroup parent) {
            jeagoViewHolder viewHolder;
            if (convertView == null) {
                convertView = inflater.inflate(layout, parent, false);
                viewHolder = new jeagoViewHolder();
                viewHolder.ArtCode = (TextView) convertView
                    .findViewById(R.id.TxtbonsaArtCode);
                viewHolder.ArtNAme = (TextView) convertView
                    .findViewById(R.id.TxtbonsaArtNAme);
                viewHolder.StanDard = (TextView) convertView
                    .findViewById(R.id.TxtbonsaStanDard);
                viewHolder.Unit = (TextView) convertView
                    .findViewById(R.id.TxtbonsaUnit);
                viewHolder.SaleCost = (TextView) convertView
                    .findViewById(R.id.TxtSaleCost);
                viewHolder.AMount = (TextView) convertView
                    .findViewById(R.id.TxtbonsaAMount);
                viewHolder.jAMount = (TextView) convertView
                    .findViewById(R.id.TxtjAMount);
                viewHolder.chkbox = (CheckBox) convertView.findViewById(R.id.chkbox);
                convertView.setTag(viewHolder);

            }
            else{
                viewHolder = (jeagoViewHolder) convertView.getTag();
            }

            double danga = Double.parseDouble(datalist.get(position).BSaleCost);
            double danga1 = Double.parseDouble(String.format("%.0f", danga));
            final int danga2 = (int) danga1;
                DecimalFormat df = new DecimalFormat("#,##0");
                viewHolder.ArtCode.setText(datalist.get(position).BArtCode);
                viewHolder.ArtNAme.setText(datalist.get(position).BArtNAme);
                viewHolder.StanDard.setText(datalist.get(position).BStanDard);
                viewHolder.Unit.setText(datalist.get(position).BUnit);
                viewHolder.SaleCost.setText(df.format(danga2));
                viewHolder.AMount.setText(datalist.get(position).BAMount);
                viewHolder.jAMount.setText(datalist.get(position).BjAMount);
                if (pref.getString("PTVatMode", "").equals("1")) {
                   int vat = (danga2 / 11) * 1;
                   int money = danga2 - vat;
                   int tmoney = (money + vat) * 1;
                    db.execSQL("INSERT INTO jumun VALUES(null,'" + datalist.get(position).BArtCode + "', '" + datalist.get(position).BArtNAme + "','" + datalist.get(position).BStanDard + "','" + datalist.get(position).BUnit + "','1','" + danga2 + "','"+money+"','"+vat+"','"+tmoney+"','','0','0');");

                }
                else {
                    int vat = (danga2 / 10) * 1;
                    int money = (danga2) * 1;

                    int tmoney = vat + money;
                    db.execSQL("INSERT INTO jumun VALUES(null,'" + datalist.get(position).BArtCode + "', '" + datalist.get(position).BArtNAme + "','" + datalist.get(position).BStanDard + "','" + datalist.get(position).BUnit + "','1','" + danga2 + "','" + money + "','" + vat + "','" + tmoney + "','','0','0');");

                }
            viewHolder.chkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                    @Override
                    public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
                        if (isChecked) {
                            int id = position+1;
                            db.execSQL("Update jumun set checkYN1 = '1' where _id = '" +id + "';");
                           System.out.println("id값"+ id);
                        } else {
                            int id = position+1;
                            db.execSQL("Update jumun set checkYN1 = '0' where _id = '" +id + "';");

                        }

                    }
                });
            fab.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                        db.execSQL("Insert into orderTable(ArtCode,ArtName,StanDard,Unit,Amount,SaleCost,money,Vat,Tmoney,bigo,checkYN,checkYN1) select ArtCode,ArtName,StanDard,Unit,Amount,SaleCost,money,Vat,Tmoney,bigo,checkYN,checkYN1 from jumun where checkYN1='1';");
                        Intent i = new Intent(bonsajeagoActivity.this, jumunsinchung.class);
                        startActivity(i);
                    finish();
                }
            });
            viewHolder.chkbox.setChecked(((ListView)parent).isItemChecked(position));
            return convertView;
        }
    }

    public class jeagoViewHolder
        {
            public TextView ArtCode;
            public TextView ArtNAme;
            public TextView StanDard;
            public TextView Unit;
            public TextView SaleCost;
            public TextView AMount;
            public TextView jAMount;
            public CheckBox chkbox;

        }

 

아잉훗 (570 포인트) 님이 2016년 6월 7일 질문

1개의 답변

+1 추천
 
채택된 답변

AdapterView - Adapter - Data 관계에서

AdapterView는 각 데이터의 뷰를 표시하며 표시할 수 있는 Row 갯수 이상의 뷰를 만들지 않도록 재사용 하도록 되어있습니다.

Adapter는 AdapterView의 Row뷰를 제공합니다.

Data는 Row가 보여질때 사용할 값이 있습니다.

 

이 관계를 생각해 보시면 뷰를 체크했다고 실제 그 데이터가 체크됨이 아님을 알 수 있습니다.

AdapterView는 뷰가 어떤 데이터를 Bind해서 표시되는지 알 필요가 없으니까요. 그냥 getView에서 제공된 뷰만 보여줍니다.

그렇기에 CHOICE_MODE_SINGLE과 CHOICE_MODE_MULTIPLE이 있습니다.

isItemChecked의 정의를 보면,


isItemChecked

Added in API level 1

boolean isItemChecked (int position)

Returns the checked state of the specified position. The result is only valid if the choice mode has been set to CHOICE_MODE_SINGLE or CHOICE_MODE_MULTIPLE.

Parameters
positionint: The item whose checked state to return
Returns
booleanThe item's checked state or false if choice mode is invalid

"특정한 포지션의 선택 상태를 반환합니다. 결과는 choice mode가 설정되었을 때만 유효(valid)합니다."

라고 되어있네요.

리턴값의 설명은 "아이템의 선택상태를 반환하거나 choice mode가 아닌경우 false를 반환합니다."

문제는 이게... CheckBox등을 따로 구현해서 Row를 표시했다면 동작하지 않습니다.

ListView의 초이스 모드를 변경하시고,

listView.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);

아래와 같은 방법으로 구현하시면 동작합니다.

class MyAdapter extends BaseAdapter {

        ArrayList<String> items;

        public MyAdapter(ArrayList<String> items) {
            this.items = items;
        }

        @Override
        public int getCount() {
            return items.size();
        }

        @Override
        public Object getItem(int position) {
            return items.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            Holder holder = null;
            if (convertView == null) {
                convertView = LayoutInflater.from(getContext()).inflate(R.layout.mylistitem, parent, false);
                holder = new Holder(convertView);
            } else {
                holder = (Holder) convertView.getTag();
            }

            holder.position = position;
            holder.checkBox.setChecked(listView.isItemChecked(position));

            return convertView;
        }


        class Holder implements CompoundButton.OnCheckedChangeListener {
            View itemRoot;

            CheckBox checkBox;

            int position;

            public Holder(View itemRoot) {
                this.itemRoot = itemRoot;
                this.itemRoot.setTag(this);
                checkBox = (CheckBox) itemRoot.findViewById(R.id.checkBox);
                checkBox.setOnCheckedChangeListener(this);
            }

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                listView.setItemChecked(position, isChecked);
            }
        }
    }

 

따로 관리하고 싶으시다면,

EachList_4를 데이터로 사용하시는거 같은데 isSelected 같은 boolean 변수를 사용하시거나, 변수 추가가 여의치 않다면

EachList_4의 size만큼의 boolean array를 선언하셔서 check값을 관리하셔야 합니다.

칠리님 (10,910 포인트) 님이 2016년 6월 8일 답변
아잉훗님이 2016년 6월 8일 채택됨
자세한 설명 감사합니다.
알려주신대로 한번 진행해봐야겠네요.
listView. <- 이 부분에서 listView는 어디에서 가져오는 건가요?
다른 클래스에서 생성한 객체일텐데
...