/*
* 自定义的ViewGroup
*
* 1/onMeasure
* 决定内部的子View的宽和高,以及最后决定自己的宽和高
*
* 2/onLayout
* 决定子View的摆放位置
*
* 3/onTouchEvent
*
*/
import com.nineoldandroids.view.ViewHelper;
import android.content.Context;
import android.content.res.Resources;
import android.text.method.MovementMethod;
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 WindowWidth;
//单位是dp,但是我们要px,需要转化
private int mMenuRightPadding = 50;
private int mMenuWidth;
private boolean once;
private boolean isOpen;
/**
* 未使用自定义属性是,调用两个参数的构造方法
* @param context
* @param attrs
*/
public SlidingMenu(Context context, AttributeSet attrs) {
super(context, attrs);
getResources();
/**
* Activity类里面有getSystemService方法,Context类下也有getSystemService方法
*
* 两个getSystemService的参数是Context.xxx 如Context.WINDOW_SERVICE Context.LOCATION_SEVICE
*/
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
WindowWidth = outMetrics.widthPixels;
/**
* context有getResource方法,View也有getResource方法,Activity也有getResource方法
*/
//把dp转化为px
mMenuRightPadding =
(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, context.getResources().getDisplayMetrics());
}
/*
* 设置子view的宽和高,设置自己的宽和高
* @see android.widget.HorizontalScrollView#onMeasure(int, int)
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
/**
* onMeasure会被多次调用,为避免每次都设置一下宽和高,使用once
*/
if(!once){
/*
* ViewGroup下的getChildAt(index)方法 ,返回值类型为View
*/
//HorizontalScrollView里面有且只有一个LinearLayout
mWapper = (LinearLayout) getChildAt(0);
mMenu = (ViewGroup) mWapper.getChildAt(0);
mContent = (ViewGroup) mWapper.getChildAt(1);
/*
* View下面的getLayoutParams()方法,返回类型为ViewGroup.LayoutParams
*/
mMenuWidth = mMenu.getLayoutParams().width = WindowWidth - mMenuRightPadding;
mContent.getLayoutParams().width = WindowWidth;
//mWapper里面有mMenu和mContent,就不显示设置自己了
once = true;
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
/***
* 设置偏移量,将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){
/*
* x为正,内容区向左移动
*/
this.scrollTo(mMenuWidth, 0);
}
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
// TODO Auto-generated method stub
int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_UP:
int scrollX = getScrollX();//获取当前所处的X坐标
if(scrollX > mMenuWidth/2){
this.smoothScrollTo(mMenuWidth, 0);
isOpen = false;
}
else{
this.smoothScrollTo(0, 0);
isOpen = true;
}
return true;
default:
break;
}
return super.onTouchEvent(ev);
}
public void openMenu(){
if(isOpen){
}
else{
this.smoothScrollTo(0, 0);
isOpen = true;
}
}
public void closeMenu(){
if(isOpen){
this.smoothScrollTo(mMenuWidth, 0);
isOpen = false;
}
}
public void switchMenu(){
if(isOpen){
closeMenu();
}
else{
openMenu();
}
}
/*
* 滚动发生时,不管是自动滚动还是手动滚动
* (non-Javadoc)
* @see android.view.View#onScrollChanged(int, int, int, int)
*/
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
// TODO Auto-generated method stub
super.onScrollChanged(l, t, oldl, oldt);
/*
* 调用属性动画,设置TranslationX
*
* PS:Translation意思是平移
*/
float scale = (float) (1.0*l/mMenuWidth); //由于l的变化,是scale在0-1之间变化
ViewHelper.setTranslationX(mMenu, (float) (mMenuWidth*scale*0.7));
/*直接mMenu.setTranslationX(l);兼容到3.0,
或者ViewHelper.setTransklationX(mMenu, l);兼容到2.0,
*
*/
float mContentScale = (float) (0.7 + 0.3 * scale);
ViewHelper.setScaleX(mContent, mContentScale);
ViewHelper.setScaleY(mContent, mContentScale);
ViewHelper.setPivotX(mContent, 0);
ViewHelper.setPivotY(mContent, (float) (1.0* mContent.getHeight() / 2));
float mMenuScale = (float) (1.0 - 0.3 * scale);
ViewHelper.setScaleX(mMenu, mMenuScale);
ViewHelper.setScaleY(mMenu, mMenuScale);
ViewHelper.setPivotX(mMenu, 0);
ViewHelper.setPivotY(mMenu, (float) (1.0*mMenu.getHeight()/2));
float mMenuAlpha = (float) (1.0 - 0.3 * scale);
ViewHelper.setAlpha(mMenu, mMenuAlpha);
ViewHelper.setPivotX(mMenu, 0);
ViewHelper.setPivotY(mMenu, (float) (1.0*mMenu.getHeight()/2));
}
/**
* QQ5.0抽屉式效果,显示菜单时,菜单区大小比例由0.7到1.0,
* 内容区大小比例由1.0到0.7,菜单区透明度由0.7到1.0
* float scale 1.0-0.0
* float mMenuScale = 0.7 + 0.3 * scale
* float mContentScale = 1.0 - 0.3 * scale
* float mMenuAlpha = 0.7 + 0.3 * scale
*/
}
模仿QQ5.0侧滑菜单栏
最新推荐文章于 2024-09-27 15:39:55 发布