• 自定义侧滑面板(SlieMenu)控件详解


    自定义控件的三个方法

    1. onMeasure() 测量控件的宽和高
    2. onLayout() 摆放控件的位置
    3. onDraw() 绘制布局

    下面看一点下代码:

    public class SlideMenu extends ViewGroup {
    
    private float downX;
    private float moveX;
    private Scroller scroller;
    
    public SlideMenu(Context context) {
        this(context,null);
    }
    
    
    
    public SlideMenu(Context context, AttributeSet attrs) {
        this(context, null,0);
    }
    
    public SlideMenu(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }
    
    
    private void init() {
        scroller = new Scroller(getContext());
    }
    
    /**
     * 设置子View的宽高
     * @param widthMeasureSpec  当前控件的宽度(测量规则)
     * @param heightMeasureSpec 当前控件的高度(测量规则)
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        /*
        leftMenu的宽是指定的450dp,高是matchparent
         */
        //指定SlideMenu的宽高
        View leftMenu = getChildAt(0);
        //宽是子空间指定的宽,高直接是父控件的高
        Log.i(getClass().getSimpleName(),"width : "+leftMenu.getMeasuredWidth());
        leftMenu.measure(leftMenu.getLayoutParams().width,heightMeasureSpec);
    
        /*
        mainContent的宽和高都是match_parent
         */
        //指定content的宽高
        View mainContent = getChildAt(1);
        mainContent.measure(widthMeasureSpec,heightMeasureSpec);
    
        super.onMeasure(widthMeasureSpec,heightMeasureSpec);
    
    
    }
    
    /**
     * 摆放控件的位置
     * @param changed 当前控件的尺寸大小和位置是否发生了改变
     * @param l     left  当前控件的右边距
     * @param t     top   当前控件的顶边距
     * @param r     right 当前控件的右边界
     * @param b     bottom当前控件的下边界
     */
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        /*
        摆放leftMenu的位置,
         */
        View leftMenu = getChildAt(0);
        leftMenu.layout(-leftMenu.getMeasuredWidth(),0,0,b);
    
        /*
        摆放mainContent的位置
         */
        getChildAt(1).layout(l,t,r,b);
    
    
    }
    
    
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN://按下
                downX = event.getX();//获取按下时的X的坐标
                break;
            case MotionEvent.ACTION_MOVE://滑动
                moveX = event.getX();//获取滑动时的X的坐标
    
                //将要滑动的距离
                int scroll = (int) (downX - moveX);//这里是一个负值
    
                //计算将要滚动到的位置,判断是否会超出去  getScroll()右边界相对于当前View X轴的变异量,是个带正负号的值。
                int newScroll = getScrollX() + scroll;
    
                /*
                scrollTo()滚动到指定的位置
                scrollBy()在原来的基础上滚动
                 */
                //如果将要滑动的距离超过了leftMenu的宽,就直接指定X坐标的位置,将leftMenu显示出来
                if (newScroll < -getChildAt(0).getMeasuredWidth()){
                    scrollTo(-getChildAt(0).getMeasuredWidth(),0);
                }else if (newScroll>0){//如果向左滑的话,
                    scrollTo(0,0);
                } else{
                    scrollBy(scroll,0);
                }
                downX = moveX;//必须要将moveX赋值给downX,因为滑动的过程是一小段一小段的滑动
                break;
            case MotionEvent.ACTION_UP://拿起
    
                Log.i(getClass().getSimpleName(),"getScrollX: "+getScrollX());
                if (getScrollX() <= -(getChildAt(0).getMeasuredWidth())/2.0f){//当leftMenu画出来显示了一半的时候
                    scrollTo(-getChildAt(0).getMeasuredWidth(),0);
                }else {//当没有滑出一半的时候
                    scrollTo(0,0);
                }
                break;
            default:
                break;
        }
        return true;//消费事件
    }
    
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    } 
    }
    

    注意

    onMeasure()测量的时候,得到的值与你在布局文件中写的是有偏差的。

    GitHub:https://github.com/godfunc
    博客园:http://www.cnblogs.com/godfunc
    Copyright ©2019 Godfunc
  • 相关阅读:
    ARM-Linux S5PV210 UART驱动(1)----用户手册中的硬件知识
    可变参数列表---以dbg()为例
    《C和指针》 读书笔记 -- 第7章 函数
    《Visual C++ 程序设计》读书笔记 ----第8章 指针和引用
    支持异步通知的globalfifo平台设备驱动程序及其测试代码
    linux内核中sys_poll()的简化分析
    《C和指针》读书笔记——第五章 操作符和表达式
    测试方法-等价类划分法
    MonkyTalk学习-8-Agent
    MonkyTalk学习-7-Verify-Verify
  • 原文地址:https://www.cnblogs.com/Godfunc/p/6548187.html
Copyright © 2020-2023  润新知