如何无需初始化调用类公共方法?仿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);
关键细节说明
- 静态with方法:作为API的唯一入口,负责创建实例并完成基础初始化(上下文、ConstraintSet),直接返回实例供后续链式调用。
- 私有构造方法:避免外部通过
new MyAnimation()创建实例,保证所有实例都通过静态入口初始化,防止出现未初始化上下文的无效实例。 - 链式调用的核心:
from方法返回this(当前实例),这样就能在调用with后直接链式调用from,最后调用animate完成动画。 - 参数校验增强:在
with和animate中添加参数合法性检查,提前抛出明确的异常,方便调试。
内容的提问来源于stack exchange,提问作者Mehdi Haghgoo
相关产品推荐
相关产品推荐

