android: Fix profile selection/edit when the device is rotated
authorTobias Brunner <tobias@strongswan.org>
Fri, 6 Jul 2018 13:54:45 +0000 (15:54 +0200)
committerTobias Brunner <tobias@strongswan.org>
Wed, 17 Oct 2018 09:56:30 +0000 (11:56 +0200)
The previous code lost track of the selected profile IDs, but the
widgets maintained their state (i.e. the list item was still selected and the
edit button still enabled).  Clicking the edit button then caused a crash when
trying to get the first item in the set.

src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileListFragment.java

index 2ec9d0a..4a3ed9f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Tobias Brunner
+ * Copyright (C) 2012-2018 Tobias Brunner
  * Copyright (C) 2012 Giuliano Grassi
  * Copyright (C) 2012 Ralf Sager
  * HSR Hochschule fuer Technik Rapperswil
@@ -52,6 +52,7 @@ import java.util.List;
 
 public class VpnProfileListFragment extends Fragment
 {
+       private static final String SELECTED_KEY = "SELECTED";
        private static final int ADD_REQUEST = 1;
        private static final int EDIT_REQUEST = 2;
 
@@ -60,6 +61,7 @@ public class VpnProfileListFragment extends Fragment
        private VpnProfileAdapter mListAdapter;
        private ListView mListView;
        private OnVpnProfileSelectedListener mListener;
+       private HashSet<Integer> mSelected;
        private boolean mReadOnly;
 
        private BroadcastReceiver mProfilesChanged = new BroadcastReceiver()
@@ -120,7 +122,7 @@ public class VpnProfileListFragment extends Fragment
        {
                View view = inflater.inflate(R.layout.profile_list_fragment, null);
 
-               mListView = (ListView)view.findViewById(R.id.profile_list);
+               mListView = view.findViewById(R.id.profile_list);
                mListView.setAdapter(mListAdapter);
                mListView.setEmptyView(view.findViewById(R.id.profile_list_empty));
                mListView.setOnItemClickListener(mVpnProfileClicked);
@@ -147,6 +149,13 @@ public class VpnProfileListFragment extends Fragment
                if (!mReadOnly)
                {
                        setHasOptionsMenu(true);
+
+                       ArrayList<Integer> selected = null;
+                       if (savedInstanceState != null)
+                       {
+                               selected = savedInstanceState.getIntegerArrayList(SELECTED_KEY);
+                       }
+                       mSelected = selected != null ? new HashSet<>(selected) : new HashSet<>();
                }
 
                mDataSource = new VpnProfileDataSource(this.getActivity());
@@ -162,6 +171,13 @@ public class VpnProfileListFragment extends Fragment
        }
 
        @Override
+       public void onSaveInstanceState(Bundle outState)
+       {
+               super.onSaveInstanceState(outState);
+               outState.putIntegerArrayList(SELECTED_KEY, new ArrayList<>(mSelected));
+       }
+
+       @Override
        public void onDestroy()
        {
                super.onDestroy();
@@ -213,18 +229,19 @@ public class VpnProfileListFragment extends Fragment
        };
 
        private final MultiChoiceModeListener mVpnProfileSelected = new MultiChoiceModeListener() {
-               private HashSet<Integer> mSelected;
                private MenuItem mEditProfile;
 
                @Override
                public boolean onPrepareActionMode(ActionMode mode, Menu menu)
                {
-                       return false;
+                       mEditProfile.setEnabled(mSelected.size() == 1);
+                       return true;
                }
 
                @Override
                public void onDestroyActionMode(ActionMode mode)
                {
+                       mSelected.clear();
                }
 
                @Override
@@ -233,7 +250,6 @@ public class VpnProfileListFragment extends Fragment
                        MenuInflater inflater = mode.getMenuInflater();
                        inflater.inflate(R.menu.profile_list_context, menu);
                        mEditProfile = menu.findItem(R.id.edit_profile);
-                       mSelected = new HashSet<>();
                        mode.setTitle(R.string.select_profiles);
                        return true;
                }
@@ -293,7 +309,6 @@ public class VpnProfileListFragment extends Fragment
                                mSelected.remove(position);
                        }
                        final int checkedCount = mSelected.size();
-                       mEditProfile.setEnabled(checkedCount == 1);
                        switch (checkedCount)
                        {
                                case 0:
@@ -306,6 +321,7 @@ public class VpnProfileListFragment extends Fragment
                                        mode.setSubtitle(String.format(getString(R.string.x_profiles_selected), checkedCount));
                                        break;
                        }
+                       mode.invalidate();
                }
        };
 }