在我的Android应用中,我有一个Scrollview表单,其中包含一系列通过单选按钮回答的问题。每当用户按下单选按钮时,下一个问题就会从底部显示。对于新问题的动画,我使用xml属性animateLayoutChanges。问题是,Scrollview不会滚动到显示的下一个问题。
我尝试切换许多属性都无济于事。唯一可行的方法是将android:layout_gravity:bottom设置为滚动视图中嵌套的线性布局(ID为form_container的嵌套布局),但它导致了一个错误,即滚动视图将内容隐藏在屏幕上方,而没有让我向上滚动。
我的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
}
}
}
答案 0 :(得分:1)
在滚动scrollView之前,您需要等待布局更改。 为此,您可以使用viewTreeObserver和addOnGlobalLayoutListener 为避免听众泄漏,请在使用后立即销毁它。 我在这里使用的是Antonio Leiva提供的扩展程序,请看his article,以更好地了解viewTreeObserver和侦听器的工作方式
完成测量后,您需要知道scrollView完整内容的大小。 您需要找到scrollView的第一个孩子来找到高度:getChildAt(0).height
不幸的是,在afterMeasured中没有两次调用它,我无法使用smoothScroll,并且我无法解释这种行为...
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)
}
}
})
}