【问题标题】:Touch events not triggering on Android触摸事件未在 Android 上触发
【发布时间】:2019-05-09 13:56:17
【问题描述】:

我有一个活动,用户可以在其中看到关于我正在尝试开发的简单应用程序的“关于”。我正在使用“Android About Page”来显示它,但另外我想检测屏幕上的点击次数,以便在检测到正确的点击次数时会出现 Toast 消息……有点像复活节彩蛋: ) 我面临的问题是没有触发触摸事件......这是我正在使用的代码:

public class About extends AppCompatActivity {
   @Override
   public void onTouchEvent(MotionEvent event) {
      Log.i("LOG_RESPONSE", "Screen touched!");
   }  

   @Override
   protected void onCreate(Bundle savedInstanceState) {
      //// other code
   }
}

这是我的 XML:

<?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:id="@+id/layer"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   tools:context=".About">

   <View
       android:id="@+id/myView"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       app:layout_constraintBottom_toBottomOf="parent"
       app:layout_constraintEnd_toEndOf="parent"
       app:layout_constraintStart_toStartOf="parent"
       app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

没有错误,它什么也不做。

按照建议使用 onTouch() 进行编辑:

public class About extends AppCompatActivity {

   View test;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);

       test = (View)findViewById(R.id.myView);
       test.setOnTouchListener(new View.OnTouchListener() {
          @Override
          public boolean onTouch(View v, MotionEvent event) {
             Log.i("LOG_RESPONSE", "Screen touched!");
             return false;
          }
       });
       //// other code 
   }
}

这样应用就会崩溃:

Caused by: java.lang.NullPointerException

编辑 2 - 它不再崩溃,但没有识别到​​触摸:

public class About extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_about);
        View test = findViewById(R.id.layer);
        Log.i("LOG_RESPONSE", test.toString());

    test.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            Log.i("LOG_RESPONSE", "Screen touched!");
            return false;
        }
    });
}

【问题讨论】:

    标签: java android android-studio


    【解决方案1】:

    由于您想计算整个屏幕上的每次点击,而不仅仅是特定视图,您应该在活动布局上设置一个触摸事件侦听器,在您的情况下,它称为“@+id/layer”

    这就是你想要的:

    findViewById(R.id.layer).setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                counter++;
                if(counter==8)
                    Toast.makeText(About.this, "Surprise!!", Toast.LENGTH_SHORT).show();
                    Log.i("LOG_RESPONSE", "Screen touched!");
                return false;
            }
        });
    

    在示例中,我使用 8 作为事件的目标编号,但当然您可以在上面声明并使用它。

    编辑: 至于 java.lang.NullPointerException ,原因是您将视图声明为类成员对象,问题是您无法实例化它,因为它将上下文作为参数,并且由于onCreate 方法还没有运行,嗯,没有上下文,所以你无法实例化它,因此最好在 on create 方法中声明它。

    所以,这是你的问题:

    public class About extends AppCompatActivity {
        View test;//remove this
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_about);
            test =(View)findViewById(R.id.myView);
            //// other code
        }
    }
    

    这就是解决方案

    public class About extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_about);
            View test =(View)findViewById(R.id.myView);//Declare it and initialize it here
            //// other code
        }
    }
    

    【讨论】:

    • 谢谢。不幸的是它崩溃了。 “java.lang.NullPointerException”
    • 这是因为你贴花视图对象的方式
    • 它不再崩溃但没有检测到触摸。请参阅主线程中的 EDIT 2。
    【解决方案2】:

    请看下面的回答

    https://stackoverflow.com/a/5002073/9640177

    View 的用户使用 onTouch() 来获取触摸事件,而 View 的派生类使用 onTouchEvent() 获取触摸事件。

    为实现您的目的,一种可能的解决方案是使用填充整个屏幕的透明视图并在该视图上定义 onTouchListner。

    添加以下视图作为 rootView 的最后一个子视图

     <View android:id = "@+id/countTouch"
              android:layout_height = "match_parent"
              android:layout_weight = "match_parent"
              android:background = "#00000000">
    

    在你的 onCreate() 方法中设置 onTouchListener 如下

       findViewById(R.id.countTouch).setOnTouchListener(new OnTouchListnere{
             public boolean onTouch(MotionEvent e){
                    if(e.getAction()==MotionEvent.ACTION_DOWN){
                            counter++; // increment your global counter variable
                            //Log screen touched
                     }
                    return false;
             }
         };
    

    【讨论】:

      【解决方案3】:

      这是对更新问题的回答——在执行上一部分回答后的剩余问题

      您需要将wrap_content 更改为match_parent。您的视图中没有任何内容,因此wrap_content 会将其高度和宽度设置为 0。因此,当您触摸屏幕时,您触摸的是父级 ConstraintLayout 而不是您的视图。

      <View
         android:id="@+id/myView"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent" />
      

      希望这对最终来到这里的人有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-11-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多