首页 > 解决方案 > FloatingActionMenu 上的 setOnTouchListener 无法正常工作

问题描述

我正在使用 FloatingActionMenu。在下图中,我用绿色为背景着色,以便于理解问题

在此处输入图像描述

当用户拖动粉红色按钮时,我想移动 FloatingActionMenu。我编写了一个函数来通过获取运动事件来移动按钮,如下所示

fab1.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
                int action = motionEvent.getAction();
                if (action == MotionEvent.ACTION_DOWN) {

                    downRawX = motionEvent.getRawX();
                    downRawY = motionEvent.getRawY();
                    dX = view.getX() - downRawX;
                    dY = view.getY() - downRawY;

                    return true; // not Consumed for ripple effect

                } else if (action == MotionEvent.ACTION_MOVE) {

                    viewWidth = view.getWidth();
                    viewHeight = view.getHeight();

                    View viewParent = (View) view.getParent();
                    parentWidth = viewParent.getWidth();
                    parentHeight = viewParent.getHeight();

                    newX = motionEvent.getRawX() + dX;
                    newX = Math.max(layoutParams.leftMargin, newX); // Don't allow the FAB past the left hand side of the parent
                    newX = Math.min(parentWidth - viewWidth - layoutParams.rightMargin, newX); // Don't allow the FAB past the right hand side of the parent

                    newY = motionEvent.getRawY() + dY;
                    newY = Math.max(layoutParams.topMargin, newY); // Don't allow the FAB past the top of the parent
                    newY = Math.min(parentHeight - viewHeight - layoutParams.bottomMargin, newY); // Don't allow the FAB past the bottom of the parent

                    view.animate()
                            .x(newX)
                            .y(newY)
                            .setDuration(0)
                            .start();

                    return true; // Consumed

                } else if (action == MotionEvent.ACTION_UP) {

                    float upRawX = motionEvent.getRawX();
                    float upRawY = motionEvent.getRawY();

                    float upDX = upRawX - downRawX;
                    float upDY = upRawY - downRawY;

                    if (newX > ((parentWidth - viewWidth - layoutParams.rightMargin) / 2)) {
                        newX = parentWidth - viewWidth - layoutParams.rightMargin;
                    } else {
                        newX = layoutParams.leftMargin;
                    }

                    view.animate()
                            .x(newX)
                            .y(newY)
                            .setInterpolator(new OvershootInterpolator())
                            .setDuration(300)
                            .start();

                    if (Math.abs(upDX) < CLICK_DRAG_TOLERANCE && Math.abs(upDY) < CLICK_DRAG_TOLERANCE) { // A click
                        if (customClickListener != null) {
                            customClickListener.onClick(view);
                        }
                        return false;// not Consumed for ripple effect
                    } else { // A drag
                        return false; // not Consumed for ripple effect
                    }

                } else {
                    return true;
                }
            }
        });

但它不会按我的要求工作。当我从粉红色按钮拖动时,我想移动按钮。但是当我从绿色背景拖动时它会移动。不是来自粉红色区域。如何仅将触摸监听器添加到圆形图标?

当前的 XML 文件是

<RelativeLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>

    <com.github.clans.fab.FloatingActionMenu xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:fab="http://schemas.android.com/tools"
        android:id="@+id/fab_menu_icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:background="@color/colorPrimary"
        app:fab_colorNormal="#DA4336"
        app:fab_colorPressed="#E75043"
        app:fab_colorRipple="#99FFFFFF"
        app:fab_shadowColor="#66000000"
        app:fab_showShadow="true"
        app:menu_backgroundColor="#DA4336"
        app:menu_labels_colorNormal="#333333"
        app:menu_labels_colorPressed="#444444"
        app:menu_labels_colorRipple="#66FFFFFF"
        app:menu_labels_ellipsize="end"
        app:menu_labels_maxLines="-1"
        app:menu_labels_position="left"
        app:menu_labels_showShadow="true"
        app:menu_labels_singleLine="true"
        app:menu_openDirection="up">

        <com.github.clans.fab.FloatingActionButton
            android:id="@+id/fab_submit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/fab_add"
            app:fab_label="kkjj"
            app:fab_size="mini" />

        <com.github.clans.fab.FloatingActionButton
            android:id="@+id/fab_scan_item"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/fab_add"
            app:fab_label="lljjl"
            app:fab_size="mini" />

        <com.github.clans.fab.FloatingActionButton
            android:id="@+id/fab_cancel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/fab_add"
            app:fab_label="jkjkjkj"
            app:fab_size="mini" />

    </com.github.clans.fab.FloatingActionMenu>

</RelativeLayout>

标签: androidfloating-action-menufloating-action-menu-listener

解决方案


尝试使用event.getX()而不是getRawX().

下面的代码对我有用:


// below are declared as fields
    float downX;
    float downY;
    float dx;
    float dy;

// set on touch listener
fab.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getActionMasked()) {
                    case MotionEvent.ACTION_DOWN:
                        downX = event.getX();
                        downY = event.getY();
                        break;
                    case MotionEvent.ACTION_MOVE:
                        dx += event.getX() - downX;
                        dy += event.getY() - downY;
                        fab.setTranslationX(dx);
                        fab.setTranslationY(dy);
                        break;
                    case MotionEvent.ACTION_UP:
                        fab.performClick();
                        break;
                }
                return true;
            }
        });

演示

再次阅读您的代码,似乎不仅要拖动工厂,而且还想将其限制在其父区域,因此您需要ACTION_MOVE通过比较工厂的边界及其父边界来进行限制。


推荐阅读