How to use Appbar with toolbar in android
V

1

1

Hey I am working on search bar in android. I get the lead from this post. Now I want to try something more. Above post explanation in short :- I have searchview in the middle of screen. When we focus to on searchview we animate to go to top of screen and after remove focus goes to original position of search view. Now I want to show back arrow with initial screen load, look like this

Image 1

enter image description here

When we focus I need to show screen like this

Image 2

enter image description here

I tried some piece of code, but I am not succeed

ExploreConsultationsLayoutBinding.xml

<androidx.coordinatorlayout.widget.CoordinatorLayout 
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:focusable="true">


  <com.google.android.material.appbar.AppBarLayout
    android:id="@+id/appBar"
    android:layout_width="match_parent"
    android:gravity="bottom"
    android:backgroundTint="@color/red_primary_80"
    android:layout_height="?attr/collapsingToolbarLayoutLargeSize"
    android:fitsSystemWindows="true">

      <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="@color/black">

    <androidx.appcompat.widget.SearchView
        android:id="@+id/searchView"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:layout_marginStart="16dp"
        app:iconifiedByDefault="false"
        android:layout_marginEnd="16dp"
        app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
     />

     </androidx.appcompat.widget.Toolbar>

   </com.google.android.material.appbar.AppBarLayout>


             <!-- Scrollable content -->

</androidx.coordinatorlayout.widget.CoordinatorLayout>

ExploreConsultationsActivity.kt

package com.example.app.consultation

import android.content.Context
import android.graphics.Rect
import android.os.Bundle
import android.view.MotionEvent
import android.view.View
import android.view.inputmethod.InputMethodManager
import androidx.appcompat.widget.SearchView
import com.example.app.common.BaseActivity
import com.example.app.databinding.ExploreConsultationsLayoutBinding
import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koin.core.parameter.parametersOf

class ExploreConsultationsActivity : BaseActivity() {

    companion object {
        const val CONSULTATION_LIST_KEY = "consultation_list"
    }

    private val binding by lazy { ExploreConsultationsLayoutBinding.inflate(layoutInflater) }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(binding.root)
        setupView()
    }

    fun setupView() {
        hideActionBar()
        setupSearchView()
    }

    fun hideActionBar() {
        supportActionBar?.let { actionBar ->
            actionBar.hide()
        }
    }

    fun setupSearchView() {
        binding.consultationSearchView.apply {
            setOnQueryTextListener(object : SearchView.OnQueryTextListener {
                override fun onQueryTextSubmit(query: String?) = false
                override fun onQueryTextChange(newText: String?): Boolean {
                    if (newText != null) {
                        viewModel.queryText = newText
                    }
                    return true
                }
            })
            setOnQueryTextFocusChangeListener { view, hasFocus ->
                binding.appBar.setExpanded(!hasFocus)
                if (hasFocus) {
                    binding.toolbar.apply {
                        setSupportActionBar(this)
                        supportActionBar?.setDisplayHomeAsUpEnabled(true)
                    }
                } else {
                    supportActionBar?.setDisplayHomeAsUpEnabled(false)
                }
                isSelected = hasFocus
            }
        }
    }

    override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
        if (ev?.action == MotionEvent.ACTION_DOWN) {
            val view: View? = currentFocus
            if (view is SearchView.SearchAutoComplete) {
                val outRect = Rect()
                view.getGlobalVisibleRect(outRect);
                if (!outRect.contains(ev.rawX.toInt(), ev.rawY.toInt())) {
                    view.clearFocus()
                    val inputMethodManager = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
                    inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
                }
            }
        }
        return super.dispatchTouchEvent(ev)
    }
}

Mainfest.xml

<activity android:name="ExploreConsultationsActivity"
            android:screenOrientation="portrait"
            android:theme="@style/NoActionBar"/>

Style.xml

<style name="NoActionBar" parent="@style/Theme.MaterialComponents.Light.NoActionBar">
        <item name="colorPrimary">@color/abc</item>
        <item name="colorPrimaryDark">@color/xyz</item>
        <item name="colorAccent">@color/abc</item>
        <item name="android:theme">@style/AppTheme</item>
        <item name="android:colorBackground">@color/white</item>
        <item name="android:windowActionBar">false</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:statusBarColor">@color/status_bar</item>
        <item name="android:windowLightStatusBar" tools:ignore="NewApi">true</item>
</style>

Actual Output

enter image description here

enter image description here

Expected Output

Image 1 and Image 2 please look top image of question.

Github Project

UPDATE

enter image description here

my search view is very close to status bar so how can I give top margin or padding?

Volney answered 20/6, 2022 at 10:7 Comment(0)
C
1

You could change the start margin of the SearchView when it got the focus; and return it to the original margin when it loses the focus:

var originalMargin = 0
fun setupSearchView() {
    binding.consultationSearchView.apply {
        setOnQueryTextListener(object : SearchView.OnQueryTextListener {
            override fun onQueryTextSubmit(query: String?) = false
            override fun onQueryTextChange(newText: String?): Boolean {
                if (newText != null) {
                }
                return true
            }
        })

        val params =
            binding.consultationSearchView.layoutParams as CollapsingToolbarLayout.LayoutParams
        originalMargin = params.marginStart

        setOnQueryTextFocusChangeListener { view, hasFocus ->
            binding.appBar.setExpanded(!hasFocus)
            isSelected = hasFocus

            if (hasFocus)
                params.marginStart = originalMargin + 150 // arbitrary constant
            else
                params.marginStart = originalMargin
            view.layoutParams = params

        }
    }
}

Cytoplast answered 20/6, 2022 at 22:34 Comment(15)
How did you fix the whole code? Can I get the working solution?Volney
Didn't that code work with you?Cytoplast
yes it work. I have few other question should I create new question ? or ask in this one.Volney
If it is related to this question feel free to ask.. If i found it needs a long answer i would tell you to open a new question.Cytoplast
I am trying to set title but it's not working, until it explit set in xml.Volney
How do you set the titleCytoplast
I think I can open a new question. I tried some code. Can you help me on this.Volney
No problem, One question regarding this above post. In animation view you can see when you focus in the searchview, the searchview move to top and which is very close to statusbar. So How can we give margin or padding?Volney
This is because the SearchView height is android:layout_height="?attr/actionBarSize" which is the default ActionBar height; and when the CollapsingToolbar collapse; its default height will be equal to the ActionBar one; So, you see the SearchView takes the entire height... To fix this you need to make the SearchView height less than the ActionBar height.. something like "40dp" for instanceCytoplast
A little thing I forgot to mention in this answer; add android:animateLayoutChanges="true" so that it can could add some animation when the margin changes.Cytoplast
Ok I'll add above attribute. But how can I give in top margin when collapse ?Volney
You can solve it by adding a bottom margin to the Toolbar.. like android:layout_marginBottom="30dp"Cytoplast
android:animateLayoutChanges="true" in AppBarLayout or Toolbar ?Volney
Either the root layout CoordinatorLayout or AppBarLayoutCytoplast
I set to AppBarLayout. ThanksVolney

© 2022 - 2024 — McMap. All rights reserved.