美文网首页
自定义ViewGroup--仿QQ5.0侧滑菜单

自定义ViewGroup--仿QQ5.0侧滑菜单

作者: XJ_crazy | 来源:发表于2018-11-19 10:49 被阅读0次
    76892386-9cb6-4d49-90e7-e71d6048bd96.gif

    说说实现流程:
    (1)为了适配效果更好一点,使用一下代码获取屏幕宽度

    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    DisplayMetrics outMetrics = new DisplayMetrics();
    wm.getDefaultDisplay().getMetrics(outMetrics);
    mScreenWidth = outMetrics.widthPixels;
    

    (2)设置Menu区域滑动之后距离屏幕右边的padding值

    //将dp转化成px
    mMenuRightPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, context.getResources().getDisplayMetrics());
    

    (3)重写onMeasure,设置menu和content的宽度

    @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    
            if (!once) {
                mWapper = (LinearLayout) getChildAt(0);
                mMenu = (ViewGroup) mWapper.getChildAt(0);
                mContent = (ViewGroup) mWapper.getChildAt(1);
    
                //显示设置子View的宽度
                mMenuWidth = mMenu.getLayoutParams().width = mScreenWidth - mMenuRightPadding;
                mContent.getLayoutParams().width = mScreenWidth;
                once = true;
            }
    
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    

    (4)重写onLayout,使得初始状态时,menu隐藏

     /**
         * 通过设置偏移量将menu隐藏
         * @param changed
         * @param l
         * @param t
         * @param r
         * @param b
         */
        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
    
            super.onLayout(changed, l, t, r, b);
    
            if (changed) {
                this.scrollTo(mMenuWidth, 0);
            }
        }
    
    

    (5)重写onTouchEvent,监听滑动距离,判定是打开menu还是关闭

     @Override
        public boolean onTouchEvent(MotionEvent ev) {
    
            int action = ev.getAction();
    
            switch (action) {
                case MotionEvent.ACTION_UP:
                    int scrollX = getScrollX();
                    if (scrollX >= mMenuWidth/2) {
                        smoothScrollTo(mMenuWidth, 0);
                    }else if (scrollX < mMenuWidth) {
                        smoothScrollTo(0, 0);
                    }
                    return true;
            }
    
            return super.onTouchEvent(ev);
        }
    

    (6)重写onScrollChanged,监听滑动状态并加上各动画

    @Override
        protected void onScrollChanged(int l, int t, int oldl, int oldt) {
    
            super.onScrollChanged(l, t, oldl, oldt);
    
            float scale = 1.0f * l / mMenuWidth; // 1~0,获取一个渐变scale,用于绘制各动画状态
    
            float scaleContent = 1f - (1 - scale) * 0.3f;// 1~0.7
            ObjectAnimator.ofFloat(mMenu, "translationX", mMenuWidth*scale*0.7f).setDuration(0).start();
    
            mContent.setPivotX(0);
            mContent.setPivotY(mContent.getHeight() / 2);
            ObjectAnimator.ofFloat(mContent, "scaleX", scaleContent).setDuration(0).start();
            ObjectAnimator.ofFloat(mContent, "scaleY", scaleContent).setDuration(0).start();
    
            mMenu.setPivotX(0);
            mMenu.setPivotY(mMenu.getHeight() / 2);
            ObjectAnimator.ofFloat(mMenu, "scaleX", 1.7f-scaleContent).setDuration(0).start();
            ObjectAnimator.ofFloat(mMenu, "scaleY", 1.7f-scaleContent).setDuration(0).start();
        }
    

    源码:

    package com.example.admin.myapplication.custom;
    
    import android.animation.ObjectAnimator;
    import android.content.Context;
    import android.support.v4.widget.ViewDragHelper;
    import android.util.AttributeSet;
    import android.util.DisplayMetrics;
    import android.util.Log;
    import android.util.TypedValue;
    import android.view.MotionEvent;
    import android.view.ViewGroup;
    import android.view.WindowManager;
    import android.widget.HorizontalScrollView;
    import android.widget.LinearLayout;
    
    public class MyHorizontalScrollView extends HorizontalScrollView {
    
    
        private LinearLayout mWapper;
        private ViewGroup mMenu;
        private ViewGroup mContent;
        private int mScreenWidth; //屏幕宽度
        private int mMenuWidth;
    
        //dp
        private int mMenuRightPadding = 50;
    
        private boolean once = false;
    
    
        public MyHorizontalScrollView(Context context) {
            this(context, null);
        }
    
        public MyHorizontalScrollView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public MyHorizontalScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
    
            WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            DisplayMetrics outMetrics = new DisplayMetrics();
            wm.getDefaultDisplay().getMetrics(outMetrics);
            mScreenWidth = outMetrics.widthPixels;
    
            //将dp转化成px
            mMenuRightPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, context.getResources().getDisplayMetrics());
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    
            if (!once) {
                mWapper = (LinearLayout) getChildAt(0);
                mMenu = (ViewGroup) mWapper.getChildAt(0);
                mContent = (ViewGroup) mWapper.getChildAt(1);
    
                //显示设置子View的宽度
                mMenuWidth = mMenu.getLayoutParams().width = mScreenWidth - mMenuRightPadding;
                mContent.getLayoutParams().width = mScreenWidth;
                once = true;
            }
    
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    
        /**
         * 通过设置偏移量将menu隐藏
         * @param changed
         * @param l
         * @param t
         * @param r
         * @param b
         */
        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
    
            super.onLayout(changed, l, t, r, b);
    
            if (changed) {
                this.scrollTo(mMenuWidth, 0);
            }
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent ev) {
    
            int action = ev.getAction();
    
            switch (action) {
                case MotionEvent.ACTION_UP:
                    int scrollX = getScrollX();
                    if (scrollX >= mMenuWidth/2) {
                        smoothScrollTo(mMenuWidth, 0);
                    }else if (scrollX < mMenuWidth) {
                        smoothScrollTo(0, 0);
                    }
                    return true;
            }
    
            return super.onTouchEvent(ev);
        }
    
        @Override
        protected void onScrollChanged(int l, int t, int oldl, int oldt) {
    
            super.onScrollChanged(l, t, oldl, oldt);
    
            float scale = 1.0f * l / mMenuWidth; // 1~0
    
            float scaleContent = 1f - (1 - scale) * 0.3f;// 1~0.7
            ObjectAnimator.ofFloat(mMenu, "translationX", mMenuWidth*scale*0.7f).setDuration(0).start();
    
            mContent.setPivotX(0);
            mContent.setPivotY(mContent.getHeight() / 2);
            ObjectAnimator.ofFloat(mContent, "scaleX", scaleContent).setDuration(0).start();
            ObjectAnimator.ofFloat(mContent, "scaleY", scaleContent).setDuration(0).start();
    
            mMenu.setPivotX(0);
            mMenu.setPivotY(mMenu.getHeight() / 2);
            ObjectAnimator.ofFloat(mMenu, "scaleX", 1.7f-scaleContent).setDuration(0).start();
            ObjectAnimator.ofFloat(mMenu, "scaleY", 1.7f-scaleContent).setDuration(0).start();
        }
    }
    

    布局文件

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".Main2Activity">
    
        <com.example.admin.myapplication.custom.MyHorizontalScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#FFD306">
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:orientation="horizontal">
    
                <include
                    layout="@layout/menu" />
    
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:orientation="vertical"
                    android:gravity="center"
                    android:background="#985687">
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="content"/>
                </LinearLayout>
    
            </LinearLayout>
        </com.example.admin.myapplication.custom.MyHorizontalScrollView>
    
    </RelativeLayout>
    

    相关文章

      网友评论

          本文标题:自定义ViewGroup--仿QQ5.0侧滑菜单

          本文链接:https://www.haomeiwen.com/subject/qdsofqtx.html