From 46308dcbdede97a59842103a12cb99a2599d1b6e Mon Sep 17 00:00:00 2001 From: mvp76 Date: Wed, 16 Nov 2016 14:05:23 +0100 Subject: [PATCH] Added share to details view TODO: still need to add Nearby --- .../java/org/fdroid/fdroid/AppDetails2.java | 45 ++++ .../fdroid/views/ShareChooserDialog.java | 195 ++++++++++++++++++ app/src/main/res/layout/app_details2.xml | 1 + app/src/main/res/layout/share_chooser.xml | 24 +++ app/src/main/res/layout/share_header_item.xml | 57 +++++ app/src/main/res/layout/share_item.xml | 38 ++++ app/src/main/res/menu/details2.xml | 22 ++ 7 files changed, 382 insertions(+) create mode 100644 app/src/main/java/org/fdroid/fdroid/views/ShareChooserDialog.java create mode 100644 app/src/main/res/layout/share_chooser.xml create mode 100644 app/src/main/res/layout/share_header_item.xml create mode 100644 app/src/main/res/layout/share_item.xml create mode 100644 app/src/main/res/menu/details2.xml diff --git a/app/src/main/java/org/fdroid/fdroid/AppDetails2.java b/app/src/main/java/org/fdroid/fdroid/AppDetails2.java index ad94aef14..6b38149e8 100644 --- a/app/src/main/java/org/fdroid/fdroid/AppDetails2.java +++ b/app/src/main/java/org/fdroid/fdroid/AppDetails2.java @@ -13,7 +13,9 @@ import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.net.Uri; import android.os.Bundle; +import android.support.design.widget.CoordinatorLayout; import android.support.v4.content.LocalBroadcastManager; +import android.support.v4.view.MenuItemCompat; import android.support.v4.widget.TextViewCompat; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; @@ -29,6 +31,8 @@ import android.text.method.LinkMovementMethod; import android.text.style.URLSpan; import android.util.Log; import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.Button; @@ -58,6 +62,7 @@ import org.fdroid.fdroid.privileged.views.AppSecurityPermissions; import org.fdroid.fdroid.views.ApkListAdapter; import org.fdroid.fdroid.views.LinearLayoutManagerSnapHelper; import org.fdroid.fdroid.views.ScreenShotsRecyclerViewAdapter; +import org.fdroid.fdroid.views.ShareChooserDialog; import java.util.ArrayList; @@ -121,6 +126,46 @@ public class AppDetails2 extends AppCompatActivity { mApp = newApp; } + @Override + public boolean onCreateOptionsMenu(Menu menu) { + boolean ret = super.onCreateOptionsMenu(menu); + if (ret) { + getMenuInflater().inflate(R.menu.details2, menu); + } + return ret; + } + + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + super.onPrepareOptionsMenu(menu); + if (mApp == null) { + return true; + } + MenuItem itemIgnoreAll = menu.findItem(R.id.action_ignore_all); + if (itemIgnoreAll != null) { + itemIgnoreAll.setChecked(mApp.getPrefs(this).ignoreAllUpdates); + } + MenuItem itemIgnoreThis = menu.findItem(R.id.action_ignore_this); + if (itemIgnoreThis != null) { + itemIgnoreThis.setVisible(mApp.hasUpdates()); + itemIgnoreThis.setChecked(mApp.getPrefs(this).ignoreThisUpdate >= mApp.suggestedVersionCode); + } + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == R.id.action_share) { + Intent shareIntent = new Intent(Intent.ACTION_SEND); + shareIntent.setType("text/plain"); + shareIntent.putExtra(Intent.EXTRA_SUBJECT, mApp.name); + shareIntent.putExtra(Intent.EXTRA_TEXT, mApp.name + " (" + mApp.summary + ") - https://f-droid.org/app/" + mApp.packageName); + ShareChooserDialog.createChooser((CoordinatorLayout) findViewById(R.id.rootCoordinator), this, shareIntent); + return true; + } + return super.onOptionsItemSelected(item); + } + public class AppDetailsRecyclerViewAdapter extends RecyclerView.Adapter { diff --git a/app/src/main/java/org/fdroid/fdroid/views/ShareChooserDialog.java b/app/src/main/java/org/fdroid/fdroid/views/ShareChooserDialog.java new file mode 100644 index 000000000..691b1ebf7 --- /dev/null +++ b/app/src/main/java/org/fdroid/fdroid/views/ShareChooserDialog.java @@ -0,0 +1,195 @@ +package org.fdroid.fdroid.views; + +import android.app.Dialog; +import android.content.ComponentName; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.ResolveInfo; +import android.graphics.Color; +import android.graphics.drawable.ColorDrawable; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.design.widget.BottomSheetDialogFragment; +import android.support.design.widget.CoordinatorLayout; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.GridLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import org.fdroid.fdroid.BuildConfig; +import org.fdroid.fdroid.R; +import org.fdroid.fdroid.Utils; + +import java.util.ArrayList; +import java.util.List; + +public class ShareChooserDialog extends BottomSheetDialogFragment { + private RecyclerView mRecyclerView; + private ArrayList mTargets; + private int mParentWidth; + + public interface ShareChooserDialogListener { + void onItemSelected(ResolveInfo ri); + } + private ShareChooserDialogListener mListener; + + public ShareChooserDialog() { + super(); + } + + private void setListener(ShareChooserDialogListener listener) { + mListener = listener; + } + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mParentWidth = getArguments().getInt("width", 640); + Intent intent = getArguments().getParcelable("intent"); + mTargets = new ArrayList<>(); + List resInfo = getContext().getPackageManager().queryIntentActivities(intent, 0); + if (resInfo != null && resInfo.size() > 0) { + for (ResolveInfo resolveInfo : resInfo) { + String packageName = resolveInfo.activityInfo.packageName; + if (!packageName.equals(BuildConfig.APPLICATION_ID)) // Remove ourselves + { + mTargets.add(resolveInfo); + } + } + } + } + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + final Dialog dialog = super.onCreateDialog(savedInstanceState); + dialog.setOnShowListener(new DialogInterface.OnShowListener() { + @Override + public void onShow(DialogInterface dialogINterface) { + dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); + dialog.getWindow().setLayout( + mParentWidth - Utils.dpToPx(0, getContext()), // Set margins here! + ViewGroup.LayoutParams.MATCH_PARENT); + } + }); + return dialog; + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View v = inflater.inflate(R.layout.share_chooser, container, false); + setupView(v); + return v; + } + + private void setupView(View v) { + mRecyclerView = (RecyclerView)v.findViewById(R.id.recycler_view_apps); + + // Figure out how many columns that fit in the given parent width. Give them 100dp. + int appWidth = Utils.dpToPx(80, getContext()); + final int nCols = (mParentWidth - /* padding */ Utils.dpToPx(8, getContext())) / appWidth; + GridLayoutManager glm = new GridLayoutManager(getContext(), nCols); + glm.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { + @Override + public int getSpanSize(int position) { + if (mRecyclerView.getAdapter() != null) { + if (mRecyclerView.getAdapter().getItemViewType(position) == 1) { + return nCols; + } + return 1; + } + return 0; + } + }); + mRecyclerView.setLayoutManager(glm); + + + class VH extends RecyclerView.ViewHolder { + public final ImageView icon; + public final TextView label; + + public VH(View itemView) { + super(itemView); + icon = (ImageView) itemView.findViewById(R.id.ivShare); + label = (TextView) itemView.findViewById(R.id.tvShare); + } + } + mRecyclerView.setAdapter(new RecyclerView.Adapter() { + + private ArrayList mIntents; + + RecyclerView.Adapter init(List targetedShareIntents) { + mIntents = new ArrayList<>(); + mIntents.add("Nearby"); + for (ResolveInfo ri : targetedShareIntents) { + mIntents.add(ri); + } + return this; + } + + @Override + public int getItemViewType(int position) { + if (mIntents.get(position) instanceof String) + return 1; + return 0; + } + + @Override + public VH onCreateViewHolder(ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate((viewType == 1) ? R.layout.share_header_item : R.layout.share_item, parent, false); + return new VH(view); + } + + @Override + public void onBindViewHolder(VH holder, int position) { + if (getItemViewType(position) == 1) { + //holder.label.setText((CharSequence)mIntents.get(position)); + return; + } + final ResolveInfo ri = (ResolveInfo) mIntents.get(position); + holder.icon.setImageDrawable(ri.loadIcon(getContext().getPackageManager())); + holder.label.setText(ri.loadLabel(getContext().getPackageManager())); + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (mListener != null) + mListener.onItemSelected(ri); + dismiss(); + } + }); + } + + @Override + public int getItemCount() { + return mIntents.size(); + } + }.init(mTargets)); + + } + + public static void createChooser(CoordinatorLayout rootView, final AppCompatActivity parent, final Intent shareIntent) { + ShareChooserDialog d = new ShareChooserDialog(); + d.setListener(new ShareChooserDialog.ShareChooserDialogListener() { + @Override + public void onItemSelected(final ResolveInfo ri) { + startActivityForResolveInfo(ri); + } + + private void startActivityForResolveInfo(ResolveInfo ri) { + Intent intent = new Intent(shareIntent); + ComponentName name = new ComponentName(ri.activityInfo.applicationInfo.packageName, + ri.activityInfo.name); + intent.setComponent(name); + parent.startActivity(intent); + } + }); + Bundle args = new Bundle(); + args.putInt("width", rootView.getWidth()); + args.putParcelable("intent", shareIntent); + d.setArguments(args); + d.show(parent.getSupportFragmentManager(), "Share"); + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/app_details2.xml b/app/src/main/res/layout/app_details2.xml index ff5e21aae..e8a38a139 100644 --- a/app/src/main/res/layout/app_details2.xml +++ b/app/src/main/res/layout/app_details2.xml @@ -7,6 +7,7 @@ android:fitsSystemWindows="true" tools:context="org.fdroid.fdroid.AppDetails2" android:background="#fcfcfc" + android:id="@+id/rootCoordinator" > + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/share_header_item.xml b/app/src/main/res/layout/share_header_item.xml new file mode 100644 index 000000000..a2ab5b8ba --- /dev/null +++ b/app/src/main/res/layout/share_header_item.xml @@ -0,0 +1,57 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/share_item.xml b/app/src/main/res/layout/share_item.xml new file mode 100644 index 000000000..e48a3b0d1 --- /dev/null +++ b/app/src/main/res/layout/share_item.xml @@ -0,0 +1,38 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/details2.xml b/app/src/main/res/menu/details2.xml new file mode 100644 index 000000000..86e9e4c03 --- /dev/null +++ b/app/src/main/res/menu/details2.xml @@ -0,0 +1,22 @@ + + + + + + +