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)
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。