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

Android Fragment共享元素返回过渡动画不生效问题

修复Fragment返回共享元素过渡失效问题

1. 修正返回按钮逻辑,改用popBackStack替代replace

当前ShowElementFragment的返回按钮直接替换为MainFragment,破坏了Fragment栈结构,导致系统无法触发返回共享元素过渡。应改为弹出回退栈回到上一个Fragment:

showelement_backarrow.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        getActivity().getSupportFragmentManager().popBackStack();
    }
});

2. 保存并恢复Fragment A的RecyclerView滚动位置

ViewPager2会销毁不可见Fragment,返回时RecyclerView可能重新加载,导致共享元素位置丢失。需在tab1_anime类中添加状态保存逻辑:

// 添加成员变量保存滚动状态
private Parcelable recyclerViewState;

// 保存状态
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
    recyclerViewState = recycler_view.getLayoutManager().onSaveInstanceState();
    outState.putParcelable("recycler_state", recyclerViewState);
}

// 恢复状态
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    if (savedInstanceState != null) {
        recyclerViewState = savedInstanceState.getParcelable("recycler_state");
        if (recyclerViewState != null) {
            recycler_view.getLayoutManager().onRestoreInstanceState(recyclerViewState);
        }
    }
}

3. 确保Fragment A的共享元素返回时状态正确

在tab1_anime的onViewCreated中延迟返回过渡,直到RecyclerView布局完成,避免共享元素未加载:

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    // ...恢复滚动状态的代码
    
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        postponeEnterTransition();
        recycler_view.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @Override
            public boolean onPreDraw() {
                recycler_view.getViewTreeObserver().removeOnPreDrawListener(this);
                startPostponedEnterTransition();
                return true;
            }
        });
    }
}

同时在Adapter的onBindViewHolder中确保每个Item的共享元素transitionName正确:

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
    // ...其他绑定逻辑
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        holder.itemView.findViewById(R.id.main_image).setTransitionName("transition" + position);
    }
}

4. 调整Fragment B的过渡配置

避免直接修改Activity全局过渡,改为设置Fragment自身的返回过渡,并确保共享元素图片加载完成后启动过渡:

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        setSharedElementReturnTransition(TransitionInflater.from(getContext()).inflateTransition(R.transition.default_transition));
        setReturnTransition(TransitionInflater.from(getContext()).inflateTransition(android.R.transition.no_transition));
    }
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_show_element, parent, false);
    // ...其他初始化逻辑
    
    // 修改Glide加载逻辑,确保图片加载完成后启动过渡
    Glide.with(this)
            .load(elemento.image_url)
            .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
            .skipMemoryCache(false)
            .listener(new RequestListener<Drawable>() {
                @Override
                public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                    startPostponedEnterTransition();
                    return false;
                }

                @Override
                public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                    startPostponedEnterTransition();
                    return false;
                }
            })
            .into(showelement_image);
    
    // ...返回view的代码
}

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        postponeEnterTransition();
    }
}

5. 优化showFragmentWithTransition的过渡设置

确保当前Fragment和新Fragment的过渡配置正确,避免冲突:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    current.setSharedElementReturnTransition(TransitionInflater.from(this).inflateTransition(R.transition.default_transition));
    current.setExitTransition(TransitionInflater.from(this).inflateTransition(android.R.transition.no_transition));

    newFragment.setSharedElementEnterTransition(TransitionInflater.from(this).inflateTransition(R.transition.default_transition));
    newFragment.setEnterTransition(TransitionInflater.from(this).inflateTransition(android.R.transition.no_transition));
}

内容的提问来源于stack exchange,提问作者C-Gian

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 23:35:42