分享功能(自定义UI + app过滤)

本文介绍了一种不依赖第三方SDK的自定义分享功能实现方法,包括核心类的设计、UI定制及资源文件配置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

分享功能采用系统分享,未使用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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值