我在ConstraintLayout
内部有几个TextView
。这些TextView
的可见性是基于数据可用性在运行时设置的。
我需要将第一个可见的TextView
的文本加粗。
我尝试了很多方法,但都解决不了这个问题。
我试过:
- 循环遍历父布局中的子布局找到第一个孩子,让它变得大胆。这种方法总是在父布局中查找第一个子布局,而不管它是视觉效果
- 如果
view.visibility
,我在检索第一个元素之前进行了检查==
View.VISIBLE
和我检查的view.isShown
,无论可见性如何,都再次返回视图层次结构中的第一个子级。因此,view.visibility
总是返回View.VISIBLE
我缺少什么?如何使其发挥作用?
提供样本代码:
XML
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="viewModel"
type="MyViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/rootLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="24dp">
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="First textview"
android:textColor="@color/black"
android:visibility="@{viewModel.textView1Visibility}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Second textview"
android:textColor="@color/black"
android:visibility="@{viewModel.textView2Visibility}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textView1" />
<TextView
android:id="@+id/textView3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Third textview"
android:textColor="@color/black"
android:visibility="@{viewModel.textView3Visibility}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textView2" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
代码
binding.apply {
/** We have three textviews.
* textView1 doesn't have data so we are hiding it.
* textView2 has data so, we need to show it.
* and textView2 will be the first item, we need to bold it as well. */
textView1.visibility = View.GONE
/** looping through the children of root layout and bolding the first visible */
rootLayout.forEach exit@ { view ->
if(view.isVisible || view.isShown) {
(view as TextView).typeface = Typeface.DEFAULT_BOLD
return@exit
}
}
}
您的代码正在循环通过ConstraintLayout的所有子级,因为return@exit
的行为类似于continue
,而不是真正的break
。
尝试以下操作:
run exit@{
rootLayout.forEach { view ->
if (view.isVisible || view.isShown) {
(view as TextView).typeface = Typeface.DEFAULT_BOLD
return@forEach
}
}
}
也许有一种更优雅的方法可以做到这一点,但以上应该有效。
更新到代码:
rootLayout.children.firstOrNull { view ->
view.isVisible || view.isShown
}?.also { view ->
(view as TextView).typeface = Typeface.DEFAULT_BOLD
}
我还将提到,您的代码将找到ConstraintLayout子顺序的第一个可见子级,但该视图可能不是您选择的第一个查看屏幕的视图。这是因为ConstraintLayout的子级中的视图顺序可能由于布局限制而与屏幕上的顺序不同。这对你来说可能不是问题,但这是需要思考的。