From 32c17e5f72d000799e2a86da83b78971aa9372d3 Mon Sep 17 00:00:00 2001 From: Peter Serwylo Date: Wed, 27 Sep 2017 22:53:00 +1000 Subject: [PATCH] Initial framework to allow for dismissing apps in updates tab. --- .../views/apps/AppListItemController.java | 36 ++++++++++ .../fdroid/views/updates/UpdatesAdapter.java | 2 + .../updates/UpdatesItemTouchCallback.java | 70 +++++++++++++++++++ .../views/updates/UpdatesViewBinder.java | 4 ++ 4 files changed, 112 insertions(+) create mode 100644 app/src/main/java/org/fdroid/fdroid/views/updates/UpdatesItemTouchCallback.java diff --git a/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemController.java b/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemController.java index e2bdf0dca..aa5d568e1 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemController.java +++ b/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemController.java @@ -26,6 +26,7 @@ import android.widget.ImageButton; import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.TextView; +import android.widget.Toast; import com.nostra13.universalimageloader.core.DisplayImageOptions; import com.nostra13.universalimageloader.core.ImageLoader; @@ -160,6 +161,11 @@ public abstract class AppListItemController extends RecyclerView.ViewHolder { itemView.setOnClickListener(onAppClicked); } + @Nullable + protected final AppUpdateStatus getCurrentStatus() { + return currentStatus; + } + public void bindModel(@NonNull App app) { currentApp = app; @@ -187,6 +193,36 @@ public abstract class AppListItemController extends RecyclerView.ViewHolder { broadcastManager.registerReceiver(onStatusChanged, intentFilter); } + /** To be overridden if required */ + public boolean canDismiss() { + return false; + } + + /** + * If able, forwards the request onto {@link #onDismissApp(App)}. + * This mainly exists to keep the API consistent, in that the {@link App} is threaded through to the relevant + * method with a guarantee that it is not null, rather than every method having to check if it is null or not. + */ + public final void onDismiss() { + if (currentApp != null && canDismiss()) { + CharSequence message = onDismissApp(currentApp); + if (message != null) { + Toast.makeText(activity, message, Toast.LENGTH_SHORT).show(); + } + } + } + + /** + * Override to respond to the user swiping an app to dismiss it from the list. + * @return Optionally return a description of what you did if it is not obvious to the user. It will be shown as + * a {@link android.widget.Toast} for a {@link android.widget.Toast#LENGTH_SHORT} time. + * @see #canDismiss() This must also be overriden and should return true. + */ + @Nullable + protected CharSequence onDismissApp(@NonNull App app) { + return null; + } + /** * Updates both the progress bar and the circular install button (which shows progress around the outside of * the circle). Also updates the app label to indicate that the app is being downloaded. diff --git a/app/src/main/java/org/fdroid/fdroid/views/updates/UpdatesAdapter.java b/app/src/main/java/org/fdroid/fdroid/views/updates/UpdatesAdapter.java index a993910a6..03ee0bd28 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/updates/UpdatesAdapter.java +++ b/app/src/main/java/org/fdroid/fdroid/views/updates/UpdatesAdapter.java @@ -341,4 +341,6 @@ public class UpdatesAdapter extends RecyclerView.Adapter + *
  • + * {@link KnownVulnAppListItemController}: Will be marked as "Ignored" and wont warn the user in the future. + *
  • + *
  • + * {@link UpdateableAppListItemController}: Will get marked as "Ignore this update". + *
  • + *
  • + * {@link AppStatusListItemController}: + *
      + *
    • If downloading or queued to download, cancel the download.
    • + *
    • If downloaded waiting to install, forget that we downloaded it.
    • + *
    • If installed ready to run, stop prompting the user to run the app.
    • + *
    + *
  • + * + */ +public class UpdatesItemTouchCallback extends ItemTouchHelper.Callback { + + private final UpdatesAdapter adapter; + + public UpdatesItemTouchCallback(UpdatesAdapter adapter) { + this.adapter = adapter; + } + + @Override + public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { + int swipeFlags = 0; + if (viewHolder instanceof AppListItemController) { + AppListItemController controller = (AppListItemController) viewHolder; + if (controller.canDismiss()) { + swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END; + } + } + return makeMovementFlags(0, swipeFlags); + } + + @Override + public boolean onMove( + RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { + return false; + } + + @Override + public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { + AppListItemController controller = (AppListItemController) viewHolder; + controller.onDismiss(); + adapter.onItemDismissed(); + } + + @Override + public boolean isItemViewSwipeEnabled() { + return true; + } + +} diff --git a/app/src/main/java/org/fdroid/fdroid/views/updates/UpdatesViewBinder.java b/app/src/main/java/org/fdroid/fdroid/views/updates/UpdatesViewBinder.java index 84602df5b..28420cb15 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/updates/UpdatesViewBinder.java +++ b/app/src/main/java/org/fdroid/fdroid/views/updates/UpdatesViewBinder.java @@ -3,6 +3,7 @@ package org.fdroid.fdroid.views.updates; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.helper.ItemTouchHelper; import android.view.View; import android.widget.FrameLayout; import android.widget.ImageView; @@ -28,6 +29,9 @@ public class UpdatesViewBinder { list.setLayoutManager(new LinearLayoutManager(activity)); list.setAdapter(adapter); + ItemTouchHelper touchHelper = new ItemTouchHelper(new UpdatesItemTouchCallback(adapter)); + touchHelper.attachToRecyclerView(list); + emptyState = (TextView) view.findViewById(R.id.empty_state); emptyImage = (ImageView) view.findViewById(R.id.image); }