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.
Related
I'm not sure how to ask this question. It seems easy to do but I'm not sure why it's not working. Anyways, here goes. I have this Error Banner that should be visible only if the total "Weight" for the Categories is less than or greater than 100. However my issue is that when the error banner is visible, my RecyclerView's last item is cut off, I think by the height of the error banner.
It will only be fixed if I edit it once again and the keyboard is shown, the recyclerview's height is refreshed (probably).
Here's my Layout XML:
<?xml version="1.0" encoding="utf-8"?>
<layout 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"
tools:context=".presentation.screens.gradesetup.gradingcategories.GradingCategoriesFragment">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/layoutParent"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.LinearLayoutCompat
android:id="#+id/layoutGradeCategoryList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintTop_toTopOf="parent"
app:layout_constrainedHeight="true" >
<TextView
android:id="#+id/tvInvalidGradeWeightLayout"
style="#style/Default_Text_Error_Banner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="#dimen/default_margin_size_16dp"
android:text="#string/error_invalid_grade_category_weight"
android:visibility="gone" />
<!-- Constraint layout_constraintHeight_max dynamically to 24% -->
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rvGradingCategories"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/tvInfoNoData"
style="#style/Default_Text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="#string/text_no_data_display"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Barrier
android:id="#+id/barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:constraint_referenced_ids="layoutGradeCategoryList" />
<androidx.appcompat.widget.LinearLayoutCompat
android:id="#+id/layout_adjust_weight"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="#dimen/default_margin_size_16dp"
android:orientation="horizontal"
app:layout_constraintBottom_toTopOf="#+id/buttonSave"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/barrier"
app:layout_constraintVertical_bias="0.01">
<com.google.android.material.switchmaterial.SwitchMaterial
android:id="#+id/switchViewAdjustWeight"
style="#style/Default_Text_Bold"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="#dimen/screen_padding_size"
android:text="#string/text_adjust_weight"
android:theme="#style/Theme.LMS"
android:visibility="gone" />
</androidx.appcompat.widget.LinearLayoutCompat>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="#dimen/default_margin_size_30dp"
android:src="#drawable/ic_plus"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:tint="#color/white" />
<androidx.appcompat.widget.AppCompatButton
android:id="#+id/buttonSave"
style="#style/Primary_Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="#dimen/default_margin_size_30dp"
android:enabled="false"
android:text="#string/text_save"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
As you can see I also have this Constraint Barrier, so whenever the height of the RecyclerView is longer, the SwitchMaterial("switchViewAdjustWeight") is also adjusted. I set the android:layout_constraintHeight_max dynamically based on device height.
// Dynamically set constraintMaxHeight
var constraintMaxHeight = 0
constraintMaxHeight =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
val windowMetrics = activity!!.windowManager.currentWindowMetrics
val insets: Insets = windowMetrics.windowInsets
.getInsetsIgnoringVisibility(WindowInsets.Type.systemBars())
val height = windowMetrics.bounds.height() - insets.top - insets.bottom
(height * 0.7).toInt()
} else {
val displayMetrics = DisplayMetrics()
activity!!.windowManager.defaultDisplay.getMetrics(displayMetrics)
(displayMetrics.heightPixels * 0.7).toInt()
}
val constraintSet = ConstraintSet()
constraintSet.clone(layoutParent)
constraintSet.constrainMaxHeight(R.id.layoutGradeCategoryList, constraintMaxHeight)
constraintSet.applyTo(layoutParent)
In my code (kotlin): the error banner is toggled to visible if sum != 100
val result = sum == 100
binding.apply {
buttonSave.isEnabled = result
tvInvalidGradeWeightLayout.isVisible = !result
}
Target UI:
I also did change LinearLayout to ConstraintLayout However it didn't work, the Banner overlaps with the RecyclerView list :
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/layoutParent"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/layoutGradeCategoryList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintTop_toTopOf="parent"
app:layout_constrainedHeight="true" >
<TextView
android:id="#+id/tvInvalidGradeWeightLayout"
style="#style/Default_Text_Error_Banner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="#dimen/default_margin_size_16dp"
android:text="#string/error_invalid_grade_category_weight"
android:visibility="gone"
app:layout_constraintTop_toTopOf="parent"/>
<!-- Constraint layout_constraintHeight_max dynamically to 24% -->
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rvGradingCategories"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constrainedHeight="true"
app:layout_constraintTop_toBottomOf="#+id/tvInvalidGradeWeightLayout" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/tvInfoNoData"
style="#style/Default_Text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="#string/text_no_data_display"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Barrier
android:id="#+id/barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:constraint_referenced_ids="layoutGradeCategoryList" />
<androidx.appcompat.widget.LinearLayoutCompat
android:id="#+id/layout_adjust_weight"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="#dimen/default_margin_size_16dp"
android:orientation="horizontal"
app:layout_constraintBottom_toTopOf="#+id/buttonSave"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/barrier"
app:layout_constraintVertical_bias="0.01">
<com.google.android.material.switchmaterial.SwitchMaterial
android:id="#+id/switchViewAdjustWeight"
style="#style/Default_Text_Bold"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="#dimen/screen_padding_size"
android:text="#string/text_adjust_weight"
android:theme="#style/Theme.LMS"
android:visibility="gone" />
</androidx.appcompat.widget.LinearLayoutCompat>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="#dimen/default_margin_size_30dp"
android:src="#drawable/ic_plus"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:tint="#color/white" />
<androidx.appcompat.widget.AppCompatButton
android:id="#+id/buttonSave"
style="#style/Primary_Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="#dimen/default_margin_size_30dp"
android:enabled="false"
android:text="#string/text_save"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
This worked for me, I added getViewTreeObserver().addOnGlobalLayoutListener for layoutGradeCategoryList and trigger the request layout there.
layoutGradeCategoryList.getViewTreeObserver().addOnGlobalLayoutListener(OnGlobalLayoutListener {
layoutGradeCategoryList.requestLayout();
})
This helped me understand more on requestLayout/forceLayout/invalidate view.
https://stackoverflow.com/a/42430695/3777452
Hope this helps someone else.
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
android:IsScrollContainer does not working after screen transition.
I have the following layout defined:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/top_layout"
android:layout_width="0dp"
android:layout_height="66dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
</androidx.constraintlayout.widget.ConstraintLayout>
<ScrollView
android:id="#+id/scroll_view"
android:layout_width="0dp"
android:layout_height="0dp"
android:isScrollContainer="false"
app:layout_constraintTop_toBottomOf="#id/top_layout"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="#id/bottom1">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:isScrollContainer="false"
android:padding="16dp">
<androidx.appcompat.widget.AppCompatEditText
android:id="#+id/last_name_field"
android:layout_width="0dp"
android:layout_height="34dp"
android:layout_marginTop="8dp"
android:paddingStart="8dp"
android:paddingEnd="8dp"
app:hintAnimationEnabled="false"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:inputType="text"
android:textSize="14sp"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/bottom1"
android:layout_width="0dp"
android:layout_height="74dp"
android:background="#color/colorPrimaryDark"
app:layout_constraintTop_toBottomOf="#id/scroll_view"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="#id/bottom2">
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/bottom2"
android:layout_width="0dp"
android:layout_height="66dp"
android:background="#color/colorPrimary"
app:layout_constraintTop_toBottomOf="#id/bottom1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Inside the scroll view is the EditText, and there is a fixed layout above and below the scroll view.
When the Keyboard is displayed, I do not want to display the bottom Layout on the keyboard, so I set isScrollContainer to false.
My application uses NavController to perform screen transitions, but in the following cases isScrollContainer may not work.
(TargetFragment is above layout.)
A case that works.
(Select Navigation Drawer menu) -> TargetFragment
Cases that don't work.
(Select Navigation Drawer menu) -> OtherFragmnet -> (navigate) -> TargetFragment(doesn't work)
Why is isScrollContaier = false not effective after navigate the NavController even though the layout is exactly the same?
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 trying to create a screen which should look like this
But when I create the view using the XML code as per below
<android.support.constraint.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:id="#+id/fb_constraintLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="me.buddy.buddy.ui.BenefitsActivity$BenefitsFragment">
<ImageView
android:layout_width="0dp"
android:layout_height="0dp"
android:id="#+id/fb_animals"
android:src="#drawable/animal_love"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="#id/fb_meal_data"
app:layout_constraintBottom_toTopOf="#id/fb_environment"/>
<ImageView
android:layout_width="0dp"
android:layout_height="0dp"
android:id="#+id/fb_meal_data"
android:src="#drawable/food"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toRightOf="#id/fb_animals"
app:layout_constraintBottom_toTopOf="#id/fb_health"/>
<ImageView
android:layout_width="0dp"
android:layout_height="0dp"
android:id="#+id/fb_environment"
android:src="#drawable/environment"
app:layout_constraintTop_toBottomOf="#id/fb_animals"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="#id/fb_health"
app:layout_constraintBottom_toTopOf="#id/fb_hunger"/>
<ImageView
android:layout_width="0dp"
android:layout_height="0dp"
android:id="#+id/fb_health"
android:src="#drawable/health"
app:layout_constraintTop_toBottomOf="#id/fb_meal_data"
app:layout_constraintBottom_toTopOf="#id/fb_section_label"
app:layout_constraintLeft_toRightOf="#id/fb_environment"
app:layout_constraintRight_toRightOf="parent"/>
<ImageView
android:layout_width="0dp"
android:layout_height="0dp"
android:id="#+id/fb_hunger"
android:src="#drawable/bowl"
app:layout_constraintTop_toBottomOf="#id/fb_environment"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="#id/fb_section_label"/>
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:id="#+id/fb_section_label"
android:layout_marginBottom="#dimen/activity_vertical_margin"
android:layout_marginEnd="#dimen/activity_horizontal_margin"
android:layout_marginStart="#dimen/activity_horizontal_margin"
android:layout_marginTop="#dimen/activity_vertical_margin"
app:layout_constraintTop_toBottomOf="#id/fb_health"
app:layout_constraintLeft_toRightOf="#id/fb_hunger"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</android.support.constraint.ConstraintLayout>
I am getting a screen like below in my app
Do note that this layout is inside a fragment of an activity as depicted in the tools tag in the xml. Hence the additional floating action button and the back arrow in the actual layout.
However what I am not able to understand is why is icon of the food bowl getting pushed below the visible screen space in the actual layout.
Any resolution to this issue? I would like to avoid using Scrollview as much as possible.
For reference, XML Code of parent activity is attached below
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.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:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="me.buddy.buddy.ui.BenefitsActivity">
<android.support.design.widget.AppBarLayout
android:id="#+id/ab_appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="#dimen/appbar_padding_top"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/ab_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_weight="1"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/AppTheme.PopupOverlay"
app:title="#string/app_name">
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/ab_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/ab_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="#dimen/fab_margin"
app:srcCompat="#android:drawable/ic_menu_share" />
</android.support.design.widget.CoordinatorLayout>
Java code for adding fragment to main activity as per below:
First the parent class:
setContentView(R.layout.activity_benefits);
Toolbar toolbar = (Toolbar) findViewById(R.id.ab_toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.ab_container);
mViewPager.setAdapter(mSectionsPagerAdapter);
Then inside Fragment class:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_benefits_dashboard, container, false);
return rootView;}
The problem you are trying to solve is easily accomplished using ConstraintLayout Guidelines.
You just define 2 horizontal guidelines: one at 33%, the other one at 66%.
Then all you have to do, is to position your views relative to these guidelines.
Here's a skeleton implementation of your screen:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="#+id/view1"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#53d94f"
app:layout_constraintBottom_toTopOf="#+id/guideline"
app:layout_constraintEnd_toStartOf="#+id/view2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="#+id/view2"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#d9c74f"
app:layout_constraintBottom_toTopOf="#+id/guideline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/view1"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="#+id/view3"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#4f68d9"
app:layout_constraintBottom_toTopOf="#+id/guideline2"
app:layout_constraintEnd_toStartOf="#+id/view4"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#id/guideline" />
<View
android:id="#+id/view4"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#d95a4f"
app:layout_constraintBottom_toTopOf="#+id/guideline2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/view3"
app:layout_constraintTop_toTopOf="#id/guideline" />
<View
android:id="#+id/view5"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#4fd4d9"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/view6"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/guideline2" />
<View
android:id="#+id/view6"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#c94fd9"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/view5"
app:layout_constraintTop_toBottomOf="#+id/guideline2" />
<android.support.constraint.Guideline
android:id="#+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.33" />
<android.support.constraint.Guideline
android:id="#+id/guideline2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.66" />
</android.support.constraint.ConstraintLayout>
Here's the output:
The Toolbar in your Main Activity pushes down the ViewPager. The AppBarLayout is mainly used in a Tabbed Layout for using a TabLayout. If you are using a TabLayout inside the AppBarLayout, the Toolbar will hide automatically after launching the activity and your ViewPager will occupy the full window.
The Solution:
Remove the whole AppBarLayout with Toolbar from your Activity and also remove the NoActionBar theme from Activity manifest
Or, don't use CoordinatorLayout for your parent activity.