Android Studio中如何实现从按钮展开至新Activity的动画转场(Java代码实现)
嘿Stefan,我刚好做过类似的转场效果,这就给你一步步拆解怎么实现Waze/Youtube那种从按钮展开到搜索页的动画,全用Java写哈:
实现从按钮到搜索页的转场动画(Java版)
1. 先配置共享元素与转场动画资源
这种从按钮展开到搜索框的效果,用共享元素转场最贴合——让原页面的按钮和搜索页的EditText“共享”同一个视觉元素,转场时看起来就是按钮变形展开成搜索框,同时页面自然过渡。
第一步:给两个元素设置相同的transitionName
在原页面布局(比如activity_main.xml)的按钮上添加:
<Button android:id="@+id/search_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="搜索" android:transitionName="search_transition" />
在搜索页布局(activity_search.xml)的EditText上添加完全一致的transitionName:
<EditText android:id="@+id/search_et" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="输入搜索内容" android:transitionName="search_transition" />
第二步:创建转场动画文件
在res目录下新建transition文件夹,然后创建expand_from_button.xml文件,定义转场时的动画逻辑:
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android" android:duration="300"> <!-- 可自定义动画时长,单位毫秒 --> <changeBounds /> <!-- 处理元素边界大小/位置变化 --> <changeTransform /> <!-- 处理缩放/旋转等变形效果 --> <fade android:fadingMode="fade_out" /> <!-- 背景的淡入淡出过渡 --> </transitionSet>
2. 原Activity中启动带转场的搜索页
在原Activity(比如MainActivity.java)里,给按钮设置点击事件,用ActivityOptions配置转场参数:
Button searchBtn = findViewById(R.id.search_btn); searchBtn.setOnClickListener(v -> { Intent intent = new Intent(MainActivity.this, SearchActivity.class); // 配置共享元素转场选项 ActivityOptions transitionOptions = ActivityOptions.makeSceneTransitionAnimation( MainActivity.this, v, // 触发转场的按钮View "search_transition" // 必须和布局里的transitionName完全一致 ); // 启动Activity并等待返回搜索结果 startActivityForResult(intent, 100, transitionOptions.toBundle()); });
3. 搜索页配置转场与结果返回
在SearchActivity.java中,先启用转场动画支持,再处理搜索完成后的返回逻辑:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_search); // 启用窗口转场效果支持 getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); // 设置进入和退出转场动画 getWindow().setEnterTransition(TransitionInflater.from(this).inflateTransition(R.transition.expand_from_button)); getWindow().setExitTransition(TransitionInflater.from(this).inflateTransition(R.transition.expand_from_button)); EditText searchEt = findViewById(R.id.search_et); Button submitBtn = findViewById(R.id.submit_btn); submitBtn.setOnClickListener(v -> { String searchResult = searchEt.getText().toString(); // 携带搜索结果返回原页面 Intent resultIntent = new Intent(); resultIntent.putExtra("SEARCH_RESULT", searchResult); setResult(RESULT_OK, resultIntent); // 用这个方法触发退出转场动画,替代普通的finish() finishAfterTransition(); }); }
4. 原Activity接收搜索结果
在MainActivity.java中重写onActivityResult方法,处理返回的搜索结果:
@Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 100 && resultCode == RESULT_OK) { if (data != null) { String result = data.getStringExtra("SEARCH_RESULT"); // 这里可以把结果展示出来,比如更新页面上的TextView TextView resultTv = findViewById(R.id.result_tv); resultTv.setText("搜索结果:" + result); } } }
几个关键注意点
- 确保你的App使用Material Design主题(比如
Theme.MaterialComponents.Light.NoActionBar),转场动画需要依赖Material主题的支持。 - 如果需要更个性化的动画,可以调整
transition文件里的参数,比如修改android:interpolator设置动画的快慢节奏,或者添加slide动画配合。 - 如果是用AndroidX库,推荐用
registerForActivityResult替代startActivityForResult,写法更现代,不过上面的代码兼容旧版本Android系统。
内容的提问来源于stack exchange,提问作者Munteanu Stefan
相关产品推荐
相关产品推荐

