顺序执行多个弹窗任务解决方案-责任链模式

在应用中,用户进入应用首页以后经常会遇到顺序弹出多个弹窗的业务。例如进入首页以后,首先弹出运营活动弹窗,然后弹出应用评分或反馈弹窗,最后弹出应用更新弹窗等等。于是想到封装一套代码可以控制弹窗流程执行。

DialogChainOwner

弹窗链持有者。负责弹窗链节点的加入和展示入口。

/**
 * 弹窗链拥有者,用于控制链节点的添加和展示以及取消,销毁
 */
public class DialogChainOwner implements LifecycleEventObserver {

    private List<ChainNode> chainNodes = new ArrayList<>();  //链节点列表

    private Set<Integer> cancelledIds;  //取消执行的链节点集合

    private boolean isDestroyed = false;  //是否销毁

    public DialogChainOwner(@NonNull LifecycleOwner owner) {
        owner.getLifecycle().addObserver(this);
    }

    @Override
    public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
        if (event == Lifecycle.Event.ON_DESTROY) {
            destroy();
        }
    }

    /**
     * 加入链节点
     *
     * @param chainNode
     * @return
     */
    public DialogChainOwner join(ChainNode chainNode) {
        chainNodes.add(chainNode);
        return this;
    }

    //开始展示
    public void show() {
        DialogChain chain = new DialogChain(this, chainNodes, 0);
        chain.proceed();
    }

    //销毁
    public void destroy() {
        isDestroyed = true;
        chainNodes.clear();
        if (cancelledIds != null) {
            cancelledIds.clear();
        }
    }

    /**
     * 取消链节点
     *
     * @param id
     */
    public void cancel(int id) {
        if (cancelledIds == null) {
            cancelledIds = new HashSet<>();
        }

        cancelledIds.add(id);
    }

    boolean isCancelled(int id) {
        return cancelledIds != null && cancelledIds.contains(id);
    }

    boolean isDestroyed() {
        return isDestroyed;
    }
}

DialogChain

负责取对应的节点执行操作。

final class DialogChain {

    private DialogChainOwner chainOwner;
    private List<ChainNode> chainNodes;

    private final int index;

    DialogChain(DialogChainOwner owner, List<ChainNode> chainNodes, int index) {
        this.chainOwner = owner;
        this.chainNodes = chainNodes;
        this.index = index;
    }

    final void proceed() {
        if (chainOwner != null && chainOwner.isDestroyed()) {
            destroy();
            return;
        }

        if (chainNodes == null || index >= chainNodes.size()) return;

        DialogChain next = new DialogChain(chainOwner, chainNodes, index + 1);
        ChainNode chainNode = chainNodes.get(index);
        if (chainOwner != null && chainOwner.isCancelled(chainNode.getId())) {
            next.proceed();
        } else {
            chainNode.proceed(next);
        }
    }

    void destroy() {
        chainOwner = null;
        chainNodes.clear();
    }
}

ChainNode

链节点接口。弹窗实现该接口执行操作。

public interface ChainNode {
    /**
     * 返回链节点对于的Id
     *
     * @return
     */
    int getId();

    /**
     * 处理链节点
     *
     * @param next 下一个弹窗链节点
     */
    void proceed(DialogChain next);
}

示例

首先需要弹出的弹窗实现对应的链节点接口。

public class CustomDialog extends Dialog implements ChainNode {

    private String content;

    public CustomDialog(@NonNull Context context) {
        super(context, R.style.CustomDialog);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.dialog_custom);

        TextView textView = findViewById(R.id.content);
        textView.setText(content);
    }

    public void setContent(String content) {
        this.content = content;
    }

    @Override
    public int getId() {
        return 0;
    }

    @Override
    public void proceed(DialogChain chain) {
        show();
        setOnDismissListener(dialog -> chain.proceed());
    }
}

然后,依次加入对应的链接口并弹出。

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        DialogChainOwner owner = new DialogChainOwner(this);
        CustomDialog dialog1 = new CustomDialog(this);
        dialog1.setContent("第一个弹窗");
        CustomDialog dialog2 = new CustomDialog(this);
        dialog2.setContent("第二个弹窗");
        CustomDialog dialog3 = new CustomDialog(this);
        dialog3.setContent("第三个弹窗");
        CustomDialog dialog4 = new CustomDialog(this);
        dialog4.setContent("第四个弹窗");
        owner.join(dialog1).join(dialog2).join(dialog3).join(dialog4).show();
    }
}

感谢大家的支持,如有错误请指正,如需转载请标明原文出处!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值