将Android NestedScrollView水平滑动传递给父视图

时间:2017-01-30 01:42:15

标签: android android-custom-view ontouchlistener ontouchevent android-nestedscrollview

我试图制作一个左右可刷卡系统(如Tinder),卡上有一个NestedScrollView。目标是如果用户仅向上和向下滑动,NestedScrollView将滚动,但如果用户向左或向右滑动,则卡将使用该滑动。

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="4dp"
    card_view:cardUseCompatPadding="true">

    <android.support.v4.widget.NestedScrollView
        android:id="@+id/nested_scroll_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:padding="4dp">

            <TextView
                android:id="@+id/text_view"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

            <android.support.v7.widget.RecyclerView
                android:id="@+id/recycler"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

        </LinearLayout>

    </android.support.v4.widget.NestedScrollView>

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

(我使用的卡片库是https://github.com/wenchaojiang/AndroidSwipeableCardStack

compile 'com.github.wenchaojiang:AndroidSwipeableCardStack:0.1.5'

当我在NestedScrollView上放置margin_top并触摸该边距时,CardStack正确地抓住我的输入并且卡片向左或向右移动,但是如果我触摸并拖动其他任何地方,NestedScrollView会抓住我的输入而不管方向。

我应该扩展/覆盖哪个类/ onTouchEvent才能产生这种效果,或者可能有更简单的方法?

谢谢!

2 个答案:

答案 0 :(得分:0)

是的,你应该通过在Java代码上实现CardStack.CardEventListener,并将其设置为监听器mCardStack.setListener(yourListener);这是项目内的自述文件。试试这个:

Class YourListener extends CardStack.CardEventListener{
    //implement card event interface
    @Override
    public boolean swipeEnd(int direction, float distance) {
        //if "return true" the dismiss animation will be triggered 
        //if false, the card will move back to stack
        //distance is finger swipe distance in dp


        return (distance>300)? true : false;
    }

    @Override
    public boolean swipeStart(int direction, float distance) {

        return true;
    }

    @Override
    public boolean swipeContinue(int direction, float distanceX, float distanceY) {

        return true;
    }

    @Override
    public void discarded(int id, int direction) {
       //this callback invoked when dismiss animation is finished. 
    }

    @Override
    public void topCardTapped() {
         //this callback invoked when a top card is tapped by user. 
    }
}

答案 1 :(得分:0)

我为我的应用程序为2个界面执行此操作。使用GestureDetectoronFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY)检查水平速度。经过一定的阈值传递或拦截视图的触摸事件。您可以检查如何拦截或传递来自Touch api的事件。

这是一个独立于您使用的ViewGroups或Views 的通用解决方案,它可以正常工作。您在将事件传递到布局或自定义视图之前使用事件。

触摸事件传播为

  1. Activity.dispatchTouchEvent()
  2. ViewGroup.dispatchTouchEvent()
  3. View.dispatchTouchEvent()
  4. View.onTouchEvent()
  5. ViewGroup.onTouchEvent()
  6. Activity.onTouchEvent()
  7. 如果在Activity的dispatchTouchEvent()方法中使用GestureDetector,您将能够正确地使用或传播事件到ViewGroups或Views。

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        gestureDetector.onTouchEvent(event);
        // Be sure to call the superclass implementation
        return super.dispatchTouchEvent(event);
    }