CustomSidingView.class
/** * */ package com.test.sildingmenu.view; import com.nineoldandroids.view.ViewHelper; import com.test.sildingmenu.R; import android.content.Context; import android.content.res.TypedArray; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.TypedValue; import android.view.MotionEvent; import android.view.ViewGroup; import android.view.WindowManager; import android.widget.HorizontalScrollView; import android.widget.LinearLayout; /** * @author wanggenping * 自定义属性(普通侧滑菜单) */ public class CustomSidingView extends HorizontalScrollView { private LinearLayout layout;// 包含在SidingView内的LinearLayout private ViewGroup mMenu;// 左侧菜单 private ViewGroup mContent;// 主页面 private int mScreenWidth;// 屏幕宽度 private int mMenuWidth; // dp private int mMenuRightPadding; private boolean once; private boolean isOpen; /** * 未使用自定义属性时调用此构造方法 * * @param context * @param attrs * (属性) */ public CustomSidingView(Context context, AttributeSet attrs) { this(context, attrs, 0); } /** * 当使用了自定义的属性时会调用此构造方法 * * @param context * @param attrs * @param defStyle */ public CustomSidingView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // 获取我们定义的属性 TypedArray array = context.getTheme().obtainStyledAttributes(attrs, R.styleable.SildingMenu, defStyle, 0); //自定义属性中的个数 int n = array.getIndexCount(); for (int i = 0; i < n; i++) { int attr = array.getIndex(i); switch (attr) { case R.styleable.SildingMenu_rightPadding: mMenuRightPadding = array.getDimensionPixelSize(attr, (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 50, context .getResources().getDisplayMetrics())); break; default: break; } } array.recycle(); WindowManager wm = (WindowManager) context .getSystemService(Context.WINDOW_SERVICE); DisplayMetrics outMetrics = new DisplayMetrics(); wm.getDefaultDisplay().getMetrics(outMetrics); mScreenWidth = outMetrics.widthPixels; } public CustomSidingView(Context context) { this(context, null); } /** * 设置子View的宽和高 设置自己的宽和高 */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // 由于onMeasure()方法可能被多长调用,所以我们这里只设置一次宽和高,不多长设置 if (!once) { layout = (LinearLayout) getChildAt(0); // layout中的第一个元素(即:menu) mMenu = (ViewGroup) layout.getChildAt(0); // layout中的第二个元素(即:主界面) mContent = (ViewGroup) layout.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) { // menu初始状态,隐藏 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 { // 显示menu this.smoothScrollTo(0, 0); isOpen = true; } return true; } return super.onTouchEvent(ev); } /** *打开菜单 */ public void openMenu(){ if(isOpen){ return; }else{ this.smoothScrollTo(0, 0); isOpen = true; } } /** *关闭菜单 */ public void closeMenu(){ if(!isOpen){ return; }else{ this.smoothScrollTo(mMenuWidth, 0); isOpen = false; } } /** *切换菜单 */ public void toggle(){ if(isOpen){ closeMenu(); }else{ openMenu(); } } /** *抽屉式的侧滑效果需要此重新此方法,里面添加属性动画 * */ @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { // l = getScrollX(); super.onScrollChanged(l, t, oldl, oldt); float scale = l*1.0f/mMenuWidth;//1-0 //引入属性动画的jar包(由于属性动画支持3.0以上,所以需要向下兼容的话需要引入nineoldandroids-2.4.0.jar包) /* qq版侧滑与抽屉式侧滑的区别 区别1;内容区域1.0-0.7的缩放 scale:1.0-0.0 0.7+0.3*scale 区别2:菜单的偏移量需要修改 区别3:菜单显示时有缩放及透明度的变化 缩放0.7-1.0 1.0-0.3*scale 透明度:0.6-1.0 1。0-0.4*scale */ ViewHelper.setTranslationX(mMenu, mMenuWidth*scale*0.7f);//qq方式的偏移量 //内容区域的缩放 float rightScale = 0.7f+0.3f*scale; //设置缩放中心点,如果不设置会平移到屏幕右边缘(由于缩放的原因) ViewHelper.setPivotX(mContent, 0); ViewHelper.setPivotY(mContent, mContent.getHeight()/2); ViewHelper.setScaleX(mContent, rightScale); ViewHelper.setScaleY(mContent, rightScale); //菜单的缩放 float leftScale = 1.0f-0.3f*scale; ViewHelper.setScaleX(mMenu, leftScale); ViewHelper.setScaleY(mMenu, leftScale); //菜单的透明度 float leftAlpha = 1.0f-0.4f*scale; ViewHelper.setAlpha(mMenu, leftAlpha); } }
attrs.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="SildingMenu"> <attr name="rightPadding" format="dimension"/> </declare-styleable> </resources>
左侧菜单布局文件 view_side_menu.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center_vertical"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/view_side_menu_one_layout" android:padding="15dp"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/view_side_menu_image1" android:src="@drawable/icon_base_info" android:layout_alignParentLeft="true" android:layout_centerVertical="true"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/view_side_menu_text1" android:layout_toRightOf="@+id/view_side_menu_image1" android:layout_marginLeft="7dp" android:text="第一个item" android:layout_centerVertical="true" android:textColor="#fff" android:textSize="20sp"/> </RelativeLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/view_side_menu_two_layout" android:padding="15dp"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/view_side_menu_image2" android:src="@drawable/icon_borrow_description" android:layout_alignParentLeft="true" android:layout_centerVertical="true"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/view_side_menu_text2" android:layout_toRightOf="@+id/view_side_menu_image2" android:layout_marginLeft="7dp" android:text="第二个item" android:layout_centerVertical="true" android:textColor="#fff" android:textSize="20sp"/> </RelativeLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/view_side_menu_three_layout" android:padding="15dp"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/view_side_menu_image3" android:src="@drawable/icon_borrow_user_info" android:layout_alignParentLeft="true" android:layout_centerVertical="true"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/view_side_menu_text3" android:layout_toRightOf="@+id/view_side_menu_image3" android:layout_marginLeft="7dp" android:text="第三个item" android:layout_centerVertical="true" android:textColor="#fff" android:textSize="20sp"/> </RelativeLayout> </LinearLayout>
MainActivity.class
package com.test.sildingmenu; import com.test.sildingmenu.view.CustomSidingView; import android.support.v7.app.ActionBarActivity; import android.view.View; import android.os.Bundle; public class MainActivity extends ActionBarActivity { private CustomSidingView menu; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); menu = (CustomSidingView) findViewById(R.id.activity_main_scrollview); } public void toggleMenu(View view){ menu.toggle(); } }
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res/com.test.sildingmenu" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/main_bg"> <com.test.sildingmenu.view.CustomSidingView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/activity_main_scrollview" android:scrollbars="none" app:rightPadding="80dp"> <LinearLayout android:layout_width="wrap_content" android:layout_height="match_parent" android:id="@+id/activity_main_layout" android:orientation="horizontal"> <include android:layout_width="wrap_content" android:layout_height="match_parent" android:id="@+id/activity_main_side_menu" layout="@layout/view_side_menu"/> <LinearLayout android:layout_width="wrap_content" android:layout_height="match_parent" android:id="@+id/activity_main_main_layout" android:background="@drawable/loading_bg" android:orientation="vertical"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="toggleMenu" android:text="切换菜单"/> </LinearLayout> </LinearLayout> </com.test.sildingmenu.view.CustomSidingView > </RelativeLayout>