现在很多的应用基本都会集成分享这个功能,该功能包括系统分享(比如邮件,短信)和第三方分享(比如QQ和微信)。其中有些公司会选择使用第三方的库来简化这些操作,加快开发,用的比较多的比如友盟社会化分享SDK,缺点就是自由度太低,因为可能你仅仅只是需要QQ和微信,其他的公司就会选择自己导入所需要的第三方SDK来自定义分享功能,自由度高,于是这篇博客主要来介绍后一种自定义分享功能的案例demo,下图是demo的运行效果:
  
  具体分析一下源码,由于分享的内容根据需求的不同而不同,为了简单起见,我们就以最常用的图文+链接的形式为例,其他情况何以根据需求修改相关类。第一步定义分享的实体类:
  ShareModel.java

public class ShareModel {    /** 分享的类型,图片,文字等 */    public int type;    /** 分享的标题 */    public String title;    /** 分享内容 */    public String content;    /** 分享的链接 */    public String shareUrl;    /** 分享图片的网络url */    public ArrayList imageUrl;    /** 分享图片的本地path路径 */    public ArrayList imagePath;}

  这个类定义了分享的基本数据类型(按照需求修改该类即可,比如可以添加视频语音之类)。接着我们建立各自的分享模块用来区分不同的分享(这里以系统和QQ分享为例),并且每个分享模块都要继承自同一个接口IShare:
  IShare.java

public interface IShare {    /**     * @param model 调用分享的实体     * @param context 上下文     * @param type 调用该分享的类别     * @param callback 分享回调     */    void doShare(ShareModel model, Context context, int type, IShareCallback callback);    /**     * 该函数在{@link android.app.Activity#onActivityResult(int, int, Intent)}     * 调用,用来处理分享的回调,比如QQ和系统分享(微信这种不需要在onActivityResult中处理的直接返回false即可)     * @return 是否为该分享的回调      */    boolean doShareCallback(int requestCode, int resultCode, Intent data);}

  该接口定义了两个函数,一个是分享函数,另一个是分享的回调函数,系统分享和QQ分享的相关类继承该接口实现这两个函数:
  QQ分享TencentShare .class

public class TencentShare implements IShare {    @Override    public void doShare(ShareModel model, Context context, int type, IShareCallback callback) {        //具体看源码    }    @Override    public boolean doShareCallback(int requestCode, int resultCode, Intent data) {        //具体看源码    }}

  系统分享SystemShare.class

public class SystemShare implements IShare {    @Override    public void doShare(ShareModel model, Context context, int type, IShareCallback callback) {        //具体看源码    }    @Override    public boolean doShareCallback(int requestCode, int resultCode, Intent data) {        //具体看源码    }}

  如果需要集成其他第三方分享,新建相关类实现相关函数即可。然后就是最重要的管理类了,看看该类的源码:

public class ShareManager {    private Activity activity;    private IShareCallback callback;    private PopupWindow popupWindow;    /** 最新一次调用分享的对象 */    private IShare shareObject;    /**     * @param callback 分享出去的回调     */    public ShareManager(Activity activity, IShareCallback callback){        this.activity = activity;        this.callback = callback;        //初始化Share枚举类        Share demo = Share.QQ_FRIEND;    }    /**     * 用来展示分享popUpWindow     * @param model 分享出去的实体     */    public void show(final ShareModel model) {        if (popupWindow == null) {            popupWindow = new ShareGridViewPopupWindow(activity, new ShareGridViewPopupWindow.IShareClickCallback() {                @Override                public void onShareCallback(int position) {                    try {                        Class<? extends IShare> clazz = Share.values()[position].getShareClass();                        shareObject = clazz.newInstance();                        shareObject.doShare(model, activity, Share.values()[position].getType(), callback);                    } catch (InstantiationException e) {                        e.printStackTrace();                    } catch (IllegalAccessException e) {                        e.printStackTrace();                    }                }            });            popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {                @Override                public void onDismiss() {                    popupWindow = null;                }            });        }        popupWindow.showAtLocation(activity.getWindow().getDecorView(), Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 0);    }    /**     * 用来在activity的onActivityResult函数中注册分享回调,比如QQ和系统分享     * @return 是否是分享回调,如果是,返回true,表明activity不用处理相关result     */    public boolean registerOnActivityCallback(int requestCode, int resultCode, Intent data){            return shareObject!=null && shareObject.doShareCallback(requestCode, resultCode, data);    }    /**     * 在此处动态添加分享模块     */    public enum Share {        QQ_FRIEND("QQ", R.mipmap.logo_qq, 0, TencentShare.class),        QQ_ZONE("QQ空间", R.mipmap.logo_qzone, 1, TencentShare.class),        MAIL("邮件", R.mipmap.logo_email, 0, SystemShare.class),        MESSAGE("信息", R.mipmap.logo_shortmessage, 1, SystemShare.class);        private String name;        private int drawable;        private Class<? extends IShare> shareClass;        private int type;        Share(String name, int drawable, int type, Class<? extends IShare> shareClass){            this.name = name;            this.drawable = drawable;            this.type = type;            this.shareClass = shareClass;        }        public String getName(){            return name;        }        public int getDrawableId(){            return drawable;        }        public int getType(){            return type;        }        public Class<? extends IShare> getShareClass() {            return shareClass;        }    }}

  该类使用一个enum来集中定义所有的分享,每个分享都会有一个名字和图片用来展示,而点击效果的回调则是由相关继承自IShare接口的class类对象调用doShare函数来进行处理,这么做的好处是利于管理和以后的分享类别的增加和删除。该类中还有一个registerOnActivityCallback函数,该函数是用来在Activity中的onActivityResult中注册分享回调,通知相关分享的回调成功与否。
  我们在这里使用popupWindow来弹出分享框,于是需要自定义一个popupWindow:
  ShareGridViewPopupWindow.java类:

public class ShareGridViewPopupWindow extends PopupWindow {    private View mMenuView;    private LayoutInflater inflater;    private GridView gridView;    private TextView tv_dismiss;    private Activity context;    private View view;    public ShareGridViewPopupWindow(Activity context, final IShareClickCallback callback) {        super();        this.context = context;        inflater = (LayoutInflater) context.getSystemService(Service.LAYOUT_INFLATER_SERVICE);        mMenuView = inflater.inflate(R.layout.share_popupwindow, null);        gridView = (GridView) mMenuView.findViewById(R.id.gridview);        tv_dismiss = (TextView) mMenuView.findViewById(R.id.tv_dismiss);        gridView.setAdapter(new GridViewAdapter());        gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {            @Override            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {                if (callback != null)                    callback.onShareCallback(position);                dismiss();            }        });        this.setAnimationStyle(R.style.share_PopupAnimation);        //http://stackoverflow.com/questions/3121232/android-popup-window-dismissal        this.setBackgroundDrawable(new BitmapDrawable(null,""));        this.setFocusable(true);        tv_dismiss.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                dismiss();            }        });        this.setContentView(mMenuView);        this.setWidth(LayoutParams.MATCH_PARENT);        this.setHeight(LayoutParams.WRAP_CONTENT);        //点击popUpWindow其他部分消失        mMenuView.setOnTouchListener(new OnTouchListener() {            public boolean onTouch(View v, MotionEvent event) {                int height = mMenuView.findViewById(R.id.pop_layout).getTop();                int y = (int) event.getY();                if (event.getAction() == MotionEvent.ACTION_UP) {                    if (y < height) {                        dismiss();                    }                }                return true;            }        });        //增加popUpWindow其他部分的灰色效果        view = new View(context);        view.setBackgroundColor(Color.parseColor("#b0000000"));        ((ViewGroup)context.getWindow().getDecorView().getRootView()).addView(view);    }    private class GridViewAdapter extends BaseAdapter {        @Override        public int getCount() {            return ShareManager.Share.values().length;        }        @Override        public Object getItem(int position) {            return ShareManager.Share.values()[position];        }        @Override        public long getItemId(int position) {            return position;        }        @Override        public View getView(int position, View convertView, ViewGroup parent) {            if (convertView == null) {                convertView = inflater.inflate(R.layout.share_grid_item, null);            }            convertView.findViewById(R.id.iv_image).setBackgroundResource(ShareManager.Share.values()[position].getDrawableId());            ((TextView)convertView.findViewById(R.id.tv_text)).setText(ShareManager.Share.values()[position].getName());            return convertView;        }    }    @Override    public void dismiss() {        super.dismiss();        ((ViewGroup)context.getWindow().getDecorView().getRootView()).removeView(view);    }    public interface IShareClickCallback {        void onShareCallback(int position);    }}

  该popupWindow使用gridView来进行布局,大家可以根据需求修改该布局,关于popupWindow的使用我这里说几点:第一点是popupWindow点击外部和返回键消失的处理,点击外部消失需要使用setOnTouchListener函数来监控用户触摸的位置,按下返回键的处理需要先使用setBackgroundDrawable函数给该popupWindow设置一个背景,接着使用setFocusable函数设置焦点;第二点是外侧的灰色背景,我这里使用的是当popupWindow展示的时候在decorView上加入一个透明黑色的view,在dismiss的时候去掉,这样效果就达到了。
  基本的思想就介绍完了,很简单,具体的大家可以去看源码:
  https://github.com/zhaozepeng/ShareManager

更多相关文章

  1. Android第一次编译报错,不操作再次编译即可通过的现象
  2. Android(安卓)记一次解决问题的过程:从源码中分析永远是解决问题
  3. 分享:Android中利用机器码注册机制防止破解
  4. 如何利用Activity的Dialog风格完成弹出框设计 “第二届 Google
  5. 使用Qt开发Android应用程序(Qt on Android),连接安卓手机真机调试时
  6. 实用的Log打印类封装,助尼快速定位源码(android)
  7. Flickr 推出 Android(安卓)App,头条新功能是「实时照片共同欣赏」
  8. android adb 流程原理代码分析(一)
  9. [置顶] Android客户端与服务端(jsp)之间json的传输与解析【附效果

随机推荐

  1. Android adb 使用总结 (调试专用)
  2. Android TextView里显示两种颜色
  3. android com.handmark.pulltorefresh 使
  4. 用Javascript判断访问来源操作系统, 设备
  5. Android之仿iphone抖动效果
  6. 【Android开发】构建第一个APP
  7. Android7.1&8.0 audio设置音量
  8. Android - MediaPlayer
  9. Android 手机存储文件各种路径
  10. 收集android上开源的酷炫的交互动画和视