android - onTouch 和 onClick 没有正确触发

标签 android onclick

我有 ReltiveLayout,里面有 ImageView 和 TextView。

所以我有两个事件监听器:

  • 点击
  • onTouch

我正在为图像使用 9patch。当我使用 onTouch 事件时,onClick 根本没有触发,而且 onTouch 也不能很好地工作。如果我禁用 onTouch 并保留 onClick,它会触发并更改 Activity。我想让 onTouch 和 onClick 一起工作。我要:

  • 单击 RelativeLayout 时,它会显示所选按钮 ImageView
  • 否则显示普通按钮ImageView
  • onClickListener 改变 Activity 。

这是我的代码:

StartBtn = (RelativeLayout) findViewById(R.id.StartBtn);
StartBtnImage = (ImageView) findViewById(R.id.StartBtnImage);
StartBtnText = (TextView) findViewById(R.id.StartBtnText);

StartBtn.setOnTouchListener(new TouchButton(StartBtnImage)); //Commenting this line makes the onClickListener work
StartBtn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        StartBtnImage.setImageResource(R.drawable.btn_selected);
        Log.d("ButtonClick", "Done");
        Intent myIntent = new Intent(MainMenu.this, Game.class);
        startActivity(myIntent);

    }
});

还有我的 TouchButton 类:

public class TouchButton implements View.OnTouchListener {

    ImageView IV;

    public TouchButton(ImageView Image) {
        IV = Image;
    }

    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                IV.setImageResource(R.drawable.btn_selected);
                return true;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_OUTSIDE:
            default:
                IV.setImageResource(R.drawable.btn);
                return false;
        }
    }
}

这是我的布局

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainMenu">

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/MainMenuBg"
    android:background="@drawable/main_menu_bg" />

<RelativeLayout
    android:layout_width="250dp"
    android:layout_height="75dp"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="130dp"
    android:id="@+id/StartBtn"
    android:clickable="true">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/StartBtnImage"
        android:src="@drawable/btn" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="Start"
        android:id="@+id/StartBtnText"
        android:layout_centerVertical="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:singleLine="false"
        android:gravity="center|center_vertical|center_horizontal"
        android:textSize="50dp" />
</RelativeLayout>

我知道我不善于解释,所以这是一个视频: https://www.youtube.com/watch?v=PtdUsW-Dnqk

最佳答案

是的,您可以在单个 View 上使用多个监听器(如果不可能,那就会有问题)。

基本上,您的 View 的触摸事件在点击事件之前被触发。 如果触摸监听器消耗事件(从onTouch返回true),则不会调用点击监听器。 如果您从 onTouch 监听器返回 true,则您不会使用该事件(返回 false)并且任何底层监听器都将像 onClick 监听器一样被调用。

这里有两个监听器附加到一个 View (一个按钮)的例子:

    btnStart = (Button) findViewById(R.id.btn_start);

    btnStart.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            Log.d("stack", "TOUCH EVENT");
            return false;
        }
    });

    btnStart.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.d("stack", "CLICK EVENT");
            Toast.makeText(getApplicationContext(), "start game...", Toast.LENGTH_LONG).show();
        }
    });

和布局,一个简单的按钮:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

<Button
    android:id="@+id/btn_start"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="start btn"/>
</RelativeLayout>

在日志中,当您触摸按钮时,您会看到 TOUCH EVENT 在 CLICK EVENT 之前写入,因为 onTouch 监听器不使用该事件(返回 false)并首先被调用。

我建议您阅读有关 Android 中的触摸传播的文档并检查这个有用的 video Dave Smith 关于这个主题。

最后,您应该查看 xml 中的小部件状态,以便在它们被单击或聚焦时更改它们的外观,......看看 there

希望对您有所帮助。

关于android - onTouch 和 onClick 没有正确触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32725111/

相关文章:

java - 使用 AsyncTask 登录用户

html - onclick 不能可靠地工作

android - 在 sqlite android 上使用 List<> 选择行

android - 我们可以将 Flutter 模块添加到现有的 Android Studio 项目中吗?

Android OnClickListener 碰撞?

javascript - 在图像上放置 CSS 透明叠加层并在单击图像时使 JavaScript 函数起作用?

javascript 图片库查询(下一张图片)

javascript - 切换 <h1> 标签的填充

java - 如何将图库图像作为输入流

java - 为什么我的值没有从内部类添加到全局 ArrayList