这是研究了网上大神双向左右滑动后实现的上下双向滑动特效,有兴趣的朋友可以看下面代码,注释很详细,原理就是根据手指滑动的方向,来将上下两个布局进行显示与隐藏。主要用了onTouch方法,获取滑动的距离进行偏移。
import android.content.Context;
import android.os.AsyncTask;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.WindowManager;
import android.view.View.OnTouchListener;
import android.widget.RelativeLayout;
public class UpAndDownSlidinglayout extends RelativeLayout implements OnTouchListener{
/**
* 滚动显示和隐藏上侧布局时,手指滑动需要达到的速度。
*/
public static final int SNAP_VELOCITY = 200;
/**
* 滑动状态的一种,表示未进行任何滑动。
*/
public static final int DO_NOTHING = 0;
/**
* 滑动状态的一种,表示正在滑出上侧菜单。
*/
public static final int SHOW_UP_MENU = 1;
/**
* 滑动状态的一种,表示正在滑出下侧菜单。
*/
public static final int SHOW_DOWN_MENU = 2;
/**
* 滑动状态的一种,表示正在隐藏上侧菜单。
*/
public static final int HIDE_UP_MENU = 3;
/**
* 滑动状态的一种,表示正在隐藏下侧菜单。
*/
public static final int HIDE_DOWN_MENU = 4;
/**
* 记录当前的滑动状态
*/
private int slideState;
/**
* 屏幕宽度值。
*/
private int screenWidth;
private int screenHeight;
/**
* 在被判定为滚动之前用户手指可以移动的最大值。
*/
private int touchSlop;
/**
* 记录手指按下时的横坐标。
*/
private float xDown;
/**
* 记录手指按下时的纵坐标。
*/
private float yDown;
/**
* 记录手指移动时的横坐标。
*/
private float xMove;
/**
* 记录手指移动时的纵坐标。
*/
private float yMove;
/**
* 记录手机抬起时的纵坐标。
*/
private float yUp;
/**
* 上侧菜单当前是显示还是隐藏。只有完全显示或隐藏时才会更改此值,滑动过程中此值无效。
*/
private boolean isUpMenuVisible;
/**
* 下侧菜单当前是显示还是隐藏。只有完全显示或隐藏时才会更改此值,滑动过程中此值无效。
*/
private boolean isDownMenuVisible;
/**
* 是否正在滑动。
*/
private boolean isSliding;
/**
* 上侧菜单布局对象。
*/
private View upMenuLayout;
/**
* 下侧菜单布局对象。
*/
private View downMenuLayout;
/**
* 内容布局对象。
*/
private View contentLayout;
/**
* 用于监听滑动事件的View。
*/
private View mBindView;
/**
* 上侧菜单布局的参数。
*/
private MarginLayoutParams upMenuLayoutParams;
/**
* 下侧菜单布局的参数。
*/
private MarginLayoutParams downMenuLayoutParams;
/**
* 内容布局的参数。
*/
private RelativeLayout.LayoutParams contentLayoutParams;
/**
* 用于计算手指滑动的速度。
*/
private VelocityTracker mVelocityTracker;
public UpAndDownSlidinglayout(Context context, AttributeSet attrs) {
super(context, attrs);
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
screenWidth = wm.getDefaultDisplay().getWidth();
screenHeight = wm.getDefaultDisplay().getHeight();
touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}
/**
* 绑定监听滑动事件的View。
*
* @param bindView
* 需要绑定的View对象。
*/
public void setScrollEvent(View bindView) {
mBindView = bindView;
mBindView.setOnTouchListener(this);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
createVelocityTracker(event);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// 手指按下时,记录按下时的坐标
xDown = event.getRawX();
yDown = event.getRawY();
// 将滑动状态初始化为DO_NOTHING
slideState = DO_NOTHING;
break;
case MotionEvent.ACTION_MOVE:
xMove = event.getRawX();
yMove = event.getRawY();
int moveDistanceX = (int) (xMove - xDown);
int moveDistanceY = (int) (yMove - yDown);
// 检查当前的滑动状态
checkSlideState(moveDistanceX, moveDistanceY);
switch (slideState) {
case SHOW_UP_MENU:
contentLayoutParams.bottomMargin = -moveDistanceY;
checkUpMenuBorder();
contentLayout.setLayoutParams(contentLayoutParams);
break;
case HID