标签:
触摸事件
<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=".MainActivity" ><com.ly.slidemenu.view.SlideMenuandroid:id="@+id/slideMenu"android:layout_width="match_parent"android:layout_height="match_parent" ><!-- 菜单界面的布局 --><include layout="@layout/layout_menu"/><!-- 主界面的布局 --><include layout="@layout/layout_main"/></com.ly.slidemenu.view.SlideMenu></RelativeLayout>
public class SlideMenu extends FrameLayout{private View menuView,mainView;private int menuWidth = 0;private Scroller scroller;public SlideMenu(Context context, AttributeSet attrs) {super(context, attrs);init();}public SlideMenu(Context context) {super(context);init();}private void init(){scroller = new Scroller(getContext());}/*** 当1级的子view全部加载完调用,可以用初始化子view的引用,view.inflate完后* 注意,这里无法获取子view的宽高*/@Overrideprotected void onFinishInflate() {super.onFinishInflate();menuView = getChildAt(0);mainView = getChildAt(1);menuWidth = menuView.getLayoutParams().width;//可以通过这样获得}/*** widthMeasureSpec和heightMeasureSpec是系统测量SlideMenu时传入的参数,* 这2个参数测量出的宽高能让SlideMenu充满窗体,其实是正好等于屏幕宽高*///继承已有viewgroup就不需要这些了,相对布局也行,但是桢布局更快// @Override// protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {// super.onMeasure(widthMeasureSpec, heightMeasureSpec);//// int measureSpec = MeasureSpec.makeMeasureSpec(menuWidth, MeasureSpec.EXACTLY);//// //测量所有子view的宽高// //通过getLayoutParams方法可以获取到布局文件中指定宽高// menuView.measure(measureSpec, heightMeasureSpec);// //直接使用SlideMenu的测量参数,因为它的宽高都是充满父窗体// mainView.measure(widthMeasureSpec, heightMeasureSpec);//// }//为了侧边栏可以上下滑动菜单,可以根据移动的值处理掉事件,其他情况下不处理,交给主页面@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {switch (ev.getAction()) {case MotionEvent.ACTION_DOWN:downX = (int) ev.getX();break;case MotionEvent.ACTION_MOVE:int deltaX = (int) ( ev.getX()- downX);if(Math.abs(deltaX)>8){return true;}break;}return super.onInterceptTouchEvent(ev);// return super.onInterceptTouchEvent(ev);}/*** l: 当前子view的左边在父view的坐标系中的x坐标* t: 当前子view的顶边在父view的坐标系中的y坐标*/@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {// Log.e("MAIN", "L: "+l+" t: "+t +" r: "+r + " b: "+b);menuView.layout(-menuWidth, 0, 0, menuView.getMeasuredHeight());mainView.layout(0, 0, r, b);}private int downX;@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:downX = (int) event.getX();break;case MotionEvent.ACTION_MOVE:int moveX = (int) event.getX();int deltaX = (int) ( moveX- downX);int newScrollX = getScrollX() - deltaX;//移动的距离,每次移动都不一样,所以需要计算下新的if(newScrollX<-menuWidth)newScrollX = -menuWidth;if(newScrollX>0)newScrollX = 0;Log.e("Main", "scrollX: "+getScrollX());scrollTo(newScrollX, 0);downX = moveX;break;case MotionEvent.ACTION_UP://1.使用自定义动画// ScrollAnimation scrollAnimation;// if(getScrollX()>-menuWidth/2){// //关闭菜单//// scrollTo(0, 0);// scrollAnimation = new ScrollAnimation(this, 0);// }else {// //打开菜单//// scrollTo(-menuWidth, 0);// scrollAnimation = new ScrollAnimation(this, -menuWidth);// }// startAnimation(scrollAnimation);//2.使用Scrollerif(getScrollX()>-menuWidth/2){// //关闭菜单closeMenu();}else {//打开菜单openMenu();}break;}return true;}private void closeMenu(){scroller.startScroll(getScrollX(), 0, 0-getScrollX(), 0, 400);//持续的时间invalidate();}private void openMenu(){scroller.startScroll(getScrollX(), 0, -menuWidth-getScrollX(), 0, 400);invalidate();}/*** Scroller不主动去调用这个方法* 而invalidate()可以掉这个方法* invalidate->draw->computeScroll*/@Overridepublic void computeScroll() {super.computeScroll();if(scroller.computeScrollOffset()){//返回true,表示动画没结束scrollTo(scroller.getCurrX(), 0);invalidate();}}/*** 切换菜单的开和关*/public void switchMenu() {if(getScrollX()==0){//需要打开openMenu();}else {//需要关闭closeMenu();}}}
/*** 让指定view在一段时间内scrollTo到指定位置* @author Administrator**/public class ScrollAnimation extends Animation{private View view;private int targetScrollX;private int startScrollX;private int totalValue;public ScrollAnimation(View view, int targetScrollX) {super();this.view = view;this.targetScrollX = targetScrollX;startScrollX = view.getScrollX();totalValue = this.targetScrollX - startScrollX;int time = Math.abs(totalValue);setDuration(time);}/*** 在指定的时间内一直执行该方法,直到动画结束* interpolatedTime:0-1 标识动画执行的进度或者百分比* time : 0 - 0.5 - 0.7 - 1* value: 10 - 60 - 80 - 110* 当前的值 = 起始值 + 总的差值*interpolatedTime*/@Overrideprotected void applyTransformation(float interpolatedTime,Transformation t) {super.applyTransformation(interpolatedTime, t);int currentScrollX = (int) (startScrollX + totalValue*interpolatedTime);view.scrollTo(currentScrollX, 0);}}
public class MainActivity extends Activity {private ImageView btn_back;private SlideMenu slideMenu;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);setContentView(R.layout.activity_main);btn_back = (ImageView) findViewById(R.id.btn_back);slideMenu = (SlideMenu) findViewById(R.id.slideMenu);btn_back.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {slideMenu.switchMenu();}});}}
标签:
原文地址:http://www.cnblogs.com/liuyu0529/p/5041931.html