自己去定义一个SlidingMenu类继承自HorizontalScrollView,主要是在滑动过程中menu和content部分变化的一些动画,透明度啊,缩放之类的。
这里还要导入nineoldandroids-2.4.0.jar.
public class SlidingMenu extends HorizontalScrollView {
private LinearLayout mWapper;
private ViewGroup mMenu;
private ViewGroup mContent;
private int leftx;
private int mScreenWidth;
private int mMenuWidth;
private int mMenuLeftPadding = 80;
private boolean once = false;
private boolean isOpen = false;
/**
* by lijun
* 未使用自定义属性时使用
*/
public SlidingMenu(Context context, AttributeSet attrs)
{
this(context, attrs, 0);
}
public SlidingMenu(Context context, AttributeSet attrs,int defStyle) {
// TODO Auto-generated constructor stub
super(context, attrs,defStyle);
//获取我们定义的属性
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.SildingMenu, defStyle, 0);
int n = a.getIndexCount();
for (int i = 0; i < n; i++)
{
int attr = a.getIndex(i);
switch (attr)
{
case R.styleable.SildingMenu_rightPadding:
mMenuLeftPadding =a.getDimensionPixelOffset(attr,
(int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 80, context
.getResources().getDisplayMetrics()));//dp转换为px
break;
}
}
a.recycle();
WindowManager wm = (WindowManager) context
.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
mScreenWidth = outMetrics.widthPixels; //获取屏幕的宽高
}
public SlidingMenu(Context context) { //new的时候调用
// TODO Auto-generated constructor stub
super(context,null);
}
/**
* by lijun
* 设置子View的宽高设置自己的宽高
* @return
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
if(!once)
{
mWapper = (LinearLayout)getChildAt(0);
mMenu = (ViewGroup) mWapper.getChildAt(0);
mContent = (ViewGroup) mWapper.getChildAt(1);
mMenuWidth = mMenu.getLayoutParams().width = mScreenWidth - mMenuLeftPadding;
mContent.getLayoutParams().width = mScreenWidth;
once = true;
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
/**
* by lijun
* 通过设置偏移量,将menu隐藏
*/
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// TODO Auto-generated method stub
super.onLayout(changed, l, t, r, b);
if(changed)
{
this.scrollTo(mMenuWidth, 0);
}
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
// TODO Auto-generated method stub
int action = ev.getAction();
int xxxx = (int) ev.getX();
switch (action) {
case MotionEvent.ACTION_DOWN:
leftx = xxxx;
return true;
case MotionEvent.ACTION_UP:
int scrollX = getScrollX();
int lable = scrollX - leftx;
if(lable>0)
{
Log.i("aaaaaaaaa", scrollX+"okokokokok"+leftx);
if(scrollX >= mMenuWidth/2)
{
this.smoothScrollTo(mMenuWidth, 0); //带有动画效果的移动
isOpen = false;
}
else
{
this.smoothScrollTo(0, 0);
isOpen = true;
}
return true;
}
else
{
this.smoothScrollTo(0, 0);
}
default:
break;
}
return super.onTouchEvent(ev);
}
/**
* by lijun
* 打开菜单
*/
public void openMenu()
{
if(isOpen) return;
this.smoothScrollTo(0, 0);
isOpen = true;
}
public void closeMenu()
{
if(!isOpen) return;
this.smoothScrollTo(mMenuWidth, 0);
isOpen = false;
}
/**
* by lijun
* 切换菜单
*/
public void toggle()
{
if(isOpen)
{
closeMenu();
}else
{
openMenu();
}
}
/**
* by lijun
* 滚动发生时
*/
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);
/**主要代码部分
* by lijun
* 实现抽屉式拖拉
* 区别一:内容区域1.0-0。7的缩放效果
* scale:1.0-0.0
* 0.7+0.3*scale
* 区别二:菜单的偏移量需要修改
* 区别三:菜单的显示时有缩放以及透明度变化
* 缩放:0.7-1.0
* 1.0-scale*0.3
* 透明度0.6-1.0
* 0.6+0.4*(1-scale)
*/
float leftScale = 1.0f-0.3f*scale;
float leftAlpha = 0.5f+0.4f*(1-scale);
float rightScale = 0.7f+0.3f*scale;
ViewHelper.setTranslationX(mMenu, mMenuWidth*scale);
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);
}
}