滑动抽屉

                            

 

[java] view plaincopyprint?
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

posted @ 2015-07-13 15:20  Pepper.B  阅读(294)  评论(0编辑  收藏  举报