Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何将一组视图分组并一起更改它们的可见性_Android_Kotlin - Fatal编程技术网

Android 如何将一组视图分组并一起更改它们的可见性

Android 如何将一组视图分组并一起更改它们的可见性,android,kotlin,Android,Kotlin,我有一个活动,它包含两组视图,不能位于同一布局组中,但属于同一逻辑组,这意味着它们应该同时显示或隐藏并绑定单击事件。问题是我觉得写这样的东西真的很糟糕: fun hide() { view1.visibility = View.GONE view2.visibility = View.GONE view3.visibility = View.GONE // ... view9.visibility = View.GONE } fun show() {

我有一个活动,它包含两组视图,不能位于同一布局组中,但属于同一逻辑组,这意味着它们应该同时显示或隐藏并绑定单击事件。问题是我觉得写这样的东西真的很糟糕:

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() }
}
view.toggleVisibility()
我确实读过一篇文章,其中描述了一种科特林技能,通过某种方式将这些观点分组,然后只处理分组,从而简化了这一混乱局面,但不幸的是,我再也找不到这篇文章了

谢谢你的帮助

==========更新日期2019-07-31=========

我找到了解决方案,但忘了更新这个问题,我正在寻找的“分组”实际上不是Kotlin特有的功能,而是简单地使用vararg,我们可以使用Kotlin扩展(非常棒)来简化一些:

// assume we have a base activity or fragment, then put below functions in there
fun View.show() {
    visibility = View.VISIBLE
}

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

fun View.hide() {
    visibility = View.GONE
}

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

// then in any activity or fragment
show(v1, v2, v3, v4)
v9.hide()
================更新日期2020-03-07================


这正是androidx.constraintlayout.widget.Group设计的初衷,它可以从任何地方对一组视图进行逻辑分组,并且只通过更改组的可见性来控制它们的可见性

根据布局结构的不同,您可能希望在
视图组中对这些视图进行分组,如
线性布局
相对布局
框架布局
约束布局

然后,您可以仅在
视图组上更改可见性
,其所有子项也将更改可见性

编辑:

如果不使用
ViewGroup
,消除此样板文件的唯一解决方案是在项目中启用数据绑定,并将其设置为:

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() }
}
view.toggleVisibility()
在您的活动/片段中:

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>

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

fun View.toggleVisibility() {
    if (visibility == View.VISIBLE) {
        visibility = View.GONE
    } else {
        visibility = View.VISIBLE
    }
}
您可以这样使用它:

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() }
}
view.toggleVisibility()

为什么不创建一个数组:

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{  }
}
for(1..9中的i){
val id=resources.getIdentifier(“查看$i”,“id”,context.getPackageName())
val视图=findViewById(id)
view.visibility=view.visibility
view.setOnClickListener{}
}

您可以定义一个具有三个参数的函数,并使用
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)
        }
    }
}

当然,如果你有太多的观点,这不是一个有效的解决方案。我刚刚添加了这个代码片段,这是一种替代方法,特别是针对动态视图集的问题。

首先,在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()
        }
    }
}

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

val views = listOf<View>(view1, view2, ...)
views.forEach {
    it.visibility = View.GONE
}
val views=listOf(视图1、视图2,…)
视图。forEach{
it.visibility=View.GONE
}
您还可以创建
Iterable
,以简化列表视图上的任何操作

fun Iterable<View>.visibility(visibility: Int) = this.forEach {
    it.visibility = visibility
}
//usage
views.visibility(View.GONE)
fun Iterable.visibility(visibility:Int)=this.forEach{
it.visibility=可见性
}
//用法
视图.可见性(视图.消失)
也许您想从XML中的标记定位所有视图。看一看

,因为1.1您可以使用Group而不是
LayoutGroup
。 您只需将此代码添加到XML布局中即可

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

有关更多详细信息,请阅读本文

您需要创建扩展函数

例如:

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

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

您可以创建包含子视图的
线性布局
或任何其他
视图组
,并在XML文件中为其指定ID,然后在
活动
片段
类中定义这些函数:

    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
方法返回
ViewGroup
中的
子视图
s的
序列
,您可以对其进行迭代
forEach
并应用任何适用于
视图
s的操作


希望有帮助

将它们添加到一个单独的布局中,就像线性布局一样…@AmitJangid我希望这样简单,但是那些属于同一逻辑组的视图不能简单地添加到一个布局组中..它们都混在一起..感谢那些视图确实不在同一布局组下,但是根据你的建议,我仍然需要写xxxx.toggleVisibility()的十几行,这正是我想要避免的..对不起,伙计,我没有说清楚,问题现在更新了,那些属于同一逻辑组的视图不能放在同一布局组中。这肯定可以做到,谢谢!然而,这并不是我在那篇文章中看到的,这很重要。。犯错误让我们说kotlin有点神奇..当你可以通过GroupsHanks来创建不必要的循环时,你为什么要创建它呢!这是一个最接近我正在寻找和目前使用的,我已经更新了我在我的问题帖子中使用的解决方案。干杯。如果您正在使用androidx,请改用
androidx.constraintlayout.widget.Group