Commit 592b1a3f authored by Vladislav Bogdashkin's avatar Vladislav Bogdashkin 🎣

adde botoom navigation bar

parent d8e14f50
...@@ -78,7 +78,7 @@ class RoomParkMainActivity( ...@@ -78,7 +78,7 @@ class RoomParkMainActivity(
} }
override fun showAll() { override fun showAll() {
appBar.setExpanded(false,false) appBar.setExpanded(true,false)
collapsingToolbarLayout.visibility= View.VISIBLE collapsingToolbarLayout.visibility= View.VISIBLE
bottomNavigation.visibility = Toolbar.VISIBLE bottomNavigation.visibility = Toolbar.VISIBLE
bottomShadow.visibility = View.VISIBLE bottomShadow.visibility = View.VISIBLE
......
package com.biganto.visual.roompark.conductor package com.biganto.visual.roompark.conductor
import com.hannesdorfmann.mosby3.mvp.MvpView import com.hannesdorfmann.mosby3.mvp.MvpView
import timber.log.Timber
/** /**
* Created by Vladislav Bogdashkin on 28.05.2018. * Created by Vladislav Bogdashkin on 28.05.2018.
*/ */
interface BigantoBaseContract<in VS : BigantoBaseViewState> : MvpView { interface BigantoBaseContract<in VS : BigantoBaseViewState> : MvpView {
fun render(viewState: VS) fun render(viewState: VS) =
Timber.d("Render state ${viewState.javaClass}")
} }
abstract class BigantoBaseViewState abstract class BigantoBaseViewState
\ No newline at end of file
...@@ -4,8 +4,9 @@ import com.biganto.visual.roompark.domain.contract.AuthContract ...@@ -4,8 +4,9 @@ import com.biganto.visual.roompark.domain.contract.AuthContract
import com.biganto.visual.roompark.domain.model.AuthInfoModel import com.biganto.visual.roompark.domain.model.AuthInfoModel
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import io.reactivex.rxjava3.core.Completable import io.reactivex.Completable
import io.reactivex.rxjava3.core.Observable import io.reactivex.Observable
import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
...@@ -34,9 +35,14 @@ class AppModule() { ...@@ -34,9 +35,14 @@ class AppModule() {
class AuthContractModule @Inject constructor():AuthContract{ class AuthContractModule @Inject constructor():AuthContract{
init {
Timber.d("Auth Repository Created")
}
override fun signOut(): Completable = Completable.complete() override fun signOut(): Completable = Completable.complete()
override fun signIn(email: String, password: String): Observable<AuthInfoModel> { override fun signIn(email: String, password: String): Observable<AuthInfoModel> {
Timber.d("Gonna signIIn")
return Observable.just(AuthInfoModel("some tokan zzaza",1488, "hi4", "biganto@demo.ru")) return Observable.just(AuthInfoModel("some tokan zzaza",1488, "hi4", "biganto@demo.ru"))
} }
......
package com.biganto.visual.roompark.domain.contract package com.biganto.visual.roompark.domain.contract
import com.biganto.visual.roompark.domain.model.AuthInfoModel import com.biganto.visual.roompark.domain.model.AuthInfoModel
import io.reactivex.rxjava3.core.Completable import io.reactivex.Completable
import io.reactivex.rxjava3.core.Observable import io.reactivex.Observable
/** /**
......
...@@ -12,6 +12,6 @@ class AuthInteractor @Inject constructor( ...@@ -12,6 +12,6 @@ class AuthInteractor @Inject constructor(
){ ){
fun getAuth() = uc.validateAuth() fun getAuth() = uc.validateAuth()
fun authorizate(login:String, password:String) = fun signIn(login:String, password:String) =
uc.authorizate(login,password) uc.signIn(login,password)
} }
\ No newline at end of file
...@@ -14,7 +14,7 @@ class AuthUseCase @Inject constructor( ...@@ -14,7 +14,7 @@ class AuthUseCase @Inject constructor(
fun validateAuth() = Observable.just(true) fun validateAuth() = Observable.just(true)
fun authorizate(login:String,pwd:String) = authContract.signIn(login,pwd) fun signIn(login:String,pwd:String) = authContract.signIn(login,pwd)
......
...@@ -8,11 +8,14 @@ import com.biganto.visual.roompark.R ...@@ -8,11 +8,14 @@ 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.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
import com.google.android.material.textfield.TextInputLayout import com.google.android.material.textfield.TextInputLayout
import com.jakewharton.rxbinding3.view.clicks import com.jakewharton.rxbinding3.view.clicks
import io.reactivex.Observable import io.reactivex.Observable
import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
/** /**
...@@ -68,6 +71,8 @@ class AuthScreenController : ...@@ -68,6 +71,8 @@ class AuthScreenController :
override fun render(viewState: AuthScreenViewState) { override fun render(viewState: AuthScreenViewState) {
super.render(viewState)
Timber.d("Render state $viewState")
when(viewState){ when(viewState){
is AuthScreenViewState.Idle -> render(viewState) is AuthScreenViewState.Idle -> render(viewState)
is AuthScreenViewState.Authorization -> render(viewState) is AuthScreenViewState.Authorization -> render(viewState)
...@@ -83,17 +88,20 @@ class AuthScreenController : ...@@ -83,17 +88,20 @@ class AuthScreenController :
} }
private fun render(viewState: AuthScreenViewState.Authorization){ private fun render(viewState: AuthScreenViewState.Authorization){
toolBar.hideAll() // toolBar.hideAll()
signInButton.isEnabled = false
// snacky.showSnackBar("lul") // snacky.showSnackBar("lul")
} }
private fun render(viewState: AuthScreenViewState.SignedIn){ private fun render(viewState: AuthScreenViewState.SignedIn){
router.setRoot(RouterTransaction.with(HomeController()))
// snacky.showSnackBar("lul") // snacky.showSnackBar("lul")
} }
private fun render(viewState: AuthScreenViewState.SignInError){ private fun render(viewState: AuthScreenViewState.SignInError){
snackbar.showSnackBar(viewState.message, Snackbar.LENGTH_LONG) snackbar.showSnackBar(viewState.message, Snackbar.LENGTH_LONG)
toolBar.hideAll() // toolBar.hideAll()
signInButton.isEnabled=true
// snacky.showSnackBar("lul") // snacky.showSnackBar("lul")
} }
......
...@@ -2,6 +2,9 @@ package com.biganto.visual.roompark.presentation.screen.auth ...@@ -2,6 +2,9 @@ package com.biganto.visual.roompark.presentation.screen.auth
import com.biganto.visual.roompark.conductor.BigantoBasePresenter import com.biganto.visual.roompark.conductor.BigantoBasePresenter
import com.biganto.visual.roompark.domain.interactor.AuthInteractor import com.biganto.visual.roompark.domain.interactor.AuthInteractor
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
/** /**
...@@ -18,13 +21,22 @@ class AuthScreenPresenter @Inject constructor( ...@@ -18,13 +21,22 @@ class AuthScreenPresenter @Inject constructor(
override fun bindIntents() { override fun bindIntents() {
val onAuth = intent(AuthScreen::tryAuth) val onAuth = intent(AuthScreen::tryAuth)
.flatMap { interactor.getAuth() } .flatMap<AuthScreenViewState>{ model ->
interactor.signIn(model.login, model.pwd)
.doOnNext{Timber.d("auth returned $it")}
.map { it }
.map<AuthScreenViewState> { AuthScreenViewState.SignInError("") }
.map { AuthScreenViewState.SignedIn() }
}
// .startWith(Observable.just(AuthScreenViewState.Authorization()))
val state = restoreStateObservable val state = restoreStateObservable
.mergeWith(interactor.getAuth() .mergeWith(onAuth)
.map { AuthScreenViewState.ToScreen(it.toString()) }) .doOnError{ Timber.e(it)}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
subscribeViewState(state.cast(AuthScreenViewState::class.java), AuthScreen::render) subscribeViewState(state.cast(AuthScreenViewState::class.java), AuthScreen::render)
} }
......
package com.biganto.visual.roompark.presentation.screen.home
import android.os.Bundle
import android.os.Parcelable
import android.util.SparseArray
import android.view.Menu
import android.view.View
import android.view.ViewGroup
import androidx.annotation.NonNull
import androidx.core.view.contains
import androidx.core.view.forEach
import androidx.core.view.get
import androidx.viewpager.widget.PagerAdapter
import androidx.viewpager.widget.ViewPager
import com.bluelinelabs.conductor.Controller
import com.bluelinelabs.conductor.Router
import com.bluelinelabs.conductor.RouterTransaction
import com.google.android.material.bottomnavigation.BottomNavigationView
import timber.log.Timber
/**
* Created by Vladislav Bogdashkin on 11.10.2019.
*/
class BNVRouterPagerAdapter(
val host: Controller,
val bnv: BottomNavigationView,
val viewPager: ViewPager,
val pages: Map<Int, () -> Controller>
): PagerAdapter() {
companion object {
private const val KEY_SAVED_PAGES = "BottomBarRouterPagerAdapter.savedStates"
private const val KEY_MAX_PAGES_TO_STATE_SAVE = "BottomBarRouterPagerAdapter.maxPagesToStateSave"
private const val KEY_SAVE_PAGE_HISTORY = "BottomBarRouterPagerAdapter.savedPageHistory"
}
private var maxPagesToStateSave = Integer.MAX_VALUE
private val visibleRouters = SparseArray<Router>()
var currentPrimaryRouter: Router? = null
private set
var savedPageHistory = ArrayList<Int>()
private set
var savedPages: SparseArray<Bundle> = SparseArray()
private set
init {
require(bnv.menu.all { pages.containsKey(it.itemId) }) { "All menu items must have a matching page setup!" }
viewPager.adapter = this
bnv.setOnNavigationItemSelectedListener {
viewPager.currentItem = bnv.menu.indexOf(it)
true
}
}
/**
* Called when a router is instantiated. Here the router's root should be set if needed.
*
* @param router The router used for the page
* @param position The page position to be instantiated.
*/
fun configureRouter(@NonNull router: Router, position: Int) {
if(!router.hasRootController()) {
val page = pages[bnv.menu[position].itemId] ?: throw Exception("Page not found in initializers!")
router.setRoot(RouterTransaction.with(page.invoke()))
}
}
override fun getCount(): Int = bnv.menu.size()
override fun getPageTitle(position: Int): CharSequence? = bnv.menu[position].title
override fun instantiateItem(container: ViewGroup, position: Int): Any {
return host.getChildRouter(container, makeRouterName(container.id, getItemId(position))).apply {
if(!hasRootController()) {
val savedState = savedPages.get(position)
if(savedState != null) {
restoreInstanceState(savedState)
savedPages.remove(position)
savedPageHistory.remove(position)
}
rebindIfNeeded()
configureRouter(this, position)
if(this !== currentPrimaryRouter) {
backstack.forEach { it.controller().setOptionsMenuHidden(true) }
}
visibleRouters.put(position, this)
}
}
}
override fun destroyItem(container: ViewGroup, position: Int, router: Any) {
require(router is Router) { "Non-router object in router stack!" }
val savedState = Bundle()
router.saveInstanceState(savedState)
savedPages.put(position, savedState)
savedPageHistory.remove(position)
savedPageHistory.add(position)
ensurePagesSaved()
host.removeChildRouter(router)
visibleRouters.remove(position)
}
override fun setPrimaryItem(container: ViewGroup, position: Int, router: Any) {
require(router is Router) { "Non-router object in router stack!" }
if(router !== currentPrimaryRouter) {
currentPrimaryRouter?.backstack?.forEach { it.controller().setOptionsMenuHidden(true) }
router.backstack.forEach { it.controller().setOptionsMenuHidden(false) }
currentPrimaryRouter = router
}
}
override fun isViewFromObject(view: View, router: Any): Boolean {
require(router is Router) { "Non-router object in router stack!" }
for(transaction in router.backstack) if(transaction.controller().view == view) return true
return false
}
fun setMaxPagesToStateSave(maxPagesToStateSave: Int) {
require(maxPagesToStateSave >= 0) { "Only positive integers may be passed for maxPagesToStateSave." }
this.maxPagesToStateSave = maxPagesToStateSave
ensurePagesSaved()
}
override fun saveState(): Parcelable? {
return (super.saveState() as? Bundle? ?: Bundle()).apply {
putSparseParcelableArray(KEY_SAVED_PAGES, savedPages)
putInt(KEY_MAX_PAGES_TO_STATE_SAVE, maxPagesToStateSave)
putIntegerArrayList(KEY_SAVE_PAGE_HISTORY, savedPageHistory)
}
}
override fun restoreState(state: Parcelable?, loader: ClassLoader?) {
super.restoreState(state, loader)
(state as? Bundle?)?.apply {
savedPages = getSparseParcelableArray(KEY_SAVED_PAGES) ?: SparseArray()
maxPagesToStateSave = getInt(KEY_MAX_PAGES_TO_STATE_SAVE)
savedPageHistory = getIntegerArrayList(KEY_SAVE_PAGE_HISTORY) as ArrayList<Int>
}
}
fun getRouter(position: Int): Router = visibleRouters[position, null]
fun getItemId(position: Int): Long {
return bnv.menu.getItem(position).itemId.toLong()
}
private fun ensurePagesSaved() {
while (savedPages.size() > maxPagesToStateSave) {
val positionToRemove = savedPageHistory.removeAt(0)
savedPages.remove(positionToRemove)
}
}
private fun makeRouterName(viewId: Int, id: Long): String {
return "$viewId:$id"
}
}
fun Menu.all(predicate: (android.view.MenuItem) -> Boolean): Boolean {
if(size() == 0) return false
for(index in (0 until size())) if(!predicate(get(index))) return false
return true
}
fun Menu.indexOf(item: android.view.MenuItem): Int {
require(size() > 0) { "Menu is empty!" }
require(contains(item)) { "Item is not part of menu!" }
for(index in (0 until size())) if(get(index) == item) return index
throw Exception("Item is not part of menu!")
}
\ No newline at end of file
package com.biganto.visual.roompark.presentation.screen.home
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.viewpager.widget.ViewPager
import butterknife.BindView
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.conductor.BigantoBaseController
import com.biganto.visual.roompark.presentation.screen.auth.AuthScreenController
import com.biganto.visual.roompark.presentation.screen.splash.SplashScreenController
import javax.inject.Inject
/**
* Created by Vladislav Bogdashkin on 11.10.2019.
*/
class HomeController :
BigantoBaseController<HomeScreenViewState
, HomeScreen
, HomeScreenPresenter>()
, HomeScreen {
override fun injectDependencies() {
getComponent()
}
@BindView(R.id.home_router_host)
lateinit var viewpager: ViewPager
@Inject
lateinit var tb: ICollapsingToolBar
@Inject
lateinit var bottomNavigation: IBottomNavigation
@Inject
override lateinit var injectedPresenter: HomeScreenPresenter
lateinit var pageAdapter : BNVRouterPagerAdapter
// @Inject
// lateinit var snacky:ISnackBarProvider
fun getComponent() = DaggerHomeScreenComponent
.factory()
.create(RoomParkApplication.component,activity as RoomParkMainActivity)
.inject(this)
// @Inject
// lateinit var ac: RoomParkMainActivity
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup): View {
val v = super.onCreateView(inflater, container)
tb.showAll()
pageAdapter = BNVRouterPagerAdapter(this,bottomNavigation.bottomNavigation,viewpager,
mapOf(
Pair(R.id.tab_feeds,{SplashScreenController()})
,Pair(R.id.tab_favorites,{AuthScreenController()})
,Pair(R.id.tab_deals,{AuthScreenController()})
,Pair(R.id.tab_look_flat,{AuthScreenController()})
,Pair(R.id.tab_settings,{SplashScreenController()})
)
)
return v
}
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(): Int = R.layout.home_screen_viewpager
}
\ No newline at end of file
package com.biganto.visual.roompark.presentation.screen.home
import com.biganto.visual.roompark.conductor.BigantoBaseContract
import com.biganto.visual.roompark.presentation.screen.home.HomeScreenViewState
/**
* Created by Vladislav Bogdashkin on 30.09.2019.
*/
interface HomeScreen : BigantoBaseContract<HomeScreenViewState> {
}
\ No newline at end of file
package com.biganto.visual.roompark.presentation.screen.home
import android.content.Context
import com.biganto.visual.roompark.base.IBottomNavigation
import com.biganto.visual.roompark.base.ICollapsingToolBar
import com.biganto.visual.roompark.base.RoomParkMainActivity
import com.biganto.visual.roompark.di.dagger.AppComponent
import com.biganto.visual.roompark.di.dagger.AuthContractModule
import com.biganto.visual.roompark.di.dagger.PerScreen
import com.biganto.visual.roompark.domain.contract.AuthContract
import dagger.Binds
import dagger.BindsInstance
import dagger.Component
import dagger.Module
///**
// * Created by Vladislav Bogdashkin on 30.09.2019.
// */
@PerScreen
@Component(
modules = [HomeScreenModule::class],
dependencies = [AppComponent::class])
interface HomeScreenComponent {
@Component.Factory
interface Factory{
fun create(
appComponent: AppComponent
,@BindsInstance activity: RoomParkMainActivity
): HomeScreenComponent
}
val presenter: HomeScreenPresenter
fun inject(controller: HomeController)
}
@Module
abstract class HomeScreenModule{
@PerScreen
@Binds
abstract fun provideContext(activity: RoomParkMainActivity): Context
@PerScreen
@Binds
abstract fun provideAuth(contract: AuthContractModule): AuthContract
@PerScreen
@Binds
abstract fun provideToolbar(activitiy: RoomParkMainActivity): ICollapsingToolBar
@PerScreen
@Binds
abstract fun provideBottomNavigation(activitiy: RoomParkMainActivity): IBottomNavigation
}
package com.biganto.visual.roompark.presentation.screen.home
import com.biganto.visual.roompark.conductor.BigantoBasePresenter
import javax.inject.Inject
/**
* Created by Vladislav Bogdashkin on 30.09.2019.
*/
class HomeScreenPresenter @Inject constructor(
// ,var context:Context
)
: BigantoBasePresenter<HomeScreen, HomeScreenViewState>() {
override fun bindIntents() {
val state = restoreStateObservable
subscribeViewState(state.cast(HomeScreenViewState::class.java), HomeScreen::render)
}
}
\ No newline at end of file
package com.biganto.visual.roompark.presentation.screen.home
import com.biganto.visual.roompark.conductor.BigantoBaseViewState
/**
* Created by Vladislav Bogdashkin on 30.09.2019.
*/
sealed class HomeScreenViewState : BigantoBaseViewState() {
class Idle : HomeScreenViewState()
class ToScreen(val message:String) : HomeScreenViewState()
}
\ No newline at end of file
...@@ -68,7 +68,7 @@ class SplashScreenController : ...@@ -68,7 +68,7 @@ class SplashScreenController :
private fun render(viewState: SplashScreenViewState.ToScreen){ private fun render(viewState: SplashScreenViewState.ToScreen){
snackbar.showSnackBar(viewState.message, Snackbar.LENGTH_LONG) snackbar.showSnackBar(viewState.message, Snackbar.LENGTH_LONG)
tb.hideAll() // tb.hideAll()
router.pushController(RouterTransaction.with(AuthScreenController()) router.pushController(RouterTransaction.with(AuthScreenController())
.popChangeHandler(FadeChangeHandler()) .popChangeHandler(FadeChangeHandler())
.pushChangeHandler(FadeChangeHandler()) .pushChangeHandler(FadeChangeHandler())
......
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:color="@color/colorAccent" />
<item android:color="@color/colorGray" />
</selector>
\ No newline at end of file
...@@ -104,7 +104,8 @@ ...@@ -104,7 +104,8 @@
app:itemHorizontalTranslationEnabled="false" app:itemHorizontalTranslationEnabled="false"
app:itemIconTint="@drawable/bottom_navigation_icon_selector" app:itemIconTint="@drawable/bottom_navigation_icon_selector"
app:labelVisibilityMode="labeled" app:labelVisibilityMode="labeled"
app:menu="@menu/bottom_navigation_menu"> app:menu="@menu/bottom_navigation_menu"
tools:visibility="visible">
</com.google.android.material.bottomnavigation.BottomNavigationView> </com.google.android.material.bottomnavigation.BottomNavigationView>
......
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:text="@string/enter" android:text="@string/enter"
android:textAlignment="textStart" android:textAlignment="textStart"
......
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.viewpager.widget.ViewPager
android:id="@+id/home_router_host"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
\ No newline at end of file
...@@ -132,6 +132,7 @@ ...@@ -132,6 +132,7 @@
<style name="AuthButton.Enable"> <style name="AuthButton.Enable">
<item name="android:text">"ВОЙТИ"</item> <item name="android:text">"ВОЙТИ"</item>
<item name="strokeColor">@color/sign_in_button_selector</item>
</style> </style>
......
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