5

ConstraintLayout version: 2.0.0-alpha3

So I am using MotionLayout I wanted to create something similar to this. https://blog.stylingandroid.com/motionlayout-collapsing-toolbar-part-2/

I want to achieve When the user enters activity there is ProgressBar spinning when I load data (takes some time) I want ProgressBar to hide.

My problem is that when I start interacting with UI ProgressBar state is reset and is visible again

What should I do to prevent progressBar to start showing after the user starts interacting with it?

Here is a simplified version

layout file

<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:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutDescription="@xml/collapsing_toolbar"
    tools:context=".MainActivity"
    tools:showPaths="true">

    <androidx.core.widget.NestedScrollView
        android:id="@+id/scroll_view"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/toolbar_image">

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <View
                android:layout_width="match_parent"
                android:layout_height="2000dp"
                android:background="#ff2"/>
        </FrameLayout>
    </androidx.core.widget.NestedScrollView>

    <ImageView
        android:id="@+id/toolbar_image"
        android:layout_width="0dp"
        android:layout_height="200dp"
        android:background="@color/colorPrimary"
        android:src="@color/colorAccent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <ProgressBar
        android:id="@+id/progress_bar"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <TextView
        android:id="@+id/error"
        android:text="ERROR"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</androidx.constraintlayout.motion.widget.MotionLayout>

Here is layout description (xml/collapsing_toolbar)

<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <Transition
        app:constraintSetEnd="@id/collapsed"
        app:constraintSetStart="@id/expanded">

        <OnSwipe
            app:dragDirection="dragUp"
            app:touchAnchorId="@id/scroll_view"
            app:touchAnchorSide="top"/>
    </Transition>

    <ConstraintSet android:id="@+id/expanded">
        <Constraint
            android:id="@id/toolbar_image"
            android:layout_height="200dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">
        </Constraint>
    </ConstraintSet>

    <ConstraintSet android:id="@+id/collapsed">
        <Constraint
            android:id="@id/toolbar_image"
            android:layout_height="?attr/actionBarSize"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">
        </Constraint>

    </ConstraintSet>

</MotionScene>

and this is a simple activity where I hide ProgressBar after 1second

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        Handler().postDelayed({
            progress_bar.visibility = View.GONE
            error.text="NEW ERROR"
            error.visibility = View.GONE
        }, 1000)
    }
}

I am using androidx.constraintlayout:constraintlayout:2.0.0-alpha3

EDIT: I also reported this as bug https://issuetracker.google.com/issues/124812189

EDIT: partial solution for this is to set progress_bar and error visibility to GONE << However the same scenario applies here so if you interact with loading you can see scrollView, but it's better than to see ProgressBar when there should be content.

svkaka
  • 3,942
  • 2
  • 31
  • 55
  • 1
    I think Nicolas mentioned somewhere (might have been this talk https://www.youtube.com/watch?v=r8cYDlBOPaA&feature=youtu.be) that this is a bug that they are aware of and it will be fixed in alpha 4 (which is said to be released in the coming weeks). Pinging @camaelon on Twitter might also help. – jossiwolf Feb 21 '19 at 10:31
  • @jossiwolf thanks a lot, I was hoping for it to be a bug, not my abuse of their API. – svkaka Feb 21 '19 at 11:07
  • 1
    He is talking about it around https://youtu.be/r8cYDlBOPaA?t=2276 – svkaka Feb 21 '19 at 11:23
  • Possible duplicate of [android:visibility changes to children of MotionLayout](https://stackoverflow.com/questions/57168071/androidvisibility-changes-to-children-of-motionlayout) – Mohammad Alotol Sep 04 '19 at 14:16

2 Answers2

3

The bug is now fixed! Go and live your merry life without any visibility glitches :)

For future readers: This was known bug in MotionLayout where the state reset when the user touched something. Nicolas is talking about this around here: https://youtu.be/r8cYDlBOPaA?t=2276

The team fixed it in Alpha 4.

jossiwolf
  • 1,865
  • 14
  • 22
2

I've managed to get a work around for this issue until alpha4 is released.

In my use case I have a button which is normally only shown when a list is in end it mode. So to keep it hidden when the list isn't in edit mode I'm changing the constraints based on the edit mode.

 private void enableDoneButton(boolean enabled){
    int visibility = enabled ? View.VISIBLE : View.GONE;
    ConstraintSet startSet = container.getConstraintSet(R.layout.fragment_menu);
    startSet.setVisibility(R.id.fab_done, visibility);
}

Hope this helps in the meantime.

Tudor S.
  • 809
  • 2
  • 12
  • 29