自定义左右滑动菜单

来源:互联网 发布:橱柜设计师软件 编辑:程序博客网 时间:2024/06/05 19:19

存一个自定义滑动菜单:

记一些关键的函数作用:

1.定义一个FrameLayout fm,fm.measure(width,height)代表定义这个fm的长和宽。
2.onMeasure()用于测量父Layout里面的各个layout,onLayout用于布局父Layout里面的各个layout。
3.实际操作滑动距离的时候用下面的代码:

int scrollX = getScrollX();                    int dX = (int) ev.getX() - point.x;                    int finalX = 0;                    int exX = scrollX - dX;                    if(exX > 0){                        finalX = Math.max(exX,-leftFrame.getMeasuredWidth());          //最多只能滑到右边的边界                        scrollTo(finalX,0);                 //滑动操作                    }                    else{                        finalX = Math.min(exX,rightFrame.getMeasuredWidth());          //最多只能滑到左边的边界                        scrollTo(finalX,0);                    }

4.更新了蒙版效果,在滑倒其他页面时,主页面会进行灰度的渐变。
5.添加了事件监听。
MainActivity.Java

package com.example.a53125.slidingrelativelayouttest;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;public class MainActivity extends AppCompatActivity {    private MainUI mainUI;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        mainUI = new MainUI(this);        setContentView(mainUI);    }}

MainUI.Java

package com.example.a53125.slidingrelativelayouttest;import android.content.Context;import android.graphics.Color;import android.graphics.Point;import android.support.annotation.Px;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 53125 on 2017/8/16. */public class MainUI extends RelativeLayout {    @android.support.annotation.IdRes    int LEFT_ID = 0xaabbcc;    @android.support.annotation.IdRes    int MID_ID = 2222;    @android.support.annotation.IdRes    int RIGHT_ID = 3333;    private Context context;    private FrameLayout middleFrame;    private FrameLayout leftFrame;    private FrameLayout rightFrame;    private FrameLayout maskFrame;    private Scroller scroller;//    public static int LEFT_ID = 0xaabbcc;//    public final int MID_ID = 2222;//    public final int RIGHT_ID = 3333;    public MainUI(Context context) {        super(context);        this.context = context;        initView(context);    }    public MainUI(Context context, AttributeSet attrs) {        super(context, attrs);        this.context = context;    }    public void initView(Context context){        scroller = new Scroller(context,new DecelerateInterpolator());        middleFrame = new FrameLayout(context);        leftFrame = new FrameLayout(context);        rightFrame = new FrameLayout(context);        maskFrame = new FrameLayout(context);        middleFrame.setBackgroundColor(Color.GREEN);        leftFrame.setBackgroundColor(Color.YELLOW);        rightFrame.setBackgroundColor(Color.YELLOW);        maskFrame.setBackgroundColor(0x88000000);        maskFrame.setAlpha(0);        leftFrame.setId(LEFT_ID);        middleFrame.setId(MID_ID);        rightFrame.setId(RIGHT_ID);        addView(leftFrame);        addView(middleFrame);        addView(rightFrame);        addView(maskFrame);    }    @Override    public void scrollTo(@Px int x, @Px int y) {        super.scrollTo(x, y);        int scr = Math.abs(getScrollX());        float alpha = scr/(float) leftFrame.getMeasuredWidth();        maskFrame.setAlpha(alpha);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        middleFrame.measure(widthMeasureSpec,heightMeasureSpec);        maskFrame.measure(widthMeasureSpec,heightMeasureSpec);        int Screen_Width = MeasureSpec.getSize(widthMeasureSpec);//        System.out.println("widthMeasureSpec:"+widthMeasureSpec);//        System.out.println("Screen_Width"+Screen_Width);        int Left_Width = MeasureSpec.makeMeasureSpec((int)(Screen_Width*0.8f),MeasureSpec.EXACTLY);        leftFrame.measure(Left_Width,heightMeasureSpec);        rightFrame.measure(Left_Width,heightMeasureSpec);    }    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        super.onLayout(changed, l, t, r, b);        middleFrame.layout(l, t, r, b);        maskFrame.layout(l, t, r, b);        leftFrame.layout(l-leftFrame.getMeasuredWidth(), t, r, b);        rightFrame.layout(l+middleFrame.getMeasuredWidth(), t, r+rightFrame.getMeasuredWidth(), b);    }    private int state = 0;    private boolean stateSlidingLeftRight = false;        //是否左右滑动    private boolean stateSlidingUpDown = false;        //是否上下滑动    private int TEST_DIS = 20;             //滑动判定的最小距离    Point point = new Point();    @Override    public boolean dispatchTouchEvent(MotionEvent ev) {//        System.out.println("Click successfully!");//        System.out.println("LeftWidth:"+leftFrame.getMeasuredWidth());//        System.out.println("MidWidth:"+middleFrame.getMeasuredWidth());        if(!(state == 1)){            getState(ev);//            System.out.println("stateSlidingLeftRight:"+stateSlidingLeftRight);            return true;                  //一定要返回true,否则的话不会进行滑动操作        }        if(stateSlidingUpDown){                    //用于初始化横向滑动的状态,便于接着上次再次滑动            stateSlidingLeftRight = false;            state = 0;        }        if(stateSlidingLeftRight){            System.out.println("Sliding successfully!");            switch (ev.getActionMasked()){                case MotionEvent.ACTION_MOVE:                    int scrollX = getScrollX();                    int dX = (int) ev.getX() - point.x;                    int finalX = 0;                    int exX = scrollX - dX;                    if(exX > 0){                        finalX = Math.max(exX,-leftFrame.getMeasuredWidth());          //最多只能滑到右边的边界                        scrollTo(finalX,0);                 //滑动操作                    }                    else{                        finalX = Math.min(exX,rightFrame.getMeasuredWidth());          //最多只能滑到左边的边界                        scrollTo(finalX,0);                    }                    point.x = (int) ev.getX();                 //保存点,用于下一次滑动                    point.y = (int) ev.getY();                    break;                case MotionEvent.ACTION_UP:              //用于初始化横向滑动的状态,便于接着上次再次滑动                case MotionEvent.ACTION_CANCEL:         //用于初始化横向滑动的状态,便于接着上次再次滑动                    int scroll = getScrollX();                    if(Math.abs(scroll) > leftFrame.getMeasuredWidth() >>1){                        if(scroll < 0){                            scroller.startScroll(scroll,0,-leftFrame.getMeasuredWidth()-scroll,0);                        }                        else{                            scroller.startScroll(scroll,0,leftFrame.getMeasuredWidth()-scroll,0);                        }                    }                    else{                        scroller.startScroll(scroll,0,-scroll,0);                    }                    invalidate();                    stateSlidingLeftRight = false;                    state = 0;                    break;                default:break;            }        }        return super.dispatchTouchEvent(ev);    }    @Override    public void computeScroll() {        super.computeScroll();        if(!scroller.computeScrollOffset()){            return;        }        int tempX = scroller.getCurrX();        scrollTo(tempX,0);    }    private void getState(MotionEvent ev) {        switch (ev.getActionMasked()){            case MotionEvent.ACTION_UP:        //手指抬起后触发                state = 0;                stateSlidingLeftRight = false;                stateSlidingUpDown = false;                super.dispatchTouchEvent(ev);                break;            case MotionEvent.ACTION_DOWN:        //手指按下的一瞬间触发                point.x = (int) ev.getX();                point.y = (int) ev.getY();                super.dispatchTouchEvent(ev);                break;            case MotionEvent.ACTION_CANCEL:      //手指滑到边界触发                stateSlidingLeftRight = false;                state = 0;                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 > dY && dX > TEST_DIS){         //滑动举例大于TEST_DIS才算滑动                    stateSlidingLeftRight = true;                    stateSlidingUpDown = false;                    state = 1;                    point.x = (int) ev.getX();                    point.y = (int) ev.getY();                }else if(dX < dY && dY > TEST_DIS){                    stateSlidingUpDown = true;                    stateSlidingLeftRight = false;                    state = 1;                    point.x = (int) ev.getX();          //记录点用于下次滑动                    point.y = (int) ev.getY();                }                break;        }    }}
原创粉丝点击