I have a Fragment
which is used to make searches. Its layout has a "search bar" at the top, and then there is a TextView
and a RecyclerView
where I display the results. I would like to hide/show the search bar and the TextView
when user scrolls, like in this video, but instead of hiding the Toolbar
my idea is to hide the search bar and the TextView
. Something like this:
I already have a custom Toolbar
in the activity_main.xml
that must be fixed across the activity, only the search bar and the TextView
needs to be hidden/shown.
I tried to get it working using CoordinatorLayout
, but all examples I found were to show/hide the Toolbar
, hence I am not really sure if I can get what I want using CoordinatorLayout
.
After multiple attempts with CoordinatorLayout
, I decided to look for another solution and found this one. However, it does not work like in the sample. First of all, it breaks part of my code functionallity, and secondly altough the search bar and TextView
are hidden/shown, the RecyclerView
keeps it position instead of take the place of the other two views:
Finally, looking for more solutions I found this one that uses MotionLayout
. It works great except for one problem. When the RecyclerView
is empty, its visibility
is GONE
or the number of items to display can fit in the space available of the screen, the user can still scroll and hide the search bar and the TextView
:
I don't expect this behaviour, I expect the views to collapse only when the RecyclerView
is too big for the screen. How can achieve this?
I have been struggling with this the last couple of days and cannot find a solution, I hope you can help me. Find below the XML files. Thank you in advance!
Activity layout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout 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:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<!-- Contenedor principal para mostrar el Toolbar y el contenido oportuno-->
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<!-- Toolbar que hace de ActionBar -->
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="4dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
</com.google.android.material.appbar.AppBarLayout>
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<!-- Menú para moverse por la app -->
<com.google.android.material.navigation.NavigationView
android:id="@+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="@menu/menu" />
</androidx.drawerlayout.widget.DrawerLayout>
Fragment layout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:motion="http://schemas.android.com/apk/res-auto"
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"
motion:layoutDescription="@xml/motionscene"
tools:context=".SearchFragment">
<LinearLayout
android:id="@+id/buscador"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/cyan"
android:orientation="vertical"
android:paddingBottom="16dp"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent"
motion:layout_constraintBottom_toTopOf="@id/num_resultados">
<SearchView
android:id="@+id/search_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:background="@drawable/search_view_background"
android:iconifiedByDefault="false"
android:inputType="textPersonName"
android:queryBackground="@android:color/transparent"
android:queryHint="Buscar..." />
<RadioGroup
android:id="@+id/filtro_busqueda"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="horizontal">
<RadioButton
android:id="@+id/nom_futbolistico_Rb"
style="@style/SearchRadioButton"
android:checked="true"
android:text="@string/nombre_futbolistico" />
<RadioButton
android:id="@+id/nombre_Rb"
style="@style/SearchRadioButton"
android:layout_marginHorizontal="16dp"
android:text="@string/nombre" />
<RadioButton
android:id="@+id/apellidos_Rb"
style="@style/SearchRadioButton"
android:text="@string/apellidos" />
</RadioGroup>
</LinearLayout>
<TextView
android:id="@+id/num_resultados"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/recycler_view_item_search"
android:gravity="center_horizontal"
android:paddingVertical="8dp"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:visibility="gone"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toBottomOf="@id/buscador" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/lista_deportistas_Rv"
android:layout_width="match_parent"
android:layout_height="0dp"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintTop_toBottomOf="@id/num_resultados"
tools:listitem="@layout/listado_deportista_item" />
</androidx.constraintlayout.motion.widget.MotionLayout>
MotionScene:
<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:motion="http://schemas.android.com/apk/res-auto">
<Transition
motion:constraintSetEnd="@id/recogido"
motion:constraintSetStart="@id/expandido">
<OnSwipe
motion:dragDirection="dragUp"
motion:moveWhenScrollAtTop="false"
motion:touchAnchorId="@id/lista_deportistas_Rv"
motion:touchAnchorSide="top" />
</Transition>
<ConstraintSet android:id="@+id/expandido">
<Constraint android:id="@id/buscador" >
<PropertySet android:alpha="1" />
</Constraint>
<Constraint android:id="@id/num_resultados">
<PropertySet android:alpha="1"
motion:visibilityMode="ignore"/>
</Constraint>
<Constraint android:id="@id/lista_deportistas_Rv">
<PropertySet motion:visibilityMode="ignore"/>
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="@+id/recogido">
<Constraint
android:id="@id/buscador"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintBottom_toTopOf="parent">
<PropertySet android:alpha="0" />
</Constraint>
<Constraint
android:id="@id/num_resultados"
android:layout_width="match_parent"
android:layout_height="wrap_content"
motion:visibilityMode="ignore"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintBottom_toTopOf="parent">
<PropertySet android:alpha="0" />
</Constraint>
<Constraint android:id="@id/lista_deportistas_Rv">
<PropertySet motion:visibilityMode="ignore"/>
</Constraint>
</ConstraintSet>
</MotionScene>