Voltar ao ranking

bytedance/scene

Java

Android Single Activity Framework compatible with Fragment.

navigationfragmentsactivitysingle-activity-patternandroidandroid-architectureandroid-librarysingle-activity-frameworksingle-activity
Crescimento de estrelas
Estrelas
2.5k
Forks
220
Crescimento semanal
Issues
4
1k2k
jan. de 2023mar. de 2024mai. de 2025jul. de 2026
ArtefatosMavengit clone https://github.com/bytedance/scene.git
README

Scene Framework

Android Single Activity Framework compatible with Fragment.


GitHub license API

Scene is a lightweight library of navigation and UI composition based on view.

  • ✅ Fully compatible with the Jetpack Fragment framework
  • ✅ Simple navigation stack management, with support for multiple navigation stacks
  • ✅ Enhanced lifecycle management and event distribution
  • ✅ Simplifies complex cross-page and shared element animations
  • ✅ Supports modification and automatic restoration of Activity and Window properties
  • ✅ Enables data exchange between Scenes, including permission requests and grants within a Scene
  • ✅ Supports saving and restoring Scene state via Parcelable
  • ✅ No R8/Proguard configuration required

Download the latest Sample APK

Introduction

Scene is designed to replace the use of Activities and Fragments for navigation and page segmentation in Android applications. It addresses the following issues:

  1. Activity, Poor performance, with the average startup time of even an empty Activity exceeding 100ms.
  2. Fragment, Poor compatibility, Google Navigation Component destroys a Fragment’s view when it becomes invisible.

Scene provides a simple, reliable, and extensible API for lightweight, high-performance navigation and page management. We also offer a set of migration solutions to help developers gradually transition from Activities and Fragments to Scene.

Get Started

Add it to your root build.gradle at the end of repositories:

//build.gradle
allprojects {
	repositories {
		...
		maven { url 'https://jitpack.io' }
	}
}
//or settings.gradle.kts
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        ...
        maven { url = uri("https://jitpack.io") }
    }
}

Add it to your build.gradle, latest_version :

dependencies {
	implementation 'com.github.bytedance:scene:$latest_version'
        //or
	implementation 'com.github.bytedance.scene: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_fragment:$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'
}
//or build.gradle.kts
dependencies {
    implementation ("com.github.bytedance:scene:$latest_version")
    //or
    implementation ("com.github.bytedance.scene: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_fragment:$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")
}

For simple usage, just let your Activity inherit from SceneActivity:

class MainActivity : SceneActivity() {
    override fun getHomeSceneClass(): Class<out Scene> {
        return MainScene::class.java
    }

    override fun supportRestore(): Boolean {
        return false
    }
}

A simple Scene example:

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())
        }
    }
}

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")
    }
}

class ChildScene : Scene() {
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup, savedInstanceState: Bundle?): View {
        val view = View(requireSceneContext())
        view.setBackgroundColor(Color.GREEN)
        return view
    }
}

Fragment

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.bytedance.scene.fragment.getNavigationScene
import com.bytedance.scene.fragment.push

class YourFragment : Fragment() {
   override fun onCreateView(
      inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
   ): View {
      return View(requireContext())
   }

   override fun onActivityCreated(savedInstanceState: Bundle?) {
      super.onActivityCreated(savedInstanceState)
      val navigationScene = getNavigationScene()
      requireView().setOnClickListener {
         navigationScene?.push(YourFragment())
      }
   }
}

Compose

https://github.com/bytedance/scene/wiki/Compose

Sample

Scene sample is built using Gradle. On Linux, simply run:

./gradlew installDebug

Document

https://github.com/bytedance/scene/wiki

Issues

Dialog

A normal Dialog's Window is independent and in front of the Activity's Window, so if try to push a Scene in a opening Dialog, it will cause the Scene to appear behind it. You can close the dialog box when click, or use transparent Scene to implement the dialog instead of a system Dialog.

Apps using Scene

xigua xigua douyin toutiao kesong
TikTok Douyin Xigua Video Toutiao KeSong

License

Copyright (c) 2019 ByteDance Inc

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Repositórios relacionados
react-navigation/react-navigation

Routing and navigation for React Native and Web apps

TypeScriptnpmreactreact-native
reactnavigation.org
24.5k5.1k
organicmaps/organicmaps

🍃 Organic Maps is a free Android & iOS offline maps app for more than 6M travelers, tourists, hikers, and cyclists. It uses crowd-sourced OpenStreetMap data and is developed with love by the community. No ads, no tracking, no data collection, no crapware. Please donate to support the development!

C++appOtheriosandroid
organicmaps.app
14.8k1.5k
alibaba/ARouter

💪 A framework for assisting in the renovation of Android componentization (帮助 Android App 进行组件化改造的路由框架)

JavaMavenlibraryApache License 2.0androidrouter
14.5k2.6k
wix/react-native-navigation

A complete native navigation solution for React Native

MDXMIT Licensereact-nativenavigation
wix.github.io/react-native-navigation/
13.2k2.6k
gyf-dev/ImmersionBar

android 4.4以上沉浸式状态栏和沉浸式导航栏管理,适配横竖屏切换、刘海屏、软键盘弹出等问题,可以修改状态栏字体颜色和导航栏图标颜色,以及不可修改字体颜色手机的适配,适用于Activity、Fragment、DialogFragment、Dialog,PopupWindow,一句代码轻松实现,以及对bar的其他设置,详见README。简书请参考:http://www.jianshu.com/p/2a884e211a62

JavaMavenlibraryApache License 2.0statusbarnavigationbar
11.5k1.9k
recastnavigation/recastnavigation

Industry-standard navigation-mesh toolset for games

C++zlib Licenseaicrowd-simulation
recastnav.com
7.8k1.8k
WebStackPage/WebStackPage.github.io

❤️静态响应式网址导航网站 - webstack.cc

CSSnpmappMIT Licensewebstackbookmark
webstack.cc
7.3k2.1k
Devlight/NavigationTabBar

Navigation tab bar with colorful interactions.

JavaMavenlibraryApache License 2.0navigationbar
4.9k914
ros-navigation/navigation2

ROS 2 Navigation Framework and System

C++libraryOtherros2navigation
nav2.org
4.5k1.9k
telly/TLYShyNavBar

Unlike all those arrogant UINavigationBar, this one is shy and humble! Easily create auto-scrolling navigation bars!

Objective-ClibraryMIT Licenseuinavigationcontrollernavigation
3.7k419
hegaojian/JetpackMvvm

:chicken::basketball:JetpackMvvm 是一个基于 Jetpack 架构组件构建的 Android MVVM 快速开发框架,旨在帮助开发者快速搭建高质量、可维护、可扩展的应用。

KotlinlibraryApache License 2.0mvvmjetpack
github.com/hegaojian/JetpackMvvm
3.6k690
justinmk/vim-sneak

The missing motion for Vim :athletic_shoe:

Vim ScriptMIT Licensevimneovim
vim.org/scripts/script.php
3.5k90