Skip to content

Commit

Permalink
Merge pull request #142 from icerockdev/#100-search-screen
Browse files Browse the repository at this point in the history
NavigationBar.Search
  • Loading branch information
Alex009 authored Feb 25, 2020
2 parents bc7fa23 + 7e1ac54 commit a540b8a
Show file tree
Hide file tree
Showing 11 changed files with 496 additions and 139 deletions.
18 changes: 17 additions & 1 deletion sample/mpp-library/src/commonMain/kotlin/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import dev.icerock.moko.widgets.factory.SystemTabsViewFactory
import dev.icerock.moko.widgets.factory.SystemTextViewFactory
import dev.icerock.moko.widgets.flat.FlatInputViewFactory
import dev.icerock.moko.widgets.sample.InputWidgetGalleryScreen
import dev.icerock.moko.widgets.sample.ProductsSearchScreen
import dev.icerock.moko.widgets.sample.ScrollContentScreen
import dev.icerock.moko.widgets.sample.SelectGalleryScreen
import dev.icerock.moko.widgets.screen.Args
Expand Down Expand Up @@ -104,6 +105,7 @@ class App() : BaseApplication() {
theme = theme,
routes = listOf(
buildInputGalleryRouteInfo(theme, router),
buildSearchRouteInfo(theme, router),
SelectGalleryScreen.RouteInfo(
name = "Old Demo".desc(),
route = router.createPushRoute(oldDemo(router))
Expand Down Expand Up @@ -142,7 +144,21 @@ class App() : BaseApplication() {
)
}

fun oldDemo(
private fun buildSearchRouteInfo(
theme: Theme,
router: NavigationScreen.Router
): SelectGalleryScreen.RouteInfo {
val searchScreen = registerScreen(ProductsSearchScreen::class) {
ProductsSearchScreen(theme)
}

return SelectGalleryScreen.RouteInfo(
name = "SearchScreen".desc(),
route = router.createPushRoute(searchScreen)
)
}

private fun oldDemo(
router: NavigationScreen.Router
): TypedScreenDesc<Args.Empty, LoginScreen> {
val sharedFactory = SharedFactory()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class ProductScreen(
override val navigationBar
get() = NavigationBar.Normal(
title = getArgument().productId.let { "Product $it".desc() },
styles = NavigationBar.Normal.Styles(
styles = NavigationBar.Styles(
backgroundColor = Color(0x00AA00FF),
tintColor = Color(0xFF0000FF),
textStyle = TextStyle(
Expand All @@ -51,12 +51,12 @@ class ProductScreen(
)
),
actions = listOf(
NavigationBar.Normal.BarButton(
NavigationBar.BarButton(
icon = MR.images.cart_black_18
) {
println("first press")
},
NavigationBar.Normal.BarButton(
NavigationBar.BarButton(
icon = MR.images.stars_black_18
) {
println("second press")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*
* Copyright 2020 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license.
*/

package dev.icerock.moko.widgets.sample

import dev.icerock.moko.graphics.Color
import dev.icerock.moko.mvvm.livedata.LiveData
import dev.icerock.moko.mvvm.livedata.MutableLiveData
import dev.icerock.moko.mvvm.livedata.map
import dev.icerock.moko.mvvm.viewmodel.ViewModel
import dev.icerock.moko.resources.desc.StringDesc
import dev.icerock.moko.resources.desc.desc
import dev.icerock.moko.units.TableUnitItem
import dev.icerock.moko.widgets.ListWidget
import dev.icerock.moko.widgets.constraint
import dev.icerock.moko.widgets.core.Theme
import dev.icerock.moko.widgets.list
import dev.icerock.moko.widgets.screen.Args
import dev.icerock.moko.widgets.screen.WidgetScreen
import dev.icerock.moko.widgets.screen.getViewModel
import dev.icerock.moko.widgets.screen.navigation.NavigationBar
import dev.icerock.moko.widgets.screen.navigation.NavigationItem
import dev.icerock.moko.widgets.style.background.Background
import dev.icerock.moko.widgets.style.background.Fill
import dev.icerock.moko.widgets.style.view.SizeSpec
import dev.icerock.moko.widgets.style.view.WidgetSize
import dev.icerock.moko.widgets.text
import dev.icerock.moko.widgets.units.UnitItemRoot
import dev.icerock.moko.widgets.units.WidgetsTableUnitItem

class ProductsSearchScreen(
private val theme: Theme
) : WidgetScreen<Args.Empty>(), NavigationItem {

private val viewModel: ProductsSearchViewModel by lazy {
getViewModel { ProductsSearchViewModel() }
}

override val navigationBar: NavigationBar
get() = NavigationBar.Search(
title = "Products search".desc(),
styles = NavigationBar.Styles(
backgroundColor = Color(0xFFFFFFFF),
tintColor = Color(0x111111FF)
),
searchQuery = viewModel.searchQuery,
searchPlaceholder = "Product title".desc(),
androidSearchBackground = Background(
fill = Fill.Solid(color = Color(0xF2F2F2FF)),
cornerRadius = 2f
)
)

override fun createContentWidget() = with(theme) {
constraint(size = WidgetSize.AsParent) {
val results = +list(
size = WidgetSize.Const(width = SizeSpec.MatchConstraint, height = SizeSpec.MatchConstraint),
items = viewModel.products.map { products ->
products.map { ProductUnitItem(theme, itemId = it.hashCode().toLong(), data = it) as TableUnitItem }
},
id = Ids.ResultsList
)

constraints {
results topToTop root.safeArea
results leftRightToLeftRight root
results bottomToBottom root.safeArea
}
}
}

object Ids {
object ResultsList : ListWidget.Id
}

class ProductUnitItem(
private val theme: Theme,
itemId: Long,
data: String
) : WidgetsTableUnitItem<String>(itemId, data) {
override val reuseId: String = "ProductUnitItem"

override fun createWidget(data: LiveData<String>): UnitItemRoot {
return with(theme) {
constraint(
size = WidgetSize.WidthAsParentHeightWrapContent
) {
val title = +text(
size = WidgetSize.WidthAsParentHeightWrapContent,
text = data.map { it.desc() as StringDesc }
)

constraints {
title topToTop root offset 8
title leftRightToLeftRight root offset 16
title bottomToBottom root
}
}
}.let { UnitItemRoot.from(it) }
}
}
}

class ProductsSearchViewModel : ViewModel() {
val searchQuery = MutableLiveData(initialValue = "")

private val _products: List<String> = List(size = 50) { "It's product $it" }

val products: LiveData<List<String>> = searchQuery.map { query ->
_products
.filter { it.contains(query) }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class SelectGalleryScreen(

override val navigationBar: NavigationBar = NavigationBar.Normal(
title = "Select gallery".desc(),
styles = NavigationBar.Normal.Styles(
styles = NavigationBar.Styles(
backgroundColor = Color(0x4444EEFF)
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,12 @@
package dev.icerock.moko.widgets.screen.navigation

import android.content.Context
import android.graphics.Typeface
import android.os.Bundle
import android.text.Spannable
import android.text.SpannableString
import android.text.style.AbsoluteSizeSpan
import android.text.style.StyleSpan
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.ViewGroup
import android.widget.LinearLayout
import androidx.activity.OnBackPressedCallback
import androidx.appcompat.widget.Toolbar
import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.DrawableCompat
import androidx.core.view.ViewCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentContainerView
Expand All @@ -30,10 +22,9 @@ import dev.icerock.moko.widgets.screen.FragmentNavigation
import dev.icerock.moko.widgets.screen.Screen
import dev.icerock.moko.widgets.screen.TypedScreenDesc
import dev.icerock.moko.widgets.screen.unsafeSetScreenArgument
import dev.icerock.moko.widgets.style.view.FontStyle
import dev.icerock.moko.widgets.style.apply
import dev.icerock.moko.widgets.utils.ThemeAttrs
import dev.icerock.moko.widgets.utils.dp
import dev.icerock.moko.widgets.utils.sp


actual abstract class NavigationScreen<S> actual constructor(
Expand Down Expand Up @@ -202,80 +193,18 @@ actual abstract class NavigationScreen<S> actual constructor(
toolbar.visibility = View.GONE
}
is NavigationBar.Normal -> {
toolbar.visibility = View.VISIBLE

val title = navBar.title.toString(context)
toolbar.title = SpannableString(title).apply {
val size = navBar.styles?.textStyle?.size?.toFloat()?.sp(context)
if (size != null) {
val sizeSpan = AbsoluteSizeSpan(size.toInt())
setSpan(sizeSpan, 0, title.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
}

val fontStyle = navBar.styles?.textStyle?.fontStyle
if (fontStyle != null) {
val style = when (fontStyle) {
FontStyle.BOLD -> Typeface.BOLD
FontStyle.MEDIUM -> Typeface.NORMAL
}
val styleSpan = StyleSpan(style)
setSpan(styleSpan, 0, title.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
}
}

val bgColor = if (navBar.styles?.backgroundColor != null) {
navBar.styles.backgroundColor.argb.toInt()
} else {
ThemeAttrs.getPrimaryColor(context)
}
toolbar.setBackgroundColor(bgColor)

val fallbackTintColor = ThemeAttrs.getControlNormalColor(context)

val tintColor = navBar.styles?.tintColor?.argb?.toInt() ?: fallbackTintColor

toolbar.setTitleTextColor(tintColor)
toolbar.overflowIcon?.also { DrawableCompat.setTint(it, tintColor) }

if (navBar.styles?.textStyle?.color != null) {
toolbar.setTitleTextColor(navBar.styles.textStyle.color.argb.toInt())
} else {
toolbar.setTitleTextColor(fallbackTintColor)
}

val backBtn = navBar.backButton
if (backBtn != null) {
toolbar.navigationIcon = ContextCompat.getDrawable(context, backBtn.icon.drawableResId)
toolbar.setNavigationOnClickListener {
backBtn.action()
}
} else {
toolbar.navigationIcon = if (childFragmentManager.backStackEntryCount > 0) {
ThemeAttrs.getToolBarUpIndicator(requireContext())
} else {
null
}
toolbar.setNavigationOnClickListener {
childFragmentManager.popBackStack()
}
}
toolbar.navigationIcon?.also { DrawableCompat.setTint(it, tintColor) }

val actions = navBar.actions
if (actions != null) {
actions.forEach { barBtn ->
val item = toolbar.menu.add("$barBtn")
item.icon = ContextCompat.getDrawable(context, barBtn.icon.drawableResId)
DrawableCompat.setTint(item.icon, tintColor)
item.setOnMenuItemClickListener {
barBtn.action()
true
}
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS)
}
} else {
toolbar.menu.clear()
}
navBar.apply(
toolbar = toolbar,
context = context,
fragmentManager = childFragmentManager
)
}
is NavigationBar.Search -> {
navBar.apply(
toolbar = toolbar,
context = context,
fragmentManager = childFragmentManager
)
}
}
}
Expand Down
Loading

0 comments on commit a540b8a

Please sign in to comment.