android 菜单视图,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 

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 

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和点击事件效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值