Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android開發--滑動側邊欄的實現

Android開發--滑動側邊欄的實現

編輯:關於Android編程

在Android應用開發中,滑動側邊欄經常使用,今天我也試著自己進行了一個簡單的實踐,雖然功能還不是很強大,但是可以保留下來為以後的開發使用,有需要時在進行簡單的修改。實現一個滑動側邊欄思路也很簡單:

1.重寫一個SlidingMenu類繼承ViewGroup,病危該ViewGroup添加兩個子布局,分別為菜單和主界面顯示;

2.為了得到一個滑動的效果,選擇Scroller幫助我們實現,配合ViewGroup下的computeScroll方法實現界面的更新;

3.利用一個boolean來記錄菜單是否打開,在菜單打開的狀態下向右滑動不會響應,在菜單關閉的情況向左滑動不會響應;

4.為了得到一個良好的交互,我們可以為界面滑動與手指移動的距離定義一個比例,如每次觸摸事件發生,界面移動的距離僅為手指移動距離的一半;

下面是兩張效果圖,界面沒怎麼布局,大家湊合看

\ \

SlidingMenu實現代碼:

package com.example.test;

import android.content.Context;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Scroller;

public class SlidingMenu extends ViewGroup {

	private static final String TAG = SlidingMenu.class.getName();

	private enum Scroll_State {
		Scroll_to_Open, Scroll_to_Close;
	}

	private Scroll_State state;
	private int mMostRecentX;
	private int downX;
	private boolean isOpen = false;

	private View menu;
	private View mainView;

	private Scroller mScroller;

	private OnSlidingMenuListener onSlidingMenuListener;

	public SlidingMenu(Context context, View main, View menu) {
		super(context);
		// TODO Auto-generated constructor stub
		setMainView(main);
		setMenu(menu);
		init(context);
	}

	private void init(Context context) {
		mScroller = new Scroller(context);
	}

	@Override
	protected void onLayout(boolean arg0, int l, int t, int r, int b) {
		// TODO Auto-generated method stub
		mainView.layout(l, t, r, b);
		menu.layout(-menu.getMeasuredWidth(), t, 0, b);
	}

	public void setMainView(View view) {
		mainView = view;
		addView(mainView);
	}

	public void setMenu(View view) {
		menu = view;
		addView(menu);
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		// TODO Auto-generated method stub
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		mainView.measure(widthMeasureSpec, heightMeasureSpec);
		menu.measure(widthMeasureSpec - 150, heightMeasureSpec);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			mMostRecentX = (int) event.getX();
			downX = (int) event.getX();
			break;
		case MotionEvent.ACTION_MOVE:
			int moveX = (int) event.getX();
			int deltaX = mMostRecentX - moveX;
			// 如果在菜單打開時向右滑動及菜單關閉時向左滑動不會觸發Scroll事件
			if ((!isOpen && (downX - moveX) < 0)
					|| (isOpen && (downX - moveX) > 0)) {
				scrollBy(deltaX / 2, 0);
			}
			mMostRecentX = moveX;
			break;
		case MotionEvent.ACTION_UP:
			int upX = (int) event.getX();
			int dx = upX - downX;
			if (!isOpen) {// 菜單關閉時
				// 向右滑動超過menu一半寬度才會打開菜單
				if (dx > menu.getMeasuredWidth() / 3) {
					state = Scroll_State.Scroll_to_Open;
				} else {
					state = Scroll_State.Scroll_to_Close;
				}
			} else {// 菜單打開時
				// 當按下時的觸摸點在menu區域時,只有向左滑動超過menu的一半,才會關閉
				// 當按下時的觸摸點在main區域時,會立即關閉
				if (downX < menu.getMeasuredWidth()) {
					if (dx < -menu.getMeasuredWidth() / 3) {
						state = Scroll_State.Scroll_to_Close;
					} else {
						state = Scroll_State.Scroll_to_Open;
					}
				} else {
					state = Scroll_State.Scroll_to_Close;
				}
			}
			smoothScrollto();
			break;
		default:
			break;
		}
		return true;
	}

	private void smoothScrollto() {
		int scrollx = getScrollX();
		switch (state) {
		case Scroll_to_Close:
			mScroller.startScroll(scrollx, 0, -scrollx, 0, 500);
			if (onSlidingMenuListener != null && isOpen) {
				onSlidingMenuListener.close();
			}
			isOpen = false;
			break;
		case Scroll_to_Open:
			mScroller.startScroll(scrollx, 0,
					-scrollx - menu.getMeasuredWidth(), 0, 500);
			if (onSlidingMenuListener != null && !isOpen) {
				onSlidingMenuListener.close();
			}
			isOpen = true;
			break;
		default:
			break;
		}
	}

	@Override
	public void computeScroll() {
		if (mScroller.computeScrollOffset()) {
			scrollTo(mScroller.getCurrX(), 0);
		}
		invalidate();
	}

	public void open() {
		state = Scroll_State.Scroll_to_Open;
		smoothScrollto();
	}

	public void close() {
		state = Scroll_State.Scroll_to_Close;
		smoothScrollto();
	}

	public boolean isOpen() {
		return isOpen;
	}

	public void setOnSlidingMenuListener(
			OnSlidingMenuListener onSlidingMenuListener) {
		this.onSlidingMenuListener = onSlidingMenuListener;
	}

	public interface OnSlidingMenuListener {
		public void open();

		public void close();
	}

}
在MainActivity中進行調用
package com.example.test;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity {

	private Button openButton;
	private Button closeButton;
	private SlidingMenu mSlidingMenu;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		mSlidingMenu = new SlidingMenu(this, LayoutInflater
				.from(this).inflate(R.layout.fragment1, null), LayoutInflater
				.from(this).inflate(R.layout.fragment2, null));
		setContentView(mSlidingMenu);//注意setContentView需要換為我們的SlidingMenu
		openButton = (Button) findViewById(R.id.button1);
		closeButton = (Button) findViewById(R.id.button_close);
		openButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				mSlidingMenu.open();
			}
		});
		closeButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				mSlidingMenu.close();
			}
		});
	}

}



  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved