10

私は ViewPager で SlidingPaneLayout を使用しようとしています。

<?xml version="1.0" encoding="utf-8"?>

<android.support.v4.widget.SlidingPaneLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/scientific_graph_slidingPaneLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    <!--
         The first child view becomes the left pane.
    -->

    <ListView
            android:id="@+id/left_pane"
            android:layout_width="240dp"
            android:layout_height="match_parent"
            android:layout_gravity="left" />
    <!--
         The second child becomes the right (content) pane.
    -->

    <android.support.v4.view.ViewPager
            android:id="@+id/scientific_graph_viewPager"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    </android.support.v4.view.ViewPager>

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

左端から引っ張ると、SlidingPaneLayout がスライドします。ただし、右端から引っ張るとViewPagerをスライドさせることができないようです。右端から引っ張ると、ほとんどスライドせず、元に戻ります。

これを行うことは可能ですか?これを行うより良い方法はありますか?

指を上と左に動かすと、ビュー ページャーをスワイプできることがわかりました。

4

2 に答える 2

8

@Brien Colwell のソリューションから構築して、これを処理する SlidingPaneLayout のカスタム サブクラスを作成し、エッジ スワイプを追加して、ユーザーが右端までスクロールしたときに、最後までスクロールする必要がないようにします。ペインを開くには左に移動します。

これは SlidingPaneLayout のサブクラスであるため、Java で参照を変更する必要はありません。このクラスのインスタンスを (通常は XML で) インスタンス化するようにしてください。

package com.ryanharter.android.view;

import android.content.Context;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.widget.SlidingPaneLayout;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ViewConfiguration;

/**
 * SlidingPaneLayout that, if closed, checks if children can scroll before it intercepts
 * touch events.  This allows it to contain horizontally scrollable children without
 * intercepting all of their touches.
 *
 * To handle cases where the user is scrolled very far to the right, but should still be
 * able to open the pane without the need to scroll all the way back to the start, this
 * view also adds edge touch detection, so it will intercept edge swipes to open the pane.
 */
public class PagerEnabledSlidingPaneLayout extends SlidingPaneLayout {

    private float mInitialMotionX;
    private float mInitialMotionY;
    private float mEdgeSlop;

    public PagerEnabledSlidingPaneLayout(Context context) {
        this(context, null);
    }

    public PagerEnabledSlidingPaneLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public PagerEnabledSlidingPaneLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        ViewConfiguration config = ViewConfiguration.get(context);
        mEdgeSlop = config.getScaledEdgeSlop();
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {

        switch (MotionEventCompat.getActionMasked(ev)) {
            case MotionEvent.ACTION_DOWN: {
                mInitialMotionX = ev.getX();
                mInitialMotionY = ev.getY();
                break;
            }

            case MotionEvent.ACTION_MOVE: {
                final float x = ev.getX();
                final float y = ev.getY();
                // The user should always be able to "close" the pane, so we only check
                // for child scrollability if the pane is currently closed.
                if (mInitialMotionX > mEdgeSlop && !isOpen() && canScroll(this, false,
                        Math.round(x - mInitialMotionX), Math.round(x), Math.round(y))) {

                    // How do we set super.mIsUnableToDrag = true?

                    // send the parent a cancel event
                    MotionEvent cancelEvent = MotionEvent.obtain(ev);
                    cancelEvent.setAction(MotionEvent.ACTION_CANCEL);
                    return super.onInterceptTouchEvent(cancelEvent);
                }
            }
        }

        return super.onInterceptTouchEvent(ev);
    }
}
于 2015-01-15T21:57:41.260 に答える