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.