You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何无需初始化调用类公共方法?仿Glide库实现疑问

实现类似Glide的链式调用方案

要实现MyAnimation.with(context)这种类名直接调用的链式API,核心是把with方法改成静态入口方法,同时通过私有构造限制外部直接实例化,让静态方法成为唯一的实例创建渠道。下面是具体的实现思路和代码调整方案:

核心思路拆解

Glide的with之所以能直接通过类名调用,本质是它是一个静态工厂方法——负责创建并初始化类的实例,然后返回这个实例供后续链式调用。你现在的问题是with是实例方法,必须先new出对象才能调用,所以只需要把with改成静态方法,内部完成实例创建和初始化即可。

修改后的完整代码

public class MyAnimation {
    private Context mContext;
    private ConstraintSet mConstraintSet;
    private Transition mTransition;
    private ConstraintLayout mLayout;

    // 私有构造方法:禁止外部直接new实例,强制通过with方法创建
    private MyAnimation() {}

    /**
     * 静态入口方法,初始化上下文并返回实例
     * @param context 用于ConstraintSet的上下文
     * @return MyAnimation实例,支持链式调用
     */
    public static MyAnimation with(Context context) {
        if (context == null) {
            throw new IllegalArgumentException("Context cannot be null");
        }
        MyAnimation animation = new MyAnimation();
        animation.mContext = context;
        animation.mConstraintSet = new ConstraintSet();
        return animation;
    }

    /**
     * 设置起始布局约束,支持自定义过渡动画
     * @param secondKeyframe 约束布局资源ID
     * @param customTransition 自定义过渡动画
     * @return 当前实例,支持链式调用
     * @throws IllegalStateException 未初始化上下文时抛出
     */
    public MyAnimation from(@LayoutRes int secondKeyframe, Transition customTransition) throws IllegalStateException {
        if(mContext == null) {
            throw new IllegalStateException("Context not initialized. Please call with(Context) first");
        }
        mTransition = customTransition;
        mConstraintSet.clone(mContext, secondKeyframe);
        return this;
    }

    // 重载from方法:简化无自定义过渡的场景
    public MyAnimation from(@LayoutRes int secondKeyframe) throws IllegalStateException {
        return from(secondKeyframe, null);
    }

    /**
     * 对目标ViewGroup执行约束动画
     * @param view 必须是ConstraintLayout类型的ViewGroup
     */
    public void animate(ViewGroup view) {
        if (!(view instanceof ConstraintLayout)) {
            throw new IllegalArgumentException("Target view must be a ConstraintLayout");
        }
        mConstraintSet.applyTo((ConstraintLayout) view);
        mLayout = (ConstraintLayout) view;
        if(mTransition != null) {
            TransitionManager.beginDelayedTransition(mLayout, mTransition);
        } else {
            TransitionManager.beginDelayedTransition(mLayout);
        }
    }
}

调用示例(完全匹配Glide风格)

// 基础链式调用
MyAnimation.with(getContext())
           .from(R.layout.layout_start)
           .animate(myConstraintLayout);

// 带自定义过渡动画的调用
MyAnimation.with(getActivity())
           .from(R.layout.layout_start, new Slide(Gravity.RIGHT))
           .animate(myConstraintLayout);

关键细节说明

  1. 静态with方法:作为API的唯一入口,负责创建实例并完成基础初始化(上下文、ConstraintSet),直接返回实例供后续链式调用。
  2. 私有构造方法:避免外部通过new MyAnimation()创建实例,保证所有实例都通过静态入口初始化,防止出现未初始化上下文的无效实例。
  3. 链式调用的核心:from方法返回this(当前实例),这样就能在调用with后直接链式调用from,最后调用animate完成动画。
  4. 参数校验增强:在with和animate中添加参数合法性检查,提前抛出明确的异常,方便调试。

内容的提问来源于stack exchange,提问作者Mehdi Haghgoo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:30:43