Android 滑动抽屉

滑动抽屉

抽屉中放置任意个数button

Android 滑动抽屉_第1张图片             Android 滑动抽屉_第2张图片              Android 滑动抽屉_第3张图片

 

package com.pepper.panel;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Gravity;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.pepper.panel.HttpClientTast.OnCompleteListener;

public class MainActivity extends Activity {
	private Context mContext;
	private LinearLayout mPanelContent;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		mContext = this;
		mPanelContent = (LinearLayout) findViewById(R.id.panelContentLl);
		createImageView();
	}
	
	private void createImageView() {
		for (int i = 0; i < 20; i++) {		
			LinearLayout ll = new LinearLayout(mContext);
			ll.setOrientation(LinearLayout.VERTICAL);
			setParams(ll);
			mPanelContent.addView(ll);
			TextView text = new TextView(mContext);
			text.setTextColor(Color.WHITE);
			text.setText("button" + i);
			text.setTextSize(10);
			setParams(text);
			ImageView iconImageView = new ImageView(mContext);
			iconImageView.setBackgroundResource(R.drawable.ic_launcher);
			setParams(iconImageView);
			ll.addView(iconImageView);
			ll.addView(text);
		}
	}
	
	// 可在该方法里进行属性参数的相关设置
	private void setParams(LinearLayout ll) {
		// 参数:按钮的宽高
		LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,
				LayoutParams.WRAP_CONTENT);
		params.weight = 1.0f;// 重量级
		params.setMargins(60, 20, 60, 20);
		ll.setLayoutParams(params);
	}

	private void setParams(TextView text) {
		// 参数:按钮的宽高
		LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
				LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
		params.gravity = Gravity.CENTER_HORIZONTAL;// 重心
		text.setLayoutParams(params);
	}

	private void setParams(ImageView image) {
		// 参数:按钮的宽高
		LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
				getIntFromDimens(R.dimen.foot_bar_w),
				getIntFromDimens(R.dimen.foot_bar_h));
		params.gravity = Gravity.CENTER_HORIZONTAL;// 重心
		image.setLayoutParams(params);
	}

	public int getIntFromDimens(int index) {
		int result = this.getResources().getDimensionPixelSize(index);
		return result;
	}

}

package com.pepper.panel;


import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
import android.widget.LinearLayout;



public class Panel extends LinearLayout {

	/**
	 * Callback invoked when the panel is opened/closed.
	 */
	public static interface OnPanelListener {
		/**
		 * Invoked when the panel becomes fully closed.
		 */
		public void onPanelClosed(Panel panel);

		/**
		 * Invoked when the panel becomes fully opened.
		 */
		public void onPanelOpened(Panel panel);
	}

	class PanelOnGestureListener implements OnGestureListener {
		float scrollY;
		float scrollX;

		private float ensureRange(float v, int min, int max) {
			v = Math.max(v, min);
			v = Math.min(v, max);
			return v;
		}

		public boolean initChange() {
			if (mState != State.READY) {
				// we are animating or just about to animate
				return false;
			}
			mState = State.ABOUT_TO_ANIMATE;
			mIsShrinking = mContent.getVisibility() == VISIBLE;
			if (!mIsShrinking) {
				// this could make flicker so we test mState in dispatchDraw()
				// to see if is equal to ABOUT_TO_ANIMATE
				mContent.setVisibility(VISIBLE);
			}
			return true;
		}

		@Override
		public boolean onDown(MotionEvent e) {
			scrollX = scrollY = 0;
			lastRawX = curRawX = lastRawY = curRawY = -1;
			lastEventTime = curEventTime = -1;
			initChange();
			return true;
		}

		@Override
		public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
				float velocityY) {
			mState = State.FLYING;

			float velocityX2, velocityY2;
			if (lastRawX == -1 && lastRawY == -1) // 见onScroll方法
			{
				velocityX2 = (curRawX - e1.getRawX())
						/ (curEventTime - e1.getEventTime()) * 1000; // px/s
				velocityY2 = (curRawY - e1.getRawY())
						/ (curEventTime - e1.getEventTime()) * 1000;
			} else {
				velocityX2 = (curRawX - lastRawX)
						/ (curEventTime - lastEventTime) * 1000;
				velocityY2 = (curRawY - lastRawY)
						/ (curEventTime - lastEventTime) * 1000;
			}

			mVelocity = mOrientation == VERTICAL ? velocityY2 : velocityX2;

			if (Math.abs(mVelocity) > 50) {
				if (mVelocity > 0) {
					mAnimatedAcceleration = mMaximumAcceleration;
				} else {
					mAnimatedAcceleration = -mMaximumAcceleration;
				}

				long now = SystemClock.uptimeMillis();
				mAnimationLastTime = now;
				mCurrentAnimationTime = now + ANIMATION_FRAME_DURATION;
				mAnimating = true;
				mHandler.removeMessages(MSG_ANIMATE);
				mHandler.removeMessages(MSG_PREPARE_ANIMATE);
				mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE),
						mCurrentAnimationTime);
				return true;
			}
			return false;
		}

		@Override
		public void onLongPress(MotionEvent e) {
			// not used
		}

		@Override
		public boolean onScroll(MotionEvent e1, MotionEvent e2,
				float distanceX, float distanceY) {
			mState = State.TRACKING;
			float tmpY = 0, tmpX = 0;
			if (mOrientation == VERTICAL) {
				scrollY -= distanceY;
				if (mPosition == TOP) {
					tmpY = ensureRange(scrollY, -mContentHeight, 0);
				} else {
					tmpY = ensureRange(scrollY, 0, mContentHeight);
				}
			} else {
				scrollX -= distanceX;
				if (mPosition == LEFT) {
					tmpX = ensureRange(scrollX, -mContentWidth, 0);
				} else {
					tmpX = ensureRange(scrollX, 0, mContentWidth);
				}
			}

			if (tmpX != mTrackX || tmpY != mTrackY) {
				mTrackX = tmpX;
				mTrackY = tmpY;
				// invalidate(); //放在此导致极快速滑动至touch区域外界面不刷新(mTrackX、tmpX均为0)
			}
			invalidate();

			lastRawX = curRawX;
			lastRawY = curRawY;
			lastEventTime = curEventTime;
			curRawX = e2.getRawX();
			curRawY = e2.getRawY();
			curEventTime = e2.getEventTime();
			return true;
		}

		@Override
		public void onShowPress(MotionEvent e) {
			// not used
		}

		@Override
		public boolean onSingleTapUp(MotionEvent e) {
			// not used
			return false;
		}

	}

	private class SlidingHandler extends Handler {
		private void doAnimation() {

			if (mAnimating) {
				long now = SystemClock.uptimeMillis();
				float t = (now - mAnimationLastTime) / 1000.0f; // ms -> s
				final float v = mVelocity; // px/s
				final float a = mAnimatedAcceleration; // px/s/s
				mVelocity = v + (a * t); // px/s
				mAnimationLastTime = now;

				switch (mPosition) {
				case LEFT:
					mTrackX = mTrackX + (v * t) + (0.5f * a * t * t); // px
					if (mTrackX > 0) {
						mTrackX = 0;
						mState = State.READY;
						mAnimating = false;
						mIsShrinking = false;
					} else if (mTrackX < -mContentWidth) {
						mTrackX = -mContentWidth;
						mContent.setVisibility(GONE);
						mState = State.READY;
						mAnimating = false;
						mIsShrinking = true;
					}
					break;
				case RIGHT:
					mTrackX = mTrackX + (v * t) + (0.5f * a * t * t);
					if (mTrackX < 0) {
						mTrackX = 0;
						mState = State.READY;
						mAnimating = false;
					} else if (mTrackX > mContentWidth) {
						mTrackX = mContentWidth;
						mContent.setVisibility(GONE);
						mState = State.READY;
						mAnimating = false;
					}
					break;
				case TOP:
					mTrackY = mTrackY + (v * t) + (0.5f * a * t * t);
					if (mTrackY > 0) {
						mTrackY = 0;
						mState = State.READY;
						mAnimating = false;
					} else if (mTrackY < -mContentHeight) {
						mTrackY = -mContentHeight;
						mContent.setVisibility(GONE);
						mState = State.READY;
						mAnimating = false;
					}
					break;
				case BOTTOM:
					mTrackY = mTrackY + (v * t) + (0.5f * a * t * t);
					if (mTrackY < 0) {
						mTrackY = 0;
						mState = State.READY;
						mAnimating = false;
					} else if (mTrackY > mContentHeight) {
						mTrackY = mContentHeight;
						mContent.setVisibility(GONE);
						mState = State.READY;
						mAnimating = false;
					}
					break;
				}
				invalidate();

				if (!mAnimating) {
					postProcess();
					return;
				}
				mCurrentAnimationTime += ANIMATION_FRAME_DURATION;
				mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE),
						mCurrentAnimationTime);

			}
		}

		@Override
    public void handleMessage(Message m) {
			switch (m.what) {
			case MSG_ANIMATE:
				doAnimation();
				break;
			case MSG_PREPARE_ANIMATE:
				prepareAnimation();
				doAnimation();
				break;
			}
		}

		private void prepareAnimation() {

			switch (mPosition) {
			case LEFT:
				if (mIsShrinking) {
					mVelocity = -mMaximumMajorVelocity;
					mAnimatedAcceleration = -mMaximumAcceleration;

				} else {
					mVelocity = mMaximumMajorVelocity;
					mAnimatedAcceleration = mMaximumAcceleration;
					if (mTrackX == 0 && mState == State.ABOUT_TO_ANIMATE) {
						mTrackX = -mContentWidth;
					}
				}
				break;
			case RIGHT:
				if (mIsShrinking) {
					mVelocity = mMaximumMajorVelocity;
					mAnimatedAcceleration = mMaximumAcceleration;
				} else {
					mVelocity = -mMaximumMajorVelocity;
					mAnimatedAcceleration = -mMaximumAcceleration;

					if (mTrackX == 0 && mState == State.ABOUT_TO_ANIMATE) {
						mTrackX = mContentWidth;
					}
				}
				break;
			case TOP:
				if (mIsShrinking) {
					mVelocity = -mMaximumMajorVelocity;
					mAnimatedAcceleration = -mMaximumAcceleration;
				} else {
					mVelocity = mMaximumMajorVelocity;
					mAnimatedAcceleration = mMaximumAcceleration;

					if (mTrackX == 0 && mState == State.ABOUT_TO_ANIMATE) {
						mTrackY = -mContentHeight;
					}
				}
				break;
			case BOTTOM:
				if (mIsShrinking) {
					mVelocity = mMaximumMajorVelocity;
					mAnimatedAcceleration = mMaximumAcceleration;
				} else {
					mVelocity = -mMaximumMajorVelocity;
					mAnimatedAcceleration = -mMaximumAcceleration;

					if (mTrackX == 0 && mState == State.ABOUT_TO_ANIMATE) {
						mTrackY = mContentHeight;
					}
				}
				break;
			}

			if (mState == State.TRACKING) {
				if (mIsShrinking) {
					if ((mOrientation == VERTICAL && Math.abs(mTrackY) < mContentHeight / 2)
							|| (mOrientation == HORIZONTAL && Math.abs(mTrackX) < mContentWidth / 2)) {
						mVelocity = -mVelocity;
						mAnimatedAcceleration = -mAnimatedAcceleration;
						mIsShrinking = !mIsShrinking;
					}
				} else {
					if ((mOrientation == VERTICAL && Math.abs(mTrackY) > mContentHeight / 2)
							|| (mOrientation == HORIZONTAL && Math.abs(mTrackX) > mContentWidth / 2)) {
						mVelocity = -mVelocity;
						mAnimatedAcceleration = -mAnimatedAcceleration;
						mIsShrinking = !mIsShrinking;
					}
				}
			}
			if (mState != State.FLYING && mState != State.TRACKING) {
				mState = State.CLICK;
			}
		}
	};

	private enum State {
		ABOUT_TO_ANIMATE, ANIMATING, READY, TRACKING, FLYING, CLICK
	}

	private static final String TAG = "Panel";
	private static final float MAXIMUM_MAJOR_VELOCITY = 200.0f;
	private static final float MAXIMUM_ACCELERATION = 2000.0f;
	private static final int MSG_ANIMATE = 1000;
	private static final int MSG_PREPARE_ANIMATE = 2000;

	private static final int ANIMATION_FRAME_DURATION = 1000 / 60;
	public static final int TOP = 0;
	public static final int BOTTOM = 1;
	public static final int LEFT = 2;
	public static final int RIGHT = 3;

	private OnPanelListener panelListener;
	private final Handler mHandler = new SlidingHandler();

	private float mAnimatedAcceleration;
	private long mAnimationLastTime;

	private long mCurrentAnimationTime;
	private boolean mAnimating;
	private final int mMaximumMajorVelocity;
	private final int mMaximumAcceleration;
	private float lastRawX, lastRawY, curRawX, curRawY;
	private float lastEventTime, curEventTime;
	private boolean mIsShrinking;
	private int mPosition;
	@SuppressWarnings("unused")
	private int mDuration;
	@SuppressWarnings("unused")
	private boolean mLinearFlying;
	private int mHandleId;
	private int mContentId;
	private View mHandle;

	private View mContent;
	private Drawable mOpenedHandle;
	private Drawable mClosedHandle;
	private float mTrackX;
	private float mTrackY;
	private float mVelocity;
	private State mState;
	@SuppressWarnings("unused")
	private Interpolator mInterpolator;
	private GestureDetector mGestureDetector;

	private int mContentHeight;
	private int mContentWidth;
	private int mOrientation;
	private float mWeight;

	private PanelOnGestureListener mGestureListener;

	private boolean mBringToFront;

	OnTouchListener touchListener = new OnTouchListener() {

		@Override
    public boolean onTouch(View v, MotionEvent event) {

			if (mAnimating) {
				// we are animating
				return true;// 动画中不响应onTouch事件
			}

			int action = event.getAction();
			if (action == MotionEvent.ACTION_DOWN) {
				if (mBringToFront) {
					bringToFront();
				}
			}

			if (!mGestureDetector.onTouchEvent(event)) {
				if (action == MotionEvent.ACTION_UP) {
					// tup up after scrolling

					long now = SystemClock.uptimeMillis();
					mAnimationLastTime = now;
					mCurrentAnimationTime = now + ANIMATION_FRAME_DURATION;
					mAnimating = true;
					mHandler.removeMessages(MSG_ANIMATE);
					mHandler.removeMessages(MSG_PREPARE_ANIMATE);
					mHandler.sendMessageAtTime(
							mHandler.obtainMessage(MSG_PREPARE_ANIMATE),
							mCurrentAnimationTime);
				}
			}
			return false;
		}
	};

	@SuppressWarnings("deprecation")
	public Panel(Context context, AttributeSet attrs) {
		super(context, attrs);
		TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Panel);
		// duration defaults to 750 ms
		mDuration = a.getInteger(R.styleable.Panel_animationDuration, 750);
		// position defaults to BOTTOM
		mPosition = a.getInteger(R.styleable.Panel_position, BOTTOM);
		// linear Flying defaults to false
		mLinearFlying = a.getBoolean(R.styleable.Panel_linearFlying, false);
		// weight defaults to 0.0
		mWeight = a.getFraction(R.styleable.Panel_weight, 0, 1, 0.0f);
		if (mWeight < 0 || mWeight > 1) {
			mWeight = 0.0f;
			Log.w(TAG, a.getPositionDescription()
					+ ": weight must be > 0 and <= 1");
		}
		mOpenedHandle = a.getDrawable(R.styleable.Panel_openedHandle);
		mClosedHandle = a.getDrawable(R.styleable.Panel_closedHandle);

		RuntimeException e = null;
		mHandleId = a.getResourceId(R.styleable.Panel_handle, 0);
		if (mHandleId == 0) {
			e = new IllegalArgumentException(
					a.getPositionDescription()
							+ ": The handle attribute is required and must refer to a valid child.");
		}
		mContentId = a.getResourceId(R.styleable.Panel_content, 0);
		if (mContentId == 0) {
			e = new IllegalArgumentException(
					a.getPositionDescription()
							+ ": The content attribute is required and must refer to a valid child.");
		}
		a.recycle();

		final float density = getResources().getDisplayMetrics().density;
		mMaximumMajorVelocity = (int) (MAXIMUM_MAJOR_VELOCITY * density + 0.5f);
		mMaximumAcceleration = (int) (MAXIMUM_ACCELERATION * density + 0.5f);

		if (e != null) {
			throw e;
		}
		mOrientation = (mPosition == TOP || mPosition == BOTTOM) ? VERTICAL
				: HORIZONTAL;
		setOrientation(mOrientation);
		mState = State.READY;
		mGestureListener = new PanelOnGestureListener();
		mGestureDetector = new GestureDetector(mGestureListener);
		mGestureDetector.setIsLongpressEnabled(false);

		// i DON'T really know why i need this...
		setBaselineAligned(false);
	}

	/**
	 * 绘制VIew本身的内容,通过调用View.onDraw(canvas)函数实现, 绘制自己的孩子通过dispatchDraw(canvas)实现
	 */
	@Override
	protected void dispatchDraw(Canvas canvas) {
		// String name = getResources().getResourceEntryName(getId());
		// Log.d(TAG, name + " ispatchDraw " + mState);
		// this is why 'mState' was added:
		// avoid flicker before animation start
		if (mState == State.ABOUT_TO_ANIMATE && !mIsShrinking) {
			int delta = mOrientation == VERTICAL ? mContentHeight
					: mContentWidth;
			if (mPosition == LEFT || mPosition == TOP) {
				delta = -delta;
			}
			if (mOrientation == VERTICAL) {
				canvas.translate(0, delta);
			} else {
				canvas.translate(delta, 0);
			}
		}
		if (mState == State.TRACKING || mState == State.FLYING
				|| mState == State.CLICK) {
			canvas.translate(mTrackX, mTrackY);
		}
		super.dispatchDraw(canvas);
	}

	/**
	 * Gets Panel's mContent
	 *
	 * @return Panel's mContent
	 */
	public View getContent() {
		return mContent;
	}

	/**
	 * Gets Panel's mHandle
	 *
	 * @return Panel's mHandle
	 */
	public View getHandle() {
		return mHandle;
	}

	/**
	 * Returns the opened status for Panel.
	 *
	 * @return True if Panel is opened, false otherwise.
	 */
	public boolean isOpen() {
		return mContent.getVisibility() == VISIBLE;
	}

	@Override
	protected void onAttachedToWindow() {
		super.onAttachedToWindow();
		ViewParent parent = getParent();
		if (parent != null && parent instanceof FrameLayout) {
			mBringToFront = true;
		}
	}

	/**
	 * 回调函数 界面初始化快结束时调用 用于得到 mHandle/mContent
	 */
	@Override
	protected void onFinishInflate() {
		super.onFinishInflate();
		mHandle = findViewById(mHandleId);
		if (mHandle == null) {
			String name = getResources().getResourceEntryName(mHandleId);
			throw new RuntimeException(
					"Your Panel must have a child View whose id attribute is 'R.id."
							+ name + "'");
		}
		mHandle.setClickable(true);
		mHandle.setOnTouchListener(touchListener);
		// mHandle.setOnClickListener(clickListener);

		mContent = findViewById(mContentId);
		if (mContent == null) {
			String name = getResources().getResourceEntryName(mHandleId);
			throw new RuntimeException(
					"Your Panel must have a child View whose id attribute is 'R.id."
							+ name + "'");
		}

		// reposition children
		removeView(mHandle);
		removeView(mContent);
		if (mPosition == TOP || mPosition == LEFT) {
			addView(mContent);
			addView(mHandle);
		} else {
			addView(mHandle);
			addView(mContent);
		}

		if (mOpenedHandle != null) {
		  mHandle.setBackground(mOpenedHandle);
		}
		mContent.setClickable(true);
		if (mWeight > 0) {
			ViewGroup.LayoutParams params = mContent.getLayoutParams();
			if (mOrientation == VERTICAL) {
				params.height = ViewGroup.LayoutParams.MATCH_PARENT;
			} else {
				params.width = ViewGroup.LayoutParams.MATCH_PARENT;
			}
			mContent.setLayoutParams(params);
		}
	}

	/**
	 * 回调函数 此时其内所有子View 宽度/高度 都已确定
	 */
	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		super.onLayout(changed, l, t, r, b);
		mContentWidth = mContent.getWidth();
		mContentHeight = mContent.getHeight();
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		if (mWeight > 0 && mContent.getVisibility() == VISIBLE) {
			View parent = (View) getParent();
			if (parent != null) {
				if (mOrientation == VERTICAL) {
					heightMeasureSpec = MeasureSpec.makeMeasureSpec(
							(int) (parent.getHeight() * mWeight),
							MeasureSpec.EXACTLY);
				} else {
					widthMeasureSpec = MeasureSpec.makeMeasureSpec(
							(int) (parent.getWidth() * mWeight),
							MeasureSpec.EXACTLY);
				}
			}
		}
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
	}

	/**
	 * 善后工作 比如:改变mHandle背景图 通知开合监听器
	 */
	private void postProcess() {
		if (mIsShrinking && mClosedHandle != null) {
			mHandle.setBackground(mClosedHandle);
		} else if (!mIsShrinking && mOpenedHandle != null) {
			mHandle.setBackground(mOpenedHandle);
		}
		// invoke listener if any
		if (panelListener != null) {
			if (mIsShrinking) {
				panelListener.onPanelClosed(Panel.this);
			} else {
				panelListener.onPanelOpened(Panel.this);
			}
		}
	}

	/**
	 * Sets the acceleration curve for panel's animation.
	 *
	 * @param i
	 *            The interpolator which defines the acceleration curve
	 */
	public void setInterpolator(Interpolator i) {
		mInterpolator = i;
	}

	/**
	 * Sets the listener that receives a notification when the panel becomes
	 * open/close.
	 *
	 * @param onPanelListener
	 *            The listener to be notified when the panel is opened/closed.
	 */
	public void setOnPanelListener(OnPanelListener onPanelListener) {
		panelListener = onPanelListener;
	}

	/**
	 * Set the opened state of Panel.
	 *
	 * @param open
	 *            True if Panel is to be opened, false if Panel is to be closed.
	 * @param animate
	 *            True if use animation, false otherwise.
	 *
	 * @return True if operation was performed, false otherwise.
	 *
	 */
	public boolean setOpen(boolean open, boolean animate) {
		if (mState == State.READY && isOpen() ^ open) {
			mIsShrinking = !open;
			if (animate) {
				mState = State.ABOUT_TO_ANIMATE;
				if (!mIsShrinking) {
					// this could make flicker so we test mState in
					// dispatchDraw()
					// to see if is equal to ABOUT_TO_ANIMATE
					mContent.setVisibility(VISIBLE);
				}
				long now = SystemClock.uptimeMillis();
				mAnimationLastTime = now;
				mCurrentAnimationTime = now + ANIMATION_FRAME_DURATION;
				mAnimating = true;
				mHandler.removeMessages(MSG_ANIMATE);
				mHandler.removeMessages(MSG_PREPARE_ANIMATE);
				mHandler.sendMessageAtTime(
						mHandler.obtainMessage(MSG_PREPARE_ANIMATE),
						mCurrentAnimationTime);
			} else {
				mContent.setVisibility(open ? VISIBLE : GONE);
				postProcess();
			}
			return true;
		}
		return false;
	}

}

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:panel="http://schemas.android.com/apk/res/com.pepper.panel"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="${relativePackage}.${activityClass}" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

    <com.pepper.panel.Panel
          android:id="@+id/panel"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_gravity="left"
        panel:closedHandle="@drawable/foot_bar_right"
        panel:content="@+id/panelContent"
        panel:handle="@+id/panelHandle"
        panel:openedHandle="@drawable/foot_bar_left"
        panel:position="left" 
        >

        <Button
            android:id="@+id/panelHandle"
            android:layout_width="33dip"
            android:layout_height="wrap_content" />
	<HorizontalScrollView 
	     android:id="@+id/panelContent"
	        android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="#556699"
            android:fillViewport="true" 
            android:scrollbars="none">
        <LinearLayout
           android:id="@+id/panelContentLl"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="@drawable/foot_bar"
            android:gravity="center"
            android:orientation="horizontal" >
        </LinearLayout>
        </HorizontalScrollView>
    </com.pepper.panel.Panel>

</RelativeLayout>

源码地址:http://download.csdn.net/detail/bx276626237/8895319


你可能感兴趣的:(Android 滑动抽屉)