【问题标题】:No implementation of GestureDetector will work on android appGestureDetector 的任何实现都不能在 android 应用程序上运行
【发布时间】:2023-04-08 05:00:01
【问题描述】:

我正在尝试将 GestureDetector 添加到我的应用中的活动中。我从 youtube 和 stackoverflow 尝试了几种不同的方法,但都没有奏效。当我滑动或使用任何手势时,没有显示任何错误,也没有任何反应。我一直在放置调试日志,但没有人在 logcat 中注册我现在完全没有想法了。主要是我感兴趣的 onFling() 方法。

我提出了两种我尝试过的方法。我删除了一些代码并对其进行了更改,以使读者更加友好和相关。

如果有人能帮助我,我很高兴。

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

方法一定义自定义监听类

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

方法二

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

【问题讨论】:

    标签: java android android-studio android-gesture


    【解决方案1】:

    Concerning to the document of onTouchEvent(event) method: "当触摸屏事件未被其下的任何视图处理时调用。这对于处理发生在窗口边界之外的触摸事件最有用,因为没有视图可查看收到它。”。所以你应该检查:

    1. Activity中是否存在处理事件的子视图(即该子视图的onTouchEvent(event)方法返回 “”)。如果没有,请转到第 2 项

    2. 应该返回activity的onTouchEvent(event)方法 “true”。(根据文档:“如果有,则返回 true 消费了这个事件,如果你没有消费则为假。默认实现 总是返回 false" -> 使用 return super.onTouchEvent(event); 总是返回 "false")

    希望对你有帮助

    【讨论】:

    • 感谢您的帮助我已经阅读了文档和其他一些帖子,我现在感觉它与导航抽屉有关。因为它通过滑动手势打开和关闭所以我认为它是通过手势劫持
    • 如果这是来自DrawerLayout 的问题。我认为您可以创建一个从DrawerLayout 扩展的新类。之后,你重写onTouchEvent(MotionEvent)方法,取决于MotionEvent是什么你可以使用View.dispatchTouchEvent(MotionEvent)调用另一个视图的onTouchEvent(MotionEvent)方法。
    猜你喜欢
    • 2016-05-12
    • 1970-01-01
    • 1970-01-01
    • 2015-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-07
    • 2017-05-01
    相关资源
    最近更新 更多