0

I'm trying to find out why spinner is conflicting with checkBox inside a listView. If I comment the spinner lines, the checkBox listener works fine, I can select it, check if is selected and delete the row of the List. If I let the spinner declaration, as it is in the code below, the listener works, I can select the checkBox but when I try to get the selected Item (at checkToDelete method) the return of the selected checkBox is always empty (like there is nothing selected). I need the spinner to check the quantity of items and the checkBox to delete the row.

Anyway, I've been researching a solution for 2 days and wouldn't like to let this problem go before know what is going on and prevent future mistakes. One possible solution I found is to avoid the use of spinner and instead use a button with AlertDialog

Does anyone know what I'm missing here?

 @Override
        public View getView(final int position,View convertView, ViewGroup viewGroup) {
            LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            final View rowView = inflater.inflate(R.layout.menu_itens, viewGroup
                    , false);

            String itemName = MENU_ITEM.get(position);
            TextView item = (TextView) rowView.findViewById(R.id.item);     
                item.setText(itemName);
            imageView = (ImageView) rowView.findViewById(R.id.itemImage);

            checkBox[position] = (CheckBox) rowView.findViewById(R.id.check);
            checkBox[position].setTag(itemName);
            checkBox[position].setOnCheckedChangeListener(new OnCheckedChangeListener() {

                public void onCheckedChanged(CompoundButton buttonView,
                        boolean isChecked) {               
                        checkBox[position].setSelected(buttonView.isChecked());
                    }            
                });         
                spinner[position] = (Spinner) rowView.findViewById(R.id.quantity);
                spinner[position].setAdapter(spinnerAdapterArray[position]);
                spinner[position].setOnItemSelectedListener(new OnItemSelectedListener() {

                    @Override
                    public void onItemSelected(AdapterView<?> parent, View view,
                            int pos, long id) {
                        //Listener options      
                    }

                    @Override
                    public void onNothingSelected(AdapterView<?> parent) {
                        // TODO Auto-generated method stub              
                    }           
                });
                return rowView;
            }

      public List<Integer> checkListToDelete() {

        List<Integer> aux = new ArrayList<Integer>();   
        for(int i=0; i<MENU_SIZE; i++){
            System.out.println(checkBox[i].isChecked());
            if(checkBox[i].isChecked()){
                checkBox[i].setChecked(false);
                aux.add(i);
                }
            }   
        return aux; 
        }
Community
  • 1
  • 1
Victor Oliveira
  • 3,293
  • 7
  • 47
  • 77
  • This is not how you create an adapter, you can't just use an array of Views and index into them by `position`. – ashishduh May 21 '14 at 12:54
  • could you guide me please? I mean, why is wrong? until now as working perfect since I need different listener for each one of them – Victor Oliveira May 21 '14 at 12:57
  • Look at this example http://www.vogella.com/tutorials/AndroidListView/article.html#adapterperformance_example – ashishduh May 21 '14 at 12:57
  • I saw this example yesterday, but I wans't sure if I should use it. With a debug point, I realized that ``getView`` is called for each ``findViewByID``, so that means if I centralize everything in the holder maybe it's gonna work? – Victor Oliveira May 21 '14 at 13:05

1 Answers1

1
    private List<Boolean> mCheckList;

    @Override
    public View getView(final int position,View convertView, ViewGroup viewGroup) {
        LayoutInflater inflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        final ViewHolder holder;
        if (convertView == null) {
            holder = new ViewHolder();
            convertView = inflater.inflate(R.layout.menu_itens, null);

            holder.textview = (TextView) convertView.findViewById(R.id.item);     
            holder.imageView = (ImageView) convertView.findViewById(R.id.itemImage);
            holder.checkBox = (CheckBox) convertView.findViewById(R.id.check);
            holder.checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
                @Override 
                public void onCheckedChanged(CompoundButton buttonView,
                    boolean isChecked) {               
                    mCheckList.set(position, isChecked);
                }            
            });

            holder.spinner = (Spinner) convertView.findViewById(R.id.quantity);
            holder.spinner.setAdapter(spinnerAdapterArray[position]);
            holder.spinner.setOnItemSelectedListener(new OnItemSelectedListener() {

                @Override
                public void onItemSelected(AdapterView<?> parent, View view,
                        int pos, long id) {
                    //Listener options      
                }

                @Override
                public void onNothingSelected(AdapterView<?> parent) {
                    // TODO Auto-generated method stub              
                }           
            });

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

        String itemName = MENU_ITEM.get(position);
        holder.textview.setText(itemName);
        holder.checkbox.setChecked(mCheckList.get(position));

        return convertView;
    }

    public List<Integer> checkListToDelete() {

        List<Integer> aux = new ArrayList<Integer>();   
        for(int i=0; i<MENU_SIZE; i++){
            System.out.println(mCheckList.get(i));
            if(mCheckList.get(i)){
                aux.add(i);
            }

            mCheckList.set(i, false);
        }

        notifyDataSetChanged();
        return aux; 
    }

    class ViewHolder {
        TextView textview;
        ImageView imageview;
        Spinner spinner;
        CheckBox checkbox;
    }
ashishduh
  • 6,629
  • 3
  • 30
  • 35
  • I made the adapts of your code to my entire code here, the only point I'm missing to test your solution it ``mCheckList.get(i) = false`` or ``mCheckList.get(i) = isChecked`` it is saying that ``mCheckList.get(i)`` needs to be a variable - trying to solve this to test – Victor Oliveira May 21 '14 at 13:45
  • I was trying to use ``mCheckList.add(i, isChecked)``; anyway, the app is visually working, which until now is good, but when I try to check the box crashes. This happens 'cause ``mCheckList`` is null, it's not initialized. I'm trying ``List mCheckList = new ArrayList();`` even though still getting NullPointerException – Victor Oliveira May 21 '14 at 14:23
  • You need to initialize the list in the constructor of your adapter. Also, where are you calling `checkListToDelete()`? Show me all that code. – ashishduh May 21 '14 at 14:28
  • So far, what I'm thinking is that you can't set something that haven't been added. I tryed to use ``mCheckList.add(isChecked);`` to static delete only the first position and it works fine, I will see what I can do from here to handle it dynamically - I will accept your answer, would be also more than thankful if you could simple explain the usage of holder, whats makes the difference using it or not. Thank you very much! – Victor Oliveira May 21 '14 at 14:31
  • 1
    You need to initialize the list to be the same size as the list of items (`MENU_SIZE`?) and then you can use `mCheckList.set`. But the purpose of the ViewHolder is so you don't constantly use `findViewById` which is very intensive operation. It allows for smooth scrolling of list. – ashishduh May 21 '14 at 14:33