一、普通侧滑
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"