From 2310dfc2de619e28876c66fd12f40fbe77083161 Mon Sep 17 00:00:00 2001 From: <> Date: Tue, 13 Feb 2024 19:05:38 +0000 Subject: [PATCH] Deployed 430830b with MkDocs version: 1.5.3 --- .nojekyll | 0 404.html | 1133 +++ apps/childaware/index.html | 1327 ++++ apps/configuration/index.html | 1287 ++++ apps/lifecycle/index.html | 1314 ++++ apps/plugins/index.html | 1407 ++++ apps/structure/index.html | 1375 ++++ assets/favicon.svg | 1 + assets/images/favicon.png | Bin 0 -> 1870 bytes assets/javascripts/bundle.8fd75fb4.min.js | 29 + assets/javascripts/bundle.8fd75fb4.min.js.map | 7 + assets/javascripts/lunr/min/lunr.ar.min.js | 1 + assets/javascripts/lunr/min/lunr.da.min.js | 18 + assets/javascripts/lunr/min/lunr.de.min.js | 18 + assets/javascripts/lunr/min/lunr.du.min.js | 18 + assets/javascripts/lunr/min/lunr.el.min.js | 1 + assets/javascripts/lunr/min/lunr.es.min.js | 18 + assets/javascripts/lunr/min/lunr.fi.min.js | 18 + assets/javascripts/lunr/min/lunr.fr.min.js | 18 + assets/javascripts/lunr/min/lunr.he.min.js | 1 + assets/javascripts/lunr/min/lunr.hi.min.js | 1 + assets/javascripts/lunr/min/lunr.hu.min.js | 18 + assets/javascripts/lunr/min/lunr.hy.min.js | 1 + assets/javascripts/lunr/min/lunr.it.min.js | 18 + assets/javascripts/lunr/min/lunr.ja.min.js | 1 + assets/javascripts/lunr/min/lunr.jp.min.js | 1 + assets/javascripts/lunr/min/lunr.kn.min.js | 1 + assets/javascripts/lunr/min/lunr.ko.min.js | 1 + assets/javascripts/lunr/min/lunr.multi.min.js | 1 + assets/javascripts/lunr/min/lunr.nl.min.js | 18 + assets/javascripts/lunr/min/lunr.no.min.js | 18 + assets/javascripts/lunr/min/lunr.pt.min.js | 18 + assets/javascripts/lunr/min/lunr.ro.min.js | 18 + assets/javascripts/lunr/min/lunr.ru.min.js | 18 + assets/javascripts/lunr/min/lunr.sa.min.js | 1 + .../lunr/min/lunr.stemmer.support.min.js | 1 + assets/javascripts/lunr/min/lunr.sv.min.js | 18 + assets/javascripts/lunr/min/lunr.ta.min.js | 1 + assets/javascripts/lunr/min/lunr.te.min.js | 1 + assets/javascripts/lunr/min/lunr.th.min.js | 1 + assets/javascripts/lunr/min/lunr.tr.min.js | 18 + assets/javascripts/lunr/min/lunr.vi.min.js | 1 + assets/javascripts/lunr/min/lunr.zh.min.js | 1 + assets/javascripts/lunr/tinyseg.js | 206 + assets/javascripts/lunr/wordcut.js | 6708 +++++++++++++++++ .../workers/search.b8dbb3d2.min.js | 42 + .../workers/search.b8dbb3d2.min.js.map | 7 + assets/logo.png | Bin 0 -> 13986 bytes assets/stylesheets/main.f2e4d321.min.css | 1 + assets/stylesheets/main.f2e4d321.min.css.map | 1 + assets/stylesheets/palette.06af60db.min.css | 1 + .../stylesheets/palette.06af60db.min.css.map | 1 + faq/index.html | 1626 ++++ how-to-use-appyx/codelabs/index.html | 1275 ++++ how-to-use-appyx/coding-challenges/index.html | 1253 +++ how-to-use-appyx/quick-start/index.html | 1558 ++++ how-to-use-appyx/sample-apps/index.html | 1306 ++++ index.html | 1396 ++++ navigation/composable-navigation/index.html | 1296 ++++ navigation/deep-linking/index.html | 1210 +++ navigation/explicit-navigation/index.html | 1541 ++++ navigation/implicit-navigation/index.html | 1404 ++++ navigation/model-driven-navigation/index.html | 1304 ++++ navmodel/backstack/index.html | 1722 +++++ navmodel/cards/index.html | 1473 ++++ navmodel/custom/index.html | 1471 ++++ navmodel/index.html | 1291 ++++ navmodel/promoter/index.html | 1393 ++++ navmodel/spotlight/index.html | 1623 ++++ navmodel/tiles/index.html | 1466 ++++ news/index.html | 1341 ++++ releases/changelog/index.html | 1892 +++++ releases/downloads/index.html | 1349 ++++ search/search_index.json | 1 + sitemap.xml | 143 + sitemap.xml.gz | Bin 0 -> 456 bytes stylesheets/extra.css | 22 + ui/children-view/index.html | 1343 ++++ ui/transitions/index.html | 1350 ++++ 79 files changed, 48183 insertions(+) create mode 100644 .nojekyll create mode 100644 404.html create mode 100644 apps/childaware/index.html create mode 100644 apps/configuration/index.html create mode 100644 apps/lifecycle/index.html create mode 100644 apps/plugins/index.html create mode 100644 apps/structure/index.html create mode 100644 assets/favicon.svg create mode 100644 assets/images/favicon.png create mode 100644 assets/javascripts/bundle.8fd75fb4.min.js create mode 100644 assets/javascripts/bundle.8fd75fb4.min.js.map create mode 100644 assets/javascripts/lunr/min/lunr.ar.min.js create mode 100644 assets/javascripts/lunr/min/lunr.da.min.js create mode 100644 assets/javascripts/lunr/min/lunr.de.min.js create mode 100644 assets/javascripts/lunr/min/lunr.du.min.js create mode 100644 assets/javascripts/lunr/min/lunr.el.min.js create mode 100644 assets/javascripts/lunr/min/lunr.es.min.js create mode 100644 assets/javascripts/lunr/min/lunr.fi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.fr.min.js create mode 100644 assets/javascripts/lunr/min/lunr.he.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hu.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hy.min.js create mode 100644 assets/javascripts/lunr/min/lunr.it.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ja.min.js create mode 100644 assets/javascripts/lunr/min/lunr.jp.min.js create mode 100644 assets/javascripts/lunr/min/lunr.kn.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ko.min.js create mode 100644 assets/javascripts/lunr/min/lunr.multi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.nl.min.js create mode 100644 assets/javascripts/lunr/min/lunr.no.min.js create mode 100644 assets/javascripts/lunr/min/lunr.pt.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ro.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ru.min.js create mode 100644 assets/javascripts/lunr/min/lunr.sa.min.js create mode 100644 assets/javascripts/lunr/min/lunr.stemmer.support.min.js create mode 100644 assets/javascripts/lunr/min/lunr.sv.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ta.min.js create mode 100644 assets/javascripts/lunr/min/lunr.te.min.js create mode 100644 assets/javascripts/lunr/min/lunr.th.min.js create mode 100644 assets/javascripts/lunr/min/lunr.tr.min.js create mode 100644 assets/javascripts/lunr/min/lunr.vi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.zh.min.js create mode 100644 assets/javascripts/lunr/tinyseg.js create mode 100644 assets/javascripts/lunr/wordcut.js create mode 100644 assets/javascripts/workers/search.b8dbb3d2.min.js create mode 100644 assets/javascripts/workers/search.b8dbb3d2.min.js.map create mode 100644 assets/logo.png create mode 100644 assets/stylesheets/main.f2e4d321.min.css create mode 100644 assets/stylesheets/main.f2e4d321.min.css.map create mode 100644 assets/stylesheets/palette.06af60db.min.css create mode 100644 assets/stylesheets/palette.06af60db.min.css.map create mode 100644 faq/index.html create mode 100644 how-to-use-appyx/codelabs/index.html create mode 100644 how-to-use-appyx/coding-challenges/index.html create mode 100644 how-to-use-appyx/quick-start/index.html create mode 100644 how-to-use-appyx/sample-apps/index.html create mode 100644 index.html create mode 100644 navigation/composable-navigation/index.html create mode 100644 navigation/deep-linking/index.html create mode 100644 navigation/explicit-navigation/index.html create mode 100644 navigation/implicit-navigation/index.html create mode 100644 navigation/model-driven-navigation/index.html create mode 100644 navmodel/backstack/index.html create mode 100644 navmodel/cards/index.html create mode 100644 navmodel/custom/index.html create mode 100644 navmodel/index.html create mode 100644 navmodel/promoter/index.html create mode 100644 navmodel/spotlight/index.html create mode 100644 navmodel/tiles/index.html create mode 100644 news/index.html create mode 100644 releases/changelog/index.html create mode 100644 releases/downloads/index.html create mode 100644 search/search_index.json create mode 100644 sitemap.xml create mode 100644 sitemap.xml.gz create mode 100644 stylesheets/extra.css create mode 100644 ui/children-view/index.html create mode 100644 ui/transitions/index.html diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000000..e69de29bb2 diff --git a/404.html b/404.html new file mode 100644 index 0000000000..88d1781ca0 --- /dev/null +++ b/404.html @@ -0,0 +1,1133 @@ + + + +
+ + + + + + + + + + + + + + + + + + +The framework includes the ChildAware
interface which comes with a powerful API.
It allows you to scope communication with (or between) dynamically available child nodes easily.
+In the next examples:
+SomeNode
can host multiple child nodes: Child1
, Child2
, etc.SomeInteractor
belongs to SomeNode
and is passed as a Plugin
+ to itSomeInteractor
extends the Interactor
helper class from the framework:NodeLifecycleAware
, which makes sure it will receive the onCreate
callback
+ from the frameworkChildAware
, which unlocks the DSL we'll see in the following
+ snippetsimport androidx.lifecycle.Lifecycle
+import com.bumble.appyx.core.children.whenChildAttached
+import com.bumble.appyx.core.children.whenChildrenAttached
+import com.bumble.appyx.core.clienthelper.interactor.Interactor
+
+
+class SomeInteractor : Interactor<SomeNode>() {
+
+ override fun onCreate(lifecycle: Lifecycle) {
+ lifecycle.subscribe(onCreate = {
+
+ // This lambda is executed every time a node of type Child1Node is attached:
+ whenChildAttached { commonLifecycle: Lifecycle, child1: Child1Node ->
+ // TODO:
+ // - establish communication with child1
+ // - use commonLifecycle for scoping
+ // - it will be capped by the lifecycles of child1 and the parent
+ }
+ })
+ }
+}
+
import androidx.lifecycle.Lifecycle
+import com.bumble.appyx.core.children.whenChildAttached
+import com.bumble.appyx.core.children.whenChildrenAttached
+import com.bumble.appyx.core.clienthelper.interactor.Interactor
+
+
+class SomeInteractor : Interactor<SomeNode>() {
+
+ override fun onCreate(lifecycle: Lifecycle) {
+ lifecycle.subscribe(onCreate = {
+
+ // This lambda is executed every time these two nodes are attached at the same time:
+ whenChildrenAttached { commonLifecycle: Lifecycle, child1: Child1Node, child2: Child2Node ->
+ // TODO
+ // - establish communication between child1 & child2
+ // - use commonLifecycle for scoping
+ // - it will be capped by the lifecycles of child1, child2 and the parent
+ }
+ })
+ }
+}
+
To retain objects during configuration change you can use the RetainedInstanceStore
class.
The RetainedInstanceStore
stores the objects within a singleton. The node manages whether the content should be removed by checking whether the Activity
is being recreated due to a configuration change or not.
These are the following scenarios:
+- If the Activity
is recreated: the retained instance is returned instead of a new instance.
+- If the Activity
is destroyed: the retained instance is removed and disposed.
Here is an example of how you can use the RetainedInstanceStore
:
import com.bumble.appyx.core.builder.Builder
+import com.bumble.appyx.core.modality.BuildContext
+import com.bumble.appyx.core.node.Node
+import com.bumble.appyx.core.store.getRetainedInstance
+import com.bumble.appyx.interop.rx2.store.getRetainedDisposable
+
+class RetainedInstancesBuilder : Builder<String>() {
+
+ override fun build(buildContext: BuildContext, payload: String): Node {
+ val retainedNonDisposable = buildContext.getRetainedInstance(
+ factory = { NonDisposableClass(payload) },
+ disposer = { feature.cleanUp() }
+ )
+ val retainedFeature = buildContext.getRetainedDisposable {
+ RetainedInstancesFeature(payload)
+ }
+
+ val view = RetainedInstancesViewImpl()
+ val interactor = RetainedInstancesInteractor(
+ feature = retainedFeature,
+ nonDisposable = retainedNonDisposable,
+ view = view
+ )
+
+ return RetainedInstancesNode(
+ buildContext = buildContext,
+ view = view,
+ plugins = listOf(interactor)
+ )
+ }
+}
+
Nodes have their own lifecycles, directly using the related classes of androidx.lifecycle
.
No node can be in a higher lifecycle state than any of its parents or the Android Activity it lives in.
+NavModel
controls which children should be rendered on the screen and which should not with NavModel.screenState
.
+The behaviour is customisable in BaseNavModel
via OnScreenStateResolver
.
When a NavElement
of the node is marked as on-screen, its lifecycle follows the parent node's lifecycle.
+The rendering status does not affect it – the node might not be added to Compose view and still be in a RESUMED
state.
When a NavElement
of the node is marked as off-screen, the following might happen:
CREATED
(or STOPPED
) in case of ChildEntry.KeepMode.KEEP
. ChildEntry.KeepMode.SUSPEND
.ChildEntry.KeepMode
settings can be configured for each ParentNode
individually or globally via Appyx.defaultChildKeepMode
.
When a node is removed completely from NavModel
, it will be in DESTROYED
state.
The lifecycle state can be affected by:
+Nodes
and changing their on-screen status)An example demonstrating the above:
+ +Note that NavModels might have their slight differences (e.g. whether their operations remove a Node
only from the view, or completely destroy it).
In the case of the back stack:
+Push
operation adds a new element and stashes the currently active one – the stashed one will be removed from the view & STOPPED
Pop
operation removes an element, the child Node
will be DESTROYED
Nodes
are meant to be simple structural elements, and should be kept lean.
To keep the framework agnostic of any specific approach / pattern you want to use, there aren't any fixed parts. Rather, the Node
offers an extension point using Plugins
in its constructor:
abstract class Node(
+ buildContext: BuildContext,
+ val view: NodeView = EmptyNodeView,
+ plugins: List<Plugin> = emptyList() // <--
+)
+
So what is a Plugin
?
A Plugin
is an empty interface extended by many actual ones:
interface Plugin
+
interface NodeLifecycleAware : Plugin {
+ fun onCreate(lifecycle: Lifecycle) {}
+}
+
+fun interface Destroyable : Plugin {
+ fun destroy()
+}
+
Sometimes you need to grab a reference to the component as a whole, either as an interface, or its implementation, the Node
.
This will come especially handy when working with workflows.
+interface NodeAware : Plugin {
+ val node: Node<*>
+
+ fun init(node: Node<*>) {}
+}
+
There are helper classes found in the library, so you don't have to implement the above interfaces, you can just use delegation:
+class SomeClass(
+ private val nodeAware: NodeAware = NodeAwareImpl()
+) : NodeAware by nodeAware {
+
+ fun foo() {
+ // [node] is an automatically available property coming from the NodeAware interface
+ // the reference is automatically set for you by the framework + the NodeAwareImpl class
+ // so you can use it right away:
+ node.doSomething()
+ }
+}
+
⚠️ Note: the reference to node
is set by Node
automatically, and isn't available immediately after constructing your object, but only after the construction of the Node
itself.
In case if you need to control navigation behaviour, you can use these plugins:
+interface UpNavigationHandler : Plugin {
+ fun handleUpNavigation(): Boolean = false
+}
+
+interface BackPressHandler : Plugin {
+ val onBackPressedCallback: OnBackPressedCallback? get() = null
+}
+
UpNavigationHandler
controls Node.navigateUp
behaviour and allows to intercept its invocation.
BackPressHandler
controls device back press behaviour via androidx.activity.OnBackPressedCallback
.
+You can read more about it here.
⚠️ Note: OnBackPressedCallback
are invoked in the following order:
+1. From children to parents. Render order of children matters! The last rendered child will be the first to handle back press.
+2. Direct order of plugins within a node. Plugins are invoked in order they appears in Node(plugins = ...)
before the NavModel.
All plugins are designed to have empty {}
default implementations (or other sensible defaults when a return value is defined), so it's convenient to implement them only if you need.
Don't forget to pass your Plugins
to your Node
:
internal class MyNode(
+ // ...
+ plugins: List<Plugins> = emptyList()
+ // ...
+) : Node<Nothing>(
+ // ...
+ plugins = plugins
+ // ...
+)
+
⚠️ Note: plugins
is a List
, as the order matters here. All Plugin
instances are invoked in the order they appear in the list.
As seen in Composable navigation, you can make NavModels
composable.
To achieve this, Appyx offers the Node
class as the structural element.
In many of the examples you'll see this panel as an illustration of a very simple Node
– it has some local state (id, colour, and a counter).
If you launch the sample app in the :app
module, you can also change its state (colour) by tapping it. Its counter is stepped automatically. This is to illustrate that it has its own state, persisted and restored.
You can think of a Node
as a standalone component with:
@Composable
viewParentNodes
can have other Nodes
as children. This means you can represent your whole application as a tree of Appyx nodes.
You can go as granular or as high-level as it fits you. This allows to keep the complexity low in individual Nodes
by extracting responsibilities to children, as well as composing other components to build more complex functionality.
Nodes
offer the structure – NavModels
add dynamism to it.
Read more in Composable navigation
+Nodes have their own lifecycles, directly using the related classes of androidx.lifecycle
.
Read more in Lifecycle
+React to dynamically added child nodes in the tree: ChildAware API
+A summary of Appyx's approach to structuring applications:
+Nodes
with their own lifecycles and stateNavModels
NavModels
{"use strict";/*!
+ * escape-html
+ * Copyright(c) 2012-2013 TJ Holowaychuk
+ * Copyright(c) 2015 Andreas Lubbe
+ * Copyright(c) 2015 Tiancheng "Timothy" Gu
+ * MIT Licensed
+ */var Va=/["'&<>]/;qn.exports=za;function za(e){var t=""+e,r=Va.exec(t);if(!r)return t;var o,n="",i=0,s=0;for(i=r.index;i