Сбой прокрутки при использовании по умолчанию animateLayoutChanges - PullRequest
0 голосов
/ 11 февраля 2019

В моем приложении для Android у меня есть форма в Scrollview, состоящая из серии вопросов, на которые можно ответить с помощью переключателей.Всякий раз, когда пользователь нажимает переключатель, следующий вопрос отображается снизу.Для анимации нового вопроса я использую атрибут xml animateLayoutChanges.Проблема в том, что Scrollview не прокручивает до следующего вопроса, который появляется.

Я попытался переключить множество атрибутов, но безрезультатно.Единственное, что сработало, это установка андроида: layout_gravity: снизу к линейному макету, вложенному в представление scrollview (с идентификатором form_container), но это привело к ошибке, когда представление scrollview скрывает содержимое сверху, которое исчезает с экрана и не 'Позвольте мне прокрутить вверх.

Мой XML

<LinearLayout
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:animateLayoutChanges="true"
    android:clipToPadding="false"
    android:clipChildren="false"
    android:background="@color/colorPrimaryDark">

    <include layout="@layout/progress_bar_container"/>

    <RelativeLayout android:id="@+id/content_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:clipToPadding="false"
        android:clipChildren="false">

        <ScrollView android:id="@+id/form_scroll"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:animateLayoutChanges="true"
            android:padding="20dp"
            android:scrollbars="none"
            android:clipToPadding="false"
            android:clipChildren="false">

            <LinearLayout android:id="@+id/form_container"
                android:orientation="vertical"
                android:layout_width="match_parent"
                android:layout_gravity="bottom"
                android:animateLayoutChanges="true"
                android:layout_height="wrap_content"
                android:clipToPadding="false"
                android:clipChildren="false">

                <LinearLayout
                    android:id="@+id/intro_container"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical"
                    android:clipToPadding="false"
                    android:clipChildren="false">

                    <TextView android:id="@+id/search_title"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:paddingBottom="5dp"
                        android:text="@string/search_title"
                        android:textColor="@android:color/white"
                        android:textSize="24sp"
                        />

                    <TextView
                        android:id="@+id/search_description"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:text="@string/search_description"
                        android:textColor="@android:color/white"
                        android:textSize="22sp"
                        />

                    <ImageView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:paddingBottom="32dp"
                        android:paddingTop="30dp"
                        android:src="@drawable/random" />

                </LinearLayout>

                <LinearLayout android:id="@+id/container1"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:animateLayoutChanges="true"
                    android:orientation="vertical"
                    android:visibility="gone"
                    android:paddingTop="20dp">

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:paddingBottom="15dp"
                        android:text="whatever"
                        android:textColor="@android:color/white"
                        android:textSize="18sp"
                        />

                    <org.apmem.tools.layouts.FlowLayout android:id="@+id/flow"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:orientation="horizontal" />

                </LinearLayout>

                <LinearLayout android:id="@+id/container2"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical"
                    android:animateLayoutChanges="true"
                    android:visibility="visible"
                    >

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:paddingBottom="15dp"
                        android:text="whatever2"
                        android:textColor="@android:color/white"
                        android:textSize="18sp"
                        android:typeface="monospace" />

                    <RadioGroup android:id="@+id/radio_group1"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:orientation="horizontal"
                        android:animateLayoutChanges="true"
                        >

                        <android.support.v7.widget.AppCompatRadioButton android:id="@+id/radio1"
                            android:layout_width="0dp"
                            android:layout_weight="1"
                            android:gravity="center"
                            android:paddingStart="20dp"
                            android:layout_height="50dp"
                            android:background="@drawable/radio"
                            android:button="@android:color/transparent"
                            android:text="whatever"
                            android:layout_marginEnd="5dp"
                            />
                        <android.support.v7.widget.AppCompatRadioButton android:id="@+id/radio2"
                            android:layout_marginStart="5dp"
                            android:layout_width="0dp"
                            android:paddingStart="20dp"
                            android:layout_weight="1"
                            android:gravity="center"
                            android:layout_height="50dp"
                            android:background="@drawable/radio"
                            android:button="@android:color/transparent"
                            android:text="whatever"
                            />
                    </RadioGroup>
                </LinearLayout>

                <LinearLayout android:id="@+id/container3"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:visibility="gone"
                    android:orientation="vertical"
                    android:paddingTop="20dp"
                    android:animateLayoutChanges="true"
                    >

                    <TextView
                        android:id="@+id/label"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:paddingBottom="10dp"
                        android:letterSpacing=".07"
                        android:text="@string/confirm"
                        android:textColor="@android:color/white"
                        android:textSize="18sp"
                        android:typeface="monospace" />


                    <include android:id="@+id/search_bar"
                        layout="@layout/custom_dummy_search_view"
                        android:layout_height="60dp"
                        android:layout_width="match_parent"/>
                </LinearLayout>

                <LinearLayout android:id="@+id/container4"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical"
                    android:visibility="gone"
                    android:paddingTop="20dp"
                    android:animateLayoutChanges="true"
                    >

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:paddingBottom="15dp"
                        android:letterSpacing=".07"
                        android:text="whatever"
                        android:textColor="@android:color/white"
                        android:textSize="18sp"
                        android:typeface="monospace" />

                    <org.apmem.tools.layouts.FlowLayout android:id="@+id/flow2"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:orientation="horizontal"
                        android:animateLayoutChanges="true"
                        />

                </LinearLayout>

                <LinearLayout android:id="@+id/container5"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical"
                    android:visibility="gone"
                    android:paddingTop="20dp"
                    android:animateLayoutChanges="true"
                    >

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:paddingBottom="15dp"
                        android:letterSpacing=".07"
                        android:text="whatever"
                        android:textColor="@android:color/white"
                        android:textSize="18sp"
                        android:typeface="monospace" />

                    <RadioGroup android:id="@+id/radio_group2"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:orientation="horizontal"
                        android:animateLayoutChanges="true"
                        >

                        <android.support.v7.widget.AppCompatRadioButton android:id="@+id/radio3"
                            android:layout_width="0dp"
                            android:layout_weight="1"
                            android:gravity="center"
                            android:paddingStart="20dp"
                            android:layout_height="50dp"
                            android:background="@drawable/radio"
                            android:button="@android:color/transparent"
                            android:text="whatever"
                            android:layout_marginEnd="5dp"
                            />
                        <android.support.v7.widget.AppCompatRadioButton android:id="@+id/radio4"
                            android:layout_marginStart="5dp"
                            android:paddingStart="20dp"
                            android:layout_width="0dp"
                            android:layout_weight="1"
                            android:gravity="center"
                            android:layout_height="50dp"
                            android:background="@drawable/radio"
                            android:button="@android:color/transparent"
                            android:text="whatever"
                            />
                    </RadioGroup>


                </LinearLayout>

                <android.support.constraint.ConstraintLayout android:id="@+id/container6"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:paddingTop="20dp"
                    android:background="@null"
                    android:visibility="gone"
                    android:animateLayoutChanges="true"
                    >

                    <Button android:id="@+id/button"
                        style="?android:attr/borderlessButtonStyle"
                        android:layout_width="match_parent"
                        android:layout_height="60dp"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintEnd_toEndOf="parent"
                        app:layout_constraintStart_toStartOf="parent" />

                    <ImageView android:id="@+id/search_icon"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginStart="16dp"
                        android:layout_marginTop="8dp"
                        android:layout_marginBottom="8dp"
                        android:src="@drawable/search"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintTop_toTopOf="parent" />

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginStart="8dp"
                        android:layout_marginTop="8dp"
                        android:layout_marginBottom="8dp"
                        android:text="whatever"
                        android:textAllCaps="true"
                        android:textSize="18sp"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintEnd_toEndOf="@+id/button"
                        app:layout_constraintStart_toStartOf="@+id/button"
                        app:layout_constraintTop_toTopOf="parent" />

                </android.support.constraint.ConstraintLayout>
            </LinearLayout>
        </ScrollView>
    </RelativeLayout>
</LinearLayout>

Чтобы изменить видимость представлений, используется простейший код:

radioButton.setOnCheckedChangeListener { compoundButton, b ->
            mContainer2.visibility = View.VISIBLE

Редактировать:

Пример кода, который воспроизводит проблему:

XML

<ScrollView android:id="@+id/form_scroll"
        xmlns:android="http://schemas.android.com/apk/res/android"
            android:background="@color/colorPrimaryDark"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:animateLayoutChanges="true"
        android:padding="20dp"
        android:scrollbars="none">
    <RelativeLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:animateLayoutChanges="true"
            android:gravity="bottom"
            android:clipChildren="false"
            android:layout_height="wrap_content">

    <TextView android:id="@+id/text1"
            android:layout_width="wrap_content"
              android:visibility="visible"
              android:text="text1text1text1text1text1text1text1text1text1text1text1text1text1text1text1text1text1text1"
              android:textSize="40sp"
              android:background="@color/colorPrimary"
              android:layout_height="wrap_content"/>

    <TextView android:id="@+id/text2"
              android:layout_below="@id/text1"
              android:layout_width="wrap_content"
              android:text="text2text2text2text2text2text2text2text2text2text2text2text2text2text2text2text2text2text2text2"
              android:textSize="40sp"
              android:visibility="gone"
              android:background="@color/colorPrimary"
              android:layout_height="wrap_content"/>
    <TextView android:id="@+id/text3"
              android:layout_below="@id/text2"
              android:layout_width="wrap_content"
              android:text="text3text3text3text3text3text3text3text3text3text3text3text3text3text3text3text3text3text3text3text3text3text3text3text3text3"
              android:textSize="40sp"
              android:visibility="gone"
              android:background="@color/colorPrimary"
              android:layout_height="wrap_content"/>
    <TextView android:id="@+id/text4"
              android:layout_below="@id/text3"
              android:layout_width="wrap_content"
              android:text="text4text4text4text4text4text4text4text4text4text4text4text4text4text4text4text4text4text4text4text4text4text4text4text4text4text4text4text4text4text4text4text4text4text4text4text4text4text4text4text4"
              android:textSize="40sp"
              android:visibility="gone"
              android:background="@color/colorPrimary"
              android:layout_height="wrap_content"/>
    </RelativeLayout>
</ScrollView>

Активность:

class MainActivity : AppCompatActivity() {

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

    val mScroll = findViewById<ScrollView>(R.id.form_scroll)

    val mText1 = findViewById<TextView>(R.id.text1)
    val mText2 = findViewById<TextView>(R.id.text2)
    val mText3 = findViewById<TextView>(R.id.text3)
    val mText4 = findViewById<TextView>(R.id.text4)

    mText1.setOnClickListener {
        mText2.visibility = View.VISIBLE
    }
    mText2.setOnClickListener {
        mText3.visibility = View.VISIBLE
    }
    mText3.setOnClickListener {
        mText4.visibility = View.VISIBLE
    }
}
}

1 Ответ

0 голосов
/ 13 февраля 2019

Вам нужно подождать, пока ваш макет изменится, прежде чем прокручивать в scrollView.Для этого вы можете использовать viewTreeObserver и addOnGlobalLayoutListener. Чтобы избежать любой утечки вашего слушателя, вы уничтожаете его сразу после использования.Я использую расширение, предоставленное Антонио Лейвой здесь, посмотрите его статью , чтобы лучше понять, как работают viewTreeObserver и слушатель

Как только измерение будет выполнено, вам нужно знатьразмер полного содержимого вашего scrollView.Вам нужно найти первого дочернего элемента scrollView, чтобы найти высоту: getChildAt (0) .height

К сожалению, я не смог использовать smoothScroll, не вызвав его дважды в afterMeasured, и яне в состоянии объяснить это поведение ...

class MainActivity : AppCompatActivity() {

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

        val mScroll = findViewById<ScrollView>(R.id.form_scroll)

        val mText1 = findViewById<TextView>(R.id.text1)
        val mText2 = findViewById<TextView>(R.id.text2)
        val mText3 = findViewById<TextView>(R.id.text3)
        val mText4 = findViewById<TextView>(R.id.text4)

        mText1.setOnClickListener {
            mText2.visibility = View.VISIBLE
            mText2.afterMeasured {
                mScroll.scrollTo(0, mScroll.getChildAt(0).height)
            }

        }
        mText2.setOnClickListener {
            mText3.visibility = View.VISIBLE
            mText3.afterMeasured {
                mScroll.scrollTo(0, mScroll.getChildAt(0).height)
            }
        }
        mText3.setOnClickListener {
            mText4.visibility = View.VISIBLE

            mText4.afterMeasured {
                mScroll.scrollTo(0, mScroll.getChildAt(0).height)
            }
        }
    }
}

inline fun View.afterMeasured(crossinline f: View.() -> Unit) {
    viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
        override fun onGlobalLayout() {
            if (measuredWidth > 0 && measuredHeight > 0) {
                println(measuredHeight)
                f()
                viewTreeObserver.removeOnGlobalLayoutListener(this)
            }
        }
    })
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...