Android实现网易新闻客户端侧滑菜单(2)
前面已经讲过通过三方开源库SlideMenu来实现这种效果,请参考Android实现网易新闻客户端侧滑菜单(一)
今天通过自定义View来实现这种功能。
代码如下:
SlideMenu.java
packagecom.jackie.slidemenu.view; importandroid.content.Context; importandroid.graphics.Canvas; importandroid.util.AttributeSet; importandroid.view.MotionEvent; importandroid.view.View; importandroid.view.ViewConfiguration; importandroid.view.ViewGroup; importandroid.widget.Scroller; publicclassSlideMenuextendsViewGroup{ privateintmMostRecentX;//最后一次x轴的偏移量 privatefinalintMENU_SCREEN=0;//菜单界面 privatefinalintMAIN_SCREEN=1;//主界面 privateintmCurrentScreen=MAIN_SCREEN;//当前屏幕显示的是主界面 privateScrollermScroller; privateinttouchSlop; publicSlideMenu(Contextcontext,AttributeSetattrs){ super(context,attrs); mScroller=newScroller(context); touchSlop=ViewConfiguration.get(context).getScaledTouchSlop(); } /** *测量出所有子布局的宽和高 */ @Override protectedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec){ super.onMeasure(widthMeasureSpec,heightMeasureSpec); measureView(widthMeasureSpec,heightMeasureSpec); } /** *测量所有子布局的宽和高 *@paramwidthMeasureSpec父布局也就是ViewGroup的宽度测量规格 *@paramheightMeasureSpec父布局也就是ViewGroup的高度测量规格 */ privatevoidmeasureView(intwidthMeasureSpec,intheightMeasureSpec){ //测量菜单的宽和高 ViewmenuView=getChildAt(0); menuView.measure(menuView.getLayoutParams().width,heightMeasureSpec); //测量主界面的宽和高 ViewmainView=getChildAt(1); mainView.measure(widthMeasureSpec,heightMeasureSpec);//主界面的宽和高和父控件viewgroup的宽高一样 } @Override protectedvoidonLayout(booleanchanged,intl,intt,intr,intb){ //布置菜单的位置 ViewmenuView=getChildAt(0); menuView.layout(-menuView.getMeasuredWidth(),0,0,b); //布置主界面的位置 ViewmainView=getChildAt(1); mainView.layout(0,0,r,b); } @Override publicbooleanonTouchEvent(MotionEventevent){ switch(event.getAction()){ caseMotionEvent.ACTION_DOWN: mMostRecentX=(int)event.getX(); break; caseMotionEvent.ACTION_MOVE: //最新的x轴偏移量 intmoveX=(int)event.getX(); //增量值 intdeltaX=mMostRecentX-moveX; //把最新的x轴偏移量赋值给成员变量 mMostRecentX=moveX; //得到x轴移动后的偏移量 intnewScrollX=getScrollX()+deltaX; if(newScrollX<-getChildAt(0).getWidth()){//当前屏幕x轴的偏移量超过了菜单的左边界 //回到菜单的左边界位置 scrollTo(-getChildAt(0).getWidth(),0); }elseif(newScrollX>0){//超过了主界面的右边界 //回到主界面的右边界 scrollTo(0,0); }else{ scrollBy(deltaX,0); } break; caseMotionEvent.ACTION_UP: intscrollX=getScrollX();//x轴最新的偏移量 intmenuXCenter=-getChildAt(0).getWidth()/2;//菜单x轴的中心点 if(scrollX>menuXCenter){//切换到主界面 mCurrentScreen=MAIN_SCREEN; }else{//切换到菜单界面 mCurrentScreen=MENU_SCREEN; } switchScreen(); break; default: break; } returntrue; } /** *根据mCurrentScreen切换屏幕 */ privatevoidswitchScreen(){ intscrollX=getScrollX();//当前x轴的偏移量 intdx=0; if(mCurrentScreen==MAIN_SCREEN){//切换到主界面 //scrollTo(0,0); dx=0-scrollX; }elseif(mCurrentScreen==MENU_SCREEN){//切换到菜单界面 //scrollTo(-getChildAt(0).getWidth(),0); dx=-getChildAt(0).getWidth()-scrollX; } mScroller.startScroll(scrollX,0,dx,0,Math.abs(dx)*5); invalidate();//invalidate->drawChild->child.draw->computeScroll } /** *invalidate出发此方法,更新屏幕的x轴的偏移量 */ @Override publicvoidcomputeScroll(){ if(mScroller.computeScrollOffset()){//判断是否正在模拟数据中,true正在进行false数据模拟完毕 scrollTo(mScroller.getCurrX(),0); invalidate();//引起computeScroll的调用 } } /** *是否显示菜单 *@return */ publicbooleanisShowMenu(){ returnmCurrentScreen==MENU_SCREEN; } /** *隐藏菜单 */ publicvoidhideMenu(){ mCurrentScreen=MAIN_SCREEN; switchScreen(); } /** *显示菜单 */ publicvoidshowMenu(){ mCurrentScreen=MENU_SCREEN; switchScreen(); } /** *拦截事件的方法 */ @Override publicbooleanonInterceptTouchEvent(MotionEventev){ switch(ev.getAction()){ caseMotionEvent.ACTION_DOWN: mMostRecentX=(int)ev.getX(); break; caseMotionEvent.ACTION_MOVE: intdiffX=(int)(ev.getX()-mMostRecentX); if(Math.abs(diffX)>touchSlop){ returntrue; } break; default: break; } returnsuper.onInterceptTouchEvent(ev); } }
MainActivity.java
packagecom.jackie.slidemenu; importcom.jackie.slidemenu.view.SlideMenu; importandroid.os.Bundle; importandroid.app.Activity; importandroid.view.Menu; importandroid.view.View; importandroid.view.View.OnClickListener; importandroid.view.Window; importandroid.widget.TextView; importandroid.widget.Toast; publicclassMainActivityextendsActivityimplementsOnClickListener{ privateSlideMenumSlideMenu; @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); //去除标题,需要在setContentView之前调用 requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); mSlideMenu=(SlideMenu)findViewById(R.id.slidemenu); findViewById(R.id.iv_slidemenu_main_back).setOnClickListener(this); } @Override publicbooleanonCreateOptionsMenu(Menumenu){ //Inflatethemenu;thisaddsitemstotheactionbarifitispresent. getMenuInflater().inflate(R.menu.main,menu); returntrue; } @Override publicvoidonClick(Viewv){ if(mSlideMenu.isShowMenu()){ mSlideMenu.hideMenu(); }else{ mSlideMenu.showMenu(); } } publicvoidclick(Viewv){ TextViewtv=(TextView)v; Toast.makeText(this,tv.getText(),0).show(); } }
系列文章:
Android实现网易新闻客户端效果
Android实现网易新闻客户端侧滑菜单(1)
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。