java - 如何使用 Framelayout 中的手势检测器在其所属的卡片 View 上启动左右动画?

标签 java android xml android-layout android-activity

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

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

代码:

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>

最佳答案

如果我没记错的话,您正在尝试在框架布局中实现滑动行为。我在你们的类里面尝试并做了一些改变。希望这会对您有所帮助......

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

}

关于java - 如何使用 Framelayout 中的手势检测器在其所属的卡片 View 上启动左右动画?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28724595/

相关文章:

xml - 在忽略格式的颠覆中管理 XML 文档

Android 开关 - 在开/关时更改开关的背景

xml - 如果使用标准 linux 工具包含特定字符串,如何从 xml 文件中提取整个记录

java - 打乱排序的数组

java - 如何正确混合泛型和继承以获得预期的结果?

java - 类型安全的通用 Java 观察器编译时错误

java - 虚拟设备中没有后退按钮

android - Android中如何知道EditText发生了删除操作?

javascript - 为什么我的POST方法无法接收这个ajax?

Android Studio R.java