I have a layout with a root element LinearLayout
which encloses two other LinearLayouts
, which make up for two rows. Those contain a Switch
respectively.
In reality it looks somewhat like this: example picture
This is how my example layout file looks like:
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<LinearLayout android:id="@+id/layout_row_1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Switch android:id="@+id/switch_row_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout android:id="@+id/layout_row_2"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Switch android:id="@+id/switch_row_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
Now, what I want to accomplish is, that touching the area of the first LinearLayout
will trigger the first Switch
and touching the area of the second LinearLayout
will trigger the second Switch
.
As explained in Is there an example of how to use a TouchDelegate in Android to increase the size of a view's click target? and How To Use Multiple TouchDelegate I used a TouchDelegate to increase the touchable area of the Switch
to its parent View
, the LinearLayout
.
Here is my method for that:
public static void expandTouchArea(final View smallView, final View largeView) {
largeView.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect delegateArea = new Rect();
largeView.getHitRect(delegateArea);
TouchDelegate delegate = new TouchDelegate(delegateArea, smallView);
largeView.setTouchDelegate(delegate);
}
});
}
In my onCreate()
I call it for both rows:
mLayoutRow1 = findViewById(R.id.layout_row_1);
mLayoutRow2 = findViewById(R.id.layout_row_2);
mSwitchRow1 = (Switch) findViewById(R.id.switch_row_1);
mSwitchRow2 = (Switch) findViewById(R.id.switch_row_2);
expandTouchArea(mSwitchRow1, mLayoutRow1);
expandTouchArea(mSwitchRow2, mLayoutRow2);
What I cannot understand is, that for row 1 it is working, but for row 2 (and any other successive calls to expandTouchArea
) it does NOT work.
I also tried to instead of adding the OnGlobalLayoutListener
, post a Runnable
to the event message queue of the Switch
itself, resulting in exactly the same behavior.
So the question I could not answer so far is: Is it possible to have multiple TouchDelegates
for different LinearLayouts
that route touch events to separate Switches
respectively, in one layout?
I found that when I add another LinearLayout
around each row, both TouchDelegates
work.
Now my example layout file looks like this:
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout android:id="@+id/layout_row_1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Switch android:id="@+id/switch_row_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout android:id="@+id/layout_row_2"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Switch android:id="@+id/switch_row_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
Maybe there is another solution. This one seems somehow tedious.