此笔记是为了复习之前在某视频网站上的教程,下面附上代码
主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和点击事件效果