I would like to implement DragSelect feature in LinearLayout. For RecyclerView it already exists for example: here
But in LinearLayout
it gets more complicated. Because onTouch events. The use case would be for day selection. This is a Custom class viewgroup that has this 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>
I tried inside the custom class with:
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()
}
}
}
But no success. It sometimes recognizes that the day is touched and sometimes it doesn't so it isn't very reliable. I tried to putting on touch event inside the children, but it only recognizes the first one and doesn't trigger for others. So the TouchListener
needs to be implemented in the ViewGroup
.