From 3cc3658544034a1bc30c3fc8da8ca3858debc5bc Mon Sep 17 00:00:00 2001 From: Kirill Kamakin Date: Sun, 20 Nov 2022 14:18:51 +0100 Subject: [PATCH] Implement custom Toolbar View --- .../mealient/ui/activity/MainActivity.kt | 59 ++++++------------- .../mealient/ui/activity/ToolbarView.kt | 41 +++++++++++++ app/src/main/res/drawable/bg_toolbar.xml | 7 +++ .../main/res/layout/fragment_recipe_info.xml | 8 +-- app/src/main/res/layout/main_activity.xml | 12 ++-- .../res/layout/view_holder_instruction.xml | 2 +- .../main/res/layout/view_holder_recipe.xml | 8 +-- .../layout/view_navigation_drawer_header.xml | 2 +- app/src/main/res/layout/view_toolbar.xml | 36 +++++++++++ app/src/main/res/values-ru/strings.xml | 1 + app/src/main/res/values/dimens.xml | 1 + app/src/main/res/values/strings.xml | 1 + 12 files changed, 122 insertions(+), 56 deletions(-) create mode 100644 app/src/main/java/gq/kirmanak/mealient/ui/activity/ToolbarView.kt create mode 100644 app/src/main/res/drawable/bg_toolbar.xml create mode 100644 app/src/main/res/layout/view_toolbar.xml diff --git a/app/src/main/java/gq/kirmanak/mealient/ui/activity/MainActivity.kt b/app/src/main/java/gq/kirmanak/mealient/ui/activity/MainActivity.kt index 19f31ad..1a5ce60 100644 --- a/app/src/main/java/gq/kirmanak/mealient/ui/activity/MainActivity.kt +++ b/app/src/main/java/gq/kirmanak/mealient/ui/activity/MainActivity.kt @@ -4,10 +4,9 @@ import android.os.Bundle import android.view.MenuItem import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity -import androidx.appcompat.widget.SearchView -import androidx.appcompat.widget.SearchView.OnQueryTextListener import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import androidx.core.view.WindowInsetsControllerCompat +import androidx.core.view.isVisible import androidx.core.view.iterator import androidx.drawerlayout.widget.DrawerLayout import androidx.navigation.NavController @@ -60,13 +59,15 @@ class MainActivity : AppCompatActivity(R.layout.main_activity) { private fun setupUi() { binding.toolbar.setNavigationOnClickListener { binding.drawer.open() } + binding.toolbar.onSearchQueryChanged { query -> + viewModel.onSearchQuery(query.trim().takeUnless { it.isEmpty() }) + } binding.navigationView.setNavigationItemSelectedListener(::onNavigationItemSelected) with(WindowInsetsControllerCompat(window, window.decorView)) { val isAppearanceLightBars = !isDarkThemeOn() isAppearanceLightNavigationBars = isAppearanceLightBars isAppearanceLightStatusBars = isAppearanceLightBars } - setupSearchItem(binding.toolbar.menu.findItem(R.id.search_recipe_action)) viewModel.uiStateLive.observe(this, ::onUiStateChange) } @@ -104,44 +105,22 @@ class MainActivity : AppCompatActivity(R.layout.main_activity) { menuItem.isChecked = itemId == uiState.checkedMenuItemId } - if (uiState.navigationVisible) { - binding.root.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED) - binding.toolbar.setNavigationIcon(R.drawable.ic_menu) - } else { - binding.root.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED) - binding.toolbar.navigationIcon = null - } - - binding.toolbar.menu.findItem(R.id.search_recipe_action).isVisible = uiState.searchVisible - } - - private fun setupSearchItem(searchItem: MenuItem) { - logger.v { "setupSearchItem() called with: searchItem = $searchItem" } - val searchView = searchItem.actionView as? SearchView - if (searchView == null) { - logger.e { "setupSearchItem: search item's actionView is null or not SearchView" } - return - } - - searchView.queryHint = getString(R.string.search_recipes_hint) - searchView.isSubmitButtonEnabled = false - searchView.setIconifiedByDefault(false) - - searchView.setOnCloseListener { - logger.v { "onClose() called" } - viewModel.onSearchQuery(null) - false - } - - searchView.setOnQueryTextListener(object : OnQueryTextListener { - override fun onQueryTextSubmit(query: String?): Boolean = true - - override fun onQueryTextChange(newText: String?): Boolean { - logger.v { "onQueryTextChange() called with: newText = $newText" } - viewModel.onSearchQuery(newText?.trim()?.takeUnless { it.isEmpty() }) - return true + binding.toolbar.isVisible = uiState.navigationVisible + binding.root.setDrawerLockMode( + if (uiState.navigationVisible) { + DrawerLayout.LOCK_MODE_UNLOCKED + } else { + DrawerLayout.LOCK_MODE_LOCKED_CLOSED } - }) + ) + + binding.toolbar.isSearchVisible = uiState.searchVisible + + if (uiState.searchVisible) { + binding.toolbarHolder.setBackgroundResource(R.drawable.bg_toolbar) + } else { + binding.toolbarHolder.background = null + } } private fun navigateTo(directions: NavDirections) { diff --git a/app/src/main/java/gq/kirmanak/mealient/ui/activity/ToolbarView.kt b/app/src/main/java/gq/kirmanak/mealient/ui/activity/ToolbarView.kt new file mode 100644 index 0000000..65b1204 --- /dev/null +++ b/app/src/main/java/gq/kirmanak/mealient/ui/activity/ToolbarView.kt @@ -0,0 +1,41 @@ +package gq.kirmanak.mealient.ui.activity + +import android.content.Context +import android.util.AttributeSet +import android.view.LayoutInflater +import androidx.annotation.AttrRes +import androidx.annotation.StyleRes +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.view.isVisible +import androidx.core.widget.doAfterTextChanged +import gq.kirmanak.mealient.databinding.ViewToolbarBinding + +class ToolbarView @JvmOverloads constructor( + context: Context, + attributeSet: AttributeSet? = null, + @AttrRes defStyleAttr: Int = 0, + @StyleRes defStyleRes: Int = 0, +) : ConstraintLayout(context, attributeSet, defStyleAttr, defStyleRes) { + + private lateinit var binding: ViewToolbarBinding + + var isSearchVisible: Boolean + get() = binding.searchEdit.isVisible + set(value) { + binding.searchEdit.isVisible = value + } + + override fun onFinishInflate() { + super.onFinishInflate() + val inflater = LayoutInflater.from(context) + binding = ViewToolbarBinding.inflate(inflater, this) + } + + fun setNavigationOnClickListener(listener: OnClickListener?) { + binding.navigationIcon.setOnClickListener(listener) + } + + fun onSearchQueryChanged(block: (String) -> Unit) { + binding.searchEdit.doAfterTextChanged { block(it.toString()) } + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_toolbar.xml b/app/src/main/res/drawable/bg_toolbar.xml new file mode 100644 index 0000000..b123a8a --- /dev/null +++ b/app/src/main/res/drawable/bg_toolbar.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_recipe_info.xml b/app/src/main/res/layout/fragment_recipe_info.xml index 37a95bc..7f5e8b8 100644 --- a/app/src/main/res/layout/fragment_recipe_info.xml +++ b/app/src/main/res/layout/fragment_recipe_info.xml @@ -73,7 +73,7 @@ @@ -102,7 +102,7 @@ android:id="@+id/ingredients_list" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginHorizontal="10dp" + android:layout_marginHorizontal="@dimen/margin_small" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" tools:itemCount="3" tools:listitem="@layout/view_holder_ingredient" /> diff --git a/app/src/main/res/layout/main_activity.xml b/app/src/main/res/layout/main_activity.xml index 6b18902..684e7ba 100644 --- a/app/src/main/res/layout/main_activity.xml +++ b/app/src/main/res/layout/main_activity.xml @@ -17,16 +17,15 @@ android:id="@+id/toolbar_holder" android:layout_width="match_parent" android:layout_height="wrap_content" + android:layout_marginHorizontal="@dimen/margin_medium" + android:background="@drawable/bg_toolbar" app:liftOnScroll="true"> - + android:layout_height="wrap_content" + app:layout_scrollFlags="scroll|snap|enterAlways" /> diff --git a/app/src/main/res/layout/view_holder_instruction.xml b/app/src/main/res/layout/view_holder_instruction.xml index fe9fece..e633e30 100644 --- a/app/src/main/res/layout/view_holder_instruction.xml +++ b/app/src/main/res/layout/view_holder_instruction.xml @@ -2,7 +2,7 @@ diff --git a/app/src/main/res/layout/view_holder_recipe.xml b/app/src/main/res/layout/view_holder_recipe.xml index 6574973..a4152b5 100644 --- a/app/src/main/res/layout/view_holder_recipe.xml +++ b/app/src/main/res/layout/view_holder_recipe.xml @@ -2,12 +2,12 @@ + android:layout_marginVertical="@dimen/margin_small" + android:layout_marginStart="@dimen/margin_medium" + android:layout_marginEnd="@dimen/margin_medium"> + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index f5a69f7..36e0879 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -49,4 +49,5 @@ Ошибка загрузки. Сменить URL Найти рецепты + Открыть меню навигации \ No newline at end of file diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 1f2708e..3b149f6 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -1,4 +1,5 @@ 8dp + 16dp \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ce8f5b8..6c8778f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -52,4 +52,5 @@ Change URL Search recipes @string/app_name + Open navigation drawer \ No newline at end of file