1

I create a gridview with some String. WHen I click on each of it I change its status to activated and I use that property to change the color of the selected item.

All works correctly if I don't scroll the gridview, but If I selected one item and after I scroll the gridview , the item start to change its color every time that I scroll the gridview.

Can you help me to find the error ? :(

THis is my code :

@Override
    public View getView(int i, View view, ViewGroup viewGroup) 
    {
        ViewHolder viewHolder;
        // General ListView optimization code.

        if (view == null) {
            view = mInflator.inflate(R.layout.gridview_command_element, null);
            viewHolder = new ViewHolder();
            viewHolder.boh = (TextView) view.findViewById(R.id.cmd_name);
            view.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) view.getTag();
        }


        final String Name = lista.get(i);

        if (Name != null)
        {  
            viewHolder.boh.setText(Name);
        }

        return view;
    }

    static class ViewHolder 
    {
       TextView boh;
    }

this is the onitemclicklistener:

@Override
    public void onItemClick(AdapterView<?> parent, View view, int position,long id) 
    {


        if(adapter4selectedCmd.getCount() < 10)
        {   

            view.setActivated(true);
            String cmd = (String)adapter.getItem(position);
        }
        else
        {
            view.setActivated(false);
        }

    }

This is the xml layout and selector :

    <?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_activated="true" android:color="@color/tableTextSelectedColor" />
    <item android:color="@color/tableTextColor" />
</selector>


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:gravity="center_vertical|center_horizontal"
              android:id="@+id/ecu_list_element"
              >

    <TextView android:id="@+id/cmd_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="24dp"
            android:textColor="@color/text_selector"
            android:gravity="center_horizontal|center_vertical"/>


</LinearLayout>
aeroxr1
  • 1,014
  • 1
  • 14
  • 36
  • similar to this http://stackoverflow.com/questions/20611123/listview-subobject-clickable-confilct – Raghunandan Jul 16 '15 at 03:26
  • Rather than setting to the view, update the data model and keep track of all the changes to it, and in adapter getview method react according to the model values. – jitain sharma Jul 16 '15 at 03:34

2 Answers2

2

When you scroll your grid view the views are recycled. If you change the state of one child view and then scroll down and that child view is reused but the new data does not have the same state your child view will have the same state that it had the first time you set it. Create a SparseBooleanArray to save the state of each object. Instead of setting the view to activated only in the button click you also need to update the sparse boolean array and check the boolean array in the getView() method call to set the activated position.

SparseBooleanArray booleanArray = new SparseBooleanArray();
@Override
public View getView(int i, View view, ViewGroup viewGroup) 
{
    ViewHolder viewHolder;
    // General ListView optimization code.

    if (view == null) {
        view = mInflator.inflate(R.layout.gridview_command_element, null);
        viewHolder = new ViewHolder();
        viewHolder.boh = (TextView) view.findViewById(R.id.cmd_name);
        view.setTag(viewHolder);
    } else {
        viewHolder = (ViewHolder) view.getTag();
    }


    final String Name = lista.get(i);

    if (Name != null)
    {  
        viewHolder.boh.setText(Name);
    }
    if(booleanArray.get(i)){
        view.setActivated(true);
    } else {
        view.setActivated(false);
    }
    return view;
}

static class ViewHolder 
{
   TextView boh;
}

here is the onitemclicklistener:

@Override
public void onItemClick(AdapterView<?> parent, View view, int position,long id) 
{


    if(adapter4selectedCmd.getCount() < 10)
    {   

        view.setActivated(true);
        booleanArray.put(position, true);
        String cmd = (String)adapter.getItem(position);
    }
    else
    {
        view.setActivated(false);
        view.put(position, false);
    }

}
doubleA
  • 2,446
  • 22
  • 45
  • Thanks ! Therefore at the buttonclick I have to call adapter method that populated this sparseBooleanArray ? Can you do a little example ? Sorry .. – aeroxr1 Jul 16 '15 at 03:34
  • yes check edits I was assuming that your onclick is in the same class but you should get the idea. – doubleA Jul 16 '15 at 03:38
  • It's works perfectly !!! And I have learned a new thing on the listview/gridview ! Thanks :D – aeroxr1 Jul 23 '15 at 22:23
1

Problem is

if (Name != null)
        {  
            viewHolder.boh.setText(Name);
        }

You have to use a else statement with a if statement in getView method.

You need to write else statement also Beacause adapter reuses the old views which are already created So if and else both should be there.

J.R
  • 2,113
  • 19
  • 21