本文参考幕课网讲师 hyman(同我新入行的小伙伴可以去关注他,写了很多教程)
主要是引用了一个动画包,为了兼容3.0以下版本
先看下效果图
自定义的slidingmenu
/** * 自定义ViewGroup 1.onMeasure(决定内部View(子view)的宽和高,以及自己的宽和高) 2.onLayout(决定子view的放置的位置) 3.onTouchEvent(控制手指抬起按下) 自定义属性 允许用户设置菜单离屏幕右边的边距 1.书写xml文件 values/attr.xml 2.在布局文件中进行使用,特别注意xmlns 3.在构造方法中(3个参数的构造方法)中获得我们设置的值 * @author chenxianda * */ public class SlidingMenu extends HorizontalScrollView{ /** * 屏幕宽度 * @param context */ private int mScreenWidth; /** * dp * @param context */ private int mMenuRightPadding = 50; /** * 菜单的宽度 * @param context */ private ViewGroup mMenu; private ViewGroup mContent; private LinearLayout mWapper; private int mMenuWidth; private int mHalfMenuWidth; private boolean isOpen; private boolean once; public SlidingMenu(Context context, AttributeSet attrs) { this(context, attrs,0); } /** * 当使用了自定义了属性时,会调用此构造方法 * @param context * @param attrs * @param defStyle */ public SlidingMenu(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); //获取我们定义的属性 TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.SlidingMenu, defStyle, 0); int n = a.getIndexCount(); for (int i = 0; i < n; i++) { int attr = a.getIndex(i); switch (attr) { case R.styleable.SlidingMenu_rightPadding: mMenuRightPadding = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, getResources().getDisplayMetrics())); break; default: break; } } a.recycle(); WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); DisplayMetrics outMetrics = new DisplayMetrics(); wm.getDefaultDisplay().getMetrics(outMetrics); mScreenWidth = outMetrics.widthPixels; //把转化为px } public SlidingMenu(Context context) { this(context,null); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (!once) { mWapper = (LinearLayout) getChildAt(0); mMenu = (ViewGroup) mWapper.getChildAt(0); mContent = (ViewGroup) mWapper.getChildAt(1); mMenuWidth =mMenu.getLayoutParams().width = mScreenWidth - mMenuRightPadding; mContent.getLayoutParams().width = mScreenWidth; once = true; } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } /** * 通过设置偏移量,将menu隐藏 */ @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) { this.smoothScrollTo(mMenuWidth, 0); isOpen = false; }else { this.smoothScrollTo(0, 0); isOpen = true; } return true; } return super.onTouchEvent(ev); } /** * 打开菜单 */ public void openMenu(){ if (isOpen) return; this.smoothScrollTo(0, 0); isOpen = true; } /** * 打开菜单 */ public void closeMenu(){ if (!isOpen)return; this.smoothScrollTo(mMenuWidth, 0); isOpen = false; } /** * 切换菜单 */ public void toggle(){ if (isOpen) { closeMenu(); }else { openMenu(); } } /** * 滚动发生时 * (以下说明是像QQ滑动有缩放等效果) * 区别1:内容区域1.0~0.7缩放的效果 scale:1.0~0.0 0.7+0.3*scale 区别2:菜单的偏移量需要修改 区别3:菜单的显示时有缩放以及透明度变化 缩放:0.7~1.0 1.0-scale*0.3 透明度0.6+0.4(1-scale); */ @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { super.onScrollChanged(l, t, oldl, oldt); float scale = l*1.0f/mMenuWidth;// 1~0 float rightScale = 0.7f+0.3f*scale; float leftScale = 1.0f-scale*0.3f; float leftAlpha = 0.6f+0.4f*(1-scale); //调用属性动画,设置Translation ViewHelper.setTranslationX(mMenu, mMenuWidth*scale*0.7f); //设置content的缩放的中心点 ViewHelper.setScaleX(mMenu, leftScale); ViewHelper.setScaleY(mMenu, leftScale); ViewHelper.setAlpha(mMenu, leftAlpha); ViewHelper.setPivotX(mContent, 0); ViewHelper.setPivotY(mContent, mContent.getHeight()/2); ViewHelper.setScaleX(mContent, rightScale); ViewHelper.setScaleY(mContent, rightScale); } }