Android Transition ChangeBounds切换至小场景时动画失效问题求助
TransitionManager双向切换动画失效问题解决
问题出在两个Scene对应的布局里的LinearLayout是独立的View实例,ChangeBounds过渡无法将它们识别为同一个动画目标。从expandScene切换到smallScene时,旧的View被直接移除,新的View被添加,Transition找不到前后可关联的View,因此无法触发动画。
解决方案一:给两个布局的View设置相同ID
Transition默认通过View的id来匹配前后Scene中的元素,只要让两个布局里的LinearLayout拥有相同的id,Transition就能识别它们是同一个目标,从而执行ChangeBounds动画。
修改small_view.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/content_layout" android:layout_gravity="center_vertical" android:layout_width="100dp" android:layout_height="100dp" android:background="#AFB2D1"></LinearLayout>
修改expand_view.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/content_layout" android:layout_gravity="center_vertical" android:layout_width="200dp" android:layout_height="100dp" android:background="#ff5344"> </LinearLayout>
修改后无需改动Java代码,双向切换都会触发ChangeBounds动画。
解决方案二:使用单View修改LayoutParams替代Scene切换
这种方式更简洁,避免多View实例的问题,直接在同一个View上修改尺寸,通过TransitionManager.beginDelayedTransition触发动画:
- 修改activity_main.xml,添加固定的内容View:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/viewcontainer" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_vertical"> <LinearLayout android:id="@+id/content_layout" android:layout_width="100dp" android:layout_height="100dp" android:background="#AFB2D1"/> </LinearLayout>
- 修改MainActivity代码:
import android.graphics.Color; import android.os.Bundle; import android.widget.LinearLayout; import androidx.appcompat.app.AppCompatActivity; import androidx.transition.ChangeBounds; import androidx.transition.TransitionManager; import androidx.transition.TransitionSet; import com.example.yourpackage.databinding.ActivityMainBinding; public class MainActivity extends AppCompatActivity { private ActivityMainBinding binding; boolean toggler = true; private LinearLayout contentLayout; private final Transition mTransition = new TransitionSet().addTransition(new ChangeBounds()) .setDuration(1000); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = ActivityMainBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); contentLayout = findViewById(R.id.content_layout); binding.fab.setOnClickListener(view -> { // 触发过渡动画 TransitionManager.beginDelayedTransition(binding.viewcontainer, mTransition); LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) contentLayout.getLayoutParams(); if (toggler) { params.width = getResources().getDimensionPixelSize(R.dimen.small_width); contentLayout.setBackgroundColor(Color.parseColor("#AFB2D1")); } else { params.width = getResources().getDimensionPixelSize(R.dimen.expand_width); contentLayout.setBackgroundColor(Color.parseColor("#ff5344")); } contentLayout.setLayoutParams(params); toggler = !toggler; }); } }
- 在res/values/dimens.xml中定义宽度:
<dimen name="small_width">100dp</dimen> <dimen name="expand_width">200dp</dimen>
这种方式无需切换Scene,直接修改现有View的属性,动画逻辑更清晰,也不会出现View匹配问题。
内容的提问来源于stack exchange,提问作者yanqi06
相关产品推荐
相关产品推荐

