Motionlayout: WARNING could not find view id -1

1.5k views Asked by At

My problem is, that I constantly get the warning W/MotionLayout: WARNING could not find view id -1. Because of this, my MotionLayout is really laggy and nearly jumps from the expanded state to the collapsed state. After waiting a couple of seconds, the animation starts getting better (no jumping / laggs anymore), but the warning remains.

Base XML

<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">

    <data>
        <variable
            name="product"
            type="com.example.app.framework.datasource.models.product.Product" />
    </data>

    <androidx.constraintlayout.motion.widget.MotionLayout
        android:id="@+id/shop_motion_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layoutDescription="@xml/shop_item_content_scene"
        app:showPaths="true"
        tools:context=".framework.ui.view.fragments.shop.ShopItemFragment">

        <com.google.android.material.appbar.MaterialToolbar
            android:id="@+id/shop_toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/ThemeOverlay.AppCompat.Light"
            app:menu="@menu/shop_item_toolbar"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <ImageView
            android:id="@+id/product_image"
            android:layout_width="0dp"
            android:layout_height="142dp"
            android:layout_marginStart="72dp"
            android:layout_marginTop="@dimen/standard8dpMargin"
            android:layout_marginEnd="72dp"
            android:adjustViewBounds="true"
            android:contentDescription="@null"
            android:fitsSystemWindows="true"
            app:loadImage="@{product.images[0]}"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/shop_toolbar" />

        <com.google.android.material.textview.MaterialTextView
            android:id="@+id/product_name"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="@dimen/big16dpMargin"
            android:layout_marginBottom="12dp"
            android:ellipsize="end"
            android:fontFamily="sans-serif-medium"
            android:maxLines="2"
            android:text="@{product.name}"
            android:textAlignment="textStart"
            android:textColor="@color/color_text_dark"
            android:textSize="@dimen/textHeadlineNormal1"
            app:layout_constraintBottom_toTopOf="@id/scrollview_shop"
            app:layout_constraintEnd_toEndOf="@id/barrier"
            app:layout_constraintStart_toStartOf="@id/margin_left"
            app:layout_constraintTop_toBottomOf="@+id/product_image"
            tools:text="Long text to test some stuff etc. bla bla" />

        <com.google.android.material.button.MaterialButton
            android:id="@+id/btn_shop"
            style="@style/Widget.MaterialComponents.Button.Icon"
            android:layout_width="56dp"
            android:layout_height="56dp"
            android:layout_marginEnd="16dp"
            android:backgroundTint="@color/color_btn_blue"
            android:insetLeft="0dp"
            android:insetTop="0dp"
            android:insetRight="0dp"
            android:insetBottom="0dp"
            android:padding="0dp"
            app:icon="@drawable/ic_shopping_cart_filled"
            app:iconGravity="textStart"
            app:iconPadding="0dp"
            app:layout_constraintBottom_toTopOf="@id/scrollview_shop"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="@id/scrollview_shop"
            app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.Example.Button.Circle" />

        <!-- My scrollview -->
        <androidx.core.widget.NestedScrollView
            android:id="@+id/scrollview_shop"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:fillViewport="true"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/product_name">

            <androidx.constraintlayout.widget.ConstraintLayout
                android:id="@+id/someID"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <com.google.android.material.textview.MaterialTextView
                    android:id="@+id/product_article_number"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="@dimen/standard8dpMargin"
                    android:text="FISCH"
                    android:textAlignment="textStart"
                    android:textColor="@color/color_text_gray"
                    android:textDirection="locale"
                    android:textSize="@dimen/textDescriptionNormal2"
                    android:textStyle="normal"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent"
                    tools:text="A 1234567" />

                <com.google.android.material.textview.MaterialTextView
                    android:id="@+id/tv_mwst_disclaimer"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="@dimen/standard8dpMargin"
                    android:text="SEIFE"
                    android:textAlignment="textStart"
                    android:textColor="@color/color_text_mwst"
                    android:textDirection="locale"
                    android:textSize="@dimen/textDescriptionNormal4"
                    android:textStyle="italic"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toBottomOf="@id/product_article_number"
                    tools:text="PREIS" />

            </androidx.constraintlayout.widget.ConstraintLayout>
        </androidx.core.widget.NestedScrollView>

        <androidx.constraintlayout.widget.Barrier
            android:id="@+id/barrier"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:barrierDirection="left"
            app:constraint_referenced_ids="btn_shop" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/margin_left"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintGuide_begin="@dimen/big16dpMargin" />

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

ContentScene XML

<?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"
    xmlns:motion="http://schemas.android.com/tools">

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

        <OnSwipe
            motion:dragDirection="dragUp"
            app:onTouchUp="stop"
            motion:touchAnchorId="@id/scrollview_shop"
            motion:touchAnchorSide="top" />

        <KeyFrameSet>
            <KeyAttribute
                app:motionTarget="@id/product_image"
                app:framePosition="40"
                android:alpha="0.0" />
        </KeyFrameSet>
    </Transition>

    <ConstraintSet android:id="@+id/expanded" />

    <ConstraintSet android:id="@+id/collapsed">
        <Constraint
            android:id="@id/product_image"
            android:layout_height="?attr/actionBarSize"
            android:layout_marginStart="56dp"
            android:layout_marginEnd="56dp"
            android:alpha="0.0"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
        <Constraint
            android:id="@id/product_name"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="56dp"
            android:layout_marginEnd="@dimen/standard8dpMargin"
            android:scaleX="0.925"
            android:scaleY="0.925"
            app:layout_constraintBottom_toBottomOf="@id/shop_toolbar"
            app:layout_constraintTop_toTopOf="@id/shop_toolbar"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="@id/barrier" />

        <Constraint
            android:id="@id/btn_shop"
            android:layout_marginEnd="@dimen/big16dpMargin"
            android:layout_width="56dp"
            android:layout_height="56dp"
            app:layout_constraintBottom_toBottomOf="@id/shop_toolbar"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/product_name" />
    </ConstraintSet>

</MotionScene>

Fragment

class ShopItemFragment : Fragment(R.layout.fragment_shop_item) {
    private val productArgs by navArgs<ShopItemFragmentArgs>()

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? = FragmentShopItemBinding.inflate(inflater, container, false).apply {
        product = productArgs.product
    }.root

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initToolbar()
    }

    private fun initToolbar() = shop_toolbar.apply {
        setupWithNavController(findNavController(), AppBarConfiguration(findNavController().graph))
    }
}

Expanded

Expanded

Collapsed

Collapsed

EDIT

I've tried to debug my code as good as I can and I found following: In my view, the mConstraintSetId has the value -1, and I think that logcat is warning me about that. How can I change this value or to say better: Why is this value -1? enter image description here

2

There are 2 answers

5
Jason Pearson On BEST ANSWER

The Issue:

The main thing you needed was not not be using both app and motion xml namespaces mixed in the same MotionScene:

xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:motion="http://schemas.android.com/tools"

You can use either, but you have to stick with one. I prefer app - makes it easier for me to jump between layout XML and motion scene XML.

As it stood, because you were using both, MotionLayout just picked up attributes tagged with app and disregarded motion ones, which meant your instructions for OnSwipe were the same as this:

<OnSwipe app:onTouchUp="stop" />

That's why you were seeing the WARNING could not find view id -1, which probably means MotionLayout needs a better error message in that case, or shouldn't compile at all if more than one namespace is used.


Solution:

So let's say you delete motion namespace, then all you have to do is update the OnSwipe transition to this:

        <OnSwipe
            app:dragDirection="dragUp"
            app:onTouchUp="stop"
            app:touchAnchorId="@id/scrollview_shop"
            app:touchAnchorSide="top" />

And then your transition should run just fine.

0
Tobi On

You should have the same <Constraint ../> in both <ConstraintSet ../>

Please try to update you scene and add:

<ConstraintSet android:id="@+id/expanded" >
    <Constraint
        android:id="@id/product_image"
        .... />
    <Constraint
        android:id="@id/product_name"
        .... />

    <Constraint
        android:id="@id/btn_shop"
        .... />
</ConstraintSet>