From 266cb5640d98556888c1f7a2ff884e6db8efdc8e Mon Sep 17 00:00:00 2001 From: Alex Baker Date: Mon, 25 Sep 2017 14:40:18 -0500 Subject: [PATCH] Show checkmark on calendar and gtask list picker --- .../astrid/gtasks/GtasksPreferences.java | 25 +++++----- .../NativeGoogleTaskListPicker.java | 23 +++++++++- .../SupportGoogleTaskListPicker.java | 37 +++++++++++++-- .../org/tasks/ui/GoogleTaskListFragment.java | 3 +- .../astrid/core/DefaultsPreferences.java | 29 ++++++------ .../activities/CalendarSelectionActivity.java | 5 +- .../activities/CalendarSelectionDialog.java | 40 ++++++++-------- .../org/tasks/calendars/AndroidCalendar.java | 2 - .../java/org/tasks/ui/CalendarControlSet.java | 4 +- .../tasks/ui/SingleCheckedArrayAdapter.java | 46 +++++++++++++++++++ .../simple_list_item_single_choice_themed.xml | 10 ++-- 11 files changed, 163 insertions(+), 61 deletions(-) create mode 100644 app/src/main/java/org/tasks/ui/SingleCheckedArrayAdapter.java diff --git a/app/src/googleplay/java/com/todoroo/astrid/gtasks/GtasksPreferences.java b/app/src/googleplay/java/com/todoroo/astrid/gtasks/GtasksPreferences.java index a2fdab044..ac45c9389 100644 --- a/app/src/googleplay/java/com/todoroo/astrid/gtasks/GtasksPreferences.java +++ b/app/src/googleplay/java/com/todoroo/astrid/gtasks/GtasksPreferences.java @@ -8,6 +8,7 @@ package com.todoroo.astrid.gtasks; import android.content.Intent; import android.os.Bundle; import android.preference.CheckBoxPreference; +import android.preference.Preference; import android.support.annotation.NonNull; import com.todoroo.andlib.utility.DateUtilities; @@ -16,7 +17,6 @@ import com.todoroo.astrid.data.Metadata; import com.todoroo.astrid.gtasks.auth.GtasksLoginActivity; import org.tasks.R; -import org.tasks.activities.NativeGoogleTaskListPicker; import org.tasks.analytics.Tracker; import org.tasks.analytics.Tracking; import org.tasks.dialogs.DialogBuilder; @@ -31,6 +31,7 @@ import org.tasks.preferences.PermissionRequestor; import javax.inject.Inject; import static org.tasks.PermissionUtil.verifyPermissions; +import static org.tasks.activities.NativeGoogleTaskListPicker.newNativeGoogleTaskListPicker; public class GtasksPreferences extends InjectingPreferenceActivity implements GoogleTaskListSelectionHandler { @@ -93,12 +94,20 @@ public class GtasksPreferences extends InjectingPreferenceActivity implements Go .show(); return true; }); - findPreference(R.string.p_gtasks_default_list).setOnPreferenceClickListener(preference -> { - new NativeGoogleTaskListPicker() + Preference defaultListPreference = findPreference(R.string.p_gtasks_default_list); + defaultListPreference.setOnPreferenceClickListener(preference -> { + newNativeGoogleTaskListPicker(getDefaultList()) .show(getFragmentManager(), FRAG_TAG_GOOGLE_TASK_LIST_SELECTION); return false; }); - updateDefaultGoogleTaskList(); + GtasksList defaultList = getDefaultList(); + if (defaultList != null) { + defaultListPreference.setSummary(defaultList.getName()); + } + } + + private GtasksList getDefaultList() { + return gtasksListService.getList(gtasksPreferenceService.getDefaultList()); } private void requestLogin() { @@ -153,13 +162,7 @@ public class GtasksPreferences extends InjectingPreferenceActivity implements Go tracker.reportEvent(Tracking.Events.GTASK_DEFAULT_LIST); String listId = list.getRemoteId(); gtasksPreferenceService.setDefaultList(listId); - updateDefaultGoogleTaskList(); + findPreference(R.string.p_gtasks_default_list).setSummary(list.getName()); } - private void updateDefaultGoogleTaskList() { - GtasksList list = gtasksListService.getList(gtasksPreferenceService.getDefaultList()); - if (list != null) { - findPreference(R.string.p_gtasks_default_list).setSummary(list.getName()); - } - } } diff --git a/app/src/googleplay/java/org/tasks/activities/NativeGoogleTaskListPicker.java b/app/src/googleplay/java/org/tasks/activities/NativeGoogleTaskListPicker.java index 7bd162bde..ba22c1f4e 100644 --- a/app/src/googleplay/java/org/tasks/activities/NativeGoogleTaskListPicker.java +++ b/app/src/googleplay/java/org/tasks/activities/NativeGoogleTaskListPicker.java @@ -4,6 +4,8 @@ import android.app.Activity; import android.app.Dialog; import android.os.Bundle; +import com.todoroo.astrid.data.StoreObject; +import com.todoroo.astrid.gtasks.GtasksList; import com.todoroo.astrid.gtasks.GtasksListService; import org.tasks.dialogs.DialogBuilder; @@ -18,6 +20,18 @@ import static org.tasks.activities.SupportGoogleTaskListPicker.createDialog; public class NativeGoogleTaskListPicker extends InjectingNativeDialogFragment { + public static NativeGoogleTaskListPicker newNativeGoogleTaskListPicker(GtasksList defaultList) { + NativeGoogleTaskListPicker dialog = new NativeGoogleTaskListPicker(); + Bundle arguments = new Bundle(); + if (defaultList != null) { + arguments.putParcelable(EXTRA_SELECTED, defaultList.getStoreObject()); + } + dialog.setArguments(arguments); + return dialog; + } + + public static final String EXTRA_SELECTED = "extra_selected"; + @Inject DialogBuilder dialogBuilder; @Inject GtasksListService gtasksListService; @Inject ThemeCache themeCache; @@ -26,7 +40,14 @@ public class NativeGoogleTaskListPicker extends InjectingNativeDialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { - return createDialog(getActivity(), themeCache, dialogBuilder, gtasksListService, list -> handler.selectedList(list)); + Bundle arguments = getArguments(); + StoreObject storeObject = arguments.getParcelable(EXTRA_SELECTED); + GtasksList selected = null; + if (storeObject != null) { + selected = new GtasksList(storeObject); + } + return createDialog(getActivity(), themeCache, dialogBuilder, gtasksListService, + selected, list -> handler.selectedList(list)); } @Override diff --git a/app/src/googleplay/java/org/tasks/activities/SupportGoogleTaskListPicker.java b/app/src/googleplay/java/org/tasks/activities/SupportGoogleTaskListPicker.java index 4b99f5158..b188d7a26 100644 --- a/app/src/googleplay/java/org/tasks/activities/SupportGoogleTaskListPicker.java +++ b/app/src/googleplay/java/org/tasks/activities/SupportGoogleTaskListPicker.java @@ -13,8 +13,9 @@ import android.support.v7.app.AlertDialog; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; -import android.widget.TextView; +import android.widget.CheckedTextView; +import com.todoroo.astrid.data.StoreObject; import com.todoroo.astrid.gtasks.GtasksList; import com.todoroo.astrid.gtasks.GtasksListService; @@ -34,6 +35,18 @@ import static com.todoroo.andlib.utility.AndroidUtilities.atLeastJellybeanMR1; public class SupportGoogleTaskListPicker extends InjectingDialogFragment { + public static SupportGoogleTaskListPicker newSupportGoogleTaskListPicker(GtasksList selected) { + SupportGoogleTaskListPicker dialog = new SupportGoogleTaskListPicker(); + Bundle arguments = new Bundle(); + if (selected != null) { + arguments.putParcelable(EXTRA_SELECTED, selected.getStoreObject()); + } + dialog.setArguments(arguments); + return dialog; + } + + private static final String EXTRA_SELECTED = "extra_selected"; + @Inject DialogBuilder dialogBuilder; @Inject GtasksListService gtasksListService; @Inject ThemeCache themeCache; @@ -43,7 +56,14 @@ public class SupportGoogleTaskListPicker extends InjectingDialogFragment { @NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { - return createDialog(getActivity(), themeCache, dialogBuilder, gtasksListService, list -> handler.selectedList(list)); + Bundle arguments = getArguments(); + StoreObject storeObject = arguments.getParcelable(EXTRA_SELECTED); + GtasksList selected = null; + if (storeObject != null) { + selected = new GtasksList(storeObject); + } + return createDialog(getActivity(), themeCache, dialogBuilder, gtasksListService, + selected, list -> handler.selectedList(list)); } @Override @@ -53,15 +73,24 @@ public class SupportGoogleTaskListPicker extends InjectingDialogFragment { handler = (GoogleTaskListSelectionHandler) activity; } - public static AlertDialog createDialog(Context context, ThemeCache themeCache, DialogBuilder dialogBuilder, GtasksListService gtasksListService, final GoogleTaskListSelectionHandler handler) { + public static AlertDialog createDialog(Context context, ThemeCache themeCache, + DialogBuilder dialogBuilder, GtasksListService gtasksListService, + GtasksList selected, final GoogleTaskListSelectionHandler handler) { final List lists = gtasksListService.getLists(); ArrayAdapter adapter = new ArrayAdapter(context, R.layout.simple_list_item_single_choice_themed, lists) { @SuppressLint("NewApi") @NonNull @Override public View getView(int position, View convertView, ViewGroup parent) { - TextView view = (TextView) super.getView(position, convertView, parent); + CheckedTextView view = (CheckedTextView) super.getView(position, convertView, parent); GtasksList list = lists.get(position); + if (selected != null && list.getRemoteId().equals(selected.getRemoteId())) { + view.setCheckMarkDrawable(R.drawable.ic_check_white_24dp); + view.setChecked(true); + } else { + view.setCheckMarkDrawable(null); + view.setChecked(false); + } int color = list.getColor(); ThemeColor themeColor = themeCache.getThemeColor(color >= 0 ? color : 19); view.setText(list.getName()); diff --git a/app/src/googleplay/java/org/tasks/ui/GoogleTaskListFragment.java b/app/src/googleplay/java/org/tasks/ui/GoogleTaskListFragment.java index c065772ae..2aca815c6 100644 --- a/app/src/googleplay/java/org/tasks/ui/GoogleTaskListFragment.java +++ b/app/src/googleplay/java/org/tasks/ui/GoogleTaskListFragment.java @@ -29,6 +29,7 @@ import butterknife.BindView; import butterknife.OnClick; import static com.todoroo.andlib.utility.DateUtilities.now; +import static org.tasks.activities.SupportGoogleTaskListPicker.newSupportGoogleTaskListPicker; public class GoogleTaskListFragment extends TaskEditControlFragment { @@ -110,7 +111,7 @@ public class GoogleTaskListFragment extends TaskEditControlFragment { @OnClick(R.id.google_task_list) void clickGoogleTaskList(View view) { - new SupportGoogleTaskListPicker() + newSupportGoogleTaskListPicker(selectedList) .show(getChildFragmentManager(), FRAG_TAG_GOOGLE_TASK_LIST_SELECTION); } diff --git a/app/src/main/java/com/todoroo/astrid/core/DefaultsPreferences.java b/app/src/main/java/com/todoroo/astrid/core/DefaultsPreferences.java index 10f40ce72..05f271340 100644 --- a/app/src/main/java/com/todoroo/astrid/core/DefaultsPreferences.java +++ b/app/src/main/java/com/todoroo/astrid/core/DefaultsPreferences.java @@ -24,12 +24,6 @@ import javax.inject.Inject; import static org.tasks.PermissionUtil.verifyPermissions; -/** - * Displays the preference screen for users to edit their preferences - * - * @author Tim Su - * - */ public class DefaultsPreferences extends InjectingPreferenceActivity { private static final int REQUEST_CALENDAR_SELECTION = 10412; @@ -52,22 +46,24 @@ public class DefaultsPreferences extends InjectingPreferenceActivity { } return false; }); - setCalendarSummary(preferences.getStringValue(R.string.gcal_p_default)); - } - - private void setCalendarSummary(String calendarId) { - AndroidCalendar calendar = calendarProvider.getCalendar(calendarId); - defaultCalendarPref.setSummary(calendar == null + String defaultCalendarName = getDefaultCalendarName(); + defaultCalendarPref.setSummary(defaultCalendarName == null ? getString(R.string.none) - : calendar.getName()); + : defaultCalendarName); } private void startCalendarSelectionActivity() { Intent intent = new Intent(DefaultsPreferences.this, CalendarSelectionActivity.class); intent.putExtra(CalendarSelectionActivity.EXTRA_SHOW_NONE, true); + intent.putExtra(CalendarSelectionActivity.EXTRA_CALENDAR_NAME, getDefaultCalendarName()); startActivityForResult(intent, REQUEST_CALENDAR_SELECTION); } + private String getDefaultCalendarName() { + AndroidCalendar calendar = calendarProvider.getCalendar(preferences.getStringValue(R.string.gcal_p_default)); + return calendar == null ? null : calendar.getName(); + } + @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (requestCode == PermissionRequestor.REQUEST_CALENDAR) { @@ -82,9 +78,10 @@ public class DefaultsPreferences extends InjectingPreferenceActivity { @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_CALENDAR_SELECTION && resultCode == RESULT_OK) { - String calendarId = data.getStringExtra(CalendarSelectionActivity.EXTRA_CALENDAR_ID); - preferences.setString(R.string.gcal_p_default, calendarId); - setCalendarSummary(calendarId); + preferences.setString(R.string.gcal_p_default, + data.getStringExtra(CalendarSelectionActivity.EXTRA_CALENDAR_ID)); + defaultCalendarPref.setSummary( + data.getStringExtra(CalendarSelectionActivity.EXTRA_CALENDAR_NAME)); } else { super.onActivityResult(requestCode, resultCode, data); } diff --git a/app/src/main/java/org/tasks/activities/CalendarSelectionActivity.java b/app/src/main/java/org/tasks/activities/CalendarSelectionActivity.java index 08ce3e767..03da5bfdb 100644 --- a/app/src/main/java/org/tasks/activities/CalendarSelectionActivity.java +++ b/app/src/main/java/org/tasks/activities/CalendarSelectionActivity.java @@ -24,7 +24,10 @@ public class CalendarSelectionActivity extends InjectingAppCompatActivity implem FragmentManager fragmentManager = getSupportFragmentManager(); CalendarSelectionDialog fragmentByTag = (CalendarSelectionDialog) fragmentManager.findFragmentByTag(FRAG_TAG_CALENDAR_PREFERENCE_SELECTION); if (fragmentByTag == null) { - fragmentByTag = newCalendarSelectionDialog(getIntent().getBooleanExtra(EXTRA_SHOW_NONE, false)); + Intent intent = getIntent(); + fragmentByTag = newCalendarSelectionDialog( + intent.getBooleanExtra(EXTRA_SHOW_NONE, false), + intent.getStringExtra(EXTRA_CALENDAR_NAME)); fragmentByTag.show(fragmentManager, FRAG_TAG_CALENDAR_PREFERENCE_SELECTION); } fragmentByTag.setCalendarSelectionHandler(this); diff --git a/app/src/main/java/org/tasks/activities/CalendarSelectionDialog.java b/app/src/main/java/org/tasks/activities/CalendarSelectionDialog.java index f622d795e..0671881b3 100644 --- a/app/src/main/java/org/tasks/activities/CalendarSelectionDialog.java +++ b/app/src/main/java/org/tasks/activities/CalendarSelectionDialog.java @@ -4,7 +4,6 @@ import android.app.Dialog; import android.content.DialogInterface; import android.os.Bundle; import android.support.annotation.NonNull; -import android.widget.ArrayAdapter; import android.widget.Toast; import org.tasks.R; @@ -18,6 +17,7 @@ import org.tasks.preferences.FragmentPermissionRequestor; import org.tasks.preferences.PermissionChecker; import org.tasks.preferences.PermissionRequestor; import org.tasks.themes.Theme; +import org.tasks.ui.SingleCheckedArrayAdapter; import java.util.ArrayList; import java.util.List; @@ -29,9 +29,12 @@ import static org.tasks.PermissionUtil.verifyPermissions; public class CalendarSelectionDialog extends InjectingDialogFragment { - public static CalendarSelectionDialog newCalendarSelectionDialog(boolean enableNone) { + public static CalendarSelectionDialog newCalendarSelectionDialog(boolean enableNone, String selected) { CalendarSelectionDialog dialog = new CalendarSelectionDialog(); - dialog.enableNone = enableNone; + Bundle arguments = new Bundle(); + arguments.putBoolean(EXTRA_NONE_ENABLED, enableNone); + arguments.putString(EXTRA_SELECTED, selected); + dialog.setArguments(arguments); return dialog; } @@ -41,6 +44,7 @@ public class CalendarSelectionDialog extends InjectingDialogFragment { void cancel(); } + private static final String EXTRA_SELECTED = "extra_selected"; private static final String EXTRA_NONE_ENABLED = "extra_none_enabled"; @Inject DialogBuilder dialogBuilder; @@ -48,29 +52,29 @@ public class CalendarSelectionDialog extends InjectingDialogFragment { @Inject FragmentPermissionRequestor fragmentPermissionRequestor; @Inject PermissionChecker permissionChecker; @Inject Theme theme; + private CalendarSelectionHandler handler; - private boolean enableNone; - private ArrayAdapter adapter; + private String selected; + private SingleCheckedArrayAdapter adapter; private final List calendars = new ArrayList<>(); private final List calendarNames = new ArrayList<>(); @NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { - if (savedInstanceState == null) { - fragmentPermissionRequestor.requestCalendarPermissions(); - } else { - enableNone = savedInstanceState.getBoolean(EXTRA_NONE_ENABLED); - } + fragmentPermissionRequestor.requestCalendarPermissions(); + + Bundle arguments = getArguments(); + selected = arguments.getString(EXTRA_SELECTED); theme.applyToContext(getActivity()); - adapter = new ArrayAdapter<>(getActivity(), R.layout.simple_list_item_single_choice_themed, calendarNames); + adapter = new SingleCheckedArrayAdapter(getActivity(), calendarNames); AlertDialogBuilder builder = dialogBuilder.newDialog() - .setAdapter(adapter, (dialog, which) -> handler.selectedCalendar(calendars.get(which))) + .setSingleChoiceItems(adapter, -1, (dialog, which) -> handler.selectedCalendar(calendars.get(which))) .setNegativeButton(android.R.string.cancel, (dialogInterface, i) -> handler.cancel()); - if (enableNone) { - builder.setNeutralButton(R.string.none, (dialog, which) -> handler.selectedCalendar(AndroidCalendar.NONE)); + if (arguments.getBoolean(EXTRA_NONE_ENABLED)) { + builder.setNeutralButton(R.string.none, (dialog, which) -> handler.selectedCalendar(new AndroidCalendar("-1", getString(R.string.none)))); } return builder.show(); @@ -89,18 +93,12 @@ public class CalendarSelectionDialog extends InjectingDialogFragment { Toast.makeText(getActivity(), R.string.no_calendars_found, Toast.LENGTH_LONG).show(); handler.cancel(); } else { + adapter.setChecked(selected); adapter.notifyDataSetChanged(); } } } - @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - - outState.putBoolean(EXTRA_NONE_ENABLED, enableNone); - } - @Override public void onCancel(DialogInterface dialog) { super.onCancel(dialog); diff --git a/app/src/main/java/org/tasks/calendars/AndroidCalendar.java b/app/src/main/java/org/tasks/calendars/AndroidCalendar.java index 11a5fc48c..53c032ac5 100644 --- a/app/src/main/java/org/tasks/calendars/AndroidCalendar.java +++ b/app/src/main/java/org/tasks/calendars/AndroidCalendar.java @@ -4,8 +4,6 @@ public class AndroidCalendar { private final String id; private final String name; - public static final AndroidCalendar NONE = new AndroidCalendar("-1", "NONE"); - public AndroidCalendar(String id, String name) { this.id = id; this.name = name; diff --git a/app/src/main/java/org/tasks/ui/CalendarControlSet.java b/app/src/main/java/org/tasks/ui/CalendarControlSet.java index 498c18fd7..1befe0f2c 100644 --- a/app/src/main/java/org/tasks/ui/CalendarControlSet.java +++ b/app/src/main/java/org/tasks/ui/CalendarControlSet.java @@ -240,7 +240,9 @@ public class CalendarControlSet extends TaskEditControlFragment { @OnClick(R.id.calendar_display_which) void clickCalendar(View view) { if (Strings.isNullOrEmpty(eventUri)) { - startActivityForResult(new Intent(context, CalendarSelectionActivity.class), REQUEST_CODE_PICK_CALENDAR); + Intent intent = new Intent(context, CalendarSelectionActivity.class); + intent.putExtra(CalendarSelectionActivity.EXTRA_CALENDAR_NAME, calendarName); + startActivityForResult(intent, REQUEST_CODE_PICK_CALENDAR); } else { if (permissionRequestor.requestCalendarPermissions(REQUEST_CODE_OPEN_EVENT)) { openCalendarEvent(); diff --git a/app/src/main/java/org/tasks/ui/SingleCheckedArrayAdapter.java b/app/src/main/java/org/tasks/ui/SingleCheckedArrayAdapter.java new file mode 100644 index 000000000..47490af38 --- /dev/null +++ b/app/src/main/java/org/tasks/ui/SingleCheckedArrayAdapter.java @@ -0,0 +1,46 @@ +package org.tasks.ui; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.CheckedTextView; + +import org.tasks.R; + +import java.util.List; + +public class SingleCheckedArrayAdapter extends ArrayAdapter { + + private final List items; + private int checkedPosition = -1; + + public SingleCheckedArrayAdapter(@NonNull Context context, @NonNull List items) { + super(context, R.layout.simple_list_item_single_choice_themed, items); + this.items = items; + } + + @NonNull + @Override + public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { + CheckedTextView view = (CheckedTextView) super.getView(position, convertView, parent); + if (this.checkedPosition == position) { + view.setCheckMarkDrawable(R.drawable.ic_check_white_24dp); + view.setChecked(true); + } else { + view.setCheckMarkDrawable(null); + view.setChecked(false); + } + return view; + } + + public void setChecked(T item) { + setChecked(items.indexOf(item)); + } + + public void setChecked(int position) { + this.checkedPosition = position; + } +} diff --git a/app/src/main/res/layout/simple_list_item_single_choice_themed.xml b/app/src/main/res/layout/simple_list_item_single_choice_themed.xml index 7930e9302..2f847e17c 100644 --- a/app/src/main/res/layout/simple_list_item_single_choice_themed.xml +++ b/app/src/main/res/layout/simple_list_item_single_choice_themed.xml @@ -13,14 +13,18 @@ limitations under the License. --> - + android:textColor="?attr/asTextColor" />