Expand View's Touch area in Android

There is an issue that I met a few days ago, my colleague wants me to improve the checkbox's clickable experience in Android. Following is the layout code and its visual effect.


Then the xml layout file:

<LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical">
            <LinearLayout
                android:id="@+id/checkbox1_container"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginEnd="50dp"
                android:layout_marginRight="50dp"
                android:gravity="center"
                android:orientation="horizontal">
                <CheckBox
                    android:id="@+id/checkbox1"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_margin="10dp"
                    />
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="CheckBox 1"/>
            </LinearLayout>

            <LinearLayout
                android:id="@+id/checkbox2_container"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginEnd="50dp"
                android:layout_marginRight="50dp"
                android:gravity="center"
                android:orientation="horizontal">
                <CheckBox
                    android:id="@+id/checkbox2"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_margin="10dp"
                    />
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="CheckBox 2"/>
            </LinearLayout>

            <LinearLayout
                android:id="@+id/checkbox3_container"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginEnd="50dp"
                android:layout_marginRight="50dp"
                android:gravity="center"
                android:orientation="horizontal">
                <CheckBox
                    android:id="@+id/checkbox3"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_margin="10dp"
                    />
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="CheckBox 3"/>
            </LinearLayout>

        </LinearLayout>

My first response to those question is to listen the CheckBox's parent container then control its state. While it works, until I met the TouchDelegate which is also mentioned in the official document.

Here is the much more elegant solution by employing the TouchDelegate(written by kotlin).


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val box1 = findViewById(R.id.checkbox1)
        val box1Parent = findViewById(R.id.checkbox1_container)

        val box2 = findViewById(R.id.checkbox2)
        val box2Parent = findViewById(R.id.checkbox2_container)

        val box3 = findViewById(R.id.checkbox3)
        val box3Parent = findViewById(R.id.checkbox3_container)

        expandViewHitArea(box1Parent, box1)
        expandViewHitArea(box2Parent, box2)
        expandViewHitArea(box3Parent, box3)
    }

    private fun expandViewHitArea(parent : View, child : View) {

        parent.post {

            val parentRect = Rect()
            val childRect = Rect()
            parent.getHitRect(parentRect)
            child.getHitRect(childRect)

            childRect.left = 0
            childRect.top = 0
            childRect.right = parentRect.width()
            childRect.bottom = parentRect.height()

            parent.touchDelegate = TouchDelegate(childRect, child)
        }
    }


Comments

Popular posts from this blog

Bluedroid stack in android

How to setup a NAT server?

Network programming in elisp