侧滑菜单

自定义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>


layout_menu.xml

<?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>


layout_main.xml


<?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>

自定义的动画ScrollAnimation.java


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);
	}
}

mainactiviy.java


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();
			}
		});
	}

}



项目源码: https://github.com/xh2015/sildeMenu.git

你可能感兴趣的:(侧滑菜单)