视频来源:http://www.imooc.com/video/4386
实现过程:主要是实现一个继承于HorizontalScrollView
的控件SlideMenu
,大致步骤:
- 重写
OnMeasure
方法来定义子View
的大小 - 重写
onLayout
方法来初始化子View
的位置 - 重写
onTouchEvent
方法来设置滑动事件 重写
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())
}
}
效果如图: