垂直滑动布局内的水平滚动

horizontal scroll inside a vertical sliding layout

我有一个 custom view class 类似于导航抽屉,但它是从下到上打开的。

在我的 XML 中,我有一个水平的 recyclerview 被这个自定义包裹 class。

<?xml version="1.0" encoding="utf-8"?>
<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:id="@+id/video_cutter_root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="?attr/videoview_bg"
    android:orientation="vertical"
    tools:ignore="RtlHardcoded">

    <RelativeLayout
        android:id="@+id/layout_surface_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/layout"
        android:background="@android:color/transparent"
        android:gravity="center"
        android:orientation="vertical">


        <com.devbrackets.android.exomedia.ui.widget.VideoView
            android:id="@+id/video_loader"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true" />


        <ImageView
            android:id="@+id/icon_video_play"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:background="@drawable/play_button"
            android:contentDescription="@null" />

    </RelativeLayout>


    <RelativeLayout
        android:id="@+id/layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="72dp"
        android:background="?attr/video_timeline_bg">


        <RelativeLayout
            android:id="@+id/timeText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <TextView
                android:id="@+id/textTimeStart"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentLeft="true"
                android:layout_marginStart="7dp"
                android:layout_marginLeft="7dp"
                android:gravity="left"
                android:text="@string/timer2" />

            <TextView
                android:id="@+id/textTime"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:gravity="center"
                android:text="@string/timer2"
                android:textColor="?attr/color_accent" />

            <TextView
                android:id="@+id/textTimeEnd"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:layout_marginEnd="7dp"
                android:layout_marginRight="7dp"
                android:layout_toEndOf="@+id/textTime"
                android:layout_toRightOf="@+id/textTime"
                android:gravity="right"
                android:text="@string/timer2" />

        </RelativeLayout>


        <androidx.appcompat.widget.AppCompatSeekBar
            android:id="@+id/handlerTop"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:max="1000"
            android:paddingTop="30dp"
            android:progressDrawable="@android:color/transparent"
            android:secondaryProgress="0"
            android:thumb="@drawable/vector_apptheme_text_select_handle_middle" />


        <View
            android:id="@+id/lineTop"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_below="@+id/handlerTop"
            android:background="@color/line_button" />


    </RelativeLayout>


    <SlidingLayer xmlns:slidingLayer="http://schemas.android.com/apk/res-auto"
        android:id="@+id/slider_panel"
        android:layout_width="match_parent"
        android:layout_height="400dip"
        android:layout_below="@+id/layout_surface_view"
        android:layout_gravity="bottom"
        android:gravity="bottom"
        slidingLayer:openLayer="false"
        slidingLayer:stickTo="bottom">


        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="400dip"
            android:background="@color/slider_panel_color_trans98">


            <TextView
                android:id="@+id/added_clips_count"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentLeft="true"
                android:layout_marginTop="7dp"
                android:padding="7dp"
                android:text="Selected 0 clips"
                android:textColor="?attr/text_color"
                android:textSize="@dimen/sp12"
                android:textStyle="bold" />

            <androidx.appcompat.widget.AppCompatImageView
                android:id="@+id/slider_iv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:layout_gravity="top|center"
                android:background="?attr/selectableItemBackgroundBorderless"
                android:contentDescription="@null"
                android:padding="7dp"
                android:tint="?attr/color_accent"
                app:srcCompat="@drawable/vector_slide_down" />

            <Button
                android:id="@+id/btAdd"
                style="@style/BorderlessButton"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:gravity="center"
                android:shadowColor="?attr/textview_shadow"
                android:shadowDx="@integer/shadowDx"
                android:shadowDy="@integer/shadowDy"
                android:shadowRadius="@integer/shadowRadius"
                android:text="@string/add"
                android:textColor="?attr/color_accent"
                android:textSize="@dimen/sp14"
                android:textStyle="bold" />

            <Button
                android:id="@+id/btNext"
                style="@style/BorderlessButton"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_toLeftOf="@+id/btAdd"
                android:gravity="center"
                android:paddingLeft="15dp"
                android:paddingRight="15dp"
                android:shadowColor="?attr/textview_shadow"
                android:shadowDx="@integer/shadowDx"
                android:shadowDy="@integer/shadowDy"
                android:shadowRadius="@integer/shadowRadius"
                android:text="@string/next"
                android:textColor="?attr/color_accent"
                android:textSize="@dimen/sp14"
                android:textStyle="bold" />

            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/mRecyclerView"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@+id/btAdd"
                android:background="@color/slider_panel_color_trans98"
                android:scrollbarSize="@dimen/scrollbar_size"
                android:scrollbarStyle="outsideInset"
                android:scrollbarThumbHorizontal="?attr/color_accent"
                android:scrollbars="horizontal" />


        </RelativeLayout>

    </SlidingLayer>


</RelativeLayout>

所以我有一个水平滚动(recyclerview),在垂直滑动(自定义视图)内。

问题是这样的,请看下面的GIF文件:

如您所见,我无法在 recyclerview 中正确滚动。

你有什么建议吗?

SlidingLayer.java class 中 onInterceptTouchEvent 方法中为 MotionEvent.ACTION_MOVE 操作添加以下代码:

if (xDiff > yDiff) {
    return false;
}

看起来像:

switch (action) {
    case MotionEvent.ACTION_MOVE:
        .
        .
        .

        if (xDiff > yDiff) {
            return false;
        }

        if (validHorizontalDrag || validVerticalDrag) {
            mIsDragging = true;
            setDrawingCacheEnabled(true);
        }

        break;

    .
    .
    .

您可以执行以下操作:

1) MainActivity.class:

public class MainActivity extends AppCompatActivity {

private final String TAG = MainActivity.class.getSimpleName();
private RecyclerView mRecyclerView;

/*private float mDownMotionX = 0;
private float mDownMotionY = 0;

private final int SWIPE_SENSITIVITY = 100;

private final int SWIPE_X_SENSITIVITY = 10;
private final int SWIPE_Y_SENSITIVITY = 10;

private final int SWIPE_X_SENSITIVITY_MIN = 0;
private int SWIPE_X_SENSITIVITY_MAX = 0;
private final int SWIPE_Y_SENSITIVITY_MIN = 0;
private int SWIPE_Y_SENSITIVITY_MAX = 0;
*/

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mRecyclerView = (RecyclerView) findViewById(R.id.mRecyclerView);

    List<String> data = new ArrayList<>();
    for (int i = 0; i < 100; i++) {
        data.add("I " + (i + 1));
    }
    LinearLayoutManager layoutManager
            = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
    mRecyclerView.setLayoutManager(layoutManager);
    HorizontalRecyclerViewAdapter horizontalRecyclerViewAdapter = new HorizontalRecyclerViewAdapter(MainActivity.this, data);
    mRecyclerView.setAdapter(horizontalRecyclerViewAdapter);
    mRecyclerView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent ev) {

            mRecyclerView.getParent().requestDisallowInterceptTouchEvent(true);

            /**
             * You can adjust sensitivity by doing something similar to the code below
             */
            /*final int action = ev.getAction();

            switch (action & MotionEvent.ACTION_MASK) {

                case MotionEvent.ACTION_DOWN:
                    // Remember where the motion event started
                    mDownMotionX = ev.getX();
                    mDownMotionY = ev.getY();
                    break;
                case MotionEvent.ACTION_MOVE:
                    // Scroll to follow the motion event
                    final float x = ev.getX();
                    final float y = ev.getY();
                    if (Math.abs(x - mDownMotionX) >= SWIPE_SENSITIVITY &&
                            mDownMotionX >= SWIPE_X_SENSITIVITY_MIN &&
                            mDownMotionX <= SWIPE_X_SENSITIVITY_MAX &&
                            Math.abs(y - mDownMotionY) <= SWIPE_Y_SENSITIVITY) {

                        mRecyclerView.getParent().requestDisallowInterceptTouchEvent(true);

                    } else{

                        mRecyclerView.getParent().requestDisallowInterceptTouchEvent(false);
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    break;
                case MotionEvent.ACTION_CANCEL:
                    break;
            }*/
            return false;
        }
    });

    final Display display = ((WindowManager) MainActivity.this.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
    final Point deviceDisplay = new Point();
    display.getSize(deviceDisplay);

    /*
    SWIPE_X_SENSITIVITY_MAX = deviceDisplay.x;
    SWIPE_Y_SENSITIVITY_MAX = mRecyclerView.getHeight();
    */

}

public class HorizontalRecyclerViewAdapter extends RecyclerView.Adapter<HorizontalRecyclerViewAdapter.MyViewHolder> {

    private final String TAG = HorizontalRecyclerViewAdapter.class.getSimpleName();
    private final Context context;
    private final List<String> data;

    public HorizontalRecyclerViewAdapter(Context context, List<String> data) {
        this.context = context;
        this.data = data;
    }

    @Override
    @NonNull
    public HorizontalRecyclerViewAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = getLayoutInflater().inflate(R.layout.horizontal_recycler_view_item, parent, false);
        return new HorizontalRecyclerViewAdapter.MyViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull HorizontalRecyclerViewAdapter.MyViewHolder holder, int position) {
        holder.tv.setText(data.get(position));
    }

    @Override
    public int getItemCount() {
        return data.size();
    }

    class MyViewHolder extends RecyclerView.ViewHolder {
        final TextView tv;

        private MyViewHolder(View itemView) {
            super(itemView);
            tv = (TextView) itemView.findViewById(R.id.tv);
        }
    }

}

}

2) activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<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:id="@+id/video_cutter_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black"
android:orientation="vertical"
tools:ignore="RtlHardcoded">

<RelativeLayout
    android:id="@+id/layout_surface_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_above="@+id/layout"
    android:background="@android:color/transparent"
    android:gravity="center"
    android:orientation="vertical">

    <VideoView
        android:id="@+id/video_loader"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true" />

    <ImageView
        android:id="@+id/icon_video_play"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:contentDescription="@null" />

</RelativeLayout>

<com.wunderlist.slidinglayer.SlidingLayer
    android:id="@+id/layout"
    android:layout_alignParentBottom="true"
    android:layout_width="match_parent"
    android:layout_height="400dip"
    app:stickTo="bottom"
    app:offsetDistance="400dp"
    app:changeStateOnTap="true">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="400dip"
        android:background="@android:color/black">

        <TextView
            android:id="@+id/added_clips_count"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_marginTop="7dp"
            android:padding="7dp"
            android:text="Selected 0 clips"
            android:textColor="@android:color/white"
            android:textSize="12sp"
            android:textStyle="bold" />

        <androidx.appcompat.widget.AppCompatImageView
            android:id="@+id/slider_iv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_gravity="top|center"
            android:background="?attr/selectableItemBackgroundBorderless"
            android:contentDescription="@null"
            android:padding="7dp"
            android:tint="@color/colorAccent"/>

        <Button
            android:id="@+id/btAdd"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:gravity="center"
            android:text="Add"
            android:textColor="@color/colorAccent"
            android:textSize="14sp"
            android:textStyle="bold" />

        <Button
            android:id="@+id/btNext"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toLeftOf="@+id/btAdd"
            android:gravity="center"
            android:paddingLeft="15dp"
            android:text="Next"
            android:textColor="@color/colorAccent"
            android:textSize="14sp"
            android:textStyle="bold" />

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/mRecyclerView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/btAdd"
            android:scrollbars="horizontal" />

    </RelativeLayout>

</com.wunderlist.slidinglayer.SlidingLayer>

</RelativeLayout>

3) horizontal_recycler_view_item.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:padding="20dp"
android:background="@android:color/black"
android:layout_height="wrap_content">

<TextView
    android:layout_width="110dp"
    android:layout_height="130dp"
    android:id="@+id/tv"
    android:textSize="16sp"
    android:background="@android:color/holo_red_dark"
    android:textColor="@android:color/white"
    android:gravity="center"
    android:padding="40dp"/>

</LinearLayout>

4) 结果: