一、普通侧滑
1、新建left_menu.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <LinearLayout android:layout_height="wrap_content" android:layout_width="match_parent" android:layout_centerInParent="true" android:orientation="vertical"> <TextView android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="row 1" android:textSize="30sp" android:layout_gravity="center" /> <TextView android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="row 2" android:textSize="30sp" android:layout_gravity="center" /> <TextView android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="row 3" android:textSize="30sp" android:layout_gravity="center" /> <TextView android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="row 4" android:textSize="30sp" android:layout_gravity="center" /> </LinearLayout> </RelativeLayout>
<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" tools:context="com.example.slidingmenu.MainActivity" > <com.example.slidingmenu.view.slidingMenu android:layout_width="match_parent" android:layout_height="match_parent" <pre name="code" class="html"><span style="white-space:pre"> </span> android:background="@drawable/menu"<span style="font-family: Arial, Helvetica, sans-serif;">></span><LinearLayout android:layout_width="wrap_content" android:layout_height="match_parent" android:orientation="horizontal"> <include layout="@layout/left_menu"/> <LinearLayout android:layout_width="match_parent"android:layout_height="match_parent" android:background="@drawable/main1"> </LinearLayout> </LinearLayout> </com.example.slidingmenu.view.slidingMenu> </RelativeLayout>
3.自定义HorizontalScrollView
自定义ViewGroup
(1)onMeasure(起到测量的作用)
决定内部view(子view)的宽和高,以及自己的宽和高
(2)onLayout
决定子view放置的位置
(3)onTouchEvent(在这里,要判断用户手指操作状态)
public class slidingMenu extends HorizontalScrollView { private LinearLayout mWapper; private ViewGroup mMenu; private ViewGroup mContent; private int screenWidth;//屏幕宽度 private int mMenuWidth;//menu宽度 private int menuRightPadding ;//menu与屏幕右侧边距 private boolean once = false;//防止onMeasure()多次调用 /** * 未使用自定义属性时调用 * @param context * @param attrs */ public slidingMenu(Context context, AttributeSet attrs) { super(context, attrs); this.setVerticalScrollBarEnabled(false);//去掉滚动条 //获取宽度 WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); DisplayMetrics outMetrics = new DisplayMetrics(); wm.getDefaultDisplay().getMetrics(outMetrics); screenWidth = outMetrics.widthPixels; //把dp转化为px,默认60dp menuRightPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 60, context.getResources().getDisplayMetrics()); } /** * 设置子view的宽和高,自己的宽和高 */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if(!once){ mWapper = (LinearLayout) getChildAt(0);//layout里第一个元素 mMenu = (ViewGroup) mWapper.getChildAt(0);//LinearLayout里第一个元素 mContent = (ViewGroup) mWapper.getChildAt(1);//LinearLayout里第一个元素 //menu的宽度 mMenuWidth = mMenu.getLayoutParams().width = screenWidth - menuRightPadding; mContent.getLayoutParams().width = screenWidth; 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);//将menu隐藏到左侧 } } @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); }else{ this.smoothScrollTo(0, 0); } return true; } return super.onTouchEvent(ev); } }
4、添加菜单切换按钮
(1)修改代码
public class slidingMenu extends HorizontalScrollView { private LinearLayout mWapper; private ViewGroup mMenu; private ViewGroup mContent; private int screenWidth; private int mMenuWidth; private int menuRightPadding ; private boolean once = false; private boolean isOpen ;//表示menu是否打开的状态 public slidingMenu(Context context, AttributeSet attrs) { super(context, attrs); WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); DisplayMetrics outMetrics = new DisplayMetrics(); wm.getDefaultDisplay().getMetrics(outMetrics); screenWidth = outMetrics.widthPixels; menuRightPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 80, 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); mMenuWidth = mMenu.getLayoutParams().width = screenWidth - menuRightPadding; mContent.getLayoutParams().width = screenWidth; once = true; } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @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;//实时改变isOpen状态 }else{ this.smoothScrollTo(0, 0); isOpen = true;//实时改变isOpen状态 } 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(); } } }(2) 添加 button
<Button android:onClick="toggleMenu" android:layout_width="80dp" android:layout_height="50dp" android:text="TOG"/>
(3)在MainActivity添加方法
public class MainActivity extends ActionBarActivity { private slidingMenu mMenu;//创建mMenu @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); mMenu = (slidingMenu) findViewById(R.id.menu); } public void toggleMenu(View view){ mMenu.toggle(); } }
二、抽屉侧滑
随着move,我们人为使menu偏移,所以看起来好像没动。。。。
在这里还要使用到nineoldandroids-2.4.0.jar 包实现属性动画效果,可以向下兼容
只需要重写slidingMenu的onScrollChanged()方法
<span style="white-space:pre"> </span>/** * 发生滚动时 */ @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 //调用属性动画,设置TranslationX ViewHelper.setTranslationX(mMenu, mMenuWidth*scale); }
android:background="@drawable/menu"
二、抽屉侧滑+缩放
<span style="white-space:pre"> </span>/** * 发生滚动时 */ @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 ViewHelper.setTranslationX(mMenu, mMenuWidth*scale*0.7f);//*0.7使得menu一部分从屏幕外被拉进来 //缩放部分,缩放前还要设置缩放中心点 float rightScale = 0.7f + 0.3f*scale;//用于content缩放 float leftScale = 1.0f - scale*0.3f;//用于menu缩放 float leftAlpha = 0.6f + 0.4f*(1-scale);//用于透明度 ViewHelper.setScaleX(mContent,leftScale); ViewHelper.setScaleY(mContent,leftScale); ViewHelper.setAlpha(mMenu,leftAlpha); ViewHelper.setPivotX(mContent, 0); ViewHelper.setPivotY(mContent, mContent.getHeight()/2); ViewHelper.setScaleX(mContent, rightScale); ViewHelper.setScaleY(mContent, rightScale); }
android:background="@drawable/menu"