Android自定义组件系列【15】——四个方向滑动的菜单实现
2015-01-15 00:23
781 查看
今天无意中实现了一个四个方向滑动的菜单,感觉挺好玩,滑动起来很顺手,既然已经做出来了就贴出来让大家也玩弄一下。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201501/4f9b27615e97e51b66160ec20cc97429)
(向上滑动)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201501/97ce9b683d20c2228379149f41d492d5)
(向下滑动)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201501/eb5a6d6f17261fe0a2705fd23622dc51)
(向左滑动)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201501/c04ee9171a7f496294cd606a92ce5ec8)
(向右滑动)
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
mTopView.layout(0, -mViewHeight, mViewWidth, 0);
mBottomView.layout(0, mViewHeight, mViewWidth, 2 * mViewHeight);
mCenterView.layout(0, 0, mViewWidth, mViewHeight);
mLeftView.layout(-mViewWidth, 0, 0, mViewHeight);
mRightView.layout(mViewWidth, 0, 2 * mViewWidth, mViewHeight);
}
![](https://oscdn.geek-share.com/Uploads/Images/Content/201501/dc246e203cad3cdbd54d0944a107cfa0)
转载请说明出处:http://blog.csdn.net/dawanganban
2、通过onTouchEvent事件来判断移动方向
private float mDownY;
private float mDownX;
@Override
public boolean onTouchEvent(MotionEvent event) {
int disY;
int disX;
float eventY = event.getY();
float eventX = event.getX();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mDownY = eventY;
mDownX = eventX;
break;
case MotionEvent.ACTION_UP:
disY = (int)(eventY - mDownY);
disX = (int)(eventX - mDownX);
if(Math.abs(disY) > Math.abs(disX)){
if(Math.abs(disY) > MIN_VIEW_HEIGHT / 2){
if(disY > 0){ //向下滑动
Log.d(TAG, "TO_BOTTOM");
changeToBottom();
}else{ //向上滑动
Log.d(TAG, "TO_TOP");
changeToTop();
}
}
}else{
if(Math.abs(disX) > MIN_VIEW_WIDTH / 2){
if(disX > 0){ //向右滑动
Log.d(TAG, "TO_RIGHT");
changeToRight();
}else{ //向左滑动
Log.d(TAG, "TO_LEFT");
changeToLeft();
}
}
}
break;
default:
break;
}
return true;
}3、通过computerScroll()方法实现平滑移动
@Override
public void computeScroll() {
super.computeScroll();
if(mScroller.computeScrollOffset()){
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
postInvalidate();
}
}4、判断临界条件(否则会一直向一个方向滑动)
int[] location = new int[2];
mCenterView.getLocationOnScreen(location);
if(location[1] >= mViewHeight - MIN_VIEW_HEIGHT * 2) return;例如上面代码就是判断向下滑动的临界条件,location[1]代表中间View的y坐标(相对于屏幕)。
一、效果演示
(说明:目前没有安装Android模拟器,制作的动态图片太卡了,就贴一下静态图片吧,实际效果可以下载源代码查看)(向上滑动)
(向下滑动)
(向左滑动)
(向右滑动)
二、实现过程介绍
1、放置5个View (分别是上下左右中)@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
mTopView.layout(0, -mViewHeight, mViewWidth, 0);
mBottomView.layout(0, mViewHeight, mViewWidth, 2 * mViewHeight);
mCenterView.layout(0, 0, mViewWidth, mViewHeight);
mLeftView.layout(-mViewWidth, 0, 0, mViewHeight);
mRightView.layout(mViewWidth, 0, 2 * mViewWidth, mViewHeight);
}
转载请说明出处:http://blog.csdn.net/dawanganban
2、通过onTouchEvent事件来判断移动方向
private float mDownY;
private float mDownX;
@Override
public boolean onTouchEvent(MotionEvent event) {
int disY;
int disX;
float eventY = event.getY();
float eventX = event.getX();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mDownY = eventY;
mDownX = eventX;
break;
case MotionEvent.ACTION_UP:
disY = (int)(eventY - mDownY);
disX = (int)(eventX - mDownX);
if(Math.abs(disY) > Math.abs(disX)){
if(Math.abs(disY) > MIN_VIEW_HEIGHT / 2){
if(disY > 0){ //向下滑动
Log.d(TAG, "TO_BOTTOM");
changeToBottom();
}else{ //向上滑动
Log.d(TAG, "TO_TOP");
changeToTop();
}
}
}else{
if(Math.abs(disX) > MIN_VIEW_WIDTH / 2){
if(disX > 0){ //向右滑动
Log.d(TAG, "TO_RIGHT");
changeToRight();
}else{ //向左滑动
Log.d(TAG, "TO_LEFT");
changeToLeft();
}
}
}
break;
default:
break;
}
return true;
}3、通过computerScroll()方法实现平滑移动
@Override
public void computeScroll() {
super.computeScroll();
if(mScroller.computeScrollOffset()){
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
postInvalidate();
}
}4、判断临界条件(否则会一直向一个方向滑动)
int[] location = new int[2];
mCenterView.getLocationOnScreen(location);
if(location[1] >= mViewHeight - MIN_VIEW_HEIGHT * 2) return;例如上面代码就是判断向下滑动的临界条件,location[1]代表中间View的y坐标(相对于屏幕)。
三、整个View的源码
package com.example.testmx4update; import android.content.Context; import android.graphics.Color; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.Scroller; /** * 自定义可以拖动的View * @author 阳光小强 http://blog.csdn.net/dawanganban * */ public class MyCanPullView extends ViewGroup{ private static final int MIN_VIEW_HEIGHT = 200; private static final int MIN_VIEW_WIDTH = 400; private static final String TAG = "TEST"; private int mViewHeight; private int mViewWidth; private View mTopView; private View mBottomView; private View mCenterView; private View mLeftView; private View mRightView; private Scroller mScroller; public MyCanPullView(Context context, AttributeSet attrs) { super(context, attrs); initView(context); mScroller = new Scroller(context); } private void initView(Context context) { setTopView(context); setBottomView(context); setCenterView(context); setLeftView(context); setRightView(context); } private float mDownY; private float mDownX; @Override public boolean onTouchEvent(MotionEvent event) { int disY; int disX; float eventY = event.getY(); float eventX = event.getX(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mDownY = eventY; mDownX = eventX; break; case MotionEvent.ACTION_UP: disY = (int)(eventY - mDownY); disX = (int)(eventX - mDownX); if(Math.abs(disY) > Math.abs(disX)){ if(Math.abs(disY) > MIN_VIEW_HEIGHT / 2){ if(disY > 0){ //向下滑动 Log.d(TAG, "TO_BOTTOM"); changeToBottom(); }else{ //向上滑动 Log.d(TAG, "TO_TOP"); changeToTop(); } } }else{ if(Math.abs(disX) > MIN_VIEW_WIDTH / 2){ if(disX > 0){ //向右滑动 Log.d(TAG, "TO_RIGHT"); changeToRight(); }else{ //向左滑动 Log.d(TAG, "TO_LEFT"); changeToLeft(); } } } break; default: break; } return true; } private void changeToBottom(){ int[] location = new int[2]; mCenterView.getLocationOnScreen(location); if(location[1] >= mViewHeight - MIN_VIEW_HEIGHT * 2) return; int dy = (int)(mViewHeight - MIN_VIEW_HEIGHT); mScroller.startScroll(0, getScrollY(), 0, -dy, 500); invalidate(); } private void changeToTop(){ int[] location = new int[2]; mTopView.getLocationOnScreen(location); if(location[1] <= -mViewHeight - MIN_VIEW_HEIGHT / 2) return; int dy = (int)(mViewHeight - MIN_VIEW_HEIGHT); mScroller.startScroll(0, getScrollY(), 0, dy, 500); invalidate(); } private void changeToRight(){ int[] location = new int[2]; mCenterView.getLocationOnScreen(location); if(location[0] >= mViewWidth - MIN_VIEW_WIDTH * 2) return; int dx = (int)(mViewWidth - MIN_VIEW_WIDTH); mScroller.startScroll(getScrollX(), 0, -dx, 0, 500); invalidate(); } private void changeToLeft(){ Log.d(TAG, "TO_LEFT"); int[] location = new int[2]; mLeftView.getLocationOnScreen(location); if(location[0] <= -mViewWidth - MIN_VIEW_WIDTH / 2) return; int dx = (int)(mViewWidth - MIN_VIEW_WIDTH); mScroller.startScroll(getScrollX(), 0, dx, 0, 500); invalidate(); } @Override public void computeScroll() { super.computeScroll(); if(mScroller.computeScrollOffset()){ scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); postInvalidate(); } } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { mTopView.layout(0, -mViewHeight, mViewWidth, 0); mBottomView.layout(0, mViewHeight, mViewWidth, 2 * mViewHeight); mCenterView.layout(0, 0, mViewWidth, mViewHeight); mLeftView.layout(-mViewWidth, 0, 0, mViewHeight); mRightView.layout(mViewWidth, 0, 2 * mViewWidth, mViewHeight); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //获取整个View的宽高 mViewWidth = MeasureSpec.getSize(widthMeasureSpec); mViewHeight = MeasureSpec.getSize(heightMeasureSpec); } private void setTopView(Context context){ View topButton = new View(context); topButton.setBackgroundColor(Color.RED); mTopView = topButton; this.addView(mTopView); } private void setBottomView(Context context){ View bottomButton = new View(context); bottomButton.setBackgroundColor(Color.GREEN); mBottomView = bottomButton; this.addView(mBottomView); } private void setCenterView(Context context){ View centerButton = new View(context); centerButton.setBackgroundColor(Color.WHITE); mCenterView = centerButton; this.addView(mCenterView); } private void setLeftView(Context context){ View leftButton = new View(context); leftButton.setBackgroundColor(Color.BLUE); mLeftView = leftButton; this.addView(mLeftView); } private void setRightView(Context context){ View rightButton = new View(context); rightButton.setBackgroundColor(Color.YELLOW); mRightView = rightButton; this.addView(mRightView); } }获取全部源代码,请加群在群共享中获取(142979499)
相关文章推荐
- Android自定义组件系列【15】——四个方向滑动的菜单实现
- Android自定义组件——四个方向滑动的菜单实现
- Android自定义组件系列【4】——自定义ViewGroup实现双侧滑动
- Android自定义组件系列【4】——自定义ViewGroup实现双侧滑动
- Android自定义组件系列【4】——自定义ViewGroup实现双侧滑动
- Android UI设计系列之自定义DrawView组件实现数字签名效果(5)
- android三档自定义滑动开关,禁止点击功能的实现,用默认的seekbar组件实现
- Android自定义组件系列【11】——实现3D立体旋转效果
- (转)android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu
- android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu
- android三档自定义滑动开关,禁止点击功能的实现,用默认的seekbar组件实现
- Android自定义组件系列【3】——自定义ViewGroup实现侧滑
- Android自定义LinearLayout实现左右侧滑菜单,完美兼容ListView、ScrollView、ViewPager等滑动控件
- android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu
- android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu
- Android自定义组件系列【14】——Android5.0按钮波纹效果实现
- Android自定义组件系列【10】——随ViewPager滑动的导航条
- android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu
- Android自定义组件系列【10】——随ViewPager滑动的导航条
- Android自定义组件系列【11】——实现3D立体旋转效果