I created a layout using constraint layout where the body view (viewpager for fragments) depend on header (e.g., viewpager has property layout_constraintTop_toBottomOf="@+id/button1" where button1 is view at the very bottom of header). Now I need to create animation like collapsible header, but I got some issue with CollapsingToolbarLayout because viewpager and the header is connecting and I think I need ConstraintLayout to do that, not CoordinatorLayout.
I did some research and found droidcon video that explain about using ConstraintLayout to replace the CollapsingToolbarLayout in this stackoverflow answer . I tried to implement it but it's not exactly what I need because it just let me create the header using ConstraintLayout while I need ConstraintLayout as the root layout. I need to set onClickListener button1 (in header) from activity and I can't do that if I put the button in 2 different layout (in header_open.xml and header_close.xml). or i'm missing something and I actually can do that?
I another way to create collapsible header using MotionLayout, it works perfect just like what I want because I just want to change visibility and constraints for some views in the header. But MotionLayout need dependency ConstraintLayout 2.0 and unfotunately I found bug in one of the devices I use to test (pages that use ConstraintLayout is messed up).
Is there any alternative I can use that works just like MotionLayout but using dependency ConstraintLayout 1.xx ? May be using constraintset and transition?
p.s. I tried to use constraint set and transition manager but all examples and explanation that I found use onClickListener to trigger animation or layout changes (from constrainset 1 to 2) while I need scroll to trigger the changes) I think I can use constraint set and transition if I know what can I use to trigger changes with behavior like <OnSwipe>
in Motion Layout. So my question can be "Is there any alternative I can use that works just like <OnSwipe>
in MotionLayout?"
or may be someone can tell me why pages that use ConstraintLayout messed up when using dependency androidx.constraintlayout:constraintlayout:2.0.0-rc1
?
My code with collapsing constraint layout still got some errors, so I will just put my code with MotionLayout.
<?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/constraintRoot"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary"
app:layoutDescription="@xml/scene_activity_main"
tools:context=".presentation.MainActivity">
<ImageView
android:id="@+id/imgHeader"
android:layout_width="@dimen/dimen_0dp"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:src="@drawable/bg_header"
tools:ignore="ContentDescription" />
<ImageView
android:id="@+id/btnBack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen_12dp"
android:layout_marginTop="@dimen/dimen_35dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:src="@drawable/ic_back"
tools:ignore="ContentDescription" />
<TextView
android:id="@+id/btnHistory"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen_8dp"
android:text="@string/label_history"
android:textColor="@android:color/white"
android:textSize="@dimen/text_size_12sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/imgBanner" />
<TextView
android:id="@+id/tvLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dimen_12dp"
android:text="@string/label_text"
android:textColor="@android:color/white"
android:textSize="@dimen/text_size_18sp"
android:textStyle="bold"
app:layout_constraintBottom_toTopOf="@id/imgBanner"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<ImageView
android:id="@+id/imgBanner"
android:layout_width="@dimen/dimen_203dp"
android:layout_height="@dimen/dimen_35dp"
app:layout_constraintBottom_toBottomOf="@+id/imgHeader"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/imgHeader"
android:src="@drawable/bg_rounded_primary"
tools:ignore="ContentDescription" />
<ImageView
android:id="@+id/imgIcon"
android:layout_width="@dimen/dimen_47dp"
android:layout_height="@dimen/dimen_47dp"
android:src="@drawable/ic_point"
app:layout_constraintBottom_toBottomOf="@id/imgBanner"
app:layout_constraintStart_toStartOf="@id/imgBanner"
app:layout_constraintTop_toTopOf="@id/imgBanner" />
<TextView
android:id="@+id/tvValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/dimen_10dp"
android:textColor="@android:color/white"
android:textSize="@dimen/text_size_20sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/imgBanner"
app:layout_constraintEnd_toEndOf="@+id/imgBanner"
app:layout_constraintTop_toTopOf="@+id/imgBanner"
tools:text="100" />
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewPager"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="@dimen/dimen_24dp"
android:background="@drawable/bg_primary_tab"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btnHistory">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorTransparent"
android:paddingVertical="@dimen/dimen_8dp"
app:tabBackground="@drawable/bg_primary_tab"
app:tabGravity="fill"
app:tabIndicator="@drawable/bg_indicator_tab"
app:tabIndicatorColor="@color/colorGrey19"
app:tabIndicatorFullWidth="true"
app:tabIndicatorGravity="center"
app:tabInlineLabel="true"
app:tabMode="fixed"
app:tabRippleColor="@null"
app:tabTextAppearance="@style/CustomTextAppearanceTab">
<com.google.android.material.tabs.TabItem
android:id="@+id/tab1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:icon="@drawable/ic_play"
android:text="@string/label_tab1" />
<com.google.android.material.tabs.TabItem
android:id="@+id/tab2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:icon="@drawable/ic_coin"
android:text="@string/label_tab2" />
</com.google.android.material.tabs.TabLayout>
</androidx.viewpager.widget.ViewPager>
</androidx.constraintlayout.motion.widget.MotionLayout>
Here is my scene code
<?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/end"
app:constraintSetStart="@+id/start"
app:duration="500"
app:motionInterpolator="linear">
<OnSwipe
app:dragDirection="dragUp"
app:touchAnchorId="@id/viewPager"
app:touchAnchorSide="top" />
</Transition>
<ConstraintSet android:id="@+id/start">
<Constraint android:id="@+id/btnHistory">
<PropertySet android:visibility="visible" />
</Constraint>
<Constraint android:id="@+id/tvLabel">
<PropertySet android:visibility="visible" />
</Constraint>
<Constraint android:id="@+id/imgBanner">
<Layout
android:layout_width="@dimen/dimen_203dp"
android:layout_height="@dimen/dimen_35dp"
app:layout_constraintBottom_toBottomOf="@+id/imgHeader"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/imgHeader" />
</Constraint>
<Constraint android:id="@+id/imgIcon">
<Layout
android:layout_width="@dimen/dimen_47dp"
android:layout_height="@dimen/dimen_47dp"
app:layout_constraintBottom_toBottomOf="@id/imgBanner"
app:layout_constraintStart_toStartOf="@id/imgBanner"
app:layout_constraintTop_toTopOf="@id/imgBanner" />
</Constraint>
<Constraint android:id="@+id/viewPager">
<Layout
android:layout_marginTop="@dimen/dimen_24dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btnHistory" />
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint android:id="@+id/btnHistory">
<PropertySet android:visibility="invisible" />
</Constraint>
<Constraint android:id="@+id/tvLabel">
<PropertySet android:visibility="invisible" />
</Constraint>
<Constraint android:id="@+id/imgBanner">
<Layout
android:layout_width="@dimen/dimen_176dp"
android:layout_height="@dimen/dimen_35dp"
app:layout_constraintBottom_toBottomOf="@+id/btnBack"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/btnBack" />
</Constraint>
<Constraint android:id="@+id/imgIcon">
<Layout
android:layout_width="@dimen/dimen_35dp"
android:layout_height="@dimen/dimen_35dp"
app:layout_constraintBottom_toBottomOf="@id/imgBanner"
app:layout_constraintStart_toStartOf="@id/imgBanner"
app:layout_constraintTop_toTopOf="@id/imgBanner" />
</Constraint>
<Constraint android:id="@+id/viewPager">
<Layout
android:layout_marginTop="@dimen/dimen_16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imgBanner" />
</Constraint>
</ConstraintSet>
</MotionScene>
I use bold for my questions in case my explanation is confusing. Sorry for my grammar, english is not my first language. I open for all suggestion related to this problem (even just links to some references would be appreciated). Thankyou in advance.