Android TouchDelegate收缩视图组触摸区域不工作

Android TouchDelegate收缩视图组触摸区域不工作,android,Android,我的布局有点复杂。我版面上的一些按钮上有阴影,我将它们显示为图像。问题是图像周围有很多额外的空间,所以它们最终会重叠——当这些图像用于按钮时,这意味着触摸区域重叠 在做了一些阅读和搜索之后,我意识到TouchDelegate类应该能够完美地解决我的问题,但是我无法让它工作 基于我遇到的特殊情况,我创建了一个小测试项目来演示我看到的问题。下面是包含此测试项目的各种文件中的代码,它再现了我看到的问题: activity_main.xml(布局): 运行上述程序时,您应该看到的图像: 屏幕左中部有两

我的布局有点复杂。我版面上的一些按钮上有阴影,我将它们显示为图像。问题是图像周围有很多额外的空间,所以它们最终会重叠——当这些图像用于按钮时,这意味着触摸区域重叠

在做了一些阅读和搜索之后,我意识到TouchDelegate类应该能够完美地解决我的问题,但是我无法让它工作

基于我遇到的特殊情况,我创建了一个小测试项目来演示我看到的问题。下面是包含此测试项目的各种文件中的代码,它再现了我看到的问题:

activity_main.xml(布局):

运行上述程序时,您应该看到的图像:

屏幕左中部有两个按钮。这两个按钮的宽度都是150dp,但最右边的按钮有120dp的显式边距,这意味着最左边的30dp位于第一个按钮的顶部。小圆圈仅用于说明目的,但代表我在主要应用程序中的内容

我预期的行为:

  • 单击蓝色区域的任意位置将显示一个祝酒词,上面写着“Button ONE Clicked”
  • 点击红色区域中绿色/白色圆圈的任意位置将显示一个祝酒词,上面写着“Button TWO Clicked”
  • 单击紫色区域的任意位置(实际上是按钮2的左30dp)应显示“按钮1已单击”,因为父级上安装了TouchDelegate
观察到的行为:

  • 按预期点击蓝色/红色区域,如上所示
  • 点击紫色区域显示“按钮二已点击”-点击未被TouchDelegate拒绝
请注意,我正在使用API 22的设备上运行此程序

通过使用调试器,我已确认提供给TouchDelegate对象的矩形已设置了预期值

同样通过使用调试器,我在
ViewGroup.java
View.java
中逐步查看了
dispatchTouchEvent
中的代码,并观察到触摸代理仅在
View.java
onTouchEvent()函数中检查过。在我下面演示的情况下,从未调用安装TouchDelegate的视图的
onTouchEvent()
函数。这只会在我的布局中为“internal_container”ConstraintLayout调用,但它不是添加TouchDelegate的那个,因此它从未被选中

匿名重写TouchDelegate的onTouchEvent方法并在其中放置断点也表明它永远不会运行。断点永远不会被命中

我是否误解了如何在这里使用TouchDelegate,或者是否有其他方法(最好不必创建视图的自定义子类)可以实现我想要的?(为了重新迭代,项目将重叠,但我想切断button2的触摸区域,这样与button1重叠的最左侧部分就不会记录自身的点击)

还要注意,仅仅在布局中移动两个按钮的顺序也不能解决我的问题,因为这样button1将是重叠的button2

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/button1"
        android:layout_width="150dp"
        android:layout_height="50dp"
        android:clickable="true"
        android:focusable="true"
        android:src="@android:color/holo_blue_dark"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"/>

    <android.support.constraint.ConstraintLayout
        android:id="@+id/outer_container"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        android:layout_marginLeft="120dp">

        <android.support.constraint.ConstraintLayout
            android:id="@+id/inner_container"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:clickable="true"
            android:focusable="true">

            <ImageView
                android:id="@+id/button2"
                android:layout_width="150dp"
                android:layout_height="50dp"
                android:duplicateParentState="true"
                android:src="@drawable/button2_background"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintBottom_toBottomOf="parent"/>

            <ImageView
                android:id="@+id/button2_icon"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/button_icon"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintBottom_toBottomOf="parent"/>

        </android.support.constraint.ConstraintLayout>

    </android.support.constraint.ConstraintLayout>

</android.support.constraint.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_pressed="true">
        <shape android:shape="oval">
            <corners android:radius="12.5dp"/>
            <size android:width="25dp" android:height="25dp"/>
            <solid android:color="@android:color/white"/>
        </shape>
    </item>

    <item>
        <shape android:shape="oval">
            <corners android:radius="12.5dp"/>
            <size android:width="25dp" android:height="25dp"/>
            <solid android:color="@android:color/holo_green_dark"/>
        </shape>
    </item>

</selector>
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item>
        <shape android:shape="rectangle">
            <solid android:color="@android:color/holo_purple"/>
            <size android:width="30dp"/>
        </shape>
    </item>
    <item android:left="30dp">
        <shape android:shape="rectangle">
            <solid android:color="@android:color/holo_red_dark"/>
        </shape>
    </item>

</layer-list>
package com.company.touchdelegatetest;

import android.graphics.Rect;
import android.os.Bundle;
import android.support.constraint.ConstraintLayout;
import android.support.v7.app.AppCompatActivity;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.TouchDelegate;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    ImageView button1;
    ConstraintLayout outerContainer;
    ConstraintLayout innerContainer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button1 = findViewById(R.id.button1);
        outerContainer = findViewById(R.id.outer_container);
        innerContainer = findViewById(R.id.inner_container);

        button1.setOnClickListener(v -> {
            Toast.makeText(this, "Button ONE Clicked", Toast.LENGTH_SHORT).show();
        });

        innerContainer.setOnClickListener(v -> {
            Toast.makeText(this, "Button TWO Clicked", Toast.LENGTH_SHORT).show();
        });

        outerContainer.post(() -> {
            Rect delegateArea = new Rect();
            innerContainer.getHitRect(delegateArea);
            DisplayMetrics metrics = getResources().getDisplayMetrics();
            float leftOffsetDp = 30f;
            float leftOffsetPixels = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, leftOffsetDp, metrics);
            int pixels = Math.round(leftOffsetPixels);
            delegateArea.left += pixels;
            TouchDelegate touchDelegate = new TouchDelegate(delegateArea, innerContainer);
            outerContainer.setTouchDelegate(touchDelegate);
        });
    }
}