GestureListener - onFling()不会阻止事件传播

时间:2014-01-18 19:13:09

标签: android android-layout android-fragments gesture event-capturing

我正在使用SimpleGestureListener进行练习,我可以很好地捕捉到fling事件,但即使我的onFling()返回true,布局中的片段也会抓住它并对其作出反应。我不希望这种情况发生。

该活动有一个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 个答案:

答案 0 :(得分:0)

如果有人在努力解决这个问题,我在这里找到了一个很好的答案: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交互时,请使用false调用setPagingEnabled,并使用true调用reeenable。