实现效果:
- 左右侧滑菜单,侧滑栏占主屏比为60%
- 监听触控,自定义滑动动画,当侧边栏滑动超过50%松开触控将自动滑动到60%,未超过50%松开触控回归侧边栏隐藏
- 为主屏设置蒙版效果,根据侧滑菜单的占屏比设置主屏蒙版透明度
不知道如何制作动画,所以就将就着看吧,懂意思就行,如图:
代码如下:MainActivity
package com.example.mymenu;
import android.os.Bundle;
import android.app.Activity;
import android.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.view.Menu;
public class MainActivity extends FragmentActivity {
private MainUI mainui;
private LeftMenu leftMenu;
private RightMenu rightMenu;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mainui=new MainUI(this);
setContentView(mainui);
leftMenu=new LeftMenu();
rightMenu=new RightMenu();
getSupportFragmentManager().beginTransaction().add(MainUI.LEFT_ID, leftMenu).commit();
getSupportFragmentManager().beginTransaction().add(MainUI.RIGHT_ID, rightMenu).commit();
}
}
MainUI:
package com.example.mymenu;
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;
public class MainUI extends RelativeLayout{
private Context context;
private FrameLayout leftMenu;
private FrameLayout rightMenu;
private FrameLayout middMenu;
private Scroller mscroller;
private FrameLayout middMask;
public static final int LEFT_ID=0xaabbcc;
public static final int MIDEELE_ID=0xaaccdd;
public static final int RIGHT_ID=0xddbbcc;
public MainUI(Context context) {
super(context);
setView(context);
}
public MainUI(Context context, AttributeSet attrs) {
super(context, attrs);
}
private void setView(Context context){
this.context=context;
mscroller=new Scroller(context,new DecelerateInterpolator());
leftMenu=new FrameLayout(context);
rightMenu=new FrameLayout(context);
middMenu=new FrameLayout(context);
middMask=new FrameLayout(context);
leftMenu.setBackgroundColor(Color.LTGRAY);
rightMenu.setBackgroundColor(Color.GREEN);
middMenu.setBackgroundColor(Color.CYAN);
middMask.setBackgroundColor(0x88000000);//蒙版颜色
leftMenu.setId(LEFT_ID);
middMenu.setId(MIDEELE_ID);
rightMenu.setId(RIGHT_ID);
addView(leftMenu);
addView(middMenu);
addView(rightMenu);
addView(middMask);
middMask.setAlpha(0);
onMiddleMask();
}
public float onMiddleMask(){
System.out.println("透明度"+middMask.getAlpha());
return middMask.getAlpha();
}
/*
* 根据滑动改变蒙版的透明度
*/
@Override
public void scrollTo(int x, int y) {
super.scrollTo(x, y);
int curX=Math.abs(getScrollX());
float scale=curX/(float)leftMenu.getMeasuredWidth();
middMask.setAlpha(scale);
}
/*
*绘制界面
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
middMenu.measure(widthMeasureSpec, heightMeasureSpec);
middMask.measure(widthMeasureSpec, heightMeasureSpec);
int realWidth=MeasureSpec.getSize(widthMeasureSpec);
int tempWithMeasure=MeasureSpec.makeMeasureSpec((int)(realWidth*0.6f),MeasureSpec.EXACTLY);
leftMenu.measure(tempWithMeasure, heightMeasureSpec);
rightMenu.measure(tempWithMeasure,heightMeasureSpec);
// middMenu.measure(tempWithMeasure, heightMeasureSpec);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
middMenu.layout(l, t, r, b);
middMask.layout(l, t, r, b);
leftMenu.layout(l-leftMenu.getMeasuredWidth(), t, r, b);
rightMenu.layout(l+middMenu.getMeasuredWidth(),t, l+middMenu.getMeasuredWidth()+rightMenu.getMeasuredWidth(), b);
}
/*
* 判断是怎么样的一个事件
*/
private boolean isTestCompete;
private boolean isleftrightEvent;
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if(!isTestCompete){
getEventType(ev);//判断触控的类型
return true;
}
/*
* 有滑动事件
*/
if(isleftrightEvent){
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();//判断滑动的距离是否超过了Menu的一半
if(Math.abs(curScrollX)>leftMenu.getMeasuredWidth()>>1){
//判断左右滑动
if(curScrollX<0){
mscroller.startScroll(curScrollX, 0, -leftMenu.getMeasuredWidth()-curScrollX, 0,200);
}else{
mscroller.startScroll(curScrollX, 0, leftMenu.getMeasuredWidth()-curScrollX, 0,200);
}
}else{
mscroller.startScroll(curScrollX, 0, -curScrollX, 0,200);
}
invalidate();
isleftrightEvent=false;
isTestCompete=false;
break;
}
}else{
/*
* /上下滑动监听
*/
switch (ev.getActionMasked()) {
case MotionEvent.ACTION_UP:
isleftrightEvent=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 TEST_DIS=20;//设置一个被比较的值
private void getEventType(MotionEvent ev) {
switch (ev.getActionMasked()) {
case MotionEvent.ACTION_DOWN://按下
point.x=(int) ev.getX();
point.y=(int) ev.getY();
super.dispatchTouchEvent(ev);
break;
case MotionEvent.ACTION_MOVE:
/*
* 移动的距离
*/
int dX=Math.abs((int) ev.getX()-point.x);
int dY=Math.abs((int) ev.getY()-point.y);
if(dX>=TEST_DIS&&dX>dY){//左右滑动的距离
isleftrightEvent=true;
isTestCompete=true;
/*
* 滑动之后获取当前的 坐标
*/
point.x=(int) ev.getX();
point.y=(int) ev.getY();
}else if(dY>=TEST_DIS&&dY>dX){//上下滑动
isleftrightEvent=false;
isTestCompete=true;
point.x=(int) ev.getX();
point.y=(int) ev.getY();
}
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_CANCEL:
super.dispatchTouchEvent(ev);
isleftrightEvent=false;
isTestCompete=false;
break;
}
}
}
两侧的菜单代码就不帖了!GemeOver