不知不觉已经工作一个月了,时间过的真快,提早一年步入社会,心里感触还是挺大了,所有的一切都没有了在学校的那种感觉 .....
废话不多说,在公司做android的时候用到这个侧滑,公司里用的是开源框架,SlidingMenu,自己也尝试着去引用,感觉自己基础不好,实现起来十分费劲。
无意之中,发现黑马老师的视频里有这个就听了下,基本照写了一遍,代码就放在这里,方便自己查看,复习,也方便像我这样的android小白,来研究学习。
主界面:
package com.tai.dandelion;import com.tai.dandelion.view.SlideMenu;import android.os.Bundle;import android.app.Activity;import android.view.KeyEvent;import android.view.Menu;import android.view.View;import android.view.View.OnClickListener;import android.view.ViewGroup;import android.view.Window;import android.widget.ImageView;import android.widget.TextView;import android.widget.Toast;public class MainActivity extends Activity implements OnClickListener{ private SlideMenu viewGroup;//这就是下面自定义ViewGroup private ImageView slidingmenu; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //去除标题 一定要在setContentView之前 requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); viewGroup = (SlideMenu) findViewById(R.id.slidmenu); slidingmenu = (ImageView) findViewById(R.id.iv_slidmenu_back); slidingmenu.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.iv_slidmenu_back: if(viewGroup.isShow()) { viewGroup.showMenu(); } else { viewGroup.hideMenu(); } break; default: break; } }@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event){ if (keyCode == KeyEvent.KEYCODE_MENU) { if(viewGroup.isShow()) { viewGroup.showMenu(); } else { viewGroup.hideMenu(); } return true; } return super.onKeyDown(keyCode, event);}//菜单的点击事件,在与布局文件中对应,这里的方法名与xml中的方法名对应。public void click(View v){ TextView tv = (TextView) v; Toast.makeText(this, tv.getText(), Toast.LENGTH_SHORT).show();}}
侧滑菜单:ViewGroup
1 package com.tai.dandelion.view; 2 3 import android.content.Context; 4 import android.util.AttributeSet; 5 import android.view.MotionEvent; 6 import android.view.View; 7 import android.view.ViewConfiguration; 8 import android.view.ViewGroup; 9 import android.widget.Scroller; 10 11 public class SlideMenu extends ViewGroup 12 { 13 private int touchSlop; 14 public SlideMenu(Context context, AttributeSet attrs) 15 { 16 super(context, attrs); 17 mScroller = new Scroller(context); 18 //startX, startY, dx, dy,duration 19 //滑动间距的距离 默认为8 20 touchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); 21 } 22 23 //测量出所有子布局的宽和高 24 @Override 25 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 26 { 27 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 28 //这个super必须要重写的 29 measureView(widthMeasureSpec,heightMeasureSpec); 30 } 31 /** 32 * int widthMeasureSpec, int heightMeasureSpec 33 * @param widthMeasureSpec 父布局的测量 34 * @param heightMeasureSpec 35 */ 36 private void measureView(int widthMeasureSpec, int heightMeasureSpec) 37 { 38 //测量菜单布局 39 View menuView = getChildAt(0); 40 menuView.measure(menuView.getLayoutParams().width, heightMeasureSpec); 41 //测量主界面的布局 42 View mainView = getChildAt(1); 43 mainView.measure(widthMeasureSpec, heightMeasureSpec); 44 45 } 46 //设置菜单和主界面的布局 47 @Override 48 protected void onLayout(boolean chenged, int l, int t, int r, int b) 49 { 50 //布置菜单的位置 51 View menuView = getChildAt(0); 52 //得到测量之后的边长 53 menuView.layout(-menuView.getMeasuredWidth(), 0, 0, b); 54 //布置主界面的位置 55 View mainView =getChildAt(1); 56 57 mainView.layout(0, 0, r, b); 58 59 } 60 private int mMostRecentX;//最后一次的X轴偏移量 61 private int MenuScreen = 0;//菜单页面 62 private int MainScreen = 1;//主界面 63 private int mCurrentScreen = MainScreen;//当前屏幕的主界面 64 //定义数据模拟器 来动态模拟数据的增量 65 private Scroller mScroller; 66 67 @Override 68 public boolean onTouchEvent(MotionEvent event) 69 { 70 switch (event.getAction()) 71 { 72 case MotionEvent.ACTION_DOWN: 73 mMostRecentX = (int) event.getX(); 74 break; 75 case MotionEvent.ACTION_MOVE: 76 //最新的X轴偏移量 77 int moveX = (int) event.getX(); 78 //增量值 79 int detaX = mMostRecentX - moveX; 80 //把最新的X轴偏移量赋值给最后一次的X轴偏移量 81 mMostRecentX = moveX; 82 83 //得到X轴移动后的偏移量 84 int newScrolLX = (int) (getScrollX() + detaX); 85 //当前X轴的偏移量超过了菜单的边界 86 if(newScrolLX<-getChildAt(0).getWidth()) 87 { 88 //回到菜单的左边界 89 scrollTo(-getChildAt(0).getWidth(), 0); 90 } 91 else if(newScrolLX>0) 92 { 93 //回到主界面的左边界 94 scrollTo(0, 0); 95 } 96 else 97 { 98 scrollBy(detaX, 0); 99 }100 break;101 case MotionEvent.ACTION_UP :102 //最新的X轴偏移量103 int scrollX = (int) getScrollX();104 //菜单的中心X轴105 int menuXCenter = -getChildAt(0).getWidth()/2;106 if(scrollX>menuXCenter)107 { //切换到主界面108 mCurrentScreen = MainScreen;109 }110 else111 { //切换到菜单界面112 mCurrentScreen = MenuScreen;113 }114 switchScreen();115 break;116 default:117 break;118 }119 120 return true;121 }122 123 private void switchScreen()124 {125 int scrollX = getScrollX();126 int dx = 0;127 if(mCurrentScreen == MainScreen)128 { //切换到主界面129 // scrollTo(0, 0);130 dx = 0-scrollX;131 }132 else if(mCurrentScreen == MenuScreen)133 { //切换到菜单界面134 // scrollTo(-getChildAt(0).getWidth(), 0);135 dx = -getChildAt(0).getWidth()-scrollX;136 }137 mScroller.startScroll(scrollX, 0, dx, 0, Math.abs(dx)*3);138 139 invalidate();//invalidate --> drawChild -->chlid.draw -->computerScroll140 }141 @Override142 public void computeScroll()143 {144 //invaliadate调用此方法,更新X轴的偏移量145 if(mScroller.computeScrollOffset()) //判断是否正在模拟数据中,true 正在进行146 {147 scrollTo(mScroller.getCurrX(), 0);148 149 invalidate();//引起computeScroll的调用150 }151 }152 //时候显示菜单153 public boolean isShow()154 {155 return mCurrentScreen == MainScreen;156 }157 158 public void hideMenu()159 {160 mCurrentScreen = MainScreen;161 switchScreen();162 }163 164 public void showMenu()165 {166 mCurrentScreen = MenuScreen;167 switchScreen();168 }169 /**170 * 拦截事件的方法171 */172 @Override173 public boolean onInterceptTouchEvent(MotionEvent ev)174 {175 switch (ev.getAction())176 {177 case MotionEvent.ACTION_DOWN:178 mMostRecentX = (int) ev.getX();179 break;180 case MotionEvent.ACTION_MOVE:181 int diffX = (int) (ev.getX() - mMostRecentX);182 if(Math.abs(diffX)>touchSlop)183 {184 return true;185 }186 break;187 default:188 break;189 }190 return super.onInterceptTouchEvent(ev);191 }192 }
主要的核心方法:Scrollto、ScrollBy
invalidate();//invalidate --> drawChild -->chlid.draw -->computerScroll 这里比较复杂,大家可以查阅一下有关资料 布局文件:
16 7 11 14 15 1612 13
非android原生控件定义的时候要写上自定义类的全名
com.tai.dandelion.view.SlideMenu
侧滑主界面
1 26 11 30 31 32 3317 21 29 40 41 42 43 44
侧滑隐藏菜单
1 25 6 11 47 48 4916 21 26 31 36 41 46
style中的菜单的样式:
1
菜单项的选择器
1 23 - 4
- 5
Manifast中Activity的声明就这里就不贴了。别的基本没什么。代码就在这里,有用的到的朋友可以研究一下。
整理By android小白。
最终效果: