From a7de8b0e31f6c3537538cd1c2c48d91ccd302991 Mon Sep 17 00:00:00 2001 From: Alexey Kuznetsov Date: Sat, 12 Mar 2016 18:05:51 +0300 Subject: [PATCH] add POpupShareActionProvider --- .../activities/MainActivity.java | 55 ++---- .../axet/audiorecorder/app/Storage.java | 3 + .../widgets/PopupShareActionProvider.java | 174 ++++++++++++++++++ app/src/main/res/layout/recording.xml | 10 +- 4 files changed, 197 insertions(+), 45 deletions(-) create mode 100644 app/src/main/java/com/github/axet/audiorecorder/widgets/PopupShareActionProvider.java diff --git a/app/src/main/java/com/github/axet/audiorecorder/activities/MainActivity.java b/app/src/main/java/com/github/axet/audiorecorder/activities/MainActivity.java index b369431..662bdb4 100644 --- a/app/src/main/java/com/github/axet/audiorecorder/activities/MainActivity.java +++ b/app/src/main/java/com/github/axet/audiorecorder/activities/MainActivity.java @@ -17,6 +17,7 @@ import android.support.design.widget.FloatingActionButton; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.PopupMenu; import android.support.v7.widget.Toolbar; import android.util.Log; import android.view.LayoutInflater; @@ -27,11 +28,8 @@ import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.ArrayAdapter; import android.widget.ImageView; -import android.widget.LinearLayout; import android.widget.ListView; -import android.widget.PopupMenu; import android.widget.SeekBar; -import android.widget.ShareActionProvider; import android.widget.TextView; import android.widget.Toast; @@ -40,6 +38,7 @@ import com.github.axet.audiorecorder.animations.RecordingAnimation; import com.github.axet.audiorecorder.animations.RemoveItemAnimation; import com.github.axet.audiorecorder.app.MainApplication; import com.github.axet.audiorecorder.app.Storage; +import com.github.axet.audiorecorder.widgets.PopupShareActionProvider; import java.io.File; import java.lang.reflect.Field; @@ -81,6 +80,7 @@ public class MainActivity extends AppCompatActivity implements AbsListView.OnScr public class Recordings extends ArrayAdapter { MediaPlayer player; Runnable updatePlayer; + PopupShareActionProvider shareProvider; Map duration = new TreeMap<>(); @@ -112,26 +112,6 @@ public class MainActivity extends AppCompatActivity implements AbsListView.OnScr sort(new SortFiles()); } - public void setForceShowIcon(PopupMenu popupMenu) { - try { - Field[] fields = popupMenu.getClass().getDeclaredFields(); - for (Field field : fields) { - if ("mPopup".equals(field.getName())) { - field.setAccessible(true); - Object menuPopupHelper = field.get(popupMenu); - Class classPopupHelper = Class.forName(menuPopupHelper - .getClass().getName()); - Method setForceIcons = classPopupHelper.getMethod( - "setForceShowIcon", boolean.class); - setForceIcons.invoke(menuPopupHelper, true); - break; - } - } - } catch (Throwable e) { - e.printStackTrace(); - } - } - String formatSize(long s) { if (s > 0.1 * 1024 * 1024) { float f = s / 1024f / 1024f; @@ -262,29 +242,20 @@ public class MainActivity extends AppCompatActivity implements AbsListView.OnScr share.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - PopupMenu p = new PopupMenu(getContext(), share); + shareProvider = new PopupShareActionProvider(getContext(), share); - AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); + Intent emailIntent = new Intent(Intent.ACTION_SEND); + emailIntent.setType("audio/mp4a-latm"); + emailIntent.putExtra(Intent.EXTRA_EMAIL, ""); + emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(f)); + emailIntent.putExtra(Intent.EXTRA_SUBJECT, f.getName()); + emailIntent.putExtra(Intent.EXTRA_TEXT, "Shared via App Recorder"); - ShareActionProvider a = new ShareActionProvider(getContext()); - a.setShareHistoryFileName(ShareActionProvider.DEFAULT_SHARE_HISTORY_FILE_NAME); + shareProvider.setShareIntent(emailIntent); - Intent shareIntent = new Intent(Intent.ACTION_SEND); - shareIntent.setType("text/plain"); - shareIntent.putExtra(Intent.EXTRA_TEXT, "http://android-er.blogspot.com/"); + shareProvider.show(); - a.setShareIntent(shareIntent); - - View action = a.onCreateActionView(); - LinearLayout ll = new LinearLayout(getContext()); - ll.setOrientation(LinearLayout.VERTICAL); - ll.addView(action); - builder.setView(ll); - builder.show(); - -// MenuItem share = p.getMenu().add("Share"); -// share.setActionProvider(a).setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_IF_ROOM); -// p.show(); + Log.d("123","show"); } }); diff --git a/app/src/main/java/com/github/axet/audiorecorder/app/Storage.java b/app/src/main/java/com/github/axet/audiorecorder/app/Storage.java index a758109..e9af936 100644 --- a/app/src/main/java/com/github/axet/audiorecorder/app/Storage.java +++ b/app/src/main/java/com/github/axet/audiorecorder/app/Storage.java @@ -73,6 +73,9 @@ public class Storage { File t = new File(path); File[] ff = l.listFiles(); + if (ff == null) + return; + for (File f : ff) { File tt = getNextFile(t, f); move(f, tt); diff --git a/app/src/main/java/com/github/axet/audiorecorder/widgets/PopupShareActionProvider.java b/app/src/main/java/com/github/axet/audiorecorder/widgets/PopupShareActionProvider.java new file mode 100644 index 0000000..9954666 --- /dev/null +++ b/app/src/main/java/com/github/axet/audiorecorder/widgets/PopupShareActionProvider.java @@ -0,0 +1,174 @@ +package com.github.axet.audiorecorder.widgets; + +import android.content.Context; +import android.content.Intent; +import android.content.res.Resources; +import android.support.v4.view.MenuItemCompat; +import android.support.v7.view.menu.ListMenuItemView; +import android.support.v7.view.menu.MenuBuilder; +import android.support.v7.view.menu.MenuItemImpl; +import android.support.v7.view.menu.MenuView; +import android.support.v7.view.menu.SubMenuBuilder; +import android.support.v7.widget.PopupMenu; +import android.support.v7.widget.ShareActionProvider; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.MenuItem; +import android.view.SubMenu; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.BaseAdapter; +import android.widget.FrameLayout; +import android.widget.ListAdapter; +import android.widget.ListPopupWindow; + +/** + * PopupMenu window for ShareActionProvider + */ +public class PopupShareActionProvider extends ListPopupWindow { + PopupMenu popup; + ShareActionProvider action; + MenuAdapter adp; + FrameLayout mMeasureParent; + Context context; + + public class MenuAdapter extends BaseAdapter { + static final int ITEM_LAYOUT = android.support.v7.appcompat.R.layout.abc_popup_menu_item_layout; + + private SubMenu menu; + + boolean mForceShowIcon = true; + + public MenuAdapter(SubMenu menu) { + this.menu = menu; + } + + public void setMenu(SubMenu menu) { + this.menu = menu; + notifyDataSetChanged(); + } + + public int getCount() { + return menu.size(); + } + + public MenuItemImpl getItem(int position) { + return (MenuItemImpl) menu.getItem(position); + } + + public long getItemId(int position) { + // Since action menu item's ID is optional, we'll use the position as an + // ID for the item in the AdapterView + return position; + } + + public View getView(int position, View convertView, ViewGroup parent) { + if (convertView == null) { + LayoutInflater inflater = LayoutInflater.from(parent.getContext()); + convertView = inflater.inflate(ITEM_LAYOUT, parent, false); + } + + MenuView.ItemView itemView = (MenuView.ItemView) convertView; + if (mForceShowIcon) { + ((ListMenuItemView) convertView).setForceShowIcon(true); + } + itemView.initialize(getItem(position), 0); + return convertView; + } + + @Override + public void notifyDataSetChanged() { + super.notifyDataSetChanged(); + } + } + + + public PopupShareActionProvider(Context context, View anchor) { + super(context); + + this.context = context; + + setAnchorView(anchor); + + action = new ShareActionProvider(context); + action.setShareHistoryFileName(ShareActionProvider.DEFAULT_SHARE_HISTORY_FILE_NAME); + + popup = new PopupMenu(context, anchor); + } + + public void setShareIntent(Intent shareIntent) { + action.setShareIntent(shareIntent); + + MenuItem share = popup.getMenu().add("Share"); + MenuItemCompat.setActionProvider(share, action).setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_IF_ROOM); + + MenuItemImpl i = (MenuItemImpl) share; + final MenuBuilder mb = (MenuBuilder) popup.getMenu(); + SubMenuBuilder sb = new SubMenuBuilder(context, mb, i); + i.setSubMenu(sb); + + action.onPrepareSubMenu(sb); + + adp = new MenuAdapter(i.getSubMenu()); + + setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + MenuItem item = adp.getItem(position); + if(item.hasSubMenu()) { + adp.setMenu(item.getSubMenu()); + }else { + mb.performItemAction(item, 0); + dismiss(); + } + } + }); + + setAdapter(adp); + + setContentWidth(measureContentWidth(context)); + + setModal(true); + } + + public int measureContentWidth(Context mContext) { + final Resources res = mContext.getResources(); + int mPopupMaxWidth = Math.max(res.getDisplayMetrics().widthPixels / 2, + res.getDimensionPixelSize(android.support.v7.appcompat.R.dimen.abc_config_prefDialogWidth)); + + // Menus don't tend to be long, so this is more sane than it looks. + int maxWidth = 0; + View itemView = null; + int itemType = 0; + + final ListAdapter adapter = adp; + final int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + final int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + final int count = adapter.getCount(); + for (int i = 0; i < count; i++) { + final int positionType = adapter.getItemViewType(i); + if (positionType != itemType) { + itemType = positionType; + itemView = null; + } + + if (mMeasureParent == null) { + mMeasureParent = new FrameLayout(mContext); + } + + itemView = adapter.getView(i, itemView, mMeasureParent); + itemView.measure(widthMeasureSpec, heightMeasureSpec); + + final int itemWidth = itemView.getMeasuredWidth(); + if (itemWidth >= mPopupMaxWidth) { + return mPopupMaxWidth; + } else if (itemWidth > maxWidth) { + maxWidth = itemWidth; + } + } + + return maxWidth; + } + +} diff --git a/app/src/main/res/layout/recording.xml b/app/src/main/res/layout/recording.xml index 2a5e4b0..2c16308 100644 --- a/app/src/main/res/layout/recording.xml +++ b/app/src/main/res/layout/recording.xml @@ -67,6 +67,7 @@ android:id="@+id/recording_player" android:layout_width="match_parent" android:layout_height="wrap_content" + android:layout_marginBottom="5dp" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:background="#dedede" @@ -112,21 +113,24 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/play" - android:backgroundTint="@color/colorAccent" /> + android:backgroundTint="@color/colorAccent" + android:padding="20dp" /> + android:backgroundTint="@color/colorAccent" + android:padding="20dp" /> + android:backgroundTint="@color/colorAccent" + android:padding="20dp" />