Android TouchDelegate收缩视图组触摸区域不工作
我的布局有点复杂。我版面上的一些按钮上有阴影,我将它们显示为图像。问题是图像周围有很多额外的空间,所以它们最终会重叠——当这些图像用于按钮时,这意味着触摸区域重叠 在做了一些阅读和搜索之后,我意识到TouchDelegate类应该能够完美地解决我的问题,但是我无法让它工作 基于我遇到的特殊情况,我创建了一个小测试项目来演示我看到的问题。下面是包含此测试项目的各种文件中的代码,它再现了我看到的问题: activity_main.xml(布局): 运行上述程序时,您应该看到的图像: 屏幕左中部有两个按钮。这两个按钮的宽度都是150dp,但最右边的按钮有120dp的显式边距,这意味着最左边的30dp位于第一个按钮的顶部。小圆圈仅用于说明目的,但代表我在主要应用程序中的内容 我预期的行为:Android TouchDelegate收缩视图组触摸区域不工作,android,Android,我的布局有点复杂。我版面上的一些按钮上有阴影,我将它们显示为图像。问题是图像周围有很多额外的空间,所以它们最终会重叠——当这些图像用于按钮时,这意味着触摸区域重叠 在做了一些阅读和搜索之后,我意识到TouchDelegate类应该能够完美地解决我的问题,但是我无法让它工作 基于我遇到的特殊情况,我创建了一个小测试项目来演示我看到的问题。下面是包含此测试项目的各种文件中的代码,它再现了我看到的问题: activity_main.xml(布局): 运行上述程序时,您应该看到的图像: 屏幕左中部有两
- 单击蓝色区域的任意位置将显示一个祝酒词,上面写着“Button ONE Clicked”
- 点击红色区域中绿色/白色圆圈的任意位置将显示一个祝酒词,上面写着“Button TWO Clicked”
- 单击紫色区域的任意位置(实际上是按钮2的左30dp)应显示“按钮1已单击”,因为父级上安装了TouchDelegate
- 按预期点击蓝色/红色区域,如上所示
- 点击紫色区域显示“按钮二已点击”-点击未被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);
});
}
}