自定义viewgroup->sildeMenu.java
package com.xuhao.sliding.view; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.widget.FrameLayout; import android.widget.Scroller; public class SildeMenu extends FrameLayout { private View menuView, mainView; private int menuWidth = 0; private Scroller scroller; public SildeMenu(Context context) { super(context); init(); } public SildeMenu(Context context, AttributeSet attrs) { super(context, attrs); 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; // Log.e("Main", menuWidth + ""); } /** * widthMeasureSpec和heightMeasureSpec是系统测量SlideMenu时传入的参数 * 这2个参数测kiang出来的宽高能让slidemenu充满船体,其实是正好等于屏幕的宽高 */ // @Override // protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // super.onMeasure(widthMeasureSpec, heightMeasureSpec); // int measureSpec = MeasureSpec.makeMeasureSpec(menuWidth, // MeasureSpec.EXACTLY); // // Log.e("Main", measureSpec + "measureSpec"); // // 测量所有子view的宽高 // // 通过getLayoutParams方法可以获取到布局文件中指定宽高 // menuView.measure(measureSpec, heightMeasureSpec); // // 直接使用slidemenu的测量参数,以为他的狂傲就是充满父窗体 // mainView.measure(widthMeasureSpec, heightMeasureSpec); // } // dispatchTouchEvent(MotionEvent ev) @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){ //如果左右滑动大于8就让slidemenu处理 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) { 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 detalX = moveX - downX; int newScrollX = getScrollX() - detalX; if (newScrollX < -menuWidth) newScrollX = -menuWidth; if (newScrollX > 0) newScrollX = 0; scrollTo(newScrollX, 0); downX = moveX; break; case MotionEvent.ACTION_UP: // ScrollAnimation animation; // if (getScrollX() > -menuWidth / 2) { // // 关闭菜单 // animation = new ScrollAnimation(this, 0); // // scrollTo(0, 0); // } else { // // 打开菜单 // animation = new ScrollAnimation(this, -menuWidth); // // scrollTo(-menuWidth, 0); // } // startAnimation(animation); if (getScrollX() > -menuWidth / 2) { // 关闭菜单 closeMenu(); } else { // 打开菜单 openMenu(); } break; } return true; } /** * 打开惨淡 */ private void openMenu() { scroller.startScroll(getScrollX(), 0, -menuWidth - getScrollX(), 0, 400); invalidate(); } /** * 关闭菜单 */ private void closeMenu() { scroller.startScroll(getScrollX(), 0, 0 - 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(); } } }activity_main.xml
<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" > <com.xuhao.sliding.view.SildeMenu android:id="@+id/sildemenu" android:layout_width="match_parent" android:layout_height="match_parent" > <!-- 菜单布局 --> <include layout="@layout/layout_menu" /> <!-- 主界面布局 --> <include layout="@layout/layout_main" /> </com.xuhao.sliding.view.SildeMenu> </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" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:paddingBottom="300dp" > <TextView style="@style/MenuTabStyle" android:background="#33ababab" android:drawableLeft="@drawable/tab_news" android:text="新闻" /> <TextView style="@style/MenuTabStyle" android:drawableLeft="@drawable/tab_read" android:text="订阅" /> <TextView style="@style/MenuTabStyle" android:drawableLeft="@drawable/tab_ties" android:text="跟帖" /> <TextView style="@style/MenuTabStyle" android:drawableLeft="@drawable/tab_pics" android:text="图片" /> <TextView style="@style/MenuTabStyle" android:drawableLeft="@drawable/tab_ugc" android:text="话题" /> <TextView style="@style/MenuTabStyle" android:drawableLeft="@drawable/tab_vote" android:text="投票" /> <TextView style="@style/MenuTabStyle" 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="#ccc" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="60dp" android:gravity="center_vertical" android:background="@drawable/top_bar_bg" > <ImageView android:id="@+id/iv_menu" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/main_back" /> <View android:layout_width="1dp" android:layout_height="match_parent" android:layout_marginBottom="5dp" android:layout_marginTop="5dp" android:background="@drawable/top_bar_divider" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="15dp" android:text="序号新闻" android:textColor="#ffffff" android:textSize="22sp" /> </LinearLayout> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:textColor="#000000" android:textSize="30sp" android:gravity="center" android:text="钓鱼岛是中国的..."/> </LinearLayout>
package com.xuhao.sliding.view; import android.view.View; import android.view.animation.Animation; import android.view.animation.Transformation; public class ScrollAnimation extends Animation { private View view; private int startScrollX; private int totalValue; private int targetScrollX; public ScrollAnimation(View view, int targetScrollX) { super(); this.view = view; this.targetScrollX = targetScrollX; startScrollX = view.getScrollX(); totalValue = 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.xuhao.sliding; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.view.Window; import android.widget.ImageView; import com.xuhao.sliding.view.SildeMenu; import comxuhao.sliding.R; public class MainActivity extends Activity { private ImageView iv; private SildeMenu sildeMenu; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); iv=(ImageView) findViewById(R.id.iv_menu); sildeMenu=(SildeMenu) findViewById(R.id.sildemenu); iv.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { sildeMenu.switchMenu(); } }); } }