GestureListener - onFling() не останавливает распространение событий

Я практикуюсь с SimpleGestureListener, и я могу ловить события fling, но даже когда мой onFling() возвращает true, фрагменты в макете ловят fling и реагируют на него. Я не хочу, чтобы это случилось.

У действия есть ViewPager, который загружает фрагменты (эти фрагменты загружают изображения из папки на SD-карте, и в ViewPager добавлено столько фрагментов, сколько изображений в папке). Я прикрепил свой собственный GestureListener к RelativeLayout, который служит основным контейнером макета действия. Я только переопределил событие onFling().

Код следующим образом:

Деятельность:

public class MainActivity extends FragmentActivity {

private GestureDetector gestureDetector;
private ViewPager vwpMain;
private PagerAdapter pgaMain;
private RelativeLayout layout;
private LinearLayout topLayout, bottomLayout;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.activity_main);
    layout = (RelativeLayout) findViewById(R.id.container);
    topLayout = (LinearLayout) findViewById(R.id.topPanel);
    bottomLayout = (LinearLayout) findViewById(R.id.bottomPanel);
    vwpMain = (ViewPager) findViewById(R.id.vwpMain);
    pgaMain = new MyPagerAdapter(getSupportFragmentManager());
    vwpMain.setAdapter(pgaMain);
    gestureDetector = new GestureDetector(this, new MyGestureListener(
            getApplicationContext(), topLayout, bottomLayout));
    layout.setOnTouchListener(new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            gestureDetector.onTouchEvent(event);
            return true;
        }
    });
}

public boolean dispatchTouchEvent(MotionEvent ev) {
    super.dispatchTouchEvent(ev);
    return gestureDetector.onTouchEvent(ev);
}

private class MyPagerAdapter extends FragmentPagerAdapter {

    public MyPagerAdapter(FragmentManager fragmentManager) {
        super(fragmentManager);
    }

    @Override
    public Fragment getItem(int pos) {
        return ImageFragment.create(pos);
    }

    @SuppressLint("SdCardPath")
    @Override
    public int getCount() {
        File f = new File("/mnt/sdcard/FragmentImages/");
        return f.listFiles().length;
    }
}
}

GestureListener:

public class MyGestureListener extends SimpleOnGestureListener {

private static final int SWIPE_MIN_DISTANCE = 75;
private static final int SWIPE_MAX_OFF_PATH = 100;
private static final int SWIPE_THRESHOLD_VELOCITY = 50;

public Context context;
public View topView, bottomView;

private enum ActivePanel {
    Top, Bottom, None
}

private ActivePanel currentPanel;

public MyGestureListener(Context _context, View top, View bottom) {
    super();
    context = _context;
    topView = top;
    bottomView = bottom;
    currentPanel = ActivePanel.None;
}

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

@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
        float velocityY) {
    boolean result = false;
    float dX = e2.getX() - e1.getX();
    float dY = e1.getY() - e2.getY();
    if (Math.abs(dY) < SWIPE_MAX_OFF_PATH
            && Math.abs(velocityX) >= SWIPE_THRESHOLD_VELOCITY
            && Math.abs(dX) >= SWIPE_MIN_DISTANCE) {
        if (dX > 0) {
            Log.d("Fragment", "Swiping right");
        } else {
            Log.d("Fragment", "Swiping left");
        }
        if (currentPanel != ActivePanel.None) {
            result = true;
        }
    } else if (Math.abs(dX) < SWIPE_MAX_OFF_PATH
            && Math.abs(velocityY) >= SWIPE_THRESHOLD_VELOCITY
            && Math.abs(dY) >= SWIPE_MIN_DISTANCE) {
        if (dY > 0) {
            Log.d("Fragment", "Swiping up");
            switch (currentPanel) {
            case None:
                // Show bottom panel
                Animation showBottomPanel = AnimationUtils.loadAnimation(
                        context, R.anim.show_bottom);
                bottomView.bringToFront();
                bottomView.startAnimation(showBottomPanel);
                bottomView.setVisibility(View.VISIBLE);
                currentPanel = ActivePanel.Bottom;
                break;
            case Top:
                // Hide top panel
                Animation hideTopPanel = AnimationUtils.loadAnimation(
                        context, R.anim.hide_top);
                topView.bringToFront();
                topView.startAnimation(hideTopPanel);
                topView.setVisibility(View.GONE);
                currentPanel = ActivePanel.None;
                break;
            case Bottom:
                // Do nothing
                break;
            }
        } else {
            Log.d("Fragment", "Swiping down");
            switch (currentPanel) {
            case None:
                // Show top panel
                Animation showTopPanel = AnimationUtils.loadAnimation(
                        context, R.anim.show_top);
                topView.bringToFront();
                topView.setVisibility(View.VISIBLE);
                topView.startAnimation(showTopPanel);
                currentPanel = ActivePanel.Top;
                break;
            case Top:
                // Do nothing
                break;
            case Bottom:
                // Hide bottom panel
                Animation hideBottomPanel = AnimationUtils.loadAnimation(
                        context, R.anim.hide_bottom);
                bottomView.bringToFront();
                bottomView.startAnimation(hideBottomPanel);
                bottomView.setVisibility(View.GONE);
                currentPanel = ActivePanel.None;
                break;
            }
        }
        result = false;
    } else {
        result = false;
    }
    return result;
}
}

Планировка:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin_noborder"
    android:paddingLeft="@dimen/activity_horizontal_margin_noborder"
    android:paddingRight="@dimen/activity_horizontal_margin_noborder"
    android:paddingTop="@dimen/activity_vertical_margin_noborder"
    tools:context=".MainActivity" >

    <LinearLayout
        android:id="@+id/topPanel"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="#88000000"
        android:gravity="center"
        android:orientation="horizontal"
        android:visibility="gone" >

        <TextView
            android:id="@+id/topPanelTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/topPanelText"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:textColor="@android:color/white" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/bottomPanel"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="#88000000"
        android:gravity="center"
        android:orientation="horizontal"
        android:visibility="gone" >

        <TextView
            android:id="@+id/bottomPanelTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/bottomPanelText"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:textColor="@android:color/white" />
    </LinearLayout>

    <android.support.v4.view.ViewPager
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/vwpMain"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

1 ответ

В случае, если кто-то борется с этим, я нашел отличный ответ здесь: http://blog.svpino.com/2011/08/disabling-pagingswiping-on-android.html

По сути, создайте новый класс, который наследуется от ViewPager, следующим образом:

public class CustomViewPager extends ViewPager {

    private boolean enabled;

    public CustomViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.enabled = true;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (this.enabled) {
            return super.onTouchEvent(event);
        }

        return false;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        if (this.enabled) {
            return super.onInterceptTouchEvent(event);
        }

        return false;
    }

    public void setPagingEnabled(boolean enabled) {
        this.enabled = enabled;
    }
}

а затем замените ваш ViewPager в макете на новый класс:

<mypackage.customviewpager 
    android:id="@+id/photosViewPager" 
    android:layout_height="match_parent" 
    android:layout_width="match_parent"
    //rest of properties here
    />

Каждый раз, когда вы хотите отключить взаимодействие с ViewPager, вызывайте setPagingEnabled с false и с true на reeenable.

Другие вопросы по тегам