0

I tend to increase top area of a hit rectangle.

I refer to the code found in Is there an example of how to use a TouchDelegate in Android to increase the size of a view's click target? and http://developer.android.com/training/gestures/viewgroup.html#delegate

final View parentView = v.findViewById(R.id.touch_delegate_linear_layout);
ViewTreeObserver vto = parentView.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

    @SuppressLint("NewApi")
    @SuppressWarnings("deprecation")
    @Override
    public void onGlobalLayout() {
        final Rect r = new Rect();
        // currencyExchangeLinearLayout is currency_exchange_linear_layout.xml
        currencyExchangeLinearLayout.getHitRect(r);
        r.top -= 10;
        parentView.setTouchDelegate(new TouchDelegate(r , currencyExchangeLinearLayout));

        ViewTreeObserver obs = parentView.getViewTreeObserver();
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
            obs.removeOnGlobalLayoutListener(this);
        } else {
            obs.removeGlobalOnLayoutListener(this);
        }
    }
});

touch_delegate_linear_layout is my parent view.

currency_exchange_linear_layout is my touched target.

Here's how my layout looks like

enter image description here

The XML code for the above layout is as follow.

<LinearLayout
    android:id="@+id/touch_delegate_linear_layout"
    ...>

    <LinearLayout
        android:id="@+id/footer_linear_layout"
        ...
        android:orientation="horizontal" >

        <TextView
            android:id="@+id/footer_label_text_view"
            ... />

        <View
            android:layout_width="1px"
            ... />

        <TextView
            android:id="@+id/footer_value_text_view"
            ... />
    </LinearLayout>

    <LinearLayout
        ...
        android:orientation="horizontal" >

        <TextSwitcher
            android:id="@+id/status_bar"
            ... />

        <LinearLayout
            android:id="@+id/currency_exchange_linear_layout"
            ...>

        </LinearLayout>
    </LinearLayout>

</LinearLayout>

It works perfectly fine, if I touch within the area of currency_exchange_linear_layout

enter image description here

I expect the touch will work too, even I touch slightly above currency_exchange_linear_layout. This is because I have code r.top -= 10; to expand my touch area. However, it doesn't work as expected.

enter image description here

The strange part is, if I touch far from currency_exchange_linear_layout, the touch event will be mistakenly triggered. This is not what I'm expecting.

enter image description here

Any idea why such strange behavior occur? Is there anything wrong with my TouchDelegate code?

Demo Code

Here's the sample code, which uses to demonstrate the mentioned problem : https://www.dropbox.com/s/1wzu2w5dtpu6z5o/MyApplication2.zip?dl=0

Community
  • 1
  • 1
Cheok Yan Cheng
  • 47,586
  • 132
  • 466
  • 875

1 Answers1

0

The reason of this such behavior, is due to the fact currency_exchange_linear_layout is NOT direct child of touch_delegate_linear_layout

Hence, when we perform

currencyExchangeLinearLayout.getHitRect(r);

The obtained rectangle's coordinate is not relative to touch_delegate_linear_layout

In such case, we may use footer_value_text_view's hit rectangle, which its rectangle's Y-coordinate is relative to touch_delegate_linear_layout

final View parentView = v.findViewById(R.id.touch_delegate_linear_layout);
final View directChildView = v.findViewById(R.id.footer_value_text_view);

ViewTreeObserver vto = parentView.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

    @SuppressLint("NewApi")
    @SuppressWarnings("deprecation")
    @Override
    public void onGlobalLayout() {
        final Rect r = new Rect();
        final Rect directChild = new Rect();

        currencyExchangeLinearLayout.getHitRect(r);
        directChildView.getHitRect(directChild);

        int bestHeight = Utils.dpToPixel(48);

        directChild.top = directChild.bottom - Math.max((bestHeight - r.height()), 0);

        parentView.setTouchDelegate(new TouchDelegate(directChild, currencyExchangeLinearLayout));

        ViewTreeObserver obs = parentView.getViewTreeObserver();
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
            obs.removeOnGlobalLayoutListener(this);
        } else {
            obs.removeGlobalOnLayoutListener(this);
        }
    }
});
Cheok Yan Cheng
  • 47,586
  • 132
  • 466
  • 875