bluelinelabs / Conductor

A small, yet full-featured framework that allows building View-based Android applications
Apache License 2.0
3.9k stars 345 forks source link

[How] to re-assign(recall onCreateView) a controller's view manaully? #611

Closed amoikevin closed 4 years ago

amoikevin commented 4 years ago

PTR, thanks

dimsuz commented 4 years ago

This question needs more details and it is better be asked on Stack Overflow

amoikevin commented 4 years ago

Sorry for that. The usercase is simple, i want to create a dynamic ui, which has multiple states. I know i can create multi child controllers to achive that, but i want do it more lightly. Here is code I'm using:


fun Controller.recreate() {
    if (isBeingDestroyed || isDestroyed) return
    val root = getView() ?: return
    val parent = root.parentView ?: return
    val viewAttachHandler = getFieldValue<Controller, ViewAttachHandler>(Controller::class.java, "viewAttachHandler") ?: return
    root.removeOnAttachStateChangeListener(viewAttachHandler)
    parent.removeView(root)
    view = onCreateView(LayoutInflater.from(parent.defaultContext), parent, viewState?.getBundle(KEY_VIEW_STATE_BUNDLE))
    parent.addView(view)
    view.addOnAttachStateChangeListener(viewAttachHandler)
}

fun Controller.reattach() {
    if (isBeingDestroyed || isDestroyed) return
    val root = getView() ?: return
    val parent = root.parentView ?: return
    parent.removeView(root)
    val view = inflate(parent)
    parent.addView(view)
    attach(view)
}
dimsuz commented 4 years ago

You shouldn't be using reflection: it is very costly on android and in general code above simply breaks the rules set by a library author while it should embrace them. Breaking the rules won't get you very far: instead inconsistencies will accumulate.

I'd suggest you to learn more about state handling in UIs. Try to apply some well-known architecture pattern: MVI, MVVM, MVP whichever you'll like most.