如何将一堆视图组合在一起并一起更改其可见性

时间:2018-10-16 12:43:59

标签: android kotlin

我有一个活动,其中包含2个视图组,不能位于同一LAYOUT组中,但属于同一LOGIC组,这意味着应该显示或隐藏它们并绑定单击事件在同一时间。问题是我真的很难写这样的东西:

fun hide() {
    view1.visibility = View.GONE
    view2.visibility = View.GONE
    view3.visibility = View.GONE
    // ...
    view9.visibility = View.GONE
}


fun show() {
    view1.visibility = View.VISIBLE
    view2.visibility = View.VISIBLE
    view3.visibility = View.VISIBLE
    // ...
    view9.visibility = View.VISIBLE

    view1.setOnClickListener{ run() }
    view2.setOnClickListener{ run() }
    view3.setOnClickListener{ run() }
    // ...
    view9.setOnClickListener{ run() }
}

我确实读了一篇介绍 kotlin技能的帖子,该帖子通过某种方式将这些视图分组然后仅处理组来简化这种混乱,但是不幸的是,我找不到该帖子。

我们将不胜感激!

9 个答案:

答案 0 :(得分:3)

ConstraintLayout 1.1开始,您可以使用组代替LayoutGroup。 您可以简单地将此代码添加到XML布局中

<android.support.constraint.Group
    android:id="@+id/profile"
    app:constraint_referenced_ids="profile_name,profile_image" />

然后您可以从代码中调用它来实现所需的行为

profile.visibility = GONE
profile.visibility = VISIBLE

有关更多详细信息,请阅读本文https://medium.com/androiddevelopers/introducing-constraint-layout-1-1-d07fc02406bc

答案 1 :(得分:1)

根据布局的结构,您可能希望将这些视图分组为ViewGroupLinearLayoutRelativeLayoutFrameLayout之类的ConstraintLayout。 / p>

然后,您可以仅在ViewGroup上更改可见性,它的所有子元素也将对其进行更改。

编辑:

在没有ViewGroup的情况下,消除此样板的唯一解决方案是在项目中启用数据绑定并按以下方式进行设置:

在您的活动/片段中:

val groupVisible = ObservableBoolean()

fun changeVisibility(show: Boolean) {
    groupVisible.set(show)
}

在您的xml中:

<layout>
    <data>
        <variable name="groupVisible" type="Boolean"/>
    </data>
    <View
        android:visibility="@{groupVisible ? View.VISIBLE : View.GONE}"/>
</layout>

答案 2 :(得分:1)

您可以定义具有三个参数的函数,并使用vararg,如以下代码所示:

fun changeVisiblityAndAddClickListeners(visibility: Int,
                                        listener: View.OnClickListener,
                                        vararg views: View) {
    for (view: View in views) {
        view.visibility = visibility
        if (visibility == View.VISIBLE) {
            view.setOnClickListener(listener)
        }
    }
}

当然,如果您有太多的意见,这不是一个有效的解决方案。我只是以另一种方式添加了此代码段,尤其是对于动态视图集问题。

答案 3 :(得分:1)

创建视图列表并在其上循环

val views = listOf<View>(view1, view2, ...)
views.forEach {
    it.visibility = View.GONE
}

您还可以在Iterable<View>中创建extension function,以简化对列出视图的任何操作

fun Iterable<View>.visibility(visibility: Int) = this.forEach {
    it.visibility = visibility
}
//usage
views.visibility(View.GONE)

也许您想从XML标记中找到所有视图。看看this answer

答案 4 :(得分:0)

如果视图不在视图组之内,则可以使用extension function。您可以创建一个以切换视图的可见性:

fun View.toggleVisibility() {
    if (visibility == View.VISIBLE) {
        visibility = View.GONE
    } else {
        visibility = View.VISIBLE
    }
}

您可以像这样使用它:

view.toggleVisibility()

答案 5 :(得分:0)

为什么不创建数组:

val views = arrayOf(view1, view2, view3, view4, view5, view6, view7, view8, view9)

然后:

fun show() {
    views.forEach {
        it.visibility = View.VISIBLE
        it.setOnClickListener{  }
    }
}

fun hide() {
    views.forEach { it.visibility = View.INVISIBLE }
}

如果视图的名称确实类似于view1,view2,...,则不带数组。

for (i in 1..9) {
    val id = resources.getIdentifier("view$i", "id", context.getPackageName())
    val view = findViewById<View>(id)
    view.visibility = View.VISIBLE
    view.setOnClickListener{  }
}

答案 6 :(得分:0)

首先在xml布局中,按android:tag="group_1"属性对视图进行分组。

然后在活动内部使用for循环来实现所需的任何逻辑:

val root: ViewGroup = TODO("find your root layout")
for (i in 0 until root.childCount) {
    val v = root.getChildAt(i)
    when (v.tag) {
        "group_1" -> {
            TODO()
        }
        "group_2" -> {
            TODO()
        }
        else -> {
            TODO()
        }
    }
}

答案 7 :(得分:0)

您需要创建扩展功能。

例如:

fun View.showGroupViews(vararg view: View) {
    view.forEach {
        it.show()
    }
}

fun View.hideGroupViews(vararg view: View) {
    view.forEach {
        it.hide()
    }
}

答案 8 :(得分:0)

您可以创建一个I/TimeTable: aMaison true I/TimeTable: bMontRochelle true cHoldenManz true' I/TimeTable: dCharmonix true I/TimeTable: eDieuDonne true I/TimeTable: fGrandeProvance true gRicketyBridge true aMaison true I/TimeTable: bMontRochelle true cHoldenManz true' dCharmonix true eDieuDonne true fGrandeProvance true I/TimeTable: gRicketyBridge true aMaison true bMontRochelle true cHoldenManz true' dCharmonix true eDieuDonne true I/TimeTable: fGrandeProvance true gRicketyBridge true 或包含孩子LinearLayout的任何其他ViewGroup并在XML文件中,然后在您的Views或{{1 }}类定义以下功能:

Activity

然后在Fragment fun disableViewGroup(viewGroup: ViewGroup) { viewGroup.children.iterator().forEach { it.isEnabled = false } } fun enableViewGroup(viewGroup: ViewGroup) { viewGroup.children.iterator().forEach { it.isEnabled = true } } 中进行如下调用:

onCreate()

onStart()方法在disableViewGroup(idOfViewGroup) 中返回children个子Sequence的{​​{1}},您可以通过View进行迭代,并应用适用于{{ 1}} s。

希望有帮助!