android_105_侧滑菜单
2017-01-30 15:57
246 查看
效果:
布局:
主界面:
左侧按钮:
右侧内容:
代码:
主控制器:
自定义的滚动动画:
自定义的滑动菜单:
布局:
主界面:
<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="com.sg31.sgslidingmenu.MainActivity" > <com.sg31.sgslidingmenu.SGSlidingMenu android:id="@+id/slideMenu" android:layout_width="match_parent" android:layout_height="match_parent" > <!-- 菜单界面的布局 --> <include layout="@layout/slidingmenu_leftmenu"/> <!-- 主界面的布局 --> <include layout="@layout/slidingmenu_rightmain"/> </com.sg31.sgslidingmenu.SGSlidingMenu> </RelativeLayout>
左侧按钮:
<?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="240dp" android:layout_height="match_parent" android:background="@drawable/menu_bg" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingBottom="300dp" android:orientation="vertical" > <TextView style="@style/MenuTabText" android:background="#33aa9900" android:drawableLeft="@drawable/tab_news" android:text="新闻"/> <TextView style="@style/MenuTabText" android:drawableLeft="@drawable/tab_read" android:text="订阅"/> <TextView style="@style/MenuTabText" android:drawableLeft="@drawable/tab_ties" android:text="跟帖"/> <TextView style="@style/MenuTabText" android:drawableLeft="@drawable/tab_pics" android:text="图片"/> <TextView style="@style/MenuTabText" android:drawableLeft="@drawable/tab_ugc" android:text="话题"/> <TextView style="@style/MenuTabText" android:drawableLeft="@drawable/tab_vote" android:text="投票"/> <TextView style="@style/MenuTabText" android:drawableLeft="@drawable/tab_focus" android:text="聚合阅读"/> </LinearLayout> </ScrollView>
右侧内容:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#55666666" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:background="@drawable/top_bar_bg" android:gravity="center_vertical" android:layout_height="60dp"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/btn_back" android:background="@drawable/main_back"/> <View android:layout_width="1dp" android:layout_height="match_parent" android:layout_marginTop="5dp" android:layout_marginBottom="5dp" android:background="@drawable/top_bar_divider"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#ffffff" android:textSize="22sp" android:layout_marginLeft="15dp" android:text="黑马新闻"/> </LinearLayout> <TextView android:layout_width="match_parent" android:text="钓鱼岛是中国的..." android:textColor="#000000" android:textSize="30sp" android:gravity="center" android:layout_height="match_parent"/> </LinearLayout>
代码:
主控制器:
package com.sg31.sgslidingmenu; import android.support.v7.app.ActionBarActivity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.view.Window; import android.widget.ImageView; public class MainActivity extends ActionBarActivity { private ImageView btn_back; private SGSlidingMenu slideMenu; @Override protected 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 = (SGSlidingMenu) findViewById(R.id.slideMenu); btn_back.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { slideMenu.switchMenu(); } }); } }
自定义的滚动动画:
package com.sg31.sgslidingmenu; import android.view.View; import android.view.animation.Animation; import android.view.animation.Transformation; /** * 让指定view在一段时间内scrollTo到指定位置 * @author Administrator * */ public class SGScrollAnimation extends Animation{ private View view; private int targetScrollX; private int startScrollX; private int totalValue; public SGScrollAnimation(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 */ @Override protected void applyTransformation(float interpolatedTime, Transformation t) { super.applyTransformation(interpolatedTime, t); int currentScrollX = (int) (startScrollX + totalValue*interpolatedTime); view.scrollTo(currentScrollX, 0); } }
自定义的滑动菜单:
package com.sg31.sgslidingmenu; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.widget.FrameLayout; import android.widget.Scroller; // 继承自FrameLayout的目的是:免去了Measure的操作 public class SGSlidingMenu extends FrameLayout{ private View menuView,mainView; private int menuWidth = 0; private Scroller scroller; public SGSlidingMenu(Context context, AttributeSet attrs) { super(context, attrs); init(); } public SGSlidingMenu(Context context) { super(context); init(); } private void init(){ scroller = new Scroller(getContext()); } /** * 当1级的子view全部加载完调用,可以用初始化子view的引用 * 注意,这里无法获取子view的宽高 */ @Override protected void onFinishInflate() { super.onFinishInflate(); menuView = getChildAt(0); mainView = getChildAt(1); menuWidth = menuView.getLayoutParams().width; } /** * widthMeasureSpec和heightMeasureSpec是系统测量SlideMenu时传入的参数, * 这2个参数测量出的宽高能让SlideMenu充满窗体,其实是正好等于屏幕宽高 */ // @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); // // } @Override public 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); } /** * l: 当前子view的左边在父view的坐标系中的x坐标 * t: 当前子view的顶边在父view的坐标系中的y坐标 */ @Override protected 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; @Override public 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; 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.使用Scroller if(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 */ @Override public void computeScroll() { super.computeScroll(); if(scroller.computeScrollOffset()){//返回true,表示动画没结束 scrollTo(scroller.getCurrX(), 0); invalidate(); } } /** * 切换菜单的开和关 */ public void switchMenu() { if(getScrollX()==0){ //需要打开 openMenu(); }else { //需要关闭 closeMenu(); } } }
相关文章推荐
- Android滑动菜单特效实现,仿人人客户端侧滑效果,史上最简单的侧滑实现
- Android之侧滑菜单,即右边菜单
- Android高手进阶篇4-实现侧滑菜单框架,一分钟集成到项目中
- 导航(1) 侧滑菜单导航 可替代AndroidSideMenu
- Android滑动菜单特效实现,仿人人客户端侧滑效果,史上最简单的侧滑实现
- android中侧滑菜单的思路详解与实现
- android实例:功能导图 + 侧滑菜单
- android的左右侧滑菜单实现
- android的左右侧滑菜单实现
- Android 侧滑(双向滑动菜单)效果
- android自定义侧滑菜单slidmenu
- Android滑动菜单特效实现,仿人人客户端侧滑效果
- android文章学习 侧滑菜单实现
- Android高手进阶篇4-实现侧滑菜单框架,一分钟集成到项目中
- Android 侧滑菜单实现
- 布局菜单Android开发之侧滑菜单LeftSliderLayout
- Android:UI控件DrawerLayout、Fragment、SlidingLayout、侧滑菜单 推荐
- Android滑动菜单特效实现,仿人人客户端侧滑效果,史上最简单的侧滑实现
- Android滑动菜单特效实现,仿人人客户端侧滑效果,史上最简单的侧滑实现
- 防人人网客户端侧滑效果,简单实现Android滑动菜单特效