julianomoraes / componentizationarch Goto Github PK
View Code? Open in Web Editor NEWLicense: Apache License 2.0
License: Apache License 2.0
It isn't clear to me how this architecture would work with more complex "components". A more fleshed-out example, such as a simple to-do list, would be helpful.
Have you had a situation where you needed to embed a UiComponent/UiView in another UIComponent/UiView? Take for instance your PrimaryControlsComponent
. What if you wanted to have another screen that would just have the play/pause button but did not need to include the rewind/fast-forward logic?
I'm playing around with this architecture and hit a roadblock early on..
I have a component I want to reuse in the same fragment. Since the Event class I'm emitting to the bus is the same for both components, you can't tell if some of the events are meant for one or other component.
Example:
My RateButtonsComponent:
open class RateButtonsComponent(
parent: ViewGroup,
private val bus: EventBusFactory
) {
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
val uiView = initView(parent, bus)
open fun initView(parent: ViewGroup, bus: EventBusFactory): RateButtonsUiView {
return RateButtonsUiView(parent, bus)
}
init {
bus.getSafeManagedObservable(RateEvents::class.java)
.subscribe { event ->
when (event) {
ThumbsUpSelected -> uiView.setSelected(THUMBS_UP)
ThumbsDownSelected -> uiView.setSelected(THUMBS_DOWN)
}
}
}
fun getUserInteractionEvents(): Observable<RateButtonsUiView.RateUserInteractionEvent> {
return bus.getSafeManagedObservable(RateButtonsUiView.RateUserInteractionEvent::class.java)
}
sealed class RateEvents : ComponentEvent() {
object ThumbsUpSelected : RateEvents()
object ThumbsDownSelected : RateEvents()
}
}
My fragment:
override fun onViewCreated() {
firstQuestionRateBtnsComponent = RateButtonsComponent(firstQuestionButtons, eventBusFactory)
firstQuestionRateBtnsComponent.getUserInteractionEvents()
.subscribe { event ->
when (event) {
RateUserInteractionEvent.ThumbsUpPressed -> {
eventBusFactory.emit(RateEvents::class.java, RateEvents.ThumbsUpSelected)
}
RateUserInteractionEvent.ThumbsDownPressed -> {
eventBusFactory.emit(RateEvents::class.java, RateEvents.ThumbsDownSelected)
}
}
}
secondQuestionRateBtnsComponent = RateButtonsComponent(secondQuestionButtons, eventBusFactory)
secondQuestionRateBtnsComponent.getUserInteractionEvents()
.subscribe { event ->
when (event) {
RateUserInteractionEvent.ThumbsUpPressed -> {
eventBusFactory.emit(RateEvents::class.java, RateEvents.ThumbsUpSelected)
}
RateUserInteractionEvent.ThumbsDownPressed -> {
eventBusFactory.emit(RateEvents::class.java, RateEvents.ThumbsDownSelected)
}
}
}
}
So when I click thumbsUp on my firstQuestionComponent I receive an RateUserInteractionEvent.ThumbsUpPressed
event that then emits eventBusFactory.emit(RateEvents::class.java, RateEvents.ThumbsUpSelected)
. The issue is that both instances of the RateButtonsComponent
receive this event since they're both listening for RateEvents::class.java
..
Is this not the type of component reusability that this architecture can solve? Am I doing something wrong?
How do you working with some complex lists?
Adapter is android class so in theory should by part of UIView but logic can be quite complex which should not be placed inside View related class because can't be easly tested. Do you recomend to manage Adapter inside UIComponents or UIView?
Another problem is to manage items in that adapter. Each should be a separate SubComponent?
Hello Juliano
I was wondering if you found some way to get a layout preview as a whole.
As we adding view and constraints programmatically, I am not seeing a good way to do that in AS. So I either develop blindly, or duplicate the code to have a layout with the same constraints as the Activity and get my preview this way.
Any thoughts ?
How would you handle orientation changes or render same result when popping fragment?
Hi, Juliano
thinking about modularization/componetization and found your talk.
Just tried to build your sample app and got the following errors.
Could you please advise what is wrong? Seems smth wrong on my side..
Android Studio Beta 3.6 Beta 4
Duplicate class android.support.v4.app.INotificationSideChannel found in modules classes.jar (androidx.core:core:1.1.0-rc02) and classes.jar (com.android.support:support-compat:27.0.0)
Duplicate class android.support.v4.app.INotificationSideChannel$Stub found in modules classes.jar (androidx.core:core:1.1.0-rc02) and classes.jar (com.android.support:support-compat:27.0.0)
Duplicate class android.support.v4.app.INotificationSideChannel$Stub$Proxy found in modules classes.jar (androidx.core:core:1.1.0-rc02) and classes.jar (com.android.support:support-compat:27.0.0)
Duplicate class android.support.v4.os.IResultReceiver found in modules classes.jar (androidx.core:core:1.1.0-rc02) and classes.jar (com.android.support:support-compat:27.0.0)
Duplicate class android.support.v4.os.IResultReceiver$Stub found in modules classes.jar (androidx.core:core:1.1.0-rc02) and classes.jar (com.android.support:support-compat:27.0.0)
Duplicate class android.support.v4.os.IResultReceiver$Stub$Proxy found in modules classes.jar (androidx.core:core:1.1.0-rc02) and classes.jar (com.android.support:support-compat:27.0.0)
Duplicate class android.support.v4.os.ResultReceiver found in modules classes.jar (androidx.core:core:1.1.0-rc02) and classes.jar (com.android.support:support-compat:27.0.0)
Duplicate class android.support.v4.os.ResultReceiver$1 found in modules classes.jar (androidx.core:core:1.1.0-rc02) and classes.jar (com.android.support:support-compat:27.0.0)
Duplicate class android.support.v4.os.ResultReceiver$MyResultReceiver found in modules classes.jar (androidx.core:core:1.1.0-rc02) and classes.jar (com.android.support:support-compat:27.0.0)
Duplicate class android.support.v4.os.ResultReceiver$MyRunnable found in modules classes.jar (androidx.core:core:1.1.0-rc02) and classes.jar (com.android.support:support-compat:27.0.0)
Go to the documentation to learn how to Fix dependency resolution errors.
Hey! Thank you for open sourcing this. I really enjoyed the Medium article. I was wondering if anything has changed in the last year. How has this architecture scaled? Is the developer experience still positive? Any thoughts would be much appreciated.
I have a doubt about components lifecycle placed in a fragment(or activity).
UiComponents are destroyed and created accordingly to the fragment's lifecycle. So on each configuration changes we created a new component instance.
Where should I put long lived operations (network request, ...)? Should I use a viewmodel?
I'm also thinking on a mechanism to save the state of those components that have it.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.