I have a NestedScrollView that contains a lot of components like a recyclerview, viewPager ...
I have an editText, for search.Also, an AppBar that contains a search icon.When I click on search icon the editText slideDown, and when I click a second time on in it slideUP.
My problem is when I scrolling the activity down for example, and when I click on search editText, the activity is not fixed, move up and out of the screen.
Here's main_activity.xml code :
<LinearLayout 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:background="#color/grey"
android:fitsSystemWindows="false"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/whiteFour"
android:paddingTop="#dimen/spacing_medium"
android:paddingBottom="#dimen/spacing_medium"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.AppCompatImageView
android:id="#+id/searchButtonMain"
android:layout_width="30dp"
android:layout_height="28dp"
android:layout_marginEnd="#dimen/spacing_middle"
android:adjustViewBounds="true"
android:tint="#color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/Chart"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/ic_search" />
<.....>
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.appbar.AppBarLayout>
<LinearLayout
android:id="#+id/lytSearchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/whiteFour"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/searchFields"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="20dp"
android:layout_marginBottom="10dp"
android:background="#drawable/border"
android:drawableStart="#drawable/icn_search_x"
android:drawablePadding="#dimen/spacing_large"
android:fontFamily="#font/cairo"
android:gravity="left"
android:hint="#string/search_product"
android:inputType="text"
android:lineHeight="18dp"
android:maxLines="1"
android:paddingStart="15dp"
android:paddingTop="5dp"
android:paddingEnd="15dp"
android:paddingBottom="5dp"
android:textColorHint="#color/greyish"
android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
</LinearLayout>
<androidx.core.widget.NestedScrollView
android:id="#+id/nestedScrollView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/grey"
android:clipToPadding="true"
android:fillViewport="true"
android:scrollbars="none"
android:scrollingCache="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/appBarLayout">
<................>
When I click on search button :
searchButtonMain.setOnClickListener {
if (firstClickSearch) {
val animation = AnimationUtils.loadAnimation(
this, R.anim.slide_up
)
//appending animation to textView
lytSearchView.startAnimation(animation)
lytSearchView.visibility = View.GONE
firstClickSearch = false
} else {
val animation = AnimationUtils.loadAnimation(
this, R.anim.slide_down
)
//appending animation to textView
lytSearchView.startAnimation(animation)
lytSearchView.visibility = View.VISIBLE
firstClickSearch = true
}
}
So, what should I do to fix the NestedScrollView when click on search editText with Kotlin
Related
Android toast message set margin is not working. I want to fill horizontal and bottom gravity toast message with 16dp end and start margins. Please help me
custom_toast_message_layout.xml
<androidx.constraintlayout.widget.ConstraintLayout 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="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:background="#drawable/bg_rounded_corner"
android:backgroundTint="#color/snackBarSuccess"
android:layout_margin="16dp"
android:padding="16dp">
<TextView
android:id="#+id/comment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="#font/hanken_sans_bold"
android:maxLines="1"
android:singleLine="true"
android:text="Comment is here"
android:textColor="#color/white"
android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="MissingConstraints" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.kt
val view : View = LayoutInflater.from(requireContext())
.inflate(R.layout.custom_toast_message_layout, null)
val toast = Toast(requireContext())
toast.view = view
toast.setGravity(Gravity.BOTTOM or Gravity.FILL_HORIZONTAL, 0, 100)
toast.setMargin(0.2f, 0f)
toast.duration = Toast.LENGTH_LONG
toast.show()
thanks
try changing your custom_toast_message_layout.xml like below
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/toast_root_layout"
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="wrap_content"
android:padding="20dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/bg"
android:backgroundTint="#color/snackBarSuccess"
>
<TextView
android:id="#+id/toast_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:padding="8dp"
android:text="This is a comment"
android:textColor="#color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Referenced https://stackoverflow.com/a/63746852/9502601
I'm having a problem with my toolbar.
I want the device app and toolbar to be the same color, but don't use findviewbyid. (I'm migrating the entire project just to view binding
)
OK behavior (using findviewbyid).
NOK behavior (using view binding), is giving a little misalignment of the textView, it seems to receive a margin that was not placed.
But if I declare different in onWindowsInsetsChanged method or don't use it, I get another problem, the color is not correct.
Using findviewbyid:
override fun onWindowsInsetsChanged(view: View, insets: WindowInsets, padding: InitialPadding) {
with(binding) {
val toolbar = fragmentEditObjectiveNameRoot.findViewById<View>(R.id.toolbar)
toolbar.updatePadding(top = topInset)
editObjectiveNameRoot.updatePadding(
bottom = insets.systemWindowInsetBottom
)
}
}
Using view binding:
override fun onWindowsInsetsChanged(view: View, insets: WindowInsets, padding: InitialPadding) {
with(binding) {
//calling the include toolbar and the root of the toolbar fragment
toolbar.viewImageToolbar.updatePadding(
top = topInset
)
editObjectiveNameRoot.updatePadding(
bottom = insets.systemWindowInsetBottom
)
}
}
Different declaration in onWindowsInsetsChanged:
override fun onWindowsInsetsChanged(view: View, insets: WindowInsets, padding: InitialPadding) {
with(binding) {
//calling root from fragment and instead of calling the include toolbar and its root
fragmentEditObjectiveNameRoot.updatePadding(
top = topInset
)
editObjectiveNameRoot.updatePadding(
bottom = insets.systemWindowInsetBottom
)
}
}
I would like to leave the same color behavior when using findviewbyid, but with view binding, but without losing textView alignment.
Here is the xml that receives the toolbar include:
<?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/fragmentEditObjectiveNameRoot"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/editObjectiveNameRoot"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:id="#+id/bgColorFrameLayout"
android:layout_width="match_parent"
android:layout_height="#dimen/color_frame_layout_height"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/toolbar" />
<androidx.core.widget.NestedScrollView
android:id="#+id/scrollView"
android:layout_width="0dp"
android:layout_height="0dp"
android:fillViewport="true"
android:clipToPadding="false"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/toolbar">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="#dimen/screen_margin_horizontal"
android:layout_marginTop="18dp"
android:layout_marginEnd="#dimen/screen_margin_horizontal"
android:paddingBottom="16dp">
<com.google.android.material.card.MaterialCardView
android:id="#+id/cardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardBackgroundColor="#color/bari_white"
app:cardCornerRadius="#dimen/card_corner_radius"
app:cardElevation="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="#dimen/card_padding">
<TextView
android:id="#+id/titleSubAccount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="#string/sub_account_control_settings_edit_name"
android:textAlignment="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<br.com.bancobari.core_ui.views.text_input.BariTextInputLayout
android:id="#+id/nameInputLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
app:helperIconEnabled="true"
app:helperStart_enabled="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/titleSubAccount">
<br.com.bancobari.core_ui.views.text_input.BariTextInputEditText
android:id="#+id/nameEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPersonName|textCapWords"
android:maxLength="16"
android:textAlignment="center"
android:textSize="16sp" />
</br.com.bancobari.core_ui.views.text_input.BariTextInputLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
<br.com.bancobari.core_ui.views.SubmitButton
android:id="#+id/saveButton"
style="#style/DefaultButton.Icon.Arrow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="18dp"
android:text="#string/objective_settings_save"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/cardView"
app:layout_constraintVertical_bias="1.0" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
<include
android:id="#+id/toolbar"
layout="#layout/view_image_toolbar" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Here the toolbar xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="#+id/viewImageToolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:minHeight="#dimen/custom_toolbar_height"
app:contentInsetLeft="0dp"
app:contentInsetStart="0dp"
app:contentInsetStartWithNavigation="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<View
android:layout_width="0dp"
android:layout_height="#dimen/custom_toolbar_height" />
</androidx.appcompat.widget.Toolbar>
<TextView
android:id="#+id/iconEmojiView"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginEnd="10dp"
android:gravity="bottom"
android:textSize="22.5sp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="#id/toolbarTitleTextView"
app:layout_constraintEnd_toStartOf="#+id/toolbarTitleTextView"
tools:visibility="visible" />
<TextView
android:id="#+id/toolbarTitleTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:ellipsize="end"
android:fontFamily="#font/nunito_bold"
android:gravity="center"
android:lines="1"
android:textColor="#color/text_neutral_gray_800"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="#id/viewImageToolbar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Teste" />
<ImageView
android:id="#+id/toolbarRightIconImageView"
style="#style/Widget.AppCompat.ActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_settings"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="#id/toolbarTitleTextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="#id/toolbarTitleTextView" />
</androidx.constraintlayout.widget.ConstraintLayout>
In your first block of code with findViewById, this
val toolbar = fragmentEditObjectiveNameRoot.findViewById<View>(R.id.toolbar)
returns the ConstraintLayout at the root of your included layout with the ID toolbar.
The property toolbar in your binding is another binding for the included layout rather than the root view of that layout. The root property of that included binding in this case is the same ConstraintLayout from above, so you should use instead:
toolbar.root.updatePadding(
top = topInset
)
What you were doing was changing the padding of an inner view of your complete Toolbar layout, the viewImageToolbar element.
I'm trying to test my fragment with Espresso. No matter what view I'm trying to test I get NoMatchingViewException, I'm 100% sure that the view actually exists on the fragment.
This is my test:
#LargeTest
#ExperimentalCoroutinesApi
#RunWith(AndroidJUnit4::class)
class ExploreFragmentTest {
private lateinit var blogRepository: FakeBlogRepository
private lateinit var inAppMessagesRepository: FakeInAppMessageRepository
private lateinit var fakeFarRetailsRepository: FakeFarRetailsRepository
private lateinit var fakeUserProfileRepository: FakeUserProfileRepository
#Before
fun initRepository() {
blogRepository = FakeBlogRepository()
inAppMessagesRepository = FakeInAppMessageRepository()
fakeFarRetailsRepository = FakeFarRetailsRepository()
fakeUserProfileRepository = FakeUserProfileRepository()
ServiceLocator.blogRepository = blogRepository
ServiceLocator.inAppMessagesRepository = inAppMessagesRepository
ServiceLocator.userProfileRepository = fakeUserProfileRepository
}
#Test
fun noRetailsNearby_displaysNoRetailsNearbyLayout() = runBlockingTest {
// GIVEN - A fake repository with far retails
ServiceLocator.retailsRepository = fakeFarRetailsRepository
// WHEN - ExploreFragment launched to display retails
launchFragmentInContainer<ExploreFragment>(null, R.style.AppTheme)
// THEN - No retails layout is displayed on the screen
onView(withId(R.id.clExploreContainer)).check(matches(isDisplayed()))
}
}
This is the layout of the related fragment:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#id/clExploreContainer"
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">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/ablExplore"
android:layout_width="match_parent"
android:layout_height="#dimen/toolbar_height"
android:background="#android:color/transparent"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="#+id/ctlExploreHeader"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:statusBarScrim="#android:color/transparent"
app:toolbarId="#+id/tbExplore">
<ImageView
android:id="#+id/ivHeaderLemon"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorPrimary"
android:scaleType="centerCrop"
android:src="#drawable/bg_main"
app:layout_collapseMode="parallax" />
<androidx.appcompat.widget.Toolbar
android:id="#+id/tbExplore"
android:layout_width="match_parent"
android:layout_height="#dimen/collapsed_toolbar_height"
app:layout_collapseMode="pin"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/collapsing_logo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layout_marginStart="20dp"
android:minHeight="?attr/actionBarSize">
<ImageView
android:id="#+id/ivLogo"
android:layout_width="#dimen/toolbar_logo_width"
android:layout_height="#dimen/toolbar_logo_height"
android:adjustViewBounds="true"
android:scaleType="fitStart"
android:src="#drawable/myfoody_logo"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:id="#+id/svExplore"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/clExploreContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
android:id="#+id/miniInAppMessageLayout"
layout="#layout/mini_in_app_message_layout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible" />
<include
android:id="#+id/tutorialLayout"
layout="#layout/tutorial_layout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="20dp"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/miniInAppMessageLayout"
tools:visibility="visible" />
<include
android:id="#+id/nearToMeLayout"
layout="#layout/near_to_me_layout"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/tutorialLayout" />
<include
android:id="#+id/favouritesLayout"
layout="#layout/favourites_layout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/section_explore_margin_top"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/nearToMeLayout"
tools:visibility="visible" />
<androidx.fragment.app.FragmentContainerView
android:id="#+id/flCompanyMessageFragment"
android:name="com.anagramma.myfoody.fragments.explore.blog.RecipesFragment"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/section_explore_margin_top"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/favouritesLayout" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/clRemoteMessagesContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/flCompanyMessageFragment">
<include
android:id="#+id/rcmlExplore"
layout="#layout/remote_config_message_layout_explore"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible" />
<include
android:id="#+id/lMeetMyBrandBannerExplore"
layout="#layout/meet_my_brand_banner"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/section_explore_margin_top"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.fragment.app.FragmentContainerView
android:id="#+id/flLastArticles"
android:name="com.anagramma.myfoody.fragments.explore.blog.LastArticlesFragment"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/section_explore_margin_top"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/clRemoteMessagesContainer"
tools:layout="#layout/fragment_explore_blog_section" />
<androidx.fragment.app.FragmentContainerView
android:id="#+id/flLiveSustainable"
android:name="com.anagramma.myfoody.fragments.explore.blog.LiveSustainableFragment"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/section_explore_margin_top"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/flLastArticles"
tools:layout="#layout/fragment_explore_blog_section" />
<androidx.fragment.app.FragmentContainerView
android:id="#+id/flMyFoodyWorld"
android:name="com.anagramma.myfoody.fragments.explore.blog.MyFoodyWorldFragment"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/section_explore_margin_top"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/flLiveSustainable"
tools:layout="#layout/fragment_explore_blog_section" />
<androidx.fragment.app.FragmentContainerView
android:id="#+id/fAutoProduction"
android:name="com.anagramma.myfoody.fragments.explore.blog.AutoproductionFragment"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/section_explore_margin_top"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/flMyFoodyWorld"
tools:layout="#layout/fragment_explore_blog_section" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Every time I run the test I get this error: androidx.test.espresso.NoMatchingViewException: No views in hierarchy found matching: with id: com.anagramma.myfoody.staging:id/clExploreContainer, can't understand why. Am I missing something related to espresso framework?
My problem was that my fragment had a DialogFragment covering the entire original fragment view during its startup. Since DialogFragment has another lifecycle, my Espresso test wasn't finding any view on the parent fragment (ExploreFragment). Once removed the DialogFragment view matching turned out fine in my test.
I have two activities, activity_main.xml and activity_main_details.xml and I want the elements from the first activity to transition to the second one.
First activity:
This activity is made up of two separate constraint layouts which are included in another layout. Code below:
<androidx.constraintlayout.widget.ConstraintLayout
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:id="#+id/root">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#color/background_color"
android:transitionName="firstHalf"
app:layout_constraintBottom_toTopOf="#+id/guideline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="#+id/photo"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginTop="64dp"
android:src="#drawable/ic_add"
android:transitionName="photo"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:text="#string/add_log_here"
android:textColor="#color/white"
android:textSize="18sp"
android:transitionName="title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/photo" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.35" />
<ScrollView
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:transitionName="secondHalf"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/guideline">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/constraintLayout2"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/guideline">
<-- more code here -->>
Second activity is:
<androidx.constraintlayout.widget.ConstraintLayout 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:id="#+id/root"
tools:context=".authenthicaton.joinUs.add_company_logo_animation">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#color/background_color"
android:transitionName="firstHalf"
app:layout_constraintBottom_toTopOf="#+id/guideline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="#+id/photo"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginStart="32dp"
android:layout_marginTop="8dp"
android:src="#drawable/ic_add"
android:transitionName="photo"
app:layout_constraintStart_toEndOf="#+id/textView4"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="16dp"
android:text="#string/add_log_here"
android:textColor="#color/white"
android:textSize="18sp"
android:transitionName="title"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.08" />
<ScrollView
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:transitionName="secondHalf"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/guideline">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:id="#+id/constraintLayout2"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/guideline">
<-- more code here -->
The issue is that there should be a transition for the elements:
photo #+id/photo
textView #+id/textView4
They should change the position from the first activity to the second one. In other words the second activity should be the result after the animation.
Here is the actual kotlin code:
val root = findViewById<ConstraintLayout>(R.id.root)
var set = false
val constraint1 = ConstraintSet()
constraint1.clone(root)
val constraint2 = ConstraintSet()
constraint2.clone(this, R.layout.activity_main_details)
val floatingActionButton = findViewById<FloatingActionButton>(R.id.floatingActionButton)
floatingActionButton.setOnClickListener{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
val transition = ChangeBounds()
transition.duration = 300
TransitionManager.beginDelayedTransition(root, transition)
val constraint = if(set) constraint1 else constraint2
constraint.applyTo(root)
set = !set
}
}
My result (after the animation) :
As you can see the photo and the textview haven't changed their first position. This being the reason to why they are not there.
I have also tried to use ActivityOptions.makeSceneTransitionAnimation but this complicated my code a lot because of the focus(related to edittext boxes) issues I had.
Does anyone know why the photo and the textview havent changed like they should've done? Is constrainSet having issues with nested Constrained layouts?
I haven't been successful with ConstrainSet so I ended up using scene which really worked in my case.
Due to the fact that I have multiple nested ConstrainedLayouts , ConstrainedSet is not going to work as #Pawel pointed out. Declaring ConstrainedSet for each of the subchildren didn't worked either.
Anyway, this is my solution using scene.
val transition = ChangeBounds()
transition.duration = 800
val scene = Scene.getSceneForLayout(findViewById<ConstraintLayout>(R.id.root),
R.layout.activity_main_details,
this)
findViewById<FloatingActionButton>(R.id.floatingActionButton).setOnClickListener {
TransitionManager.go(scene, transition)
// more code here
}
I am new to motionlayout and been following various tutorials online like this to get an understanding of how it works. From a nutshell I have come to know it basically animates constraintSets, you have a start and end constraintSet which you can further customize with KeyFrameSets. I have this layout
I want to mimic Lyft's bottom sheet
With my layout the Where are you going button is suppose to slowly fade out as the search destination textInputs fade in. The recyclerview at the bottom is suppose to hold saved addresses, it will not be affected. I tried this implementation using a standard bottomsheet but had challenges with the animation, it had this weird flickering so I decided to use a MotionLayout with a normal view.
My bottomsheet layout is as follows
<com.google.android.material.card.MaterialCardView 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/cardChooseAddressBottomSheet"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
app:shapeAppearance="#style/ShapeAppearanceRoundedLargeTopCorners">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/bottomSheetConstraintLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/activity_horizontal_margin"
android:layout_marginRight="#dimen/activity_horizontal_margin"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="#+id/swipeUpHandle"
android:layout_width="50dp"
android:layout_height="30dp"
android:layout_gravity="center"
android:background="#drawable/ic_swipe_up_handle"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.textview.MaterialTextView
android:id="#+id/hiThere"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/medium_margin"
android:text="#string/hi_there"
android:textAppearance="#style/h6_headline"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/swipeUpHandle"
/>
<com.google.android.material.button.MaterialButton
android:id="#+id/btnSearch"
style="#style/Widget.MaterialComponents.Button.OutlinedButton"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginTop="#dimen/medium_margin"
android:gravity="start|center_vertical"
android:letterSpacing="0.0"
android:text="#string/where_are_you_going"
android:textAllCaps="false"
android:textAppearance="#style/subtitle1"
android:textColor="#android:color/darker_gray"
app:backgroundTint="#android:color/white"
app:icon="#drawable/ic_search"
app:iconTint="#android:color/black"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/hiThere"
app:shapeAppearanceOverlay="#style/ShapeAppearanceRoundedMediumAllCorners" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:id="#+id/addressViews"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/btnSearch">
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/inputOrigin"
style="#style/textInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/medium_margin"
android:hint="#string/search_destination"
android:textColorHint="#android:color/darker_gray"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/edtOrigin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:textAppearance="#style/subtitle1"
android:textColor="#android:color/white" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/inputDestination"
style="#style/textInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/medium_margin"
android:hint="#string/search_destination"
android:textColorHint="#android:color/darker_gray"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/inputOrigin">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/edtDestination"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:textAppearance="#style/subtitle1"
android:textColor="#android:color/white" />
</com.google.android.material.textfield.TextInputLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="0dp"
android:id="#+id/recyclerAddresses"
android:layout_marginTop="#dimen/medium_margin"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/addressViews"
tools:listitem="#layout/recycler_view_item" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
And my parent layout where I include the bottomsheet is as follows
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout 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/motionLayout"
app:layoutDescription="#xml/taxi_bottomsheet_scene"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<include
layout="#layout/choose_destination_bottom_sheet_layout"/>
</androidx.constraintlayout.motion.widget.MotionLayout>
And finally my taxi_bottomsheet_scene motion scene is
<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Transition
app:constraintSetEnd="#+id/expanded"
app:constraintSetStart="#+id/collapsed"
app:duration="1000">
<OnSwipe
app:touchAnchorId="#+id/btnSearch"
app:touchAnchorSide="top"
app:dragDirection="dragUp"/>
</Transition>
<ConstraintSet android:id="#+id/expanded">
<Constraint
android:id="#+id/cardChooseAddressBottomSheet"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHeight_percent="1"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0" />
<Constraint
android:id="#+id/addressViews"
app:layout_constraintHeight_percent="1"/>
<Constraint
android:id="#+id/btnSearch"
app:layout_constraintHeight_percent="0"/>
</ConstraintSet>
<ConstraintSet android:id="#+id/collapsed">
<Constraint
android:id="#+id/cardChooseAddressBottomSheet"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHeight_percent="0.4"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0" />
<Constraint
android:id="#+id/addressViews"
app:layout_constraintHeight_percent="0.0"/>
<Constraint
android:id="#+id/btnSearch"
app:layout_constraintHeight_percent="0.0"/>
</ConstraintSet>
</MotionScene>
When I launch this app I cannot get the bottomsheet to slide up, it simply does not respond in any way. One thing I noticed though is after adding the app:layoutDescription="#xml/taxi_bottomsheet_scene"attribute, the bottom sheet size changed to what I had specified in the constraintSetStart but the addressViews view did not.
So my layout looks like
So my question is, where I am going wrong for my bottomsheet not to respond to my swipes and addressViews to disappear in the initial state?
I finally managed to make it work, both with MotionLayout and CoordinatorLayout. I will only post the Coordinator solution as it is long and I do not have the time, if someone needs it, comment and I will post.
I created 3 layouts, 1. The main layout with the map, 2. Top bar with the to and from address EditTexts and 3. The bottom layout that slides up and reveals the top bar.
Solution 1 using CoordinatorLayout
The topbar
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:layout_marginBottom="#dimen/medium_margin"
app:layout_scrollFlags="noScroll">
<com.google.android.material.appbar.MaterialToolbar
android:id="#+id/topToolBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navigationIcon="#drawable/ic_arrow_back_black_24dp" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/addressViews"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginStart="#dimen/activity_horizontal_margin"
android:layout_marginEnd="#dimen/activity_horizontal_margin"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/topToolBar">
<androidx.appcompat.widget.AppCompatImageView
android:id="#+id/imgOrigin"
android:layout_width="#dimen/activity_horizontal_margin"
android:layout_height="#dimen/activity_horizontal_margin"
android:layout_marginStart="#dimen/medium_margin"
android:layout_marginEnd="#dimen/medium_margin"
app:layout_constraintBottom_toBottomOf="#+id/inputOrigin"
app:layout_constraintEnd_toStartOf="#+id/inputOrigin"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/inputOrigin"
app:srcCompat="#drawable/ic_origin"
app:tint="#color/colorAccent" />
<View
android:layout_width="2dp"
android:layout_height="0dp"
android:layout_marginTop="#dimen/xsmall_margin"
android:layout_marginBottom="#dimen/xsmall_margin"
android:background="#drawable/accent_to_color_primary_dark__negative_90_gradient"
app:layout_constraintBottom_toTopOf="#+id/imgDestination"
app:layout_constraintEnd_toEndOf="#+id/imgOrigin"
app:layout_constraintStart_toStartOf="#+id/imgOrigin"
app:layout_constraintTop_toBottomOf="#+id/imgOrigin" />
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/inputOrigin"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/medium_margin"
android:hint="#string/pick_up_location"
android:marqueeRepeatLimit="marquee_forever"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/imgOrigin"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/edtOrigin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/white"
android:inputType="textPostalAddress"
android:singleLine="true"
android:textAppearance="#style/subtitle1" />
</com.google.android.material.textfield.TextInputLayout>
<androidx.appcompat.widget.AppCompatImageView
android:id="#+id/imgDestination"
android:layout_width="#dimen/activity_horizontal_margin"
android:layout_height="#dimen/activity_horizontal_margin"
android:layout_marginStart="#dimen/medium_margin"
android:layout_marginEnd="#dimen/medium_margin"
app:layout_constraintBottom_toBottomOf="#+id/inputDestination"
app:layout_constraintEnd_toStartOf="#+id/inputDestination"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/inputDestination"
app:srcCompat="#drawable/ic_destination"
app:tint="#color/colorPrimaryDark" />
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/inputDestination"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/medium_margin"
android:hint="#string/search_destination"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/imgDestination"
app:layout_constraintTop_toBottomOf="#id/inputOrigin">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/edtDestination"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/white"
android:inputType="textPostalAddress"
android:singleLine="true"
android:textAppearance="#style/subtitle1" />
</com.google.android.material.textfield.TextInputLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.appbar.AppBarLayout>
The bottom layout that acts like a bottom sheet
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/cardChooseAddressBottomSheet"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:cardBackgroundColor="#color/white"
app:behavior_hideable="false"
app:layout_behavior="#string/bottom_sheet_behavior">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="#+id/swipeUpHandle"
android:layout_width="35dp"
android:layout_height="30dp"
android:layout_gravity="center"
android:layout_marginLeft="#dimen/activity_horizontal_margin"
android:layout_marginRight="#dimen/activity_horizontal_margin"
android:background="#drawable/ic_swipe_up_handle"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.textview.MaterialTextView
android:id="#+id/hiThere"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hi_there"
android:layout_marginLeft="#dimen/activity_horizontal_margin"
android:layout_marginRight="#dimen/activity_horizontal_margin"
android:textAppearance="#style/h6_headline"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/swipeUpHandle" />
<com.google.android.material.button.MaterialButton
android:id="#+id/btnSearch"
style="#style/Widget.MaterialComponents.Button.OutlinedButton"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginLeft="#dimen/activity_horizontal_margin"
android:layout_marginRight="#dimen/activity_horizontal_margin"
android:gravity="start|center_vertical"
android:letterSpacing="0.0"
android:text="#string/where_are_you_going"
android:textAllCaps="false"
android:textAppearance="#style/subtitle1"
android:textColor="#android:color/darker_gray"
app:backgroundTint="#android:color/white"
app:icon="#drawable/ic_search"
app:iconSize="#dimen/medium_icon"
app:iconTint="#color/colorAccent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/hiThere"
app:shapeAppearanceOverlay="#style/ShapeAppearanceRoundedMediumAllCorners" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerAddresses"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/btnSearch" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerSearchAddresses"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#color/white"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/btnSearch" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
And finally the two layouts included in my map layout
<?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:layout_width="match_parent"
android:id="#+id/coordinator"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent="0.67"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imgMapCenter"
android:layout_marginBottom="#dimen/xlarge_margin"
android:visibility="invisible"
android:tint="#color/colorAccent"
app:layout_constraintBottom_toBottomOf="#id/map"
app:layout_constraintEnd_toEndOf="#id/map"
app:layout_constraintStart_toStartOf="#id/map"
app:layout_constraintTop_toTopOf="#id/map"
app:srcCompat="#drawable/ic_destination" />
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/fabMyLocation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="#dimen/activity_horizontal_margin"
app:backgroundTint="#color/white"
app:fabSize="mini"
app:layout_anchor="#id/cardChooseAddressBottomSheet"
app:layout_anchorGravity="top|right"
app:srcCompat="#drawable/ic_origin"
app:tint="#color/colorAccent" />
<include layout="#layout/taxi_fragment_set_destination_top_bar" />
<include layout="#layout/taxi_fragment_bottom_sheet_addresses_layout" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
And my fragment
final private BottomSheetBehavior.BottomSheetCallback addressBottomSheetCallBack = new BottomSheetBehavior.BottomSheetCallback() {
#Override
public void onStateChanged(#NonNull View bottomSheet, int newState) {
switch (newState) {
case BottomSheetBehavior.STATE_HIDDEN:
break;
case BottomSheetBehavior.STATE_SETTLING:
break;
case BottomSheetBehavior.STATE_EXPANDED:
if (!allPermissionsGranted())
requestForLocationPermissions();
topAddressBar.setVisibility(Visibility.VISIBLE);
fabMyLocation.hide();
break;
case BottomSheetBehavior.STATE_COLLAPSED:
if (!allPermissionsGranted())
requestForLocationPermissions();
topAddressBar.setVisibility(Visibility.INVISIBLE);
fabMyLocation.show();
break;
case BottomSheetBehavior.STATE_DRAGGING:
break;
case BottomSheetBehavior.STATE_HALF_EXPANDED:
break;
}
}
BottomSheetBehavior addressBottomSheetBehavior = BottomSheetBehavior.from(cardChooseAddressBottomSheet);
topAddressBar.post(() -> {
CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) cardChooseAddressBottomSheet.getLayoutParams();
layoutParams.height = ((Resources.getSystem().getDisplayMetrics().heightPixels + (int) utils.percentageOf(62, btnSearch.getMeasuredHeight())) - topAddressBar.getMeasuredHeight());
});
addressBottomSheetBehavior.setPeekHeight((int) utils.percentageOf(29, Resources.getSystem().getDisplayMetrics().heightPixels), true);
addressBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
topToolBar.setNavigationOnClickListener(view12 -> {
if (addressBottomSheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED) {
utopAddressBar.setVisibility(INVISIBLE);
addressBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
} else
Navigation.findNavController(view12).navigateUp();
});
addressBottomSheetBehavior.addBottomSheetCallback(addressBottomSheetCallBack);
Notice am using INVISIBLE instead of GONE on the topAddressBar? that is because everytime I called GONE the layout would ideally recalculate according to my assumption and the map would flicker, to stop that I had to use invisible as the layout does not shrink instead it still takes up the same space but just not visible.
Also notice I am adding padding cardChooseAddressBottomSheet.getLayoutParams() this is because I need the Sheet not to go too deep underneath the topAddressBar as not to hide my recyclerview content. The current padding makes sure the recyclerview is fully visible and everything else on top of it is underneath the topAddressBar