1

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();
    }
}
Community
  • 1
  • 1
marco
  • 3,193
  • 4
  • 28
  • 51

1 Answers1

0

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.

mthandr
  • 3,062
  • 2
  • 23
  • 33
  • Sorry @androidpotato7 but i need some more hint :). After the Dialog is dismiss, i don't need any row to be selected, and i think `view.setSelected(false);` for every row, it would be sufficient, but it doesn't work. Neither your solution, i modified the getView method of the adapter as you suggested, and added the code `selectedPosition = position;` in the onItemClick method of the listener. Why do i need the position if i want all the round with no selector ? Thank you :) – marco Jul 29 '15 at 10:20
  • 1
    because views can be recycled at any moment, you never know. So at least the selectedPosition and the if in the getView lets you control exactly who gets selected or not. Implement the solution I have proposed and AFTER the dialog dismiss, call notifyDatasetChange() on the adapter, and all views will be redrawn, and since no position is selected (give selectedPosition = -1) all views will be drawn with selected == false – mthandr Jul 29 '15 at 14:17