I want to build searchview in center of screen and when I focus I want to move into toolbar. Remove Searchview only from toolbar when I remove focus from SearchView. I don't won't in different activities/fragments. Something similar to this view. I tried some piece of code but lack of knowledge so I didn't succeed. Can someone guide me
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
UPDATE
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@ id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.AppBarLayout
android:id="@ id/appBar"
android:layout_width="match_parent"
android:layout_height="100dp"
android:backgroundTint="@color/orange_lighter"
android:gravity="bottom"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<androidx.appcompat.widget.SearchView
android:id="@ id/consultationSearchView"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:theme="@style/SearchViewTheme"
app:closeIcon="@drawable/ic_cancel"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
app:searchIcon="@drawable/ic_search" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@ id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
// more views
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Activity code
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
class ExploreConsultationsActivity : BaseActivity() {
companion object {
const val CONSULTATION_COVER_LIST_KEY = "consultation_cover_list"
}
private val binding by lazy { ExploreConsultationsLayoutBinding.inflate(layoutInflater) }
val viewModel by viewModel<ExploreConsultationViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setupViewModel()
setContentView(binding.root)
setupView()
}
fun setupViewModel() {
viewModel.categoriesList = intent?.getParcelableArrayListExtra(CONSULTATION_COVER_LIST_KEY)
}
fun setupView() {
hideActionBar()
setupSearchView()
}
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.removeSearchViewFocus.value = false
viewModel.queryText = newText
}
return true
}
})
setOnQueryTextFocusChangeListener { _, hasFocus ->
binding.appBar.setExpanded(!hasFocus)
isSelected = hasFocus
}
}
}
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
if (ev?.action == MotionEvent.ACTION_DOWN) {
val view: View? = currentFocus
if (view is SearchView) {
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)
}
}
CodePudding user response:
To achieve something similar to the gif that you attached , you can try this :
In your activity_main.xml
layout file :
<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.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"
/>
</com.google.android.material.appbar.AppBarLayout>
<!-- Scrollable content -->
</androidx.coordinatorlayout.widget.CoordinatorLayout>
In your MainActivity.java
file :
public class MainActivity extends Activity {
private TextInputEditText txt;
private AppBarLayout appBarLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txt = findViewById(R.id.textField);
appBarLayout = findViewById(R.id.appBar);
//This code will collapse the AppBar according to the focus on the textField
txt.setOnFocusChangeListener((v, hasFocus) -> {
appBarLayout.setExpanded(!hasFocus);
});
}
// Function to clear focus from the textfield when you touch outside the view
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
View v = getCurrentFocus();
if (v instanceof SearchView.SearchAutoComplete) {
Rect outRect = new Rect();
v.getGlobalVisibleRect(outRect);
if (!outRect.contains((int)event.getRawX(), (int)event.getRawY())) {
v.clearFocus();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
}
}
return super.dispatchTouchEvent( event );
}
}
You can modify the layout further to achieve your desired look.