简体   繁体   中英

Touch events not triggering on Android

I have an activity where user can see the "about" about the simple app I'm trying to develope. I'm using "Android About Page" to show it but plus I'd like to detect the number of taps on the screen so that a Toast message can appear when the right number of taps are detected...sort of easter egg :) The problem I'm facing is that touch events are not triggered... this is the code I'm using:

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
   }
}

This is my 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>

No errors, it just does nothing.

EDIT as suggested using 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 
   }
}

This way the app crashes:

Caused by: java.lang.NullPointerException

EDIT 2 - It does not crash anymore but no touch is recognized:

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;
        }
    });
}

Please see following answer

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

onTouch() is used by users of the View to get touch events while onTouchEvent() is used by derived classes of the View to get touch events.

To achieve your purpose one possible solution would be to use a transparent view that fills entire screen and define onTouchListner on that view.

Add following view as the last child of rootView

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

In your onCreate() method set onTouchListener as follows

   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;
         }
     };

Since you want to count every tap on the entire screen and not just a particular view, you should set a touch event listener on the activity layout, in your case it's called "@+id/layer"

so this is what you want:

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;
        }
    });

In the example i used 8 as the target number for the event, but of course you can declare it above and use it.

Edit: As far as the java.lang.NullPointerException , the reason is you declared the view as a class member object, the problem is you can't instantiate it, because it takes a context as a parameter and since the onCreate method hasn't run yet, well, there is no context, so there's no way you can instantiate it therefore it's better to declare it in the on create method.

So, this your problem :

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
    }
}

and this is the solution

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
    }
}

This is answer to the updated question -- in response to the remaining issue after implementation of answer to the previous part

You need to change wrap_content to match_parent . Your view has nothing in it so wrap_content will set its height and width to 0. So when you are touching the screen you are touching the parent ConstraintLayout and not your View.

<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" />

Hope this helps someone ending up here.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM