I am trying to add a GestureDetector to an activity in my app. I have tried several different methods from youtube and stackoverflow none are working. No errors are showing and nothing happens when I swipe or use any gesture. I have put debugging logs all along the way and none are registering in the logcat Im all out of ideas now. It is the onFling() method I am mainly interested in.
I am putting up two methods i have tried. I have removed some code and changed it to make more reader friendly and relevant.
If anyone can help Id be delighted.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical">
<!-- LinearLayout has two children, Toolbar & DrawerLayout.
DrawerLayout has two children RelativeLayout (main content container)
LinearLayout is the root element so the Navigationdrawer does not open over the Toolbar.
The DrawerLayout was the root element before this.-->
<!-- adding the toolbar layout -->
<include
android:id="@+id/toolbar"
layout="@layout/toolbar"/>
<android.support.v4.widget.DrawerLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/mainDrawerLayout">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/backgroundImg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@drawable/nipple"
android:contentDescription="@string/content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<TextView android:id="@+id/main_tv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
android:gravity="center"
android:text="Hello"/>
</RelativeLayout>
<fragment android:id="@+id/fragment_navigation_drawer"
android:layout_width="280dp"
android:layout_height="match_parent"
android:layout_gravity="start"
app:layout="@layout/fragment_navigation_drawer"
android:name="com.ansgar.amazingfacts.activities.FragmentNavigationDrawer"
tools:layout="@layout/fragment_navigation_drawer"/>
</android.support.v4.widget.DrawerLayout>
</LinearLayout>
Method 1 Defining custom listener class
public class MainActivity extends AppCompatActivity implements FragmentNavigationDrawer.FragmentNavigationDrawerListener {
private ImageView image;
private TextView mTextView;
private Toolbar mToolbar;
private FragmentNavigationDrawer drawerFragment;
GestureDetectorCompat gesture;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
image = (ImageView) findViewById(R.id.backgroundImg);
mTextView = (TextView) findViewById(R.id.main_tv);
mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayShowHomeEnabled(true);
//Fragment for navigation drawer
drawerFragment = (FragmentNavigationDrawer) getSupportFragmentManager().findFragmentById(R.id.fragment_navigation_drawer);
//This method is created because we need to pass a few things from MainActivity to the FragmentNavigationDrawer
drawerFragment.sepUp(R.id.fragment_navigation_drawer, (DrawerLayout) findViewById(mainDrawerLayout), mToolbar);
drawerFragment.setDrawerListener(this);
this.gesture = new GestureDetectorCompat(this, new CustomGestureClass());
}//onCreate()
@Override
public boolean onTouchEvent(MotionEvent event) {
this.gesture.onTouchEvent(event);
Log.d("GESTURE", "OnTouchEvent");
Toast.makeText(getApplicationContext(), "Touch event", Toast.LENGTH_SHORT).show();
return super.onTouchEvent(event);
}
class CustomGestureClass extends GestureDetector.SimpleOnGestureListener {
//SimpleOnGestureListener is listener for what we want to do and how
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
//return super.onFling(e1, e2, velocityX, velocityY);
Log.d("GESTURE", "OnFling");
float sensitivity = 50;
//swipe left check
if (e1.getX() - e2.getX() > sensitivity) {
Log.d("GESTURE", "swipe left");
return true;
}
//swipe right check
if (e2.getX() - e1.getX() > sensitivity) {
Log.d("GESTURE", "Swipe Right");
Toast.makeText(getApplicationContext(), "Swipe right gesture", Toast.LENGTH_SHORT).show();
return true;
}
//swipe check down
if (e1.getY() - e2.getY() > sensitivity) {
Log.d("GESTURE", "Swipe Down");
Toast.makeText(getApplicationContext(), "Swipe down gesture", Toast.LENGTH_SHORT).show();
return true;
}
//swipe up check
if (e2.getY() - e1.getY() > sensitivity) {
Log.d("GESTURE", "Swipe Up");
Toast.makeText(getApplicationContext(), "Swipe up gesture", Toast.LENGTH_SHORT).show();
return true;
}
return true;
//return false;
}
@Override
public boolean onDown(MotionEvent e) {
Log.d("GESTURE", "OnDown");
//return super.onDown(e);
return true;
}
}//CustomGestureClass
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
//setting the title of actionBar
public void setTitle(String title){
getSupportActionBar().setTitle(title);
}
public void onCreateDrawer() {}
@Override
public void onDrawerItemSelected(View view, int position){
displayView(position);
//Log.d("DRAWER ITEM SELECTED", "the index number of item Drawer RecyclerView "+ position);
switch(position){
case 0:
break;
}
}
private void displayView(int position) {}
}//MainActivity.class
Method 2
public class MainActivity extends AppCompatActivity implements FragmentNavigationDrawer.FragmentNavigationDrawerListener,
GestureDetector.OnGestureListener {
private ImageView image;
private TextView mFactTextView;
private Toolbar mToolbar;
private FragmentNavigationDrawer drawerFragment;
GestureDetectorCompat gesture;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
image = (ImageView) findViewById(R.id.backgroundImg);
mTextView = (TextView) findViewById(R.id.main_tv);
mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayShowHomeEnabled(true);
//Fragment for navigation drawer
drawerFragment = (FragmentNavigationDrawer) getSupportFragmentManager().findFragmentById(R.id.fragment_navigation_drawer);
//This method is created because we need to pass a few things from MainActivity to the FragmentNavigationDrawer
drawerFragment.sepUp(R.id.fragment_navigation_drawer, (DrawerLayout) findViewById(mainDrawerLayout), mToolbar);
drawerFragment.setDrawerListener(this);
this.gesture = new GestureDetectorCompat(this, this);
}//onCreate()
@Override
public boolean onTouchEvent(MotionEvent event) {
this.gesture.onTouchEvent(event);
Log.d("GESTURE", "OnTouchEvent");
Toast.makeText(getApplicationContext(), "Touch event", Toast.LENGTH_SHORT).show();
return super.onTouchEvent(event);
}
@Override
public boolean onDown(MotionEvent e) {
Log.d("GESTURE", "OnDown");
return true;
}
@Override
public void onShowPress(MotionEvent e) {
Log.d("GESTURE", "OnShowPress");
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
Log.d("GESTURE", "OnSingleTapUp");
return true;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
Log.d("GESTURE", "OnScroll");
return true;
}
@Override
public void onLongPress(MotionEvent e) {
Log.d("GESTURE", "OnLongPress");
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
Log.d("GESTURE", "OnFling");
return true;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void onCreateDrawer() {}
@Override
public void onDrawerItemSelected(View view, int position){
displayView(position);
//Log.d("DRAWER ITEM SELECTED", "the index number of item Drawer RecyclerView "+ position);
switch(position){
case 0:
break;
}
}
private void displayView(int position) {}
}//MainActivity.class
Concerning to the document of onTouchEvent(event) method: "Called when a touch screen event was not handled by any of the views under it. This is most useful to process touch events that happen outside of your window bounds, where there is no view to receive it.". So you should check:
There is a child view that was handled the event in the activity or not (that means the onTouchEvent(event) method of this child view returns "true"). If no, go to number 2
The onTouchEvent(event) method of the activity should be returned "true".(according the document: "Return true if you have consumed the event, false if you haven't. The default implementation always returns false" -> using
return super.onTouchEvent(event);
always returns "false")Hope it can help you