如何在 Framelayout 中使用手势检测器在它所属的卡片视图上启动左右动画?

How can I use the Gesture detector within a Framelayout to initiate left and right animations on the cardview it is part of?

我正在使用此框架布局来保存我的每个文本视图等,并且我希望,如果可能的话,当我的手势检测器检测到向左或向右滑动以在该特定卡片视图上启动适当的向左或向右动画时。

但是我在网上找不到任何有关如何完成此操作的信息。

代码:

MyFrameLayout:

public class MyFrameLayout extends FrameLayout implements GestureDetector.OnGestureListener {
    private GestureDetectorCompat gestureDetector;
    private UserTaskListActivity userTaskListActivity;

    private static final int SWIPE_MIN_DISTANCE = 20;
    private static final int SWIPE_MAX_OFF_PATH = 100;
    private static final int SWIPE_THRESHOLD_VELOCITY = 100;

    public MyFrameLayout(Context context) {
        super(context);
        initialize(context);
    }

    public MyFrameLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        initialize(context);
    }

    public MyFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initialize(context);
    }

    private void initialize(Context context) {
        if(context instanceof UserTaskListActivity)
            userTaskListActivity = (UserTaskListActivity) context;
        gestureDetector = new GestureDetectorCompat(context, this);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        gestureDetector.onTouchEvent(event);
        return true;
    }

    public boolean onInterceptTouchEvent(MotionEvent event) {
        return super.onInterceptTouchEvent(event);
    }

    @Override
    public boolean onDown(MotionEvent event) {
        return false;
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                           float velocityY) {
        if(userTaskListActivity == null)
            return false;
        try {
            if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
                return false;
            // right to left swipe
            if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE
                    && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                leftSwipe();
                return true;
            } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
                    && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                rightSwipe();
                return true;
            }
        } catch (Exception e) {
            // nothing
        }
        return false;   }


    private void rightSwipe() {
        Toast.makeText(this.getContext(),"Swipe to the right",Toast.LENGTH_SHORT).show();
    }

    private void leftSwipe() {
        Toast.makeText(this.getContext(),"Swipe to the left",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onLongPress(MotionEvent event) {
        LogUtilities.verbose("onLongPress: " + event.toString());
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
                            float distanceY) {
        LogUtilities.verbose("onScroll: " + e1.toString() + e2.toString());
        return true;
    }

    @Override
    public void onShowPress(MotionEvent event) {
        LogUtilities.verbose("onShowPress: " + event.toString());
    }

    @Override
    public boolean onSingleTapUp(MotionEvent event) {
        LogUtilities.verbose("onSingleTapUp: " + event.toString());
        return true;
    }
}

Xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:card_view="http://schemas.android.com/apk/res-auto"
        android:id="@+id/taskViewContainer"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        app:cardElevation="8dp"
        app:cardPreventCornerOverlap="false"
        card_view:cardCornerRadius="8dp">

        <com.example.testing.android.layout.MyFrameLayout
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

           ......

        </com.example.testing.android.layout.MyFrameLayout>

    </android.support.v7.widget.CardView>

</RelativeLayout>

如果我没记错的话,您正在尝试对您的框架布局实施滑动行为。我已尝试对您的 class 进行了一些更改。希望这会对你有所帮助.....

public class MyFrameLayout extends FrameLayout {

private static final int mWidth = 500;

public MyFrameLayout(Context context) {
    super(context);
    initialize(context);
}

public MyFrameLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
    initialize(context);
}

public MyFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    initialize(context);
}

private void initialize(Context context) {
    setOnTouchListener(mTouchListener);
}

private float mDisplacementX;
// private float mLastMoveX;
private float mDisplacementY;
private float mInitialTx;
private boolean mTracking;

private OnTouchListener mTouchListener = new OnTouchListener() {

    @Override
    public boolean onTouch(View v, MotionEvent event) {

        switch (event.getActionMasked()) {
        case MotionEvent.ACTION_DOWN:

            mDisplacementX = event.getRawX();
            mDisplacementY = event.getRawY();

            mInitialTx = getTranslationX();

            return true;

        case MotionEvent.ACTION_MOVE:
            // get the delta distance in X and Y direction
            float deltaX = event.getRawX() - mDisplacementX;
            float deltaY = event.getRawY() - mDisplacementY;
            // updatePressedState(false);

            // set the touch and cancel event
            if ((Math.abs(deltaX) > ViewConfiguration.get(getContext())
                    .getScaledTouchSlop() * 2 && Math.abs(deltaY) < Math
                    .abs(deltaX) / 2)
                    || mTracking) {

                mTracking = true;

                if (getTranslationX() <= mWidth / 2
                        && getTranslationX() >= -(mWidth / 2)) {

                    setTranslationX(mInitialTx + deltaX);
                    return true;
                }
            }

            break;

        case MotionEvent.ACTION_UP:

            if (mTracking) {
                mTracking = false;
                float currentTranslateX = getTranslationX();

                if (currentTranslateX > mWidth / 4) {
                    rightSwipe();
                } else if (currentTranslateX < -(mWidth / 4)) {
                    leftSwipe();
                }

                // comment this line if you don't want your frame layout to
                // take its original position after releasing the touch
                setTranslationX(0);
                return true;
            } else {
                // handle click event
                setTranslationX(0);
            }
            break;
        }
        return false;
    }
};

private void rightSwipe() {
    Toast.makeText(this.getContext(), "Swipe to the right",
            Toast.LENGTH_SHORT).show();
  // write code to remove the data from source and notify change to adapter
  // if you want to change remove the item on swipe.
}

private void leftSwipe() {
    Toast.makeText(this.getContext(), "Swipe to the left",
            Toast.LENGTH_SHORT).show();
   // write code to remove the data from source and notify change to adapter
   // if you want to change remove the item on swipe.
}

}