我正在使用 SimpleGestureListener 练习,我可以很好地捕捉到 fling 事件,但即使我的 onFling() 返回 true,布局中的片段也会捕捉到 fling 并对其做出反应。我不希望这种情况发生。
该活动有一个加载片段的 ViewPager(这些片段从 SD 卡中的文件夹加载图像,并且添加到 ViewPager 的片段与文件夹中的图像一样多)。我已将我的自定义 GestureListener 附加到作为 Activity 布局的主容器的 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;
}
}
}
手势监听器:
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>