仿QQ侧边栏滑动的实现

视频来源:http://www.imooc.com/video/4386
实现过程:主要是实现一个继承于HorizontalScrollView 的控件SlideMenu ,大致步骤:

  1. 重写OnMeasure 方法来定义子View的大小
  2. 重写onLayout 方法来初始化子View的位置
  3. 重写onTouchEvent 方法来设置滑动事件
  4. 重写onScrollChanged 方法来设置滑动动画,以达到菜单栏左端固定于屏幕左侧出现(而不是菜单栏从右侧开始慢慢出现),以及相应的缩放、透明度设置。这里需要引入NineOldAndroid包

    代码如下:

class SlideMenu:HorizontalScrollView {
    var mWapper:LinearLayout?=null
    var mMenu:ViewGroup?=null
    var mContent:ViewGroup?=null
    var mScreenWidth:Int=0
    var once=0
    //dp
    var mMenuRightPadding=0
    constructor(context: Context,attributeSet: AttributeSet) : super(context,attributeSet){
        val wm:WindowManager= context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
        val outMetrics:DisplayMetrics= DisplayMetrics()
        wm.defaultDisplay.getMetrics(outMetrics)
        mScreenWidth=outMetrics.widthPixels
        //把dp、sp转化为px
        mMenuRightPadding= TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50F,context.resources.displayMetrics ).toInt()
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        if (once==0)
        {
            mWapper= getChildAt(0) as LinearLayout?
            mMenu= mWapper?.getChildAt(0) as ViewGroup?
            mContent= mWapper?.getChildAt(1) as ViewGroup?
            mMenu?.layoutParams?.width=mScreenWidth-mMenuRightPadding
            mContent?.layoutParams?.width=mScreenWidth
            once=1
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
    }

//    设置偏移量将menu隐藏
    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {

        super.onLayout(changed, l, t, r, b)
        if (changed)
        {
            scrollTo(mMenu?.layoutParams?.width!!,0)
        }
    }

    override fun onTouchEvent(ev: MotionEvent?): Boolean {
        val action=ev?.action
        when (action)
        {
            MotionEvent.ACTION_UP->{
                //隐藏部分大于菜单栏一般
                if (scrollX >= (mMenu?.layoutParams?.width!! /2))
                {
                    smoothScrollTo(mMenu?.layoutParams?.width!!,0)
                }
                else
                {
                    smoothScrollTo(0,0)
                }
                return true
            }
        }
        return super.onTouchEvent(ev)
    }

    override fun onScrollChanged(l: Int, t: Int, oldl: Int, oldt: Int) {
        super.onScrollChanged(l, t, oldl, oldt)
        val scale=l.toFloat()/mMenu?.layoutParams?.width!!
        ViewHelper.setTranslationX(mMenu, scale*mMenu?.layoutParams?.width!!*0.7f)
        val rightScale=0.7f+0.3f*scale
        ViewHelper.setScaleX(mContent,rightScale)
        ViewHelper.setScaleY(mContent,rightScale)
        ViewHelper.setPivotX(mContent, 0f)
        ViewHelper.setPivotY(mContent, (mContent?.height!! /2).toFloat())
        val leftScale=1.0f-scale*0.3f
        ViewHelper.setScaleX(mMenu,leftScale)
        ViewHelper.setScaleY(mMenu,leftScale)
        ViewHelper.setAlpha(mMenu,leftScale)
        ViewHelper.setPivotX(mMenu, 0f)
        ViewHelper.setPivotY(mMenu, (mMenu?.height!! /2).toFloat())

    }


}

效果如图:
这里写图片描述
这里写图片描述
这里写图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值