zoukankan      html  css  js  c++  java
  • Android自定义组件——四个方向滑动的菜单实现

    今天无意中实现了一个四个方向滑动的菜单,感觉挺好玩,滑动起来很顺手,既然已经做出来了就贴出来让大家也玩弄一下。

    一、效果演示

    (说明:目前没有安装Android模拟器,制作的动态图片太卡了,就贴一下静态图片吧,实际效果可以下载源代码查看)

    (向上滑动)

    (向下滑动)

    (向左滑动)

    (向右滑动)

    二、实现过程介绍

    1、放置5个View (分别是上下左右中)

    1. @Override  
    2. protected void onLayout(boolean changed, int l, int t, int r, int b) {  
    3.     mTopView.layout(0, -mViewHeight, mViewWidth, 0);  
    4.     mBottomView.layout(0, mViewHeight, mViewWidth, 2 * mViewHeight);  
    5.     mCenterView.layout(0, 0, mViewWidth, mViewHeight);  
    6.     mLeftView.layout(-mViewWidth, 0, 0, mViewHeight);  
    7.     mRightView.layout(mViewWidth, 0, 2 * mViewWidth, mViewHeight);  
    8. }  

    转载请说明出处:http://blog.csdn.net/dawanganban

    2、通过onTouchEvent事件来判断移动方向

    1. private float mDownY;  
    2. private float mDownX;  
    3. @Override  
    4. public boolean onTouchEvent(MotionEvent event) {  
    5.     int disY;  
    6.     int disX;  
    7.     float eventY = event.getY();  
    8.     float eventX = event.getX();  
    9.     switch (event.getAction()) {  
    10.     case MotionEvent.ACTION_DOWN:  
    11.         mDownY = eventY;      
    12.         mDownX = eventX;  
    13.         break;  
    14.     case MotionEvent.ACTION_UP:  
    15.         disY = (int)(eventY - mDownY);  
    16.         disX = (int)(eventX - mDownX);  
    17.         if(Math.abs(disY) > Math.abs(disX)){  
    18.             if(Math.abs(disY) > MIN_VIEW_HEIGHT / 2){  
    19.                 if(disY > 0){ //向下滑动  
    20.                     Log.d(TAG, "TO_BOTTOM");  
    21.                     changeToBottom();  
    22.                 }else{        //向上滑动  
    23.                     Log.d(TAG, "TO_TOP");  
    24.                     changeToTop();  
    25.                 }  
    26.             }  
    27.         }else{  
    28.             if(Math.abs(disX) > MIN_VIEW_WIDTH / 2){  
    29.                 if(disX > 0){ //向右滑动  
    30.                     Log.d(TAG, "TO_RIGHT");  
    31.                     changeToRight();  
    32.                 }else{        //向左滑动  
    33.                     Log.d(TAG, "TO_LEFT");  
    34.                     changeToLeft();  
    35.                 }  
    36.             }  
    37.         }  
    38.         break;  
    39.   
    40.     default:  
    41.         break;  
    42.     }  
    43.     return true;  
    44. }  

    3、通过computerScroll()方法实现平滑移动

    1. @Override  
    2. public void computeScroll() {  
    3.     super.computeScroll();  
    4.     if(mScroller.computeScrollOffset()){  
    5.         scrollTo(mScroller.getCurrX(), mScroller.getCurrY());  
    6.         postInvalidate();  
    7.     }  
    8. }  

    4、判断临界条件(否则会一直向一个方向滑动)

    1. int[] location = new int[2];  
    2. mCenterView.getLocationOnScreen(location);  
    3. if(location[1] >= mViewHeight - MIN_VIEW_HEIGHT * 2) return;  

    例如上面代码就是判断向下滑动的临界条件,location[1]代表中间View的y坐标(相对于屏幕)。

    三、整个View的源码

    1. package com.example.testmx4update;  
    2.   
    3. import android.content.Context;  
    4. import android.graphics.Color;  
    5. import android.util.AttributeSet;  
    6. import android.util.Log;  
    7. import android.view.MotionEvent;  
    8. import android.view.View;  
    9. import android.view.ViewGroup;  
    10. import android.widget.Scroller;  
    11.   
    12. /** 
    13.  * 自定义可以拖动的View 
    14.  * @author 阳光小强  http://blog.csdn.net/dawanganban 
    15.  * 
    16.  */  
    17. public class MyCanPullView extends ViewGroup{  
    18.       
    19.     private static final int MIN_VIEW_HEIGHT = 200;  
    20.     private static final int MIN_VIEW_WIDTH = 400;  
    21.   
    22.   
    23.     private static final String TAG = "TEST";  
    24.       
    25.       
    26.     private int mViewHeight;  
    27.     private int mViewWidth;  
    28.       
    29.     private View mTopView;  
    30.     private View mBottomView;  
    31.     private View mCenterView;  
    32.     private View mLeftView;  
    33.     private View mRightView;  
    34.       
    35.       
    36.       
    37.     private Scroller mScroller;  
    38.   
    39.     public MyCanPullView(Context context, AttributeSet attrs) {  
    40.         super(context, attrs);  
    41.           
    42.         initView(context);  
    43.           
    44.         mScroller = new Scroller(context);  
    45.     }  
    46.   
    47.     private void initView(Context context) {  
    48.         setTopView(context);  
    49.         setBottomView(context);  
    50.         setCenterView(context);  
    51.         setLeftView(context);  
    52.         setRightView(context);  
    53.     }  
    54.       
    55.       
    56.     private float mDownY;  
    57.     private float mDownX;  
    58.     @Override  
    59.     public boolean onTouchEvent(MotionEvent event) {  
    60.         int disY;  
    61.         int disX;  
    62.         float eventY = event.getY();  
    63.         float eventX = event.getX();  
    64.         switch (event.getAction()) {  
    65.         case MotionEvent.ACTION_DOWN:  
    66.             mDownY = eventY;      
    67.             mDownX = eventX;  
    68.             break;  
    69.         case MotionEvent.ACTION_UP:  
    70.             disY = (int)(eventY - mDownY);  
    71.             disX = (int)(eventX - mDownX);  
    72.             if(Math.abs(disY) > Math.abs(disX)){  
    73.                 if(Math.abs(disY) > MIN_VIEW_HEIGHT / 2){  
    74.                     if(disY > 0){ //向下滑动  
    75.                         Log.d(TAG, "TO_BOTTOM");  
    76.                         changeToBottom();  
    77.                     }else{        //向上滑动  
    78.                         Log.d(TAG, "TO_TOP");  
    79.                         changeToTop();  
    80.                     }  
    81.                 }  
    82.             }else{  
    83.                 if(Math.abs(disX) > MIN_VIEW_WIDTH / 2){  
    84.                     if(disX > 0){ //向右滑动  
    85.                         Log.d(TAG, "TO_RIGHT");  
    86.                         changeToRight();  
    87.                     }else{        //向左滑动  
    88.                         Log.d(TAG, "TO_LEFT");  
    89.                         changeToLeft();  
    90.                     }  
    91.                 }  
    92.             }  
    93.             break;  
    94.   
    95.         default:  
    96.             break;  
    97.         }  
    98.         return true;  
    99.     }  
    100.       
    101.     private void changeToBottom(){  
    102.         int[] location = new int[2];  
    103.         mCenterView.getLocationOnScreen(location);  
    104.         if(location[1] >= mViewHeight - MIN_VIEW_HEIGHT * 2) return;  
    105.         int dy = (int)(mViewHeight - MIN_VIEW_HEIGHT);  
    106.         mScroller.startScroll(0, getScrollY(), 0, -dy, 500);  
    107.         invalidate();  
    108.     }  
    109.       
    110.     private void changeToTop(){  
    111.         int[] location = new int[2];  
    112.         mTopView.getLocationOnScreen(location);  
    113.         if(location[1] <= -mViewHeight - MIN_VIEW_HEIGHT / 2) return;  
    114.         int dy = (int)(mViewHeight - MIN_VIEW_HEIGHT);  
    115.         mScroller.startScroll(0, getScrollY(), 0, dy, 500);  
    116.         invalidate();  
    117.     }  
    118.       
    119.     private void changeToRight(){  
    120.         int[] location = new int[2];  
    121.         mCenterView.getLocationOnScreen(location);  
    122.         if(location[0] >= mViewWidth - MIN_VIEW_WIDTH * 2) return;  
    123.         int dx = (int)(mViewWidth - MIN_VIEW_WIDTH);  
    124.         mScroller.startScroll(getScrollX(), 0, -dx, 0, 500);  
    125.         invalidate();  
    126.     }  
    127.       
    128.     private void changeToLeft(){  
    129.         Log.d(TAG, "TO_LEFT");  
    130.         int[] location = new int[2];  
    131.         mLeftView.getLocationOnScreen(location);  
    132.         if(location[0] <= -mViewWidth - MIN_VIEW_WIDTH / 2) return;  
    133.         int dx = (int)(mViewWidth - MIN_VIEW_WIDTH);  
    134.         mScroller.startScroll(getScrollX(), 0, dx, 0, 500);  
    135.         invalidate();  
    136.     }  
    137.       
    138.     @Override  
    139.     public void computeScroll() {  
    140.         super.computeScroll();  
    141.         if(mScroller.computeScrollOffset()){  
    142.             scrollTo(mScroller.getCurrX(), mScroller.getCurrY());  
    143.             postInvalidate();  
    144.         }  
    145.     }  
    146.   
    147.     @Override  
    148.     protected void onLayout(boolean changed, int l, int t, int r, int b) {  
    149.         mTopView.layout(0, -mViewHeight, mViewWidth, 0);  
    150.         mBottomView.layout(0, mViewHeight, mViewWidth, 2 * mViewHeight);  
    151.         mCenterView.layout(0, 0, mViewWidth, mViewHeight);  
    152.         mLeftView.layout(-mViewWidth, 0, 0, mViewHeight);  
    153.         mRightView.layout(mViewWidth, 0, 2 * mViewWidth, mViewHeight);  
    154.     }  
    155.   
    156.     @Override  
    157.     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
    158.         super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
    159.         //获取整个View的宽高  
    160.         mViewWidth = MeasureSpec.getSize(widthMeasureSpec);  
    161.         mViewHeight = MeasureSpec.getSize(heightMeasureSpec);  
    162.     }  
    163.       
    164.     private void setTopView(Context context){  
    165.         View topButton = new View(context);  
    166.         topButton.setBackgroundColor(Color.RED);  
    167.         mTopView = topButton;  
    168.         this.addView(mTopView);  
    169.     }  
    170.       
    171.     private void setBottomView(Context context){  
    172.         View bottomButton = new View(context);  
    173.         bottomButton.setBackgroundColor(Color.GREEN);  
    174.         mBottomView = bottomButton;  
    175.         this.addView(mBottomView);  
    176.     }  
    177.       
    178.     private void setCenterView(Context context){  
    179.         View centerButton = new View(context);  
    180.         centerButton.setBackgroundColor(Color.WHITE);  
    181.         mCenterView = centerButton;  
    182.         this.addView(mCenterView);  
    183.     }  
    184.       
    185.     private void setLeftView(Context context){  
    186.         View leftButton = new View(context);  
    187.         leftButton.setBackgroundColor(Color.BLUE);  
    188.         mLeftView = leftButton;  
    189.         this.addView(mLeftView);  
    190.     }  
    191.       
    192.     private void setRightView(Context context){  
    193.         View rightButton = new View(context);  
    194.         rightButton.setBackgroundColor(Color.YELLOW);  
    195.         mRightView = rightButton;  
    196.         this.addView(mRightView);  
    197.     }  
    198. }  

    获取全部源代码,请加群在群共享中获取(142979499)

  • 相关阅读:
    7 重排序与happens-before
    6 Java内存模型基础知识
    5 Java线程间的通信
    Java线程的状态及主要转化方法
    《The Boost C++ Libraries》 第一章 智能指针
    python通过swig调用静态库
    使用gdb调试
    Rsync服务部署使用
    UNP学习总结(二)
    read()函数的困惑
  • 原文地址:https://www.cnblogs.com/yudar/p/4249025.html
Copyright © 2011-2022 走看看