前面有写过一篇文章使用DrawerLayout实现Android仿网易客户端抽屉模式,昨天从群里看一哥们问抽屉式拖拉,从主界面的下方出现,而使用DrawerLayout实现的是覆盖掉主界面,今天我们就来实现一下主界面下方脱出菜单界面,先上图,方便观看
啊哦,图片好大,开始今天的实现
1.继承HorizontalScrollView,实现自定义控件
package com.sdufe.thea.guo.view;
import com.nineoldandroids.view.ViewHelper;
import android.content.Context;
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;
public class SlidingMenu extends HorizontalScrollView {
private LinearLayout mWapper;
private ViewGroup mMenu;
private ViewGroup mContent;
/**
* 屏幕宽度
*/
private int mSreenWidth;
/**
* 菜单距离右侧的宽度,单位dp
*/
private int mMenuRightPadding=100;
/**
* 菜单宽度
*/
private int mMenuWidth;
/**
* 确定onMeasure只绘制一次
*/
private boolean once;
public SlidingMenu(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
WindowManager windowManager = (WindowManager) context
.getSystemService(context.WINDOW_SERVICE);
DisplayMetrics outMetrics=new DisplayMetrics();
windowManager.getDefaultDisplay().getMetrics(outMetrics);
mSreenWidth=outMetrics.widthPixels;
/**
* 把dp转化成px
*/
mMenuRightPadding = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 100, getResources()
.getDisplayMetrics());
}
public SlidingMenu(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public SlidingMenu(Context context) {
this(context, null);
}
/**
* 确定宽高
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (!once) {
mWapper=(LinearLayout) getChildAt(0);
mMenu=(ViewGroup) mWapper.getChildAt(0);
mContent=(ViewGroup) mWapper.getChildAt(1);
/**
* 菜单设置宽度
*/
mMenuWidth=mMenu.getLayoutParams().width=mSreenWidth-mMenuRightPadding;
/**
* 内容设置宽度
*/
mContent.getLayoutParams().width=mSreenWidth;
once=true;
}
}
/**
* 设置偏移量,隐藏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) {
switch (ev.getAction()) {
case MotionEvent.ACTION_UP:
/**
* 隐藏部分宽度
*/
int scroll=getScrollX();
if (scroll>mMenuWidth/2) {
/**
* 动画实现隐藏
*/
smoothScrollTo(mMenuWidth, 0);
}else {
/**
* 动画实现显示
*/
smoothScrollTo(0, 0);
}
return true;
}
return super.onTouchEvent(ev);
}
/**
* 通过onScrollChanged实现抽屉式滑动
*/
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
ViewHelper.setTranslationX(mMenu, l);
}
}
在构造函数中获得屏幕的宽度以及将dp为单位的mMenuRightPadding转化为px
onMeasure中给宽高赋值
onLayout中确定位置
onTouch中控制手势
onScrollChanged实现抽屉式动画,这里引用了nineold动画包,兼容3.0一下版本
剩余的部分代码中注释都说的很清楚了,这里就不在扯淡了,到此差不多就实现了,下面就是使用了,
<com.sdufe.thea.guo.view.SlidingMenu 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" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<include layout="@layout/layout_menu" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/monkey"
android:orientation="vertical" >
</LinearLayout>
</LinearLayout>
</com.sdufe.thea.guo.view.SlidingMenu>
ok,结束,以上代码修改自鸿洋的qq侧滑,略有不同而已
代码下载地址:http://download.csdn.net/detail/elinavampire/8276537