Scene:字节跳动的轻量级导航和UI组合框架
1. 项目介绍
Scene 是由字节跳动开源的一个轻量级导航和 UI 组合框架,旨在解决传统 Android 开发中 Activity 和 Fragment 的诸多问题。它提供了一个简单、可靠且可扩展的 API,帮助开发者实现轻量级的导航和页面分割。
Scene 的主要特点包括:
- 简化导航栈管理,支持多导航栈
- 改进生命周期管理和分发
- 方便实现复杂的跨页面和共享元素动画
- 支持修改和自动恢复 Activity 和 Window 属性
- 支持在 Scene 之间交换数据,以及在 Scene 中请求和授予权限
- 支持保存和恢复 Scene 的 Parcelable 状态
- 无需 R8/Proguard 配置
2. 项目快速启动
添加依赖
首先,在项目的 build.gradle
文件中添加以下依赖:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
dependencies {
implementation 'com.github.bytedance:scene:latest_version'
implementation 'com.github.bytedance.scene:scene_navigation:latest_version'
implementation 'com.github.bytedance.scene:scene_ui:latest_version'
implementation 'com.github.bytedance.scene:scene_dialog:latest_version'
implementation 'com.github.bytedance.scene:scene_shared_element_animation:latest_version'
implementation 'com.github.bytedance.scene:scene_ktx:latest_version'
}
创建 SceneActivity
然后,创建一个继承自 SceneActivity
的 MainActivity
:
class MainActivity : SceneActivity() {
override fun getHomeSceneClass(): Class<out Scene> {
return MainScene::class.java
}
override fun supportRestore(): Boolean {
return false
}
}
创建 Scene
接下来,创建一个继承自 AppCompatScene
的 MainScene
:
class MainScene : AppCompatScene() {
private lateinit var mButton: Button
override fun onCreateContentView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val frameLayout = FrameLayout(requireSceneContext())
mButton = Button(requireSceneContext())
mButton.text = "Click"
frameLayout.addView(mButton, FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT))
return frameLayout
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
setTitle("Main")
toolbar?.navigationIcon = null
mButton.setOnClickListener {
navigationScene?.push(SecondScene())
}
}
}
创建另一个 SecondScene
类似:
class SecondScene : AppCompatScene() {
private val mId: Int by lazy { View.generateViewId() }
override fun onCreateContentView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val frameLayout = FrameLayout(requireSceneContext())
frameLayout.id = mId
return frameLayout
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
setTitle("Second")
add(mId, ChildScene(), "TAG")
}
}
最后,创建一个简单的 ChildScene
:
class ChildScene : Scene() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
val view = View(requireSceneContext())
view.setBackgroundColor(Color.GREEN)
return view
}
}
3. 应用案例和最佳实践
在实际应用中,Scene 框架可以用来替代传统的 Activity 和 Fragment,以实现更高效和灵活的页面导航和 UI 组合。以下是一些应用案例和最佳实践:
- 对于复杂的页面嵌套和动态页面,使用 Scene 替代 Fragment,以减少性能消耗和崩溃风险。
- 利用 Scene 提供的 API,实现自定义的页面动画和共享元素动画,提升用户体验。
- 通过 Scene 的状态保存和恢复功能,确保应用的稳定性和数据的完整性。
4. 典型生态项目
目前,Scene 框架已在字节跳动的多个项目中得到应用,例如 TikTok 的单活动架构。社区中也有许多开发者在使用 Scene 框架构建自己的项目,并在 GitHub 上分享经验和代码。以下是几个典型的生态项目:
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考