側滑菜單

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章