分享功能采用系统分享,未使用ShareSDK等第三方分享,放弃使用createChooser方式(系统UI,过滤的话无法指定label,只能使用apk名称,有点坑)。
核心类
public class Share {
private static final String TAG = "Share";
private Context mContext;
private List<ResolveInfo> mResolveFilterInfos = new ArrayList<>();
private Intent mShareIntent;
//支持分享的app包名列表
public static final String[] SHARE_APPS_LIST = new String[]
{"com.tencent.mm", "com.tencent.mobileqq", "com.sina.weibo",};
public enum ShareType {
Image,
Text
//分享Item(包含label和icon)
public static class ShareItem implements Serializable {
private CharSequence appName;
private Drawable appIcon;
ShareItem(CharSequence appName, Drawable appIcon) {
this.appName = appName;
this.appIcon = appIcon;
}
public CharSequence getAppName() {
return appName;
}
public Drawable getAppIcon() {
return appIcon;
}
@Override
public String toString() {
return "ShareItem{" +
"appName=" + appName +
", appIcon=" + appIcon +
'}';
}
}
public Share(Context context) {
this.mContext = context;
}
//执行分享
public void share(int position) {
ResolveInfo resolveInfo = mResolveFilterInfos.get(position);
if (resolveInfo != null) {
ComponentName chosenName = new ComponentName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name);
Intent intent = new Intent(mShareIntent);
intent.setComponent(chosenName);
try {
mContext.startActivity(intent);
} catch (Throwable e) {
Log.e(TAG, e.toString());
}
}
}
//指定分享类型(文字or图片),过滤app,生成分享列表
public List<ShareItem> scanShareApp(ShareType type, String content) {
mShareIntent = new Intent(Intent.ACTION_SEND);
switch (type) {
case Image:
mShareIntent.setType("image/*");
File file = new File(content);
Uri uri = Uri.fromFile(file);
mShareIntent.putExtra(Intent.EXTRA_STREAM, uri);
break;
case Text:
mShareIntent.setType("text/plain");
mShareIntent.putExtra(Intent.EXTRA_TEXT, content);
break;
}
PackageManager packageManager = mContext.getPackageManager();
List<ResolveInfo> resolveInfos = packageManager.queryIntentActivities(mShareIntent, 0);
mResolveFilterInfos.clear();
ArrayList<ShareItem> shareItems = new ArrayList<>();
for (ResolveInfo resolveInfo : resolveInfos) {
if (isInShareList(resolveInfo.activityInfo.packageName)) {
ShareItem shareItem = new ShareItem(resolveInfo.loadLabel(packageManager), resolveInfo.loadIcon(packageManager));
shareItems.add(shareItem);
mResolveFilterInfos.add(resolveInfo);
}
}
return shareItems;
}
//判断是否在指定的分享列表当中
private boolean isInShareList(String packageName) {
if (TextUtils.isEmpty(packageName)) {
return false;
}
for (int i = 0; i < SHARE_APPS_LIST.length; i++) {
if (packageName.contains(SHARE_APPS_LIST[i])) {
return true;
}
}
return false;
}
}
自定义UI
package com.argus.camera.generatedocument.ui;
import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.argus.camera.R;
import com.argus.camera.debug.Log;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class ShareViewLayout extends RelativeLayout {
private static final com.argus.camera.debug.Log.Tag TAG = new com.argus.camera.debug.Log.Tag("ShareViewLayout");
private ViewPager mPager;
private LinearLayout mLlDot;
private List<View> mPagerList;
private List<Share.ShareItem> mShareDatas;
private int pageCount;// total page count
private int pageSize = 8;// num in each page
private int curIndex = 0;// current page
private Share mShare;
public interface OnCallBack {
void onBackPressed();
}
private OnCallBack mListener;
public void setCallBack(OnCallBack listener) {
this.mListener = listener;
}
public ShareViewLayout(Context context) {
this(context, null);
}
public ShareViewLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mPager = (ViewPager) findViewById(R.id.viewpager);
mLlDot = (LinearLayout) findViewById(R.id.ll_dot);
RelativeLayout shareView = (RelativeLayout) findViewById(R.id.share_view);
shareView.setOnClickListener(null);
this.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mListener != null) {
mListener.onBackPressed();
}
}
});
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
if (mListener != null) {
mListener.onBackPressed();
}
}
return super.dispatchKeyEvent(event);
}
private void setOvalLayout() {
for (int i = 0; i < pageCount; i++) {
mLlDot.addView(LayoutInflater.from(getContext()).inflate(R.layout.dot, null));
}
mLlDot.getChildAt(0).findViewById(R.id.v_dot).setBackgroundResource(R.drawable.dot_selected);
mPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
mLlDot.getChildAt(curIndex).findViewById(R.id.v_dot).setBackgroundResource(R.drawable.dot_normal);
mLlDot.getChildAt(position).findViewById(R.id.v_dot).setBackgroundResource(R.drawable.dot_selected);
curIndex = position;
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
public boolean initShareList(Share.ShareType type, String content) {
mShareDatas = new ArrayList<>();
mShare = new Share(getContext());
List<Share.ShareItem> shareItems = mShare.scanShareApp(type, content);
for (Share.ShareItem item : shareItems) {
mShareDatas.add(new Share.ShareItem(item.getAppName(), item.getAppIcon()));
}
Log.d(TAG, "initShareList() - " + mShareDatas.size());
Log.d(TAG, "initShareList() - " + mShareDatas.toString());
if (mShareDatas.size() > 0) {
initLayout();
return true;
}
return false;
}
private void initLayout() {
pageCount = (int) Math.ceil(mShareDatas.size() * 1.0 / pageSize);
mPagerList = new ArrayList<>();
for (int i = 0; i < pageCount; i++) {
GridView gridView = (GridView) LayoutInflater.from(getContext()).inflate(R.layout.gridview, null);
gridView.setAdapter(new GridViewAdapter(getContext(), mShareDatas, i, pageSize));
mPagerList.add(gridView);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
int pos = position + curIndex * pageSize;
Log.d(TAG, "onItemClick() - pos = " + pos);
mShare.share(pos);
if (mListener != null) {
mListener.onBackPressed();
}
}
});
}
mPager.setAdapter(new ViewPagerAdapter(mPagerList));
setOvalLayout();
}
public class GridViewAdapter extends BaseAdapter {
private List<Share.ShareItem> mDatas;
private LayoutInflater inflater;
private int curIndex;
private int pageSize;
public GridViewAdapter(Context context, List<Share.ShareItem> mDatas, int curIndex, int pageSize) {
this.mDatas = mDatas;
this.pageSize = pageSize;
this.curIndex = curIndex;
inflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return mDatas.size() > (curIndex + 1) * pageSize ? pageSize : (mDatas.size() - curIndex * pageSize);
}
@Override
public Object getItem(int position) {
return mDatas.get(position + curIndex * pageSize);
}
@Override
public long getItemId(int position) {
return position + curIndex * pageSize;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder vh;
if (convertView == null) {
convertView = inflater.inflate(R.layout.gridview_item, null);
vh = new ViewHolder();
vh.iv = (ImageView) convertView.findViewById(R.id.imageView);
vh.tv = (TextView) convertView.findViewById(R.id.textView);
convertView.setTag(vh);
} else {
vh = (ViewHolder) convertView.getTag();
}
int pos = position + curIndex * pageSize;
vh.iv.setImageDrawable(mDatas.get(pos).getAppIcon());
vh.tv.setText(mDatas.get(pos).getAppName());
return convertView;
}
class ViewHolder {
public TextView tv;
public ImageView iv;
}
}
public class ViewPagerAdapter extends PagerAdapter {
private List<View> mViewList;
public ViewPagerAdapter(List<View> mViewList) {
this.mViewList = mViewList;
}
@Override
public int getCount() {
return (mViewList == null) ? 0 : mViewList.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(mViewList.get(position));
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
container.addView(mViewList.get(position));
return mViewList.get(position);
}
}
}
调用
public void share(File file) {
final WindowManager windowManager = getWindowManager();
final View root = LayoutInflater.from(this)
.inflate(R.layout.share_view_layout, null);
ShareViewLayout shareViewLayout = (ShareViewLayout) root.findViewById(R.id.shareViewLayout);
boolean hasShareList = shareViewLayout.initShareList(Share.ShareType.Image, file.getAbsolutePath());
if (hasShareList) {
windowManager.addView(root, configWindowParams());
} else {
Toast.makeText(this, "No shared apps", Toast.LENGTH_SHORT).show();
}
shareViewLayout.setCallBack(new ShareViewLayout.OnCallBack() {
@Override
public void onBackPressed() {
windowManager.removeView(root);
}
});
}
windowManager.addView(root,configWindowParams());
}
private WindowManager.LayoutParams configWindowParams() {
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_APPLICATION,
0, PixelFormat.TRANSPARENT);
params.gravity = Gravity.TOP | Gravity.LEFT;
params.windowAnimations=android.R.style.Animation_InputMethod;
return params;
}
使用到的一些资源文件
dot_normal.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="8dp" />
<solid android:color="#D4D3D3" />
</shape>
dot_selected.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@android:color/darker_gray" />
<corners android:radius="8dp" />
</shape>
dot.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<View
android:id="@+id/v_dot"
android:layout_width="8dp"
android:layout_height="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:background="@drawable/dot_normal"/>
</RelativeLayout>
gridview.xml
<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:numColumns="4"
android:overScrollMode="never" />
gridview_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:paddingBottom="10dp"
android:paddingTop="10dp">
<ImageView
android:id="@+id/imageView"
android:layout_width="48dp"
android:layout_height="48dp" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:gravity="center"
android:layout_height="wrap_content"
android:paddingTop="2dp"
android:textSize="12dp" />
</LinearLayout>
share_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#50000000">
<RelativeLayout
android:id="@+id/share_view"
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_alignParentBottom="true"
android:background="#FFFFFF">
<TextView
android:id="@+id/share_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginTop="16dp"
android:text="@string/share_to"
android:textSize="16sp"
android:textStyle="bold" />
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/share_text"
android:layout_marginTop="20dp" />
<LinearLayout
android:id="@+id/ll_dot"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="8dp"
android:gravity="center"
android:orientation="horizontal" />
</RelativeLayout>
</RelativeLayout>
share_view_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.argus.camera.generatedocument.ui.ShareViewLayout
android:id="@+id/shareViewLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include layout="@layout/share_layout" />
</com.argus.camera.generatedocument.ui.ShareViewLayout>
</RelativeLayout>