Commit 89ffc571 authored by Vladislav Bogdashkin's avatar Vladislav Bogdashkin 🎣

remove HomeController via ViewPager

added custom HomeController with bottom navigaion support
parents f6587b74 f34d33c3
...@@ -69,20 +69,27 @@ class RoomParkMainActivity( ...@@ -69,20 +69,27 @@ class RoomParkMainActivity(
override fun hideAll() { override fun hideAll() {
appBar.visibility=Toolbar.INVISIBLE appBar.visibility=Toolbar.INVISIBLE
bottomNavigation.visibility = BottomNavigationView.GONE
bottomShadow.visibility = View.GONE
Timber.e(" lay params : ${appBar.layoutParams.javaClass}") Timber.e(" lay params : ${appBar.layoutParams.javaClass}")
val params:CoordinatorLayout.LayoutParams = conductor_container.layoutParams as CoordinatorLayout.LayoutParams val params:CoordinatorLayout.LayoutParams = conductor_container.layoutParams as CoordinatorLayout.LayoutParams
params.behavior = null params.behavior = null
conductor_container.requestLayout() conductor_container.requestLayout()
} }
override fun hide() {
bottomNavigation.visibility = BottomNavigationView.GONE
bottomShadow.visibility = View.GONE
}
override fun show() {
bottomNavigation.visibility = Toolbar.VISIBLE
bottomShadow.visibility = View.VISIBLE
}
override fun showAll() { override fun showAll() {
appBar.setExpanded(true,false) appBar.setExpanded(true,false)
collapsingToolbarLayout.visibility= View.VISIBLE collapsingToolbarLayout.visibility= View.VISIBLE
bottomNavigation.visibility = Toolbar.VISIBLE
bottomShadow.visibility = View.VISIBLE
appBar.visibility= View.VISIBLE appBar.visibility= View.VISIBLE
topAppBar.visibility = View.VISIBLE topAppBar.visibility = View.VISIBLE
...@@ -96,4 +103,12 @@ class RoomParkMainActivity( ...@@ -96,4 +103,12 @@ class RoomParkMainActivity(
val behavior = params.behavior as DragControlAppBarLayoutBehaviour val behavior = params.behavior as DragControlAppBarLayoutBehaviour
behavior.allowDrag=allow behavior.allowDrag=allow
} }
override fun onBackPressed() {
if (router.handleBack()) {
Timber.d("In stack : " + router.backstackSize)
} else {
super.onBackPressed()
}
}
} }
...@@ -31,4 +31,6 @@ interface IConductorActivity{ ...@@ -31,4 +31,6 @@ interface IConductorActivity{
interface IBottomNavigation{ interface IBottomNavigation{
val bottomNavigation : BottomNavigationView val bottomNavigation : BottomNavigationView
fun hide()
fun show()
} }
...@@ -6,7 +6,7 @@ import com.biganto.visual.roompark.R ...@@ -6,7 +6,7 @@ import com.biganto.visual.roompark.R
import com.biganto.visual.roompark.base.RoomParkApplication import com.biganto.visual.roompark.base.RoomParkApplication
import com.biganto.visual.roompark.base.RoomParkMainActivity import com.biganto.visual.roompark.base.RoomParkMainActivity
import com.biganto.visual.roompark.conductor.BigantoBaseController import com.biganto.visual.roompark.conductor.BigantoBaseController
import com.biganto.visual.roompark.presentation.screen.home.HomeController import com.biganto.visual.roompark.presentation.screen.home.home_routing.HomeBottomNavigationController
import com.bluelinelabs.conductor.RouterTransaction import com.bluelinelabs.conductor.RouterTransaction
import com.google.android.material.button.MaterialButton import com.google.android.material.button.MaterialButton
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
...@@ -89,7 +89,7 @@ class AuthScreenController : ...@@ -89,7 +89,7 @@ class AuthScreenController :
} }
private fun render(viewState: AuthScreenViewState.SignedIn){ private fun render(viewState: AuthScreenViewState.SignedIn){
router.setRoot(RouterTransaction.with(HomeController())) router.setRoot(RouterTransaction.with(HomeBottomNavigationController()))
// snacky.showSnackBar("lul") // snacky.showSnackBar("lul")
} }
......
...@@ -59,7 +59,7 @@ class DealsScreenController : ...@@ -59,7 +59,7 @@ class DealsScreenController :
override fun onViewBound(v: View) { override fun onViewBound(v: View) {
// setToolbar() setToolbar()
bindRecycler() bindRecycler()
} }
......
...@@ -60,7 +60,7 @@ class FavoritesScreenController : ...@@ -60,7 +60,7 @@ class FavoritesScreenController :
} }
override fun onViewBound(v: View) { override fun onViewBound(v: View) {
// setToolbar() setToolbar()
bindRecycler() bindRecycler()
} }
......
...@@ -101,7 +101,7 @@ class ArticlesScreenController : ...@@ -101,7 +101,7 @@ class ArticlesScreenController :
override fun handleBack(): Boolean { override fun handleBack(): Boolean {
Timber.d("handle back in class ") Timber.d("handle back in class ")
router.popController(this) router.popController(this)
return super.handleBack() return true
} }
......
...@@ -97,6 +97,7 @@ class FeedsScreenController : ...@@ -97,6 +97,7 @@ class FeedsScreenController :
override lateinit var injectedPresenter: FeedsScreenPresenter override lateinit var injectedPresenter: FeedsScreenPresenter
override fun onViewBound(v: View) { override fun onViewBound(v: View) {
toolBar.hideAll()
bindRecycler() bindRecycler()
feedsBlockView.findViewById<MaterialTextView>(R.id.to_feed_articles).clicks() feedsBlockView.findViewById<MaterialTextView>(R.id.to_feed_articles).clicks()
.map{ feedsTabs.getTabAt(feedsTabs.selectedTabPosition)} .map{ feedsTabs.getTabAt(feedsTabs.selectedTabPosition)}
...@@ -121,6 +122,7 @@ class FeedsScreenController : ...@@ -121,6 +122,7 @@ class FeedsScreenController :
is FeedsScreenViewState.AlbumsPages -> render(viewState) is FeedsScreenViewState.AlbumsPages -> render(viewState)
is FeedsScreenViewState.CamsList -> render(viewState) is FeedsScreenViewState.CamsList -> render(viewState)
is FeedsScreenViewState.GetFeedArticlesPreview -> render(viewState) is FeedsScreenViewState.GetFeedArticlesPreview -> render(viewState)
is FeedsScreenViewState.RestoreView -> render(viewState)
} }
} }
...@@ -163,6 +165,30 @@ class FeedsScreenController : ...@@ -163,6 +165,30 @@ class FeedsScreenController :
(camsRecyclerView.adapter as CamsListAdapter).setItems(viewState.items) (camsRecyclerView.adapter as CamsListAdapter).setItems(viewState.items)
} }
private fun render(viewState: FeedsScreenViewState.RestoreView){
(camsRecyclerView.adapter as CamsListAdapter).setItems(viewState.restore.cams)
(feedsRecyclerView.adapter as ArticlesPreviewAdapter).setItems(viewState.restore.articles)
(devProgressRecyclerView.adapter as AlbumsPreviewAdapter).setItems(viewState.restore.albums)
feedsTabs.removeAllTabs()
viewState.restore.feeds.forEach {feed ->
val tab = feedsTabs.newTab()
.setCustomView(R.layout.feeds_tab_view)
.setTag(feed.feedId)
tab.customView
?.let {
it.findViewById<TextView>(R.id.tab_title)?.text = feed.title
it.findViewById<TextView>(R.id.tab_divider)?.visibility =
if (viewState.restore.feeds.indexOf(feed) == viewState.restore.feeds.size - 1) View.GONE
else View.VISIBLE
}
feedsTabs.addTab(tab)
}
storedFeedsList = viewState.restore.feeds
}
private fun getComponent() = DaggerFeedsScreenComponent.factory() private fun getComponent() = DaggerFeedsScreenComponent.factory()
.create(RoomParkApplication.component,activity as RoomParkMainActivity) .create(RoomParkApplication.component,activity as RoomParkMainActivity)
.inject(this) .inject(this)
......
...@@ -17,21 +17,45 @@ class FeedsScreenPresenter @Inject constructor( ...@@ -17,21 +17,45 @@ class FeedsScreenPresenter @Inject constructor(
) )
: BigantoBasePresenter<FeedsScreen, FeedsScreenViewState>() { : BigantoBasePresenter<FeedsScreen, FeedsScreenViewState>() {
private val restoreModel = RestoreModel(
arrayListOf(),
arrayListOf(),
arrayListOf(),
arrayListOf())
override fun attachView(view: FeedsScreen) {
Timber.d("AttachView ")
restoreStateObservable.accept(FeedsScreenViewState.RestoreView(restoreModel))
super.attachView(view)
}
override fun bindIntents() { override fun bindIntents() {
val fetchCams = interactor.fetchCams() val fetchCams = interactor.fetchCams()
.map {FeedsScreenViewState.CamsList(it.items) } .map {
restoreModel.cams = it.items
FeedsScreenViewState.CamsList(it.items)
}
val fetchAlbums = interactor.fetchAlbums() val fetchAlbums = interactor.fetchAlbums()
.map {FeedsScreenViewState.AlbumsPages(it) } .map {
restoreModel.albums = it
FeedsScreenViewState.AlbumsPages(it)
}
val fetchFeeds = interactor.fetchTopFeeds() val fetchFeeds = interactor.fetchTopFeeds()
.map {FeedsScreenViewState.FeedsPages(it.feeds.toList()) } .map {
restoreModel.feeds = it.feeds
FeedsScreenViewState.FeedsPages(it.feeds.toList())
}
val getFeedArticlesPreview = intent(FeedsScreen::feedsTabSelected) val getFeedArticlesPreview = intent(FeedsScreen::feedsTabSelected)
.flatMapSingle { interactor.fetchArticles(it) } .flatMapSingle { interactor.fetchArticles(it) }
.map { FeedsScreenViewState.GetFeedArticlesPreview(it.articles.toList()) } .map {
restoreModel.articles = it.articles
FeedsScreenViewState.GetFeedArticlesPreview(it.articles.toList())
}
val state = restoreStateObservable val state = restoreStateObservable
.mergeWith(fetchFeeds) .mergeWith(fetchFeeds)
......
...@@ -18,4 +18,13 @@ sealed class FeedsScreenViewState : BigantoBaseViewState() { ...@@ -18,4 +18,13 @@ sealed class FeedsScreenViewState : BigantoBaseViewState() {
class CamsList(val items:List<WebCamModel>) : FeedsScreenViewState() class CamsList(val items:List<WebCamModel>) : FeedsScreenViewState()
class GetFeedArticlesPreview(val items:List<ArticlePreviewModel>) : FeedsScreenViewState() class GetFeedArticlesPreview(val items:List<ArticlePreviewModel>) : FeedsScreenViewState()
}
\ No newline at end of file class RestoreView(val restore:RestoreModel) : FeedsScreenViewState()
}
data class RestoreModel(
var feeds:List<FeedModel>,
var albums:List<AlbumPreviewModel>,
var cams:List<WebCamModel>,
var articles:List<ArticlePreviewModel>
)
\ No newline at end of file
...@@ -24,6 +24,8 @@ import javax.inject.Inject ...@@ -24,6 +24,8 @@ import javax.inject.Inject
* Created by Vladislav Bogdashkin on 11.10.2019. * Created by Vladislav Bogdashkin on 11.10.2019.
*/ */
@Deprecated("Реализация через ViewPager сулит некоторые дополнительны проблемы и оверхед")
class HomeController : class HomeController :
BigantoBaseController<HomeScreenViewState BigantoBaseController<HomeScreenViewState
, HomeScreen , HomeScreen
......
...@@ -8,6 +8,7 @@ import com.biganto.visual.roompark.di.dagger.AppComponent ...@@ -8,6 +8,7 @@ import com.biganto.visual.roompark.di.dagger.AppComponent
import com.biganto.visual.roompark.di.dagger.AuthContractModule import com.biganto.visual.roompark.di.dagger.AuthContractModule
import com.biganto.visual.roompark.di.dagger.PerScreen import com.biganto.visual.roompark.di.dagger.PerScreen
import com.biganto.visual.roompark.domain.contract.AuthContract import com.biganto.visual.roompark.domain.contract.AuthContract
import com.biganto.visual.roompark.presentation.screen.home.home_routing.HomeBottomNavigationController
import dagger.Binds import dagger.Binds
import dagger.BindsInstance import dagger.BindsInstance
import dagger.Component import dagger.Component
...@@ -34,6 +35,7 @@ interface HomeScreenComponent { ...@@ -34,6 +35,7 @@ interface HomeScreenComponent {
val presenter: HomeScreenPresenter val presenter: HomeScreenPresenter
fun inject(controller: HomeController) fun inject(controller: HomeController)
fun inject(controller: HomeBottomNavigationController)
} }
@Module @Module
......
package com.biganto.visual.roompark.presentation.screen.home.home_routing
import android.os.Bundle
import android.util.Log
import android.util.SparseArray
import android.view.*
import androidx.annotation.IdRes
import androidx.annotation.NonNull
import com.biganto.visual.roompark.conductor.BigantoBaseController
import com.biganto.visual.roompark.presentation.screen.home.HomeScreen
import com.biganto.visual.roompark.presentation.screen.home.HomeScreenPresenter
import com.biganto.visual.roompark.presentation.screen.home.HomeScreenViewState
import com.bluelinelabs.conductor.ChangeHandlerFrameLayout
import com.bluelinelabs.conductor.Controller
import com.bluelinelabs.conductor.Router
import com.bluelinelabs.conductor.RouterTransaction
import com.bluelinelabs.conductor.changehandler.FadeChangeHandler
import com.google.android.material.bottomnavigation.BottomNavigationView
import timber.log.Timber
/**
* The [Controller] for the Bottom Navigation View. Populates a [BottomNavigationView]
* with the supplied [Menu] resource. The first item set as checked will be shown by default.
* The backstack of each [MenuItem] is switched out, in order to maintain a separate backstack
* for each [MenuItem] - even though that is against the Google Design Guidelines.
*
*
*
* Internally works similarly to [com.bluelinelabs.conductor.support.RouterPagerAdapter],
* in the sense that it keeps track of the currently active [MenuItem] and the paired Child
* [Router]. Everytime we navigate from one to another, or [ ][Controller.onSaveInstanceState] is called, we save the entire instance state of the Child
* [Router], and cache it, so we have it available when we navigate to another [ ] and can then restore the correct Child [Router] (and thus the entire backstack)
*
* @author chris6647@gmail.com
* @see [Material
* Design Guidelines](https://material.io/guidelines/components/bottom-navigation.html.bottom-navigation-behavior)
*/
abstract class BottomNavigationController :
BigantoBaseController<HomeScreenViewState
, HomeScreen
, HomeScreenPresenter>
, HomeScreen {
lateinit var bottomNavigationView: BottomNavigationView
lateinit var controllerContainer: ChangeHandlerFrameLayout
protected var currentlySelectedItemId = INVALID_INT
protected var routerSavedStateBundles: SparseArray<Bundle>? = null
/**
* Used to popToTag (this) [BottomNavigationController] instance if needed
*
* @return The tag set on the transaction contains this [BottomNavigationController]
* instance
*/
protected abstract val tag: String
constructor():super()
constructor(args: Bundle) : super(args)
@NonNull
protected fun inflateView(@NonNull inflater: LayoutInflater, @NonNull container: ViewGroup): View {
return inflater.inflate(getLayoutId(), container, false)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup): View {
val view = inflateView(inflater,container)
retainViewMode=RetainViewMode.RELEASE_DETACH
Timber.d(" onCreateView: ${this::class}")
onViewBound(view)
return view
}
@IdRes
protected abstract fun getStartupMenuId(): Int
protected override fun onAttach(@NonNull view: View) {
super.onAttach(view)
Timber.d(" OnAttachView: ${this::class}")
if (routerSavedStateBundles == null) {
/*
* Fresh start, setup everything.
* Must be done in onAttach to avoid artifacts if using multiple Activities,
* and in case of resuming the app (i.e. when the view is not created again)
*/
val menu = bottomNavigationView.menu
val menuSize = menu.size()
routerSavedStateBundles = SparseArray(menuSize)
val startUpMenuItem = menu.findItem(getStartupMenuId())
for (i in 0 until menuSize) {
val menuItem = menu.getItem(i)
/* We want start from direct menu item */
if (menuItem==startUpMenuItem) {
/*
* Seems like the BottomNavigationView always initializes index 0 as isChecked / Selected,
* regardless of what was set in the menu xml originally.
* So basically all we're doing here is always setting up menuItem index 0.
*/
val itemId = menuItem.itemId
bottomNavigationView.selectedItemId = itemId
navigateTo(getControllerFor(itemId), false)
break
}
}
} else {
/*
* Since we are restoring our state,
* and onRestoreInstanceState is called before onViewBound,
* all we need to do is rebind.
*/
getChildRouter(currentlySelectedItemId)!!.rebindIfNeeded()
}
}
/**
* Get the Child [Router] matching the supplied ItemId.
*
* @param menuItemId [MenuItem] ID
* @return
*/
protected fun getChildRouter(@IdRes menuItemId: Int): Router? {
return getChildRouter(controllerContainer, "itemId:$menuItemId")
}
/**
* Remove the supplied [Router] as a child of this Controller.
*
* @param childRouter
*/
protected fun destroyChildRouter(childRouter: Router?) {
if (childRouter!=null) removeChildRouter(childRouter)
}
/**
* Navigate to the supplied [Controller], while setting the menuItemId as selected on the
* [BottomNavigationView]. Supplied Controller must match the nextMenuItemId as defined in
* [BottomNavigationMenuItem] or an [IllegalArgumentException] will be thrown.
*
*
*
* If this method is to be called when Requires [BottomNavigationController] is not
* attached, it requires [BottomNavigationController.getTag] to return a valid tag, that
* will return this [BottomNavigationController] instance in this [Router]'s
* backstack.
*
* @param controller to navigate to
* @param shouldOverrideBackstack whether or not to navigate to whatever existing backstack, or to
* set a new one
*/
fun navigateTo(@NonNull controller: Controller, shouldOverrideBackstack: Boolean) {
if (isSupportedController(controller)) {
if (isAttached()) {
@IdRes val menuItemId = getIdForController(controller)
if (currentlySelectedItemId != menuItemId) {
/* Navigating to new menuItemId */
if (currentlySelectedItemId != INVALID_INT) {
/* Save state of current router before destroying it */
val oldChildRouter = getChildRouter(currentlySelectedItemId)
save(oldChildRouter!!, currentlySelectedItemId)
destroyChildRouter(oldChildRouter)
}
/* Configure the new childRouter */
val newChildRouter = getChildRouter(menuItemId)
val routerSavedState = routerSavedStateBundles!!.get(menuItemId)
if (!shouldOverrideBackstack
&& routerSavedState != null
&& !routerSavedState.isEmpty) {
newChildRouter!!.restoreInstanceState(routerSavedState)
routerSavedStateBundles!!.remove(menuItemId)
newChildRouter.rebindIfNeeded()
} else {
newChildRouter!!.setRoot(RouterTransaction.with(controller))
}
ensureMenuSelectionState(menuItemId)
} else if (currentlySelectedItemId != INVALID_INT) {
/* Navigating to same menuItemId */
@IdRes val newMenuItem = if (shouldOverrideBackstack) menuItemId else currentlySelectedItemId
/* Don't want to save state, because we are resetting it */
destroyChildRouter(getChildRouter(newMenuItem))
routerSavedStateBundles!!.remove(newMenuItem)
/* Must get reference to newly recreated childRouter to avoid old view not being removed */
getChildRouter(newMenuItem)!!
.setRoot(
RouterTransaction.with(controller)
.pushChangeHandler(FadeChangeHandler(true)))
if (newMenuItem != currentlySelectedItemId) {
ensureMenuSelectionState(newMenuItem)
}
} else {
Log.e(
TAG,
"Attempted to reset backstack on BottomNavigationController with currentlySelectedItemId=$currentlySelectedItemId")
}
} else {
/*
* Navigate to ourselves, and once the view is ready (so we can get the childRouter),
* navigate as instructed.
*/
this@BottomNavigationController.addLifecycleListener(
object : Controller.LifecycleListener() {
override fun postAttach(@NonNull attachedController: Controller, @NonNull view: View) {
super.postAttach(attachedController, view)
this@BottomNavigationController.removeLifecycleListener(this)
this@BottomNavigationController.navigateTo(controller, shouldOverrideBackstack)
}
override fun preDestroy(@NonNull controller: Controller) {
super.preDestroy(controller)
/* Clean ourselves up in case we're destroyed without having been attached */
this@BottomNavigationController.removeLifecycleListener(this)
}
})
router.popToTag(tag)
}
} else {
Log.e(TAG, "Attempted to navigate to unsupported controller=$controller")
}
}
/**
* Resets the backstack for the menuItemId matching the [Controller] found at backstack
* index 0.
*
* @param backstack
*/
fun navigateTo(@NonNull backstack: List<RouterTransaction>) {
val rootController = backstack[0].controller()
if (isSupportedController(rootController)) {
val menuItemId = getIdForController(rootController)
if (isAttached()) {
destroyChildRouter(getChildRouter(currentlySelectedItemId))
routerSavedStateBundles!!.remove(currentlySelectedItemId)
if (currentlySelectedItemId != menuItemId) {
ensureMenuSelectionState(menuItemId)
}
/* Must get reference to newly recreated childRouter to avoid old view not being removed */
getChildRouter(currentlySelectedItemId)!!.setBackstack(backstack, FadeChangeHandler())
} else {
/*
* Navigate to ourselves, and once the view is ready (so we can get the childRouter),
* navigate as instructed.
*/
this@BottomNavigationController.addLifecycleListener(
object : Controller.LifecycleListener() {
override fun postAttach(@NonNull controller: Controller, @NonNull view: View) {
super.postAttach(controller, view)
this@BottomNavigationController.removeLifecycleListener(this)
this@BottomNavigationController.navigateTo(backstack)
}
override fun preDestroy(@NonNull controller: Controller) {
super.preDestroy(controller)
/* Clean ourselves up in case we're destroyed without having been attached */
this@BottomNavigationController.removeLifecycleListener(this)
}
})
getRouter().popToTag(tag)
}
} else {
Log.e(
TAG,
"Attempted to navigate to backstack with unsupported root controller=$rootController")
}
}
/**
* Ensure correct Checked state based on given menuItemId
*
* @param menuItemId
*/
private fun ensureMenuSelectionState(@IdRes menuItemId: Int) {
val menu = bottomNavigationView.menu
for (i in 0 until menu.size()) {
val menuItem = menu.getItem(i)
if (menuItem.isChecked && menuItem.itemId != menuItemId) {
menuItem.isChecked = false
} else if (menuItem.itemId == menuItemId) {
menuItem.isChecked = true
currentlySelectedItemId = menuItemId
}
}
if (currentlySelectedItemId != menuItemId) {
Log.e(TAG, "Unexpected BottomNavigation selected Menu Item.")
}
}
/**
* Saves the Child [Router] into a [Bundle] and caches that [Bundle].
*
*
*
* Be cautious as this call causes the controller flag it needs reattach, so it should only be
* called just prior to destroying the router
*
* @param menuItemId [MenuItem] ID
*/
private fun save(childRouter: Router, @IdRes menuItemId: Int) {
val routerBundle = Bundle()
childRouter.saveInstanceState(routerBundle)
routerSavedStateBundles!!.put(menuItemId, routerBundle)
}
override fun onRestoreInstanceState(@NonNull savedInstanceState: Bundle) {
Timber.d(" onRestoreInstanceState: ${this::class}")
routerSavedStateBundles = savedInstanceState.getSparseParcelableArray(
KEY_STATE_ROUTER_BUNDLES
)
currentlySelectedItemId = savedInstanceState.getInt(KEY_STATE_CURRENTLY_SELECTED_ID, INVALID_INT)
}
override fun onSaveInstanceState(@NonNull outState: Bundle) {
Timber.d(" onSaveInstanceState: ${this::class}")
outState.putSparseParcelableArray(KEY_STATE_ROUTER_BUNDLES, routerSavedStateBundles)
/*
* For some reason the BottomNavigationView does not seem to correctly restore its
* selectedId, even though the view appears with the correct state.
* So we keep track of it manually
*/
outState.putInt(KEY_STATE_CURRENTLY_SELECTED_ID, currentlySelectedItemId)
}
/**
* Return a target instance of [Controller] for given menu item ID
*
* @param menuItemId the ID tapped by the user
* @return the [Controller] instance to navigate to
*/
@NonNull
protected abstract fun getControllerFor(@IdRes menuItemId: Int): Controller
/**
* @param controller
* @return the MenuItemId for matching the given [Controller]
*/
@IdRes
protected abstract fun getIdForController(@NonNull controller: Controller): Int
/**
* @param controller [Controller] to test
* @return whether or not the supplied controller is of a class supported in this [ ]
*/
protected abstract fun isSupportedController(@NonNull controller: Controller): Boolean
companion object {
val TAG = "BottomNavigationContr"
private val KEY_MENU_RESOURCE = "key_menu_resource"
private val KEY_STATE_ROUTER_BUNDLES = "key_state_router_bundles"
private val KEY_STATE_CURRENTLY_SELECTED_ID = "key_state_currently_selected_id"
val INVALID_INT = -1
}
}
\ No newline at end of file
package com.biganto.visual.roompark.presentation.screen.home.home_routing
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.annotation.IdRes
import androidx.annotation.NonNull
import com.biganto.visual.roompark.R
import com.biganto.visual.roompark.base.IBottomNavigation
import com.biganto.visual.roompark.base.ICollapsingToolBar
import com.biganto.visual.roompark.base.RoomParkApplication
import com.biganto.visual.roompark.base.RoomParkMainActivity
import com.biganto.visual.roompark.presentation.screen.deals.DealsScreenController
import com.biganto.visual.roompark.presentation.screen.favorites.FavoritesScreenController
import com.biganto.visual.roompark.presentation.screen.feeds.FeedsScreenController
import com.biganto.visual.roompark.presentation.screen.home.DaggerHomeScreenComponent
import com.biganto.visual.roompark.presentation.screen.home.HomeScreenPresenter
import com.biganto.visual.roompark.presentation.screen.home.HomeScreenViewState
import com.biganto.visual.roompark.presentation.screen.settings.SettingsScreenController
import com.biganto.visual.roompark.presentation.screen.to_flat.FindFlatScreenController
import com.bluelinelabs.conductor.Controller
import com.google.android.material.bottomnavigation.BottomNavigationView
import timber.log.Timber
import javax.inject.Inject
/**
* Created by Vladislav Bogdashkin on 14.02.2019.
*/
const val OPEN_CHILD_CONTROLLER_KEY="OPEN_HOME_SCREEN_CHILD_CONTROLLER_ID"
fun toPageBundle(@IdRes menuItemId:Int): Bundle {
val b = Bundle()
b.putInt(OPEN_CHILD_CONTROLLER_KEY, menuItemId)
return b
}
class HomeBottomNavigationController(@IdRes toPage: Int = R.id.tab_feeds)
: BottomNavigationController(toPageBundle(toPage)) {
override fun injectDependencies() {
getComponent()
}
override fun getStartupMenuId(): Int =
args.getInt(OPEN_CHILD_CONTROLLER_KEY, R.id.tab_feeds)
@Inject
lateinit var tb: ICollapsingToolBar
@Inject
lateinit var bottomNavigation: IBottomNavigation
@Inject
override lateinit var injectedPresenter: HomeScreenPresenter
fun getComponent() = DaggerHomeScreenComponent
.factory()
.create(RoomParkApplication.component,activity as RoomParkMainActivity)
.inject(this)
override fun render(viewState: HomeScreenViewState) {
when(viewState){
is HomeScreenViewState.Idle -> render(viewState)
is HomeScreenViewState.ToScreen -> render(viewState)
}
}
private fun render(viewState: HomeScreenViewState.Idle){
}
private fun render(viewState: HomeScreenViewState.ToScreen){
// snacky.showSnackBar("lul")
}
override fun getLayoutId() = R.layout.tab_routing_screen_view
override val tag: String
get() = "BottomNavigationImpl"
override fun onViewBound(@NonNull view: View) {
bottomNavigation.show()
Timber.d(" onViewBound: ${this::class}")
bottomNavigationView = ((activity as RoomParkMainActivity) as IBottomNavigation).bottomNavigation
bottomNavigationView.visibility = BottomNavigationView.VISIBLE
controllerContainer = view.findViewById(R.id.tabContainer)
bottomNavigationView.setOnNavigationItemSelectedListener { item ->
navigateTo(getControllerFor(item.itemId), false)
true
}
router.backstack.clear()
val toScreen = args.getInt(OPEN_CHILD_CONTROLLER_KEY, R.id.tab_feeds)
}
override fun getControllerFor(menuItemId: Int): Controller = when (menuItemId) {
R.id.tab_feeds -> FeedsScreenController()
R.id.tab_favorites -> FavoritesScreenController()
R.id.tab_deals -> DealsScreenController()
R.id.tab_look_flat -> FindFlatScreenController()
R.id.tab_settings -> SettingsScreenController()
else -> FeedsScreenController()
}
override fun isSupportedController(controller: Controller): Boolean {
return true
}
override fun getIdForController(controller: Controller): Int {
return when (controller) {
is FeedsScreenController -> R.id.tab_feeds
is FavoritesScreenController -> R.id.tab_favorites
is DealsScreenController -> R.id.tab_deals
is FindFlatScreenController -> R.id.tab_look_flat
is SettingsScreenController -> R.id.tab_settings
else -> 0
}
}
override fun handleBack(): Boolean {
/*
* The childRouter should handleBack,
* as this BottomNavigationController doesn't have a back step sensible to the user.
*/
Timber.d("in back stack ")
val childRouter = getChildRouter(currentlySelectedItemId)
Timber.d("in back stack - ${childRouter?.backstackSize}")
if (childRouter != null) {
val backStackSizeCondition = childRouter.backstackSize < 0
val backStackResult = childRouter.handleBack()
if (backStackResult
&& backStackSizeCondition
)
navigateTo(getControllerFor(R.id.tab_feeds), false)
return backStackResult
} else {
Log.e(TAG, "handleBack called with getChildRouter(currentlySelectedItemId) == null.",
IllegalStateException(
"handleBack called with getChildRouter(currentlySelectedItemId) == null."))
}
return false
}
}
...@@ -71,7 +71,7 @@ class SettingsScreenController : ...@@ -71,7 +71,7 @@ class SettingsScreenController :
} }
override fun onViewBound(v: View) { override fun onViewBound(v: View) {
// setToolbar() setToolbar()
pushRecycler.isNestedScrollingEnabled = true pushRecycler.isNestedScrollingEnabled = true
pushRecycler.layoutManager = pushRecycler.layoutManager =
LinearLayoutManager(activity, RecyclerView.VERTICAL, false) LinearLayoutManager(activity, RecyclerView.VERTICAL, false)
......
...@@ -72,14 +72,14 @@ class FindFlatScreenController : ...@@ -72,14 +72,14 @@ class FindFlatScreenController :
@Inject @Inject
override lateinit var injectedPresenter: FindFlatScreenPresenter override lateinit var injectedPresenter: FindFlatScreenPresenter
val estateTabs = arrayListOf( private val estateTabs = arrayListOf(
EstateTabModel("Д1",1), EstateTabModel("Д1",1),
EstateTabModel("Д2",2), EstateTabModel("Д2",2),
EstateTabModel("Д3",3) EstateTabModel("Д3",3)
) )
override fun onViewBound(v: View) { override fun onViewBound(v: View) {
// setToolbar() setToolbar()
estateTabs.forEach {estate -> estateTabs.forEach {estate ->
val tab = flatTabs.newTab() val tab = flatTabs.newTab()
.setCustomView(R.layout.to_flat_tab_view) .setCustomView(R.layout.to_flat_tab_view)
......
...@@ -55,16 +55,14 @@ ...@@ -55,16 +55,14 @@
android:id="@+id/feed_title_info_text_view" android:id="@+id/feed_title_info_text_view"
style="@style/Feed_Title" style="@style/Feed_Title"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="0dp"
android:layout_marginTop="8dp" android:layout_marginTop="4dp"
android:layout_marginBottom="4dp"
android:includeFontPadding="false" android:includeFontPadding="false"
android:text="В «РУМЯНЦЕВО-ПАРК» ПРИСТУПИЛИ К МОНТАЖУ ОКОННЫХ БЛОКОВ" android:text="В «РУМЯНЦЕВО-ПАРК» ПРИСТУПИЛИ К МОНТАЖУ ОКОННЫХ БЛОКОВ"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/guideline" app:layout_constraintStart_toStartOf="@+id/guideline"
app:layout_constraintTop_toBottomOf="@+id/feed_date_text_view" app:layout_constraintTop_toBottomOf="@+id/feed_date_text_view" />
app:layout_constraintVertical_bias="0.0" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
...@@ -58,12 +58,12 @@ ...@@ -58,12 +58,12 @@
android:id="@+id/feed_title_info_text_view" android:id="@+id/feed_title_info_text_view"
style="@style/Common_Text.Inverted" style="@style/Common_Text.Inverted"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="0dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="32dp" android:layout_marginEnd="32dp"
android:layout_marginBottom="8dp"
android:includeFontPadding="false" android:includeFontPadding="false"
android:maxLines="3" android:maxLines="3"
android:text="В «РУМЯНЦЕВО-ПАРК» ПРИСТУПИЛИ К МОНТАЖУ ОКОННЫХ БЛОКОВ" android:text="В «РУМЯНЦЕВО-ПАРК» ПРИСТУПИЛИ К МОН ТАЖУ dadasdasd a 22ЫХ БЛОКОВ"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/guideline" app:layout_constraintStart_toEndOf="@+id/guideline"
......
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary"
xmlns:android="http://schemas.android.com/apk/res/android">
<!--<com.biganto.visual.androidplayer.presentation.screen.home_routing.NonSwipeableViewPager-->
<!--android:id="@+id/tabsContainerViewPager"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="match_parent" />-->
<com.bluelinelabs.conductor.ChangeHandlerFrameLayout
android:id="@+id/tabContainer"
android:background="@color/colorPrimary"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment