Android自定义组件——四个方向滑动的菜单实现
今天无意中实现了一个四个方向滑动的菜单,感觉挺好玩,滑动起来很顺手,既然已经做出来了就贴出来让大家也玩弄一下。
一、效果演示
(说明:目前没有安装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)