策略模式在分享功能的应用

在移动端开发中,经常遇到在应用内多个页面分享多种不同的内容到不同的平台的需求。从上面这句话,可以辨别出 3 种不同的维度的变化:

  1. 被分享的内容
  2. 页面
  3. 目标平台

即使在应用内部使用 ShareSDK 减轻分享功能开发的负担,仍然可以在业务层中看到不少大同小异的代码,而且是每个存在分享功能的页面都有这么一堆代码。

Platform.ShareParams shareParams = new Platform.ShareParams();
shareParams.setText(getContent());
shareParams.setImageUrl(getPictureUrl());
Platform weibo = ShareSDK.getPlatform(SinaWeibo.NAME);
weibo.setPlatformActionListener(listener);
weibo.share(shareParams);

针对这种情况,可以考虑使用策略模式减少重复代码。

首先,分析目前的存在目标平台,抽象出分享功能的接口:

public interface Shareable extends Serializable {
    void shareToWeibo(PlatformActionListener listener);
    void shareToWechat(PlatformActionListener listener);
    void shareToMoment(PlatformActionListener listener);
    void shareToEmail(PlatformActionListener listener);
    void shareToSms(PlatformActionListener listener);
    void copyUrl(@NonNull Context context);
}

然后,被分享的内容分别实现这些接口。

public class Topic implements Shareable {
    @Override
    public void shareToWeibo(PlatformActionListener listener) {
        Platform.ShareParams shareParams = new Platform.ShareParams();
        shareParams.setText(getContent());
        shareParams.setImageUrl(getPictureUrl());
        Platform weibo = ShareSDK.getPlatform(SinaWeibo.NAME);
        weibo.setPlatformActionListener(listener);
        weibo.share(shareParams);
    }

    @Override
    public void shareToWechat(PlatformActionListener listener) {
        Platform platform = ShareSDK.getPlatform(Wechat.NAME);
        Platform.ShareParams shareParams = new Platform.ShareParams();
        shareParams.setTitle(getContent());
        shareParams.setText(getTitle());
        shareParams.setImageUrl(getPictureUrl());
        shareParams.setUrl(getShareUrl());
        shareParams.setShareType(Platform.SHARE_WEBPAGE);
        platform.setPlatformActionListener(listener);
        platform.share(shareParams);
    }

    @Override
    public void shareToMoment(PlatformActionListener listener) {
        Platform platform = ShareSDK.getPlatform(WechatMoments.NAME);
        Platform.ShareParams shareParams = new  Platform.ShareParams();
        shareParams.setTitle(getContent());
        shareParams.setText(getTitle());
        shareParams.setImageUrl(getPictureUrl());
        shareParams.setUrl(getShareUrl());
        shareParams.setShareType(Platform.SHARE_WEBPAGE);
        platform.setPlatformActionListener(listener);
        platform.share(shareParams);
    }

    @Override
    public void shareToEmail(PlatformActionListener listener) {
        Platform platform = ShareSDK.getPlatform(Email.NAME);
        Platform.ShareParams shareParams = new Platform.ShareParams();
        shareParams.setTitle(getTitle());
        shareParams.setText(getContent());
        shareParams.setImageUrl(getPictureUrl());
        platform.setPlatformActionListener(listener);
        platform.share(shareParams);
    }

    @Override
    public void shareToSms(PlatformActionListener listener) {
        Platform platform = ShareSDK.getPlatform(ShortMessage.NAME);
        Platform.ShareParams shareParams = new Platform.ShareParams();
        shareParams.setTitle(getTitle());
        shareParams.setText(getContent());
        shareParams.setImageUrl(getPictureUrl());
        platform.setPlatformActionListener(listener);
        platform.share(shareParams);
    }

    @Override
    public void copyUrl(@NonNull Context context) {
        context = context.getApplicationContext();
        ClipboardManager cmb = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
        cmb.setText(getShareUrl());
        Toast.makeText(context, "链接已复制至剪贴板", Toast.LENGTH_SHORT).show();
    }
}

最后,定义通用的分享页面,分享页面只依赖 Shareable 接口。不同的地方有不同的样式,这个主要根据业务来定。

public class ShareFragment extends DialogFragment implements View.OnClickListener, PlatformActionListener {

    private Shareable content;

    public static ShareFragment newInstance(Shareable content) {
        Bundle args = new Bundle();
        args.putSerializable("content", content);
        ShareFragment fragment = new ShareFragment();
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.ll_weibo:
                content.shareToWeibo(this);
                break;
            case R.id.ll_wechat_friend:
                content.shareToWechat(this);
                break;
            case R.id.ll_wechat_moment:
                content.shareToMoment(this);
                break;
            case R.id.ll_email:
                content.shareToEmail(this);
                break;
            case R.id.ll_sms:
                content.shareToSms(this);
                break;
            case R.id.ll_copy_url:
                content.copyUrl(getContext());
                break;
            case R.id.fl_share:
                break;
            default:
                break;
        }
        dismiss();
    }

    // ShareSdk
    @Override
    public void onComplete(Platform platform, int i, HashMap<String, Object> hashMap) {
        Toast.makeText(App.getInstance().getApplicationContext(), "分享成功", Toast.LENGTH_SHORT).show();
    }

    // ShareSdk
    @Override
    public void onError(Platform platform, int i, Throwable throwable) {
        Toast.makeText(App.getInstance().getApplicationContext(), "分享失败", Toast.LENGTH_SHORT).show();
    }

    // ShareSdk
    @Override
    public void onCancel(Platform platform, int i) {
        Toast.makeText(App.getInstance().getApplicationContext(), "分享取消", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setStyle(DialogFragment.STYLE_NO_TITLE, android.R.style.Theme_Translucent_NoTitleBar);
        Bundle args = getArguments();
        if (args == null || !args.containsKey("content")) {
            throw new IllegalArgumentException("没有分享对象");
        }
        content = (Shareable) args.getSerializable("content");
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
        return inflater.inflate(R.layout.fragment_share, container, false);
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        view.findViewById(R.id.ll_weibo).setOnClickListener(this);
        view.findViewById(R.id.ll_wechat_friend).setOnClickListener(this);
        view.findViewById(R.id.ll_wechat_moment).setOnClickListener(this);
        view.findViewById(R.id.ll_email).setOnClickListener(this);
        view.findViewById(R.id.ll_sms).setOnClickListener(this);
        view.findViewById(R.id.ll_copy_url).setOnClickListener(this);
    }
}

分享页面通过不同的策略(Shareable 接口的实现),达到重用的目的,日后也可以随意修改或者更换布局样式,而不需要修改被分享的内容。并且,重复的分享代码被统一到被分享的内容,因为被分享的内容最清楚自己应该怎么做。

-

评论

退出登录