
Brick
Take control of your apps
Brick is a lightweight library to make navigation.
Features
- Framework free (Router can be injected in any layer of project. Navigate from any place you want. Example:
UI-navigation or business logic navigation)
Samples
|
|
Desktop sample
|
Installation
Add repository in your project
repositories {
mavenCentral()
maven {
url "https://maven.pkg.jetbrains.space/public/p/compose/dev"
}
}
Add the dependency in your build.gradle
dependencies {
implementation 'io.github.alphicc:brick:2.3.0'
}
Android: Set jvmTarget in your build.gradle
kotlinOptions {
jvmTarget = '11'
}
Thats all!
Usage
- Create Router in any place of your project (Note: router contains all information about component. Router
destroyed = all navigation/components data destroyed).
val router: TreeRouter = TreeRouter.new()
- Create Component. Component != UI. Component has lifecycle, channels to communicate between other components.
Component can live without UI. UI - part of Component.
val component1 = Component<Unit>(
key = "1",
content = { _, _ -> SimpleComponent(1, "new") { smallSampleRouter.addComponent(component2) } }
)
- Provide ContainerConnector to %PLATFORM%AnimatedComponentsContainer or %PLATFORM%ComponentsContainer .
Your Router implements ContainerConnector.
class SmallSampleActivity : ComponentActivity() {
val containerConnector: ContainerConnector = ...
{
.onCreate(savedInstanceState)
setContent {
AndroidComponentsContainer(containerConnector) {
}
}
}
}
- Navigate!
Work representation
Integration schema
Work schema
Lifecycle sample
Multistack navigation
- Create nested router using branch method.
private val firstMenuRouter = mainRouter.branch(Components.bottomMenuComponent.key).apply {
addComponent(Components.innerNavigationComponent, this)
}
- Pass created nested router to your nested %PLATFORM%ComponentsContainer.
%PLATFORM % AnimatedComponentsContainer(firstMenuRouter)
- Use your nested router to make nested navigation!
Multistack graph sample (simple)
Multistack graph sample (extended)
Composite navigation
Starting with version 2.* and above, you can extract small UI components to the Component and paste this small
components in any place of other Component you want. Thus making them reusable. It also makes it possible to further
decompose work when working in the team. Allowing you to work on one small UI component (like button, text field etc.)
without affecting other components.
Screen sample
Decompose your screen by components
Code sample
Main screen component
val compositeScreen = Component<Unit>(
key = "CompositeScreen",
content = { _, compositeContainer ->
Box(modifier = Modifier.fillMaxSize()) {
Box(modifier = Modifier.align(Alignment.TopCenter)) {
compositeContainer.place(component1.key)
}
Box(modifier = Modifier.align(Alignment.Center)) {
compositeContainer.place(component3.key)
}
Box(modifier = Modifier.align(Alignment.BottomCenter)) {
compositeContainer.place(component2.key)
}
}
}
)
Components.
val component1 = Component<Unit>(
key = "CompositeScreenInternal 1",
keepAliveCompose = true,
onCreate = { _, _ -> }, lifecycle of your componentg
onDestroy = { _ -> },
content = { _, _ -> Text("CompositeScreenInternal 1") }
)
val component2 = Component<Unit>(
key = "CompositeScreenInternal 2",
content = { _, _ -> Text() }
)
component3 = Component<>(
key = ,
content = { _, _ ->
Button({}) {
Text()
}
}
)
Attach your components to main component (screen)
compositeSampleRouter.addComponent(compositeScreen)
compositeSampleRouter.attachCompositeComponent(component1, "321")
compositeSampleRouter.attachCompositeComponent(component2)
compositeSampleRouter.attachCompositeComponent(component3)
compositeSampleRouter.detachCompositeComponent(component3)
Note: composite components are shared between the component they are added to and its child components
Communicate between components
Pass data
router.passArgument(Screens.channelArgumentReceiveComponent.key, counter)
val argument: CustomArgumentType = CustomArgumentType()
router.passBroadcastArgument(argument)
router.broadcastFlow
.filterIsInstance<CustomArgumentType>()
.onEach { argument ->
}
...
Receive data
...
onCreate = { channel, _ -> return@Component ChannelArgumentReceiveViewModel(channel) },
...
channel.onEach { _count.value = it.get() }.launchIn(scope)
Navigation methods list
- currentComponentKey
- backComponent
Migrate from 1.* to 2.* version
...
content = { dataContainer -> }
...
...
content = { dataContainer, compositeContainer -> }
...