MCPcopy Index your code
hub / github.com/bytedance/scene

github.com/bytedance/scene @v1.3.4

Chat with this repo
repository ↗ · DeepWiki ↗ · release v1.3.4 ↗ · + Follow
5,047 symbols 20,345 edges 515 files 692 documented · 14%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README
<h1>Scene Framework</h1>

Android Single Activity Framework compatible with Fragment.

GitHub license API

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

  • [x] Compatible with Fragment framework
  • [x] Simple navigation stack management, support multi-navigation-stack
  • [x] Improved lifecycle management and distribution
  • [x] Easier to implement complex cross-page and shared-element animation
  • [x] Supports modification and automatic restoration of Activity and Window properties
  • [x] Support exchange data between Scenes, support request and grant permissions in Scene
  • [x] Support save and recovery parcable state of Scene
  • [x] No R8 / Proguard configuration required

Download the latest Sample APK

Introduction

Scene is designed to replace the use of Activity and Fragment on navigation and page segmentation.

The main problems of Activity: 1. The stack management of Activity is weak, Intent and LaunchMode are confusing, even if various of hacks still can't completely avoid issues like black screen 2. The performance of Activity is poor, average startup time of an empty Activity is more than 60ms (on Samsung S9) 3. Because the Activity is forced to support states recovery, it causes some problems: - Transition animation has limited ability, difficult to implement complex interactive animations. - Shared-element animation is basically unavailable, and there are some crashes unresolved in Android Framework. - Every time starting a new Activity, onSaveInstance() of the previous Activity must be executed completely first, which will lose much performance. 4. Activity relies on the Manifest file to cause injection difficulties, which also result in that Activity dynamics requires a variety of hacks

The main problems of Fragment: 1. Google Navigation Component will destory Fragment' view when it is invisible 2. There are many crashes that the Google official can't solve for a long time. Even if you don't use Fragment, it may still trigger a crash in the OnBackPressed() of AppCompatActivity. 3. The add/remove/hide/show operation is not executed immediately. With nest Fragments even if you use commitNow(), the status update of the sub Fragments cannot be guaranteed.

The Scene framework tries to solve these problems of the Activity and Fragment mentioned above.

Provides a simple, reliable, and extensible API for a lightweight navigation and page segmentation solution

At the same time, we provide a series of migration solutions to help developers gradually migrate from Activity and Fragment 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_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_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

copy FragmentScene to your project

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 parentScene = ViewUtlity.findScene(this.view()) as YourFragmentScene
    }
}

class YourFragmentScene : FragmentScene() {
    override val fragmentClass = YourFragment::class.java
}

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.

Extension points exported contracts — how you extend this code

SceneComponentFactory (Interface)
Created by JiangQi on 10/25/18. Pay attention, this method will be invoked more than once because of Scene applicati [18 …
library/scene/src/main/java/com/bytedance/scene/SceneComponentFactory.java
ActivityCompatibleBehavior (Interface)
Created by jiangqi on 2024/5/21 @author jiangqi@bytedance.com [14 implementers]
library/scene_navigation/src/main/java/com/bytedance/scene/interfaces/ActivityCompatibleBehavior.java
SceneNavigationContainer (Interface)
Created by JiangQi on 9/20/18. [3 implementers]
library/scene_ui/src/main/java/com/bytedance/scene/ui/SceneNavigationContainer.java
OnPrepareListViewListener (Interface)
Interface definition for a callback to be invoked before the ListView will be bound to an adapter.
library/scene_dialog/src/main/java/com/bytedance/scene/dialog/alert/AlertController.java
OnItemCLickListener (Interface)
(no doc) [2 implementers]
demo/src/main/java/com/bytedance/scenedemo/animation/sharedelement/ComposedAdapter.java
ChildSceneLifecycleCallbacks (Interface)
Created by JiangQi on 8/1/18. method invoke order: 1. onPreSceneMethod(invoke before Scene.onMethod) 2. onSuperScene [7 …
library/scene/src/main/java/com/bytedance/scene/interfaces/ChildSceneLifecycleCallbacks.java
Function (Interface)
@hide [8 implementers]
library/scene_navigation/src/main/java/com/bytedance/scene/interfaces/Function.java
Callback (Interface)
(no doc)
library/scene_ui/src/main/java/com/bytedance/scene/MessengerHandler.java

Core symbols most depended-on inside this repo

getState
called by 1135
library/scene/src/main/java/com/bytedance/scene/Scene.java
getView
called by 452
library/scene_dialog/src/main/java/com/bytedance/scene/dialog/alert/AlertController.java
get
called by 387
library/scene_navigation/src/main/java/com/bytedance/scene/animation/interaction/progressanimation/InteractionAnimation.java
requireSceneContext
called by 319
library/scene/src/main/java/com/bytedance/scene/Scene.java
getView
called by 283
library/scene/src/main/java/com/bytedance/scene/Scene.java
add
called by 281
library/scene_shared_element_animation/src/main/java/com/bytedance/scene/animation/interaction/transition/ViewOverlayImpl.java
getSceneList
called by 274
library/scene_navigation/src/main/java/com/bytedance/scene/navigation/NavigationScene.java
push
called by 271
library/scene_navigation/src/main/java/com/bytedance/scene/navigation/NavigationScene.java

Shape

Method 4,154
Class 770
Function 59
Interface 59
Enum 5

Languages

Java83%
Kotlin17%

Modules by API surface

library/scene_navigation/src/main/java/com/bytedance/scene/navigation/NavigationScene.java137 symbols
library/scene/src/main/java/com/bytedance/scene/Scene.java123 symbols
library/scene_navigation/src/main/java/com/bytedance/scene/navigation/NavigationSceneManager.java122 symbols
library/scene/src/main/java/com/bytedance/scene/group/GroupSceneManager.java92 symbols
library/scene/src/main/java/com/bytedance/scene/group/GroupScene.java79 symbols
library/scene_dialog/src/main/java/com/bytedance/scene/dialog/alert/AlertDialogScene.java63 symbols
library/scene_navigation/src/test/java/com/bytedance/scene/navigation/SaveAndRestoreTests.java58 symbols
library/scene_dialog/src/main/java/com/bytedance/scene/dialog/alert/AlertController.java49 symbols
library/scene/src/test/java/com/bytedance/scene/GroupSceneSeparateLifecycleTests.java49 symbols
library/scene_navigation/src/main/java/com/bytedance/scene/interfaces/PushOptions.java45 symbols
library/scene/src/test/java/com/bytedance/scene/saveandrestore/OnSaveInstanceStateChildSceneLifecycleCallbacksTests.java42 symbols
library/scene_navigation/src/main/java/com/bytedance/scene/navigation/NavigationSceneOptions.java41 symbols

For agents

$ claude mcp add scene \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact