Search code examples
javaandroidxmlandroid-listviewandroid-dialogfragment

Deselect item in ListView


This is the scenario: in a ListView i would like that the selected item remain selected until the user click on a DialogFragment button. The problem is that if the user click on back button, without any click in the DialogView, the item in the ListView remains selected.

I read this post , and the solutions work quite well: i click on a item, the dialog appears, i click the back button and the selector is gone.

But if i scroll the list, the selector comes back! Where am I wrong?

Here the code:

<ListView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/listView"
        android:layout_gravity="center"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="15dp"
        android:layout_marginRight="10dp"
        android:layout_marginBottom="15dp"
        android:divider="@android:color/transparent"
        android:visibility="visible"
        android:dividerHeight="5dp"
        android:choiceMode="singleChoice"
        android:drawSelectorOnTop="true"
        android:listSelector="@color/primario_1_alfa"/>

and the DialogFragment where i'm trying to deselect the listview element

public class MyDialog extends DialogFragment {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setMessage("Test dialog view")
                .setPositiveButton("action 1", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {

                    }
                })
                .setNegativeButton("action 2", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {

                    }
                });
        return builder.create();
    }
    @Override
    public void onDestroy(){
        super.onDestroy();
        ListView listView = (ListView) getActivity().findViewById(R.id.listView);
        listView.clearChoices();
        listView.requestLayout();
    }
}

Solution

  • This is due to recycling of views using the ViewHolder pattern.

    Since you only need a single select item at any moment, you can keep track of the position of the item that is selected in the Adapter and then check that position against the current position of the view to be populated with the ViewHolder data.

    int selectedPosition;
    ...
    onItemClickListener(int position, ...) {
       selectedPosition = position;
    }
    ...
    getView(int position, ...) {
    
       if (selectedPosition == position) {
          view.setSelected(true);
       } else {
          view.setSelected(false);
       }
    }
    

    Something along these lines.