Перетащите выделение как в RecyclerView для LinearLayout - PullRequest
0 голосов
/ 26 июня 2019

Я хотел бы реализовать функцию DragSelect в LinearLayout. Для RecyclerView он уже существует, например: здесь

Но в LinearLayout все становится сложнее. Потому что события onTouch. Вариант использования будет для выбора дня. Это пользовательская группа просмотра классов, которая имеет XML.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/containerSelectDays"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tvCurrentDaysOverall"
        style="@style/TextAppearance.SemiBold"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:text="@string/repeat"
        android:textSize="@dimen/subtitle" />

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/layoutList"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="16dp">

        <views.custom.SelectDayItemView
            android:id="@+id/day1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:layout_marginBottom="8dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toStartOf="@+id/day2"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <primoz.com.alarmcontinue.views.custom.SelectDayItemView
            android:id="@+id/day2"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="@+id/day1"
            app:layout_constraintEnd_toStartOf="@+id/day3"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/day1"
            app:layout_constraintTop_toTopOf="@+id/day1" />

        <views.custom.SelectDayItemView
            android:id="@+id/day3"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="@+id/day1"
            app:layout_constraintEnd_toStartOf="@+id/day4"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/day2"
            app:layout_constraintTop_toTopOf="@+id/day1"
            tools:layout_editor_absoluteY="0dp" />

        <views.custom.SelectDayItemView
            android:id="@+id/day4"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="@+id/day1"
            app:layout_constraintEnd_toStartOf="@+id/day5"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/day3"
            app:layout_constraintTop_toTopOf="@+id/day1"
            tools:layout_editor_absoluteY="0dp" />

        <views.custom.SelectDayItemView
            android:id="@+id/day5"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="@+id/day1"
            app:layout_constraintEnd_toStartOf="@+id/day6"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/day4"
            app:layout_constraintTop_toTopOf="@+id/day1"
            tools:layout_editor_absoluteY="0dp" />

        <views.custom.SelectDayItemView
            android:id="@+id/day6"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="@+id/day1"
            app:layout_constraintEnd_toStartOf="@+id/day7"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/day5"
            app:layout_constraintTop_toTopOf="@+id/day1"
            tools:layout_editor_absoluteY="0dp" />

        <views.custom.SelectDayItemView
            android:id="@+id/day7"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="@+id/day1"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/day6"
            app:layout_constraintTop_toTopOf="@+id/day1"
            tools:layout_editor_absoluteY="0dp" />


    </androidx.constraintlayout.widget.ConstraintLayout>

</LinearLayout>

Я пробовал внутри пользовательского класса:

override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
    val x = ev.x.roundToInt()
    val y = ev.y.roundToInt()
    handleTouch(x, y, ev, day1)
    handleTouch(x, y, ev, day2)
    handleTouch(x, y, ev, day3)
    handleTouch(x, y, ev, day4)
    handleTouch(x, y, ev, day5)
    handleTouch(x, y, ev, day6)
    handleTouch(x, y, ev, day7)
    return true
}

private fun handleTouch(
    x: Int,
    y: Int,
    ev: MotionEvent,
    day: SelectDayItemView
) {
    Log.d("Touched: $x,$y","touch")
    if (x > day.left && x < day.right && y > day.top && y < day.bottom) {
        if (ev.action == MotionEvent.ACTION_MOVE) {
            day.changeCheckedState()
        }
    }
}

Но безуспешно. Иногда он признает, что день тронут, а иногда нет, поэтому он не очень надежен. Я пытался включить сенсорное событие внутри детей, но оно распознает только первое и не срабатывает для других. Таким образом, TouchListener должен быть реализован в ViewGroup.

...