All Projects → bytedance → Scene

bytedance / Scene

Licence: apache-2.0
Android Single Activity Applications framework without Fragment.

Programming Languages

java
68154 projects - #9 most used programming language
kotlin
9241 projects

Projects that are alternatives of or similar to Scene

navigator
Annotation processor that eliminates navigation and Bundle boilerplate
Stars: ✭ 13 (-99.27%)
Mutual labels:  fragments, navigation, activity
Navigator
Android Multi-module navigator, trying to find a way to navigate into a modularized android project
Stars: ✭ 131 (-92.69%)
Mutual labels:  navigation, activity
Base
🍁 Base是针对于Android开发封装好一些常用的基类,主要包括通用的Adapter、Activity、Fragment、Dialog等、和一些常用的Util类,只为更简单。
Stars: ✭ 249 (-86.11%)
Mutual labels:  activity, fragments
kaptain
👨‍✈️ multi-module navigation on Android has never been so easier!
Stars: ✭ 24 (-98.66%)
Mutual labels:  navigation, activity
Fragnav
An Android library for managing multiple stacks of fragments
Stars: ✭ 1,379 (-23.09%)
Mutual labels:  navigation, fragments
Alligator
Alligator is a modern Android navigation library that will help to organize your navigation code in clean and testable way.
Stars: ✭ 287 (-83.99%)
Mutual labels:  navigation, fragments
Cicerone
🚦 Cicerone is a lightweight library that makes the navigation in an Android app easy.
Stars: ✭ 2,345 (+30.79%)
Mutual labels:  navigation, fragments
Flownav
Annotation processor that provides better navigation on android multi-modules projects 🛳.
Stars: ✭ 122 (-93.2%)
Mutual labels:  navigation, fragments
Androidpreferenceactivity
Provides an alternative implementation of Android's PreferenceActivity
Stars: ✭ 63 (-96.49%)
Mutual labels:  navigation, activity
Simple Stack
[ACTIVE] Simple Stack, a backstack library / navigation framework for simpler navigation and state management (for fragments, views, or whatevers).
Stars: ✭ 1,012 (-43.56%)
Mutual labels:  navigation, fragments
Flowr
FlowR is a wrapper class around the Fragment Manager.
Stars: ✭ 123 (-93.14%)
Mutual labels:  navigation, fragments
Tieguanyin
Activity Builder.
Stars: ✭ 113 (-93.7%)
Mutual labels:  activity, fragments
Mesh navigation
ROS Mesh Navigation Bundle
Stars: ✭ 114 (-93.64%)
Mutual labels:  navigation
Draggablemenu
A draggable menu that shows a thumbnail preview of an image grid
Stars: ✭ 117 (-93.47%)
Mutual labels:  navigation
Regretful Agent
PyTorch code for CVPR 2019 paper: The Regretful Agent: Heuristic-Aided Navigation through Progress Estimation
Stars: ✭ 113 (-93.7%)
Mutual labels:  navigation
Responsive Sidebar Navigation
An easy-to-integrate side, vertical navigation, ideal for dashboards and admin areas.
Stars: ✭ 111 (-93.81%)
Mutual labels:  navigation
Quickmenu
The new era of mobile navigation for the web, we're out of hamburgers.
Stars: ✭ 119 (-93.36%)
Mutual labels:  navigation
Pushy
Pushy is a responsive off-canvas navigation menu using CSS transforms & transitions.
Stars: ✭ 1,488 (-17.01%)
Mutual labels:  navigation
Wzrootnavigationcontroller
Stars: ✭ 111 (-93.81%)
Mutual labels:  navigation
Navbot
Using RGB Image as Visual Input for Mapless Robot Navigation
Stars: ✭ 111 (-93.81%)
Mutual labels:  navigation

Scene

简体中文版说明 >>>

GitHub license Maven metadata URL API

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

  1. Simple and convenient navigation and stack management, support multi-stack
  2. Improved lifecycle management and distribution
  3. Easier to implement complex cut-scenes animation
  4. Support properties modification and recovery of Activity and Window
  5. Support return value between Scenes, support request and grant permissions in Scene
  6. Support save and recovery state of Scene

Download the Demo

Apps using Scene

xigua douyin lv toutiao
Xigua Video Tik Tok CapCut Toutiao

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. 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.
  2. 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.
  3. The support of animation is poor, Z-axis order cannot be guaranteed when switching
  4. Navigation management is weak, there is no advanced stack management except for basic push and pop
  5. The lifecycle of Fragment in native Fragment and Support-v4 packages is not exactly the same

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 to your build.gradle:

implementation 'com.bytedance.scene:scene:$latest_version'
implementation 'com.bytedance.scene:scene-ui:$latest_version'
implementation 'com.bytedance.scene:scene-shared-element-animation:$latest_version'
implementation 'com.bytedance.scene:scene-ktx:$latest_version'

Scene has 2 subclasses: NavigationScene and GroupScene:

  1. NavigationScene supports navigation
  2. GroupScene supports ui composition
Scene NavigationScene GroupScene

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

Migration to Scene

A new app can use Scene by directly inheriting the SceneActivity.

But if your existing Activity is not convenient to change the inheritance relationship, you can directly using SceneDelegate to handle Scenes refer to the code of SceneActivity.

Take the homepage migration plan of XiguaVideo as an example:

First, declares a layout in the XML of the home Activity for storing the Scene: scene_container

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
 
    <...>
    
    <...>
 
    <!-- The above is the existing layout of the Activity -->
 
    <FrameLayout
        android:id="@+id/scene_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
 
</merge>

Then create a transparent Scene as the root Scene:

public static class EmptyHolderScene extends Scene {
    @NonNull
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return new View(getActivity());
    }
 
    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        getView().setBackgroundColor(Color.TRANSPARENT);
    }
 
    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        ArticleMainActivity activity = (ArticleMainActivity) requireActivity();
        activity.createSceneLifecycleCallbacksToDispatchLifecycle(getNavigationScene());
    }
}

Bind this transparent Scene to R.id.scene_container:

mSceneActivityDelegate = NavigationSceneUtility.setupWithActivity(this, R.id.scene_container, null,
        new NavigationSceneOptions().setDrawWindowBackground(false)
                .setFixSceneWindowBackgroundEnabled(true)
                .setSceneBackground(R.color.material_default_window_bg)
                .setRootScene(EmptyHolderScene.class, null), false);

In essence, there is a transparent Scene cover on the Activity, but it is not visually visible.

Then provide the Push method in the Activity:

public void push(@NonNull Class<? extends Scene> clazz, @Nullable Bundle argument, @Nullable PushOptions pushOptions) {
    if (mSceneActivityDelegate != null) {
        mSceneActivityDelegate.getNavigationScene().push(clazz, argument, pushOptions);
    }
}

This completes the basic migration, you can open a new Scene page directly in this Activity.

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 Scene to implement the dialog instead of a system Dialog.

SurfaceView and TextureView

When the Scene is popping, the animation will be executed after the Scene life cycle is executed. However, if there is a SurfaceView or a TextureView, this process will cause the SurfaceView/TextureView to turn to black.

You can get and re-assign the Surface before the animation end to avoid issues on TextureView, and capture the last bitmap and set to a ImageView to avoid issues on SurfaceView.

Status Bar related

There is no official API of notch screen before Android P, and each vendor has its own implementation.

If you try to hide the status bar with WindowFlag or View's UiVisibility, it will trigger the re-layout of the entire Activity.

This may causes the layout change of the Scene inside, and the behaviors may be not as expected in some cases.

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.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].