diff options
-rw-r--r-- | res/drawable/ic_delete.xml | 9 | ||||
-rw-r--r-- | res/drawable/ic_save.xml | 9 | ||||
-rw-r--r-- | res/drawable/list_item_background.xml | 5 | ||||
-rw-r--r-- | res/menu/menu_action_mode.xml | 14 | ||||
-rw-r--r-- | res/values/colors.xml | 2 | ||||
-rw-r--r-- | res/values/styles.xml | 6 | ||||
-rw-r--r-- | src/org/lineageos/updater/UpdatesListAdapter.java | 142 |
7 files changed, 60 insertions, 127 deletions
diff --git a/res/drawable/ic_delete.xml b/res/drawable/ic_delete.xml deleted file mode 100644 index f9213d2..0000000 --- a/res/drawable/ic_delete.xml +++ /dev/null @@ -1,9 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z"/> -</vector> diff --git a/res/drawable/ic_save.xml b/res/drawable/ic_save.xml deleted file mode 100644 index a7a81a2..0000000 --- a/res/drawable/ic_save.xml +++ /dev/null @@ -1,9 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M17,3L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,7l-4,-4zM12,19c-1.66,0 -3,-1.34 -3,-3s1.34,-3 3,-3 3,1.34 3,3 -1.34,3 -3,3zM15,9L5,9L5,5h10v4z"/> -</vector> diff --git a/res/drawable/list_item_background.xml b/res/drawable/list_item_background.xml deleted file mode 100644 index c38cac5..0000000 --- a/res/drawable/list_item_background.xml +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<selector xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:drawable="@color/background_selected" android:state_selected="true" /> - <item android:drawable="@color/cardview_light_background" android:state_selected="false" /> -</selector> diff --git a/res/menu/menu_action_mode.xml b/res/menu/menu_action_mode.xml index 6b355e6..4af7660 100644 --- a/res/menu/menu_action_mode.xml +++ b/res/menu/menu_action_mode.xml @@ -3,19 +3,11 @@ xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/menu_export_update" - android:icon="@drawable/ic_save" - android:title="@string/menu_export_update" - android:visible="false" - app:showAsAction="ifRoom" /> + android:title="@string/menu_export_update" /> <item android:id="@+id/menu_delete_action" - android:icon="@drawable/ic_delete" - android:title="@string/menu_delete_update" - android:visible="false" - app:showAsAction="ifRoom" /> + android:title="@string/menu_delete_update" /> <item android:id="@+id/menu_copy_url" - android:title="@string/menu_copy_url" - android:visible="false" - app:showAsAction="never" /> + android:title="@string/menu_copy_url" /> </menu> diff --git a/res/values/colors.xml b/res/values/colors.xml index 4df19c4..fd4ad0f 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -4,8 +4,6 @@ <color name="theme_primary_dark">#ff000000</color> <color name="theme_accent">#ff009688</color> - <color name="background_selected">#ffdddddd</color> - <color name="white">#f5f5f5</color> <color name="ic_background">#333333</color> </resources> diff --git a/res/values/styles.xml b/res/values/styles.xml index c48409f..fbf812b 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -22,4 +22,10 @@ <style name="TextAppearanceTransparent" parent="TextAppearance.AppCompat.Widget.ActionBar.Title"> <item name="android:textColor">@android:color/transparent</item> </style> + + <style name="AppTheme.PopupMenuOverlapAnchor"> + <item name="android:overlapAnchor">true</item> + <item name="android:dropDownVerticalOffset">8dp</item> + <item name="android:dropDownHorizontalOffset">-16dp</item> + </style> </resources> diff --git a/src/org/lineageos/updater/UpdatesListAdapter.java b/src/org/lineageos/updater/UpdatesListAdapter.java index 15768ff..db4985b 100644 --- a/src/org/lineageos/updater/UpdatesListAdapter.java +++ b/src/org/lineageos/updater/UpdatesListAdapter.java @@ -20,7 +20,10 @@ import android.content.SharedPreferences; import android.preference.PreferenceManager; import android.support.design.widget.Snackbar; import android.support.v7.app.AlertDialog; -import android.support.v7.view.ActionMode; +import android.support.v7.view.ContextThemeWrapper; +import android.support.v7.view.menu.MenuBuilder; +import android.support.v7.view.menu.MenuPopupHelper; +import android.support.v7.widget.PopupMenu; import android.support.v7.widget.RecyclerView; import android.text.SpannableString; import android.text.format.Formatter; @@ -28,10 +31,8 @@ import android.text.method.LinkMovementMethod; import android.text.util.Linkify; import android.util.Log; import android.util.TypedValue; +import android.view.Gravity; import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.CheckBox; @@ -65,7 +66,6 @@ public class UpdatesListAdapter extends RecyclerView.Adapter<UpdatesListAdapter. private String mSelectedDownload; private Controller mUpdaterController; private UpdatesListActivity mActivity; - private ActionMode mActionMode; private enum Action { DOWNLOAD, @@ -118,7 +118,6 @@ public class UpdatesListAdapter extends RecyclerView.Adapter<UpdatesListAdapter. public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { View view = LayoutInflater.from(viewGroup.getContext()) .inflate(R.layout.update_item_view, viewGroup, false); - view.setBackground(mActivity.getDrawable(R.drawable.list_item_background)); return new ViewHolder(view); } @@ -185,7 +184,8 @@ public class UpdatesListAdapter extends RecyclerView.Adapter<UpdatesListAdapter. viewHolder.mProgressBar.setProgress(update.getProgress()); } - viewHolder.itemView.setOnLongClickListener(getLongClickListener(update, canDelete)); + viewHolder.itemView.setOnLongClickListener(getLongClickListener(update, canDelete, + viewHolder.mBuildDate)); } private void handleNotActiveStatus(ViewHolder viewHolder, UpdateInfo update) { @@ -197,15 +197,18 @@ public class UpdatesListAdapter extends RecyclerView.Adapter<UpdatesListAdapter. viewHolder.mBuildVersion.setText(buildVersion); if (update.getPersistentStatus() == UpdateStatus.Persistent.VERIFIED) { - viewHolder.itemView.setOnLongClickListener(getLongClickListener(update, true)); + viewHolder.itemView.setOnLongClickListener( + getLongClickListener(update, true, viewHolder.mBuildDate)); setButtonAction(viewHolder.mAction, Utils.canInstall(update) ? Action.INSTALL : Action.DELETE, update.getDownloadId(), !isBusy()); } else if (!Utils.canInstall(update)) { - viewHolder.itemView.setOnLongClickListener(getLongClickListener(update, false)); + viewHolder.itemView.setOnLongClickListener( + getLongClickListener(update, false, viewHolder.mBuildDate)); setButtonAction(viewHolder.mAction, Action.INFO, update.getDownloadId(), !isBusy()); } else { - viewHolder.itemView.setOnLongClickListener(getLongClickListener(update, false)); + viewHolder.itemView.setOnLongClickListener( + getLongClickListener(update, false, viewHolder.mBuildDate)); setButtonAction(viewHolder.mAction, Action.DOWNLOAD, update.getDownloadId(), !isBusy()); } } @@ -390,7 +393,6 @@ public class UpdatesListAdapter extends RecyclerView.Adapter<UpdatesListAdapter. button.setOnClickListener(v -> { if (clickListener != null) { clickListener.onClick(v); - stopActionMode(); } }); } @@ -413,11 +415,9 @@ public class UpdatesListAdapter extends RecyclerView.Adapter<UpdatesListAdapter. } private View.OnLongClickListener getLongClickListener(final UpdateInfo update, - final boolean canDelete) { + final boolean canDelete, View anchor) { return view -> { - if (mActionMode == null) { - startActionMode(update, canDelete); - } + startActionMode(update, canDelete, anchor); return true; }; } @@ -461,86 +461,47 @@ public class UpdatesListAdapter extends RecyclerView.Adapter<UpdatesListAdapter. .setNegativeButton(android.R.string.cancel, null); } - private void stopActionMode() { - if (mActionMode != null) { - mActionMode.finish(); - } - } - - private void startActionMode(final UpdateInfo update, final boolean canDelete) { - if (mActionMode != null) { - Log.d(TAG, "Action mode already enabled"); - return; - } - + private void startActionMode(final UpdateInfo update, final boolean canDelete, View anchor) { mSelectedDownload = update.getDownloadId(); notifyItemChanged(update.getDownloadId()); - // Hide Action Bar not to steal the focus when using a D-pad - final boolean showActionBar; - if (mActivity.getSupportActionBar() != null && - mActivity.getSupportActionBar().isShowing()) { - showActionBar = true; - mActivity.getSupportActionBar().hide(); - } else { - showActionBar = false; - } - - mActionMode = mActivity.startSupportActionMode(new ActionMode.Callback() { - @Override - public boolean onCreateActionMode(ActionMode mode, Menu menu) { - MenuInflater inflater = mode.getMenuInflater(); - inflater.inflate(R.menu.menu_action_mode, menu); - menu.findItem(R.id.menu_delete_action).setVisible(canDelete); - menu.findItem(R.id.menu_copy_url).setVisible(update.getAvailableOnline()); - menu.findItem(R.id.menu_export_update).setVisible( - update.getPersistentStatus() == UpdateStatus.Persistent.VERIFIED); - return true; - } - - @Override - public boolean onPrepareActionMode(ActionMode mode, Menu menu) { - return false; - } - - @Override - public boolean onActionItemClicked(ActionMode mode, MenuItem item) { - switch (item.getItemId()) { - case R.id.menu_delete_action: - getDeleteDialog(update.getDownloadId()) - .setOnDismissListener(dialog -> mode.finish()) - .show(); - return true; - case R.id.menu_copy_url: - Utils.addToClipboard(mActivity, - mActivity.getString(R.string.label_download_url), - update.getDownloadUrl(), - mActivity.getString(R.string.toast_download_url_copied)); - mode.finish(); - return true; - case R.id.menu_export_update: - // TODO: start exporting once the permission has been granted - boolean hasPermission = PermissionsUtils.checkAndRequestStoragePermission( - mActivity, 0); - if (hasPermission) { - exportUpdate(update); - } - return true; - } - return false; - } - - @Override - public void onDestroyActionMode(ActionMode mode) { - mSelectedDownload = null; - mActionMode = null; - notifyItemChanged(update.getDownloadId()); - - if (showActionBar) { - mActivity.getSupportActionBar().show(); - } + ContextThemeWrapper wrapper = new ContextThemeWrapper(mActivity, + R.style.AppTheme_PopupMenuOverlapAnchor); + PopupMenu popupMenu = new PopupMenu(wrapper, anchor, Gravity.NO_GRAVITY, + R.attr.actionOverflowMenuStyle, 0); + popupMenu.inflate(R.menu.menu_action_mode); + + MenuBuilder menu = (MenuBuilder) popupMenu.getMenu(); + menu.findItem(R.id.menu_delete_action).setVisible(canDelete); + menu.findItem(R.id.menu_copy_url).setVisible(update.getAvailableOnline()); + menu.findItem(R.id.menu_export_update).setVisible( + update.getPersistentStatus() == UpdateStatus.Persistent.VERIFIED); + + popupMenu.setOnMenuItemClickListener(item -> { + switch (item.getItemId()) { + case R.id.menu_delete_action: + getDeleteDialog(update.getDownloadId()).show(); + return true; + case R.id.menu_copy_url: + Utils.addToClipboard(mActivity, + mActivity.getString(R.string.label_download_url), + update.getDownloadUrl(), + mActivity.getString(R.string.toast_download_url_copied)); + return true; + case R.id.menu_export_update: + // TODO: start exporting once the permission has been granted + boolean hasPermission = PermissionsUtils.checkAndRequestStoragePermission( + mActivity, 0); + if (hasPermission) { + exportUpdate(update); + } + return true; } + return false; }); + + MenuPopupHelper helper = new MenuPopupHelper(wrapper, menu, anchor); + helper.show(); } private void exportUpdate(UpdateInfo update) { @@ -553,7 +514,6 @@ public class UpdatesListAdapter extends RecyclerView.Adapter<UpdatesListAdapter. intent.putExtra(ExportUpdateService.EXTRA_SOURCE_FILE, update.getFile()); intent.putExtra(ExportUpdateService.EXTRA_DEST_FILE, dest); mActivity.startService(intent); - stopActionMode(); } private void showInfoDialog() { |