自定义左右侧滑菜单
實現效果:
- 左右側滑菜單,側滑欄占主屏比為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;@Overrideprotected 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();}/** 根據滑動改變蒙版的透明度*/@Overridepublic void scrollTo(int x, int y) {super.scrollTo(x, y);int curX=Math.abs(getScrollX());float scale=curX/(float)leftMenu.getMeasuredWidth();middMask.setAlpha(scale);}/**繪制界面*/@Overrideprotected 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);}@Overrideprotected 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;@Overridepublic 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);}@Overridepublic 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
轉載于:https://www.cnblogs.com/xiangevan/p/7818195.html
總結
- 上一篇: 爆裂飞车多少钱一辆?
- 下一篇: 求一个好听的群名字