当前位置:   article > 正文

SeniorUI25_自定义DrawerLayout设置背景和item动画效果_drawerlayout 自定义动画

drawerlayout 自定义动画

SeniorUI_高级UI汇总目录

一 自定义DrawerLayout设置背景和item动画效果

1 效果图

在这里插入图片描述

2 原理

  1. 自定义MyDrawSlideBar继承LinearLayout作为侧拉栏
  2. 自定义MyDrawerLayout从而获取对应的侧拉栏SlideBar,偷梁换柱:移除SlideBar添加一个自定义的RelativeLayout,再将一个要显示的背景View和SlideBar添加到RelativeLayout中去
  3. 背景View通过MyDrawerLayout获取移动要素,绘制背景(贝塞尔曲线),当设置背景为图片时,使用paint的Shader实现
  4. MyDrawSlideBar获取移动要素,计算出每个child的平移距离,实现动画效果

3 主要代码

MyDrawerLayout

public class MyDrawerLayout extends DrawerLayout  implements DrawerLayout.DrawerListener {
    //背景 自定义控件
    private MyDrawBgRealativeLayout myDrawBgRealativeLayout;

    //含有 布局内容的 Linealayout自定义控件
    private MyDrawSlideBar myDrawSlideBar;
    private  float y;

    private float slideOffset;
    //内容区域
    private  View contenView;
    public MyDrawerLayout(Context context) {
        super(context);
    }

    public MyDrawerLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }


    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        initChild();

    }

    private void initChild() {
        for(int i=0;i<getChildCount();i++) {
            View view = getChildAt(i);
            if (view instanceof MyDrawSlideBar) {
                myDrawSlideBar= (MyDrawSlideBar) view;
                break;
            }else {
                contenView=view;
            }
        }
        //移除子控件   因为不符合我们的需求
        removeView(myDrawSlideBar);
        myDrawBgRealativeLayout = new MyDrawBgRealativeLayout(myDrawSlideBar);
        addView(myDrawBgRealativeLayout);
        addDrawerListener(this);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {

        if (ev.getAction() == MotionEvent.ACTION_UP) {
            closeDrawers();
            myDrawBgRealativeLayout.onMotionEventUp();
            return super.dispatchTouchEvent(ev);
        }
        y=ev.getY();

        if (slideOffset < 1) {
            super.dispatchTouchEvent(ev);
        }else if(ev.getAction() == MotionEvent.ACTION_MOVE) {
            //当大于1时   内容区域不做偏移  只是把背景贝塞尔曲线进行变化  拦截后  DrawerLayout.DrawerListener 不再起作用  因为内容不做偏移
            myDrawBgRealativeLayout.setTouch(y,slideOffset);
        }
        return true;
    }

    @Override
    public void onDrawerSlide(View drawerView, float slideOffset) {
        this.slideOffset = slideOffset;
        myDrawBgRealativeLayout.setTouch(y,slideOffset);
        float contentViewoffset=drawerView.getWidth()*slideOffset/2;
        contenView.setTranslationX(contentViewoffset);
    }

    @Override
    public void onDrawerOpened(View drawerView) {

    }

    @Override
    public void onDrawerClosed(View drawerView) {

    }

    @Override
    public void onDrawerStateChanged(int newState) {

    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87

MyDrawBgRealativeLayout

public class MyDrawBgRealativeLayout extends RelativeLayout {

    private MyDrawSlideBar myDrawSlideBar;
    private MyDrawBgView myDrawBgView;


    public MyDrawBgRealativeLayout(MyDrawSlideBar myDrawSlideBar) {
        super(myDrawSlideBar.getContext() );
        init(myDrawSlideBar);
    }

    private void init(MyDrawSlideBar myDrawSlideBar) {
        //转移宽高属性
        setLayoutParams(myDrawSlideBar.getLayoutParams());
        int parentLayoutGravity = ((DrawerLayout.LayoutParams) getLayoutParams()).gravity;

        this.myDrawSlideBar=myDrawSlideBar;

        //子控件 是否居中
        myDrawBgView = new MyDrawBgView(getContext());
        addView( myDrawBgView, 0, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
        //添加滑动内容区域
        myDrawBgView.setColor(myDrawSlideBar.getBackground());
        myDrawSlideBar.setBackgroundColor(Color.TRANSPARENT);
        addView(myDrawSlideBar, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
    }


    public void setTouch(float y, float offset) {
        //背景做贝塞尔曲线
        myDrawBgView.setTouchY(y,offset);
        myDrawSlideBar.setTouchY(y,offset);
    }

    public void onMotionEventUp() {
        myDrawSlideBar.onMotionEventUp();
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

MyDrawBgRealativeLayout

public class MyDrawBgRealativeLayout extends RelativeLayout {

    private MyDrawSlideBar myDrawSlideBar;
    private MyDrawBgView myDrawBgView;


    public MyDrawBgRealativeLayout(MyDrawSlideBar myDrawSlideBar) {
        super(myDrawSlideBar.getContext() );
        init(myDrawSlideBar);
    }

    private void init(MyDrawSlideBar myDrawSlideBar) {
        //转移宽高属性
        setLayoutParams(myDrawSlideBar.getLayoutParams());
        int parentLayoutGravity = ((DrawerLayout.LayoutParams) getLayoutParams()).gravity;

        this.myDrawSlideBar=myDrawSlideBar;

        //子控件 是否居中
        myDrawBgView = new MyDrawBgView(getContext());
        addView( myDrawBgView, 0, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
        //添加滑动内容区域
        myDrawBgView.setColor(myDrawSlideBar.getBackground());
        myDrawSlideBar.setBackgroundColor(Color.TRANSPARENT);
        addView(myDrawSlideBar, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
    }


    public void setTouch(float y, float offset) {
        //背景做贝塞尔曲线
        myDrawBgView.setTouchY(y,offset);
        myDrawSlideBar.setTouchY(y,offset);
    }

    public void onMotionEventUp() {
        myDrawSlideBar.onMotionEventUp();
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

MyDrawBgView

public class MyDrawBgView extends View {

    private Paint paint;
    private Path path;
    private BitmapDrawable drawable;
    public MyDrawBgView(Context context) {
        this(context,null);
    }

    public MyDrawBgView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        paint = new Paint();
        paint.setAntiAlias(true);
        path = new Path();
    }


    public void setTouchY(float y, float percent) {
        path.reset();
        float width=getWidth()*percent;
        float height=getHeight();
        float firstPointX=width/2;
        float offsetY=height/8;
        path.lineTo(firstPointX,-offsetY);
        path.quadTo(width * 3 / 2, y, firstPointX, height + offsetY);
        path.lineTo(0, height);
        path.close();
        path.offset(getWidth() - width, 0);
        invalidate();
    }


    @Override
    protected void onDraw(Canvas canvas) {
         //完成图片的绘制
        if (drawable != null) {
            Bitmap bitmap=drawable.getBitmap();
            Shader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
            paint.setShader(shader);
        }
        paint.setStyle(Paint.Style.FILL);
        canvas.drawPath(path,paint);
    }

    public void setColor(Drawable color) {
        if (color instanceof ColorDrawable) {
            ColorDrawable colorDrawable= (ColorDrawable) color;
            paint.setColor(colorDrawable.getColor());
        } else if (color instanceof BitmapDrawable) {
            this.drawable= (BitmapDrawable) color;
        }
    }

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59

4 Demo

DrawerLayoutActivity

二 设置响应触摸区域

1 效果图

在这里插入图片描述## 2 需求
当使用DrawerLayout实现侧拉栏效果时,经常发现手势的识别如左滑,响应效果不理想,特别是华为手机系统带左滑退出当前页面时;需要扩大滑动的识别区域

3 实现

  public static void setDrawerLeftEdgeSize(Activity activity, DrawerLayout drawerLayout, float displayWidthPercentage) {
        if (activity == null || drawerLayout == null) return;
        try {
            Field leftDraggerField = drawerLayout.getClass().getDeclaredField("mLeftDragger");
            leftDraggerField.setAccessible(true);
            ViewDragHelper leftDragger = (ViewDragHelper) leftDraggerField.get(drawerLayout);
            Field edgeSizeField = leftDragger.getClass().getDeclaredField("mEdgeSize");
            edgeSizeField.setAccessible(true);
            int edgeSize = edgeSizeField.getInt(leftDragger);
            DisplayMetrics dm = new DisplayMetrics();
            activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
            edgeSizeField.setInt(leftDragger, Math.max(edgeSize, (int) (dm.widthPixels * displayWidthPercentage)));
        } catch (Exception e) {
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

4 Demo

DrawerLayoutActivity

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/279432
推荐阅读
  

闽ICP备14008679号