Android 左右滑动菜单之基本UI视图动画

此笔记是为了复习之前在某视频网站上的教程,下面附上代码

主UI类:

package com.dh.mc.de;

import android.content.Context;
import android.graphics.Color;
import android.graphics.Point;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import android.widget.Scroller;

/**
 * Created by M.c on 2015/4/14.
 */
public class MenuAct extends RelativeLayout {

    private FrameLayout leftMenu, centerMenu, rightMenu;//左中右布局控件

    private Context context;//上下文
    private Scroller mScroller;

    //构造函数1
    public MenuAct(Context context) {
        super(context);
        initView(context);
    }

    //构造函数2
    public MenuAct(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    //初始化左中右布局控件
    private void initView(Context context) {
        this.context = context;
        mScroller = new Scroller(context, new DecelerateInterpolator());
        leftMenu = new FrameLayout(context);
        centerMenu = new FrameLayout(context);
        rightMenu = new FrameLayout(context);
        leftMenu.setBackgroundColor(Color.RED);//为了看到效果 设置背景色
        centerMenu.setBackgroundColor(Color.GREEN);
        rightMenu.setBackgroundColor(Color.BLUE);
        addView(leftMenu); //添加布局到根布局
        addView(centerMenu);
        addView(rightMenu);

    }

    //设置左中右布局长宽
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        centerMenu.measure(widthMeasureSpec, heightMeasureSpec);//中间布局就是整个屏幕大小
        int realWidth = MeasureSpec.getSize(widthMeasureSpec); //获得屏幕真实宽度
        int tempWidth = MeasureSpec.makeMeasureSpec((int) (realWidth * 0.8f), MeasureSpec.EXACTLY);//获得屏幕真实宽度的80%,用于设置左右布局

        leftMenu.measure(tempWidth, heightMeasureSpec);  //设置左布局
        rightMenu.measure(tempWidth, heightMeasureSpec); //设置右布局


    }

    //设置布局边界在屏幕中的位置
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);

        centerMenu.layout(l, t, r, b);
        leftMenu.layout(l - leftMenu.getMeasuredWidth(), t, l, b);
        rightMenu.layout(l + centerMenu.getMeasuredWidth(), t, l + centerMenu.getMeasuredWidth() + rightMenu.getMeasuredWidth(), b);
    }


    private boolean isTestCompete,
            isLeftRightComplete;//

    //屏幕触摸事件处理
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (!isTestCompete) {
            getEventType(ev);
            return true;
        }

        if (isLeftRightComplete) {//如果是左右滑动
            switch (ev.getActionMasked()) {
                case MotionEvent.ACTION_MOVE:
                    int curScrollX = getScrollX();//滚动距离
                    int dis_x = (int) (ev.getX() - point.x);//手指按下后滑动距离
                    int expectX = -dis_x + curScrollX;
                    int finalX = 0; //初始化屏幕滑动距离
                    if (expectX < 0) { //向左滑动
                        finalX = Math.max(expectX, -leftMenu.getMeasuredWidth());
                    } else { //向右滑动
                        finalX = Math.min(expectX, rightMenu.getMeasuredWidth());
                    }

                    scrollTo(finalX, 0);//屏幕移动
                    point.x = (int) ev.getX();
                    break;
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL:
                    curScrollX = getScrollX();
                    if (Math.abs(curScrollX) > leftMenu.getMeasuredWidth() >> 1) {//滑动大于屏幕距离一半时,启动动画
                        System.out.println("滑动距离: "+curScrollX);
                        if (curScrollX < 0) {//向左
                            mScroller.startScroll(curScrollX, 0, -leftMenu.getMeasuredWidth() - curScrollX, 0);
                        } else {//向右
                            mScroller.startScroll(curScrollX, 0, leftMenu.getMeasuredWidth() - curScrollX, 0);
                        }
                    } else {
                        mScroller.startScroll(curScrollX, 0, -curScrollX, 0);//距离不到返回原点

                    }
                    invalidate();//View重绘
                    isLeftRightComplete = false;
                    isTestCompete = false;
                    break;
            }
        } else {//上下滑动也要初始化
            switch (ev.getActionMasked()) {
                case MotionEvent.ACTION_UP:
                    isLeftRightComplete = false;
                    isTestCompete = false;
                    break;
            }
        }

        return super.dispatchTouchEvent(ev);

    }

    //滑动回调重写
    @Override
    public void computeScroll() {
        super.computeScroll();
        if (!mScroller.computeScrollOffset()) {
            return;
        }
        int tempX = mScroller.getCurrX();//总滑动值
        scrollTo(tempX, 0);
    }

    private Point point = new Point(); //坐标点
    private static final int DIS = 20;//超过20像素是 判定为移动

    //判断滑动方向并获得坐标
    private void getEventType(MotionEvent ev) {

        switch (ev.getActionMasked()) {
            default:
                break;
            case MotionEvent.ACTION_DOWN://按下
                point.x = (int) ev.getX();//按下时的坐标,用point存
                point.y = (int) ev.getY();

                break;
            case MotionEvent.ACTION_MOVE://移动

                int dx = Math.abs((int) ev.getX() - point.x);//x轴移动距离
                int dy = Math.abs((int) ev.getY() - point.y);//y轴移动距离
                if (dx > DIS && dx > dy) { //左右滑动
                    isLeftRightComplete = true;
                    isTestCompete = true;
                    point.x = (int) ev.getX();//再次拿到坐标
                    point.y = (int) ev.getY();
                } else if (dy > DIS && dy > dx) { //上下滑动
                    isLeftRightComplete = false;
                    isTestCompete = true;
                    point.x = (int) ev.getX();
                    point.y = (int) ev.getY();
                }

                break;

            case MotionEvent.ACTION_UP://手指抬起

            case MotionEvent.ACTION_CANCEL:

                break;
        }

    }
}


在Activity中使用

package com.dh.mc.de;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;


public class MainActivity extends ActionBarActivity {

    private MenuAct menu;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        menu = new MenuAct(this);
        setContentView(menu);
    }


}


如果不好的地方,请大家指出,诚心接受任何吐槽~~~~~~~~~~ 

后续也会再加入Fragment和点击事件效果


你可能感兴趣的:(android,滑动菜单)