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

Android RecyclerView共享元素返回过渡异常:仅第11项及以上双TextView过渡正常

问题原因

最可能的原因是RecyclerView可见区域内的item(前10项)在返回过渡时,details TextView的布局状态未完全就绪,导致系统无法正确匹配共享元素;而第11项及以上的item在跳转时处于屏幕外,系统会自动生成快照来执行过渡,不受实际View布局状态的影响。此外,默认的change_image_transform过渡更适配ImageView,对TextView的布局变化支持不足,也会加剧可见item的过渡异常。


解决方案

1. 推迟返回过渡直到RecyclerView布局完成

在包含RecyclerView的列表页Fragment中添加以下代码,确保过渡在RecyclerView的item完全布局后再执行:

@Override
public void onResume() {
    super.onResume();
    postponeEnterTransition();
    recyclerView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
        @Override
        public boolean onPreDraw() {
            recyclerView.getViewTreeObserver().removeOnPreDrawListener(this);
            startPostponedEnterTransition();
            return true;
        }
    });
}

2. 使用适配TextView的共享元素过渡

创建专门针对TextView的过渡配置文件res/transition/change_text_transform.xml:

<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
    <changeBounds android:duration="300"/>
    <changeTransform android:duration="300"/>
    <changeClipBounds android:duration="300"/>
</transitionSet>

然后在目标Fragment的onCreate方法中替换原过渡:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
    sp = PreferenceManager.getDefaultSharedPreferences(requireContext());
    Transition textTransition = TransitionInflater.from(requireContext()).inflateTransition(R.transition.change_text_transform);
    setSharedElementEnterTransition(textTransition);
    setSharedElementReturnTransition(textTransition);
    // 移除不必要的exitTransition,避免干扰共享元素过渡
    // setExitTransition(...);
}

3. 优化transitionName的唯一性(可选)

将transitionName从基于position改为基于item的唯一ID,避免列表数据变化导致position改变时的过渡异常:

// 在Adapter的onBindViewHolder中
ViewCompat.setTransitionName(holder.noteTitleText, "title_" + noteItem.getId());
ViewCompat.setTransitionName(holder.noteDetailsText, "details_" + noteItem.getId());

4. 调整FragmentTransaction的动画设置

移除可能干扰共享元素过渡的全局动画,或者明确指定pop动画:

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.setReorderingAllowed(true);
ft.addSharedElement(tvTitle, ViewCompat.getTransitionName(tvTitle));
ft.addSharedElement(tvDetails, ViewCompat.getTransitionName(tvDetails));
// 仅为非共享元素设置动画,或直接移除全局动画
// ft.setCustomAnimations(R.anim.fade_in, R.anim.fade_out, R.anim.fade_in, R.anim.fade_out);
ft.addToBackStack(fragmentShowNote.getClass().getSimpleName());
ft.replace(R.id.content_frame, fragmentShowNote);
ft.commit();

验证步骤

  1. 优先添加推迟过渡的代码,这是解决可见item过渡异常最直接的方案;
  2. 如果问题仍存在,替换为适配TextView的过渡配置;
  3. 最后检查transitionName和FragmentTransaction的动画设置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 09:45:41