Как сгруппировать кучу просмотров и изменить их видимость вместе - PullRequest
0 голосов
/ 16 октября 2018

У меня есть действие, которое содержит 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 навык , чтобы упростить этот беспорядок, каким-то образом сгруппировав эти представления, а затем простообрабатывать группы, но, к сожалению, я больше не могу найти этот пост ..

Помощь будет оценена!

========= Обновление 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()

Ответы [ 9 ]

0 голосов
/ 30 июля 2019

Вам необходимо создать функции расширения.

Например:

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

fun View.hideGroupViews(vararg view: View) {
    view.forEach {
        it.hide()
    }
}
0 голосов
/ 09 августа 2019

Вы можете создать LinearLayout или любой другой ViewGroup, содержащий вашего ребенка Views и присвоить ему идентификатор в файле XML, а затем в вашем классе 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 потомков View с в ViewGroup которую вы можете повторить с помощью forEach и применить любую операцию, применимую к View с.

Надеюсь, это поможет!

0 голосов
/ 16 октября 2018

Создание списка представлений и цикл по нему

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

Вы также можете создать функцию расширения из Iterable<View>, чтобы упростить любые действия в перечисленных видах

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

Может быть, вы хотите найти все представления из тегов в XML.Взгляните на этот ответ

0 голосов
/ 16 октября 2018

Поскольку 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

0 голосов
/ 16 октября 2018

Сначала в макете 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()
        }
    }
}
0 голосов
/ 16 октября 2018

Вы можете определить функцию с тремя параметрами и использовать 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)
        }
    }
}

Конечно, если у вас слишком много представлений, это неэффективное решение.Я только что добавил этот фрагмент кода для альтернативного способа, особенно для проблем с динамическим набором представления.

0 голосов
/ 16 октября 2018

Почему бы вам не создать массив:

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{  }
}
0 голосов
/ 16 октября 2018

Если ваши представления не находятся внутри группы представлений , вы можете использовать функцию расширения .Вы могли бы создать один, чтобы переключить видимость представлений:

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

И вы можете использовать его так:

view.toggleVisibility()
0 голосов
/ 16 октября 2018

В зависимости от того, как структурирован ваш макет, вы можете сгруппировать эти представления в ViewGroup, например LinearLayout, RelativeLayout, FrameLayout или ConstraintLayout.

Затем вы можете изменить видимостьтолько на 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...