package fwp.demo.panel;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.GestureDetector.OnGestureListener;
import android.view.animation.Animation;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import android.view.animation.TranslateAnimation;
import android.view.animation.Animation.AnimationListener;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
public class SlidingDrawerXpanel extends LinearLayout {
private static final String TAG = "Panel";
/**
* Callback invoked when the panel is opened/closed.
*/
public static interface OnPanelListener {
/**
* Invoked when the panel becomes fully closed.
*/
public void onPanelClosed(SlidingDrawerXpanel panel);
/**
* Invoked when the panel becomes fully opened.
*/
public void onPanelOpened(SlidingDrawerXpanel slidingDrawerXpanel);
}
private boolean mIsShrinking;
private int mPosition;
private int mDuration;
private boolean mLinearFlying;
private int mHandleId;
private int mHandleBtnId;
private int mContentId;
private View mHandle;
private View mHandlebtn;
private View mContent;
private Drawable mOpenedHandle;
private Drawable mClosedHandle;
private float mTrackX;
private float mTrackY;
private float mVelocity;
private OnPanelListener panelListener;
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 enum State {
ABOUT_TO_ANIMATE, ANIMATING, READY, TRACKING, FLYING,
};
private State mState;
private Interpolator mInterpolator;
private GestureDetector mGestureDetector;
private int mContentHeight;
private int mContentWidth;
private int mOrientation;
private float mWeight;
private PanelOnGestureListener mGestureListener;
private boolean mBringToFront;
public SlidingDrawerXpanel(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Panel);
mDuration = a.getInteger(R.styleable.Panel_animationDuration, 750); // duration
// defaults
// to
// 750
// ms
mPosition = a.getInteger(R.styleable.Panel_position, BOTTOM); // position
// defaults
// to
// BOTTOM
mLinearFlying = a.getBoolean(R.styleable.Panel_linearFlying, false); // linearFlying
// defaults
// to
// false
mWeight = a.getFraction(R.styleable.Panel_weight, 0, 1, 0.0f); // weight
// defaults
// to
// 0.0
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.");
}
mHandleBtnId = a.getResourceId(R.styleable.Panel_handlebtn, 0);
if (mHandleBtnId == 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();
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);
}
/**
* 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;
}
/**
* Gets Panel's mHandle
*
* @return Panel's mHandle
*/
public View getHandle() {
return mHandle;
}
/**
* Gets Panel's mContent
*
* @return Panel's mContent
*/
public View getContent() {
return mContent;
}
/**
* Sets the acceleration curve for panel's animation.
*
* @param i
* The interpolator which defines the acceleration curve
*/
public void setInterpolator(Interpolator i) {
mInterpolator = i;
}
/**
* 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);
}
post(startAnimation);
} else {
mContent.setVisibility(open ? VISIBLE : GONE);
postProcess();
}
return true;
}
return false;
}
/**
* Returns the opened status for Panel.
*
* @return True if Panel is opened, false otherwise.
*/
public boolean isOpen() {
return mContent.getVisibility() == VISIBLE;
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mHandle = findViewById(mHandleId);
mHandlebtn = findViewById(mHandleBtnId);
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 + "'");
}
if (mHandlebtn == null) {
String name = getResources().getResourceEntryName(mHandleBtnId);
throw new RuntimeException(
"Your Panel must have a child View whose id attribute is 'R.id."
+ name + "'");
}
mHandlebtn.setOnTouchListener(touchListener);
mHandlebtn.setOnClickListener(clickListener);
// 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 (mClosedHandle != null) {
mHandlebtn.setBackgroundDrawable(mClosedHandle);
}
mContent.setClickable(true);
mContent.setVisibility(GONE);
if (mWeight > 0) {
ViewGroup.LayoutParams params = mContent.getLayoutParams();
if (mOrientation == VERTICAL) {
params.height = ViewGroup.LayoutParams.FILL_PARENT;
} else {
params.width = ViewGroup.LayoutParams.FILL_PARENT;
}
mContent.setLayoutParams(params);
}
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
ViewParent parent = getParent();
if (parent != null && parent instanceof FrameLayout) {
mBringToFront = true;
}
}
@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);
}
@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 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) {
canvas.translate(mTrackX, mTrackY);
}
super.dispatchDraw(canvas);
}
private float ensureRange(float v, int min, int max) {
v = Math.max(v, min);
v = Math.min(v, max);
return v;
}
OnTouchListener touchListener = new OnTouchListener() {
int initX;
int initY;
boolean setInitialPosition;
public boolean onTouch(View v, MotionEvent event) {
if (mState == State.ANIMATING) {
// we are animating
return false;
}
// Log.d(TAG, "state: " + mState + " x: " + event.getX() + " y: " +
// event.getY());
int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN) {
if (mBringToFront) {
bringToFront();
}
initX = 0;
initY = 0;
if (mContent.getVisibility() == GONE) {
// since we may not know content dimensions we use factors
// here
if (mOrientation == VERTICAL) {
initY = mPosition == TOP ? -1 : 1;
} else {
initX = mPosition == LEFT ? -1 : 1;
}
}
setInitialPosition = true;
} else {
if (setInitialPosition) {
// now we know content dimensions, so we multiply factors...
initX *= mContentWidth;
initY *= mContentHeight;
// ... and set initial panel's position
mGestureListener.setScroll(initX, initY);
setInitialPosition = false;
// for offsetLocation we have to invert values
initX = -initX;
initY = -initY;
}
// offset every ACTION_MOVE & ACTION_UP event
event.offsetLocation(initX, initY);
}
if (!mGestureDetector.onTouchEvent(event)) {
if (action == MotionEvent.ACTION_UP) {
// tup up after scrolling
post(startAnimation);
}
}
return false;
}
};
OnClickListener clickListener = new OnClickListener() {
public void onClick(View v) {
if (mBringToFront) {
bringToFront();
}
if (initChange()) {
post(startAnimation);
}
}
};
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;
}
Runnable startAnimation = new Runnable() {
public void run() {
// this is why we post this Runnable couple of lines above:
// now its save to use mContent.getHeight() && mContent.getWidth()
TranslateAnimation animation;
int fromXDelta = 0, toXDelta = 0, fromYDelta = 0, toYDelta = 0;
if (mState == State.FLYING) {
mIsShrinking = (mPosition == TOP || mPosition == LEFT)
^ (mVelocity > 0);
}
int calculatedDuration;
if (mOrientation == VERTICAL) {
int height = mContentHeight;
if (!mIsShrinking) {
fromYDelta = mPosition == TOP ? -height : height;
} else {
toYDelta = mPosition == TOP ? -height : height;
}
if (mState == State.TRACKING) {
if (Math.abs(mTrackY - fromYDelta) < Math.abs(mTrackY
- toYDelta)) {
mIsShrinking = !mIsShrinking;
toYDelta = fromYDelta;
}
fromYDelta = (int) mTrackY;
} else if (mState == State.FLYING) {
fromYDelta = (int) mTrackY;
}
// for FLYING events we calculate animation duration based on
// flying velocity
// also for very high velocity make sure duration >= 20 ms
if (mState == State.FLYING && mLinearFlying) {
calculatedDuration = (int) (1000 * Math
.abs((toYDelta - fromYDelta) / mVelocity));
calculatedDuration = Math.max(calculatedDuration, 20);
} else {
calculatedDuration = mDuration
* Math.abs(toYDelta - fromYDelta) / mContentHeight;
}
} else {
int width = mContentWidth;
if (!mIsShrinking) {
fromXDelta = mPosition == LEFT ? -width : width;
} else {
toXDelta = mPosition == LEFT ? -width : width;
}
if (mState == State.TRACKING) {
if (Math.abs(mTrackX - fromXDelta) < Math.abs(mTrackX
- toXDelta)) {
mIsShrinking = !mIsShrinking;
toXDelta = fromXDelta;
}
fromXDelta = (int) mTrackX;
} else if (mState == State.FLYING) {
fromXDelta = (int) mTrackX;
}
// for FLYING events we calculate animation duration based on
// flying velocity
// also for very high velocity make sure duration >= 20 ms
if (mState == State.FLYING && mLinearFlying) {
calculatedDuration = (int) (1000 * Math
.abs((toXDelta - fromXDelta) / mVelocity));
calculatedDuration = Math.max(calculatedDuration, 20);
} else {
calculatedDuration = mDuration
* Math.abs(toXDelta - fromXDelta) / mContentWidth;
}
}
mTrackX = mTrackY = 0;
if (calculatedDuration == 0) {
mState = State.READY;
if (mIsShrinking) {
mContent.setVisibility(GONE);
}
postProcess();
return;
}
animation = new TranslateAnimation(fromXDelta, toXDelta,
fromYDelta, toYDelta);
animation.setDuration(calculatedDuration);
animation.setAnimationListener(animationListener);
if (mState == State.FLYING && mLinearFlying) {
animation.setInterpolator(new LinearInterpolator());
} else if (mInterpolator != null) {
animation.setInterpolator(mInterpolator);
}
startAnimation(animation);
}
};
private AnimationListener animationListener = new AnimationListener() {
public void onAnimationEnd(Animation animation) {
mState = State.READY;
if (mIsShrinking) {
mContent.setVisibility(GONE);
}
postProcess();
}
public void onAnimationRepeat(Animation animation) {
}
public void onAnimationStart(Animation animation) {
mState = State.ANIMATING;
}
};
private void postProcess() {
if (mIsShrinking && mClosedHandle != null) {
mHandlebtn.setBackgroundDrawable(mClosedHandle);
} else if (!mIsShrinking && mOpenedHandle != null) {
mHandlebtn.setBackgroundDrawable(mOpenedHandle);
}
// invoke listener if any
if (panelListener != null) {
if (mIsShrinking) {
panelListener.onPanelClosed(SlidingDrawerXpanel.this);
} else {
panelListener.onPanelOpened(SlidingDrawerXpanel.this);
}
}
}
class PanelOnGestureListener implements OnGestureListener {
float scrollY;
float scrollX;
public void setScroll(int initScrollX, int initScrollY) {
scrollX = initScrollX;
scrollY = initScrollY;
}
public boolean onDown(MotionEvent e) {
scrollX = scrollY = 0;
initChange();
return true;
}
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
mState = State.FLYING;
mVelocity = mOrientation == VERTICAL ? velocityY : velocityX;
post(startAnimation);
return true;
}
public void onLongPress(MotionEvent e) {
// not used
}
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();
}
return true;
}
public void onShowPress(MotionEvent e) {
// not used
}
public boolean onSingleTapUp(MotionEvent e) {
// not used
return false;
}
}
}
调用
package fwp.demo.panel;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.Toast;
import android.widget.PopupWindow.OnDismissListener;
import android.widget.SimpleAdapter;
public class TestSlidingDrawerPopwindowActivity extends Activity {
Button expandBtn = null;
boolean isOpen = false;
PopupWindow popupWindow = null;
private boolean isPopwindowopen = false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.frmtestactivity);
expandBtn = (Button) findViewById(R.id.btnslidingdrawer);
expandBtn.setText("打开");
expandBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Log.e("tag", "expandBtn.click:isPopwindowopen="
+ isPopwindowopen);
if (isPopwindowopen) {
if (popupWindow != null) {
if (popupWindow.isShowing()) {
popupWindow.dismiss();
}
}
expandBtn.setText("打开");
} else {
// 关闭状态
if (popupWindow == null) {
popupWindow = MakePopupWindow();
}
int[] xy = new int[2];
v.getLocationOnScreen(xy);
// popupWindow.showAtLocation(v, Gravity.CENTER,-xy[0] / 2,
// xy[1] + v.getWidth());
// popupWindow.showAsDropDown(button,0, 0);
popupWindow.showAsDropDown(v);
expandBtn.setText("关闭");
}
isPopwindowopen = !isPopwindowopen;
}
});
ListView mListView = (ListView) findViewById(R.id.listView1);
final List<String> listItem = new ArrayList<String>();
for (int i = 0; i < 10; i++) {
listItem.add("Level " + i + " Finished in 1 Min 54 Secs, 70 Moves!");
}
mListView.setAdapter(new ArrayAdapter<String>(
TestSlidingDrawerPopwindowActivity.this,
android.R.layout.simple_list_item_1, android.R.id.text1,
listItem));
mListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
Toast.makeText(TestSlidingDrawerPopwindowActivity.this,
"position=" + arg2 + listItem.get(arg2),
Toast.LENGTH_SHORT).show();
}
});
}
/**
* 创建导航菜单的下拉菜单popwindow
*
* @param cx
* @return
*/
PopupWindow MakePopupWindow() {
PopupWindow window;
View contentView = LayoutInflater.from(
TestSlidingDrawerPopwindowActivity.this).inflate(
R.layout.mainthree, null);
window = new PopupWindow(contentView, LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT);
// window.setContentView(contentView);
// window.setBackgroundDrawable(getResources().getDrawable(R.drawable.pop_bg));
window.setBackgroundDrawable(new ColorDrawable(R.color.xxxer));
// window.setWidth(150);
// window.setHeight(150);
window.setOnDismissListener(new OnDismissListener() {
@Override
public void onDismiss() {
isPopwindowopen=false;
expandBtn.setText("打开");
}
});
// 设置PopupWindow外部区域是否可触摸
window.setFocusable(true); // 设置PopupWindow可获得焦点
window.setTouchable(true); // 设置PopupWindow可触摸
window.setOutsideTouchable(true); // 设置非PopupWindow区域可触摸
return window;
}
}
popwindow的布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:panel="http://schemas.android.com/apk/res/fwp.demo.panel"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<fwp.demo.panel.SlidingDrawerXpanel
android:id="@+id/topPanel"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#ff99ff99"
android:gravity="center"
panel:animationDuration="1000"
panel:closedHandle="@drawable/top_switcher_collapsed_background"
panel:content="@+id/panelContent"
panel:handle="@+id/panelHandle"
panel:handlebtn="@+id/mbutton"
panel:linearFlying="true"
panel:openedHandle="@drawable/top_switcher_expanded_background"
panel:position="top" >
<LinearLayout
android:id="@+id/panelHandle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="#ffccff99"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/mainlayoutbg"
android:gravity="center_vertical|center_horizontal" >
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="yyyyy"
android:textAppearance="?android:attr/textAppearanceMedium" />
<Button
android:id="@+id/BtnChangeBusType"
android:layout_width="150dip"
android:layout_height="30dip"
android:layout_marginLeft="10dip"
android:background="@drawable/frame"
android:text="zzzzzzzz"
android:textColor="@color/white" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/mainlayoutbg"
android:gravity="center_vertical|center_horizontal" >
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="yyyyy"
android:textAppearance="?android:attr/textAppearanceMedium" />
<Button
android:id="@+id/BtnChangeBusType"
android:layout_width="150dip"
android:layout_height="30dip"
android:layout_marginLeft="10dip"
android:background="@drawable/frame"
android:text="zzzzzzzz"
android:textColor="@color/white" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" >
<ImageButton
android:id="@+id/mbutton"
android:layout_width="160dip"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="up" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/panelContent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ffffffcc"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical|center_horizontal" >
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="yyyyy"
android:textAppearance="?android:attr/textAppearanceMedium" />
<Button
android:id="@+id/BtnChangeBusType"
android:layout_width="150dip"
android:layout_height="30dip"
android:layout_marginLeft="10dip"
android:background="@drawable/frame"
android:text="zzzzzzzz"
android:textColor="@color/white" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical|center_horizontal" >
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="yyyyy"
android:textAppearance="?android:attr/textAppearanceMedium" />
<Button
android:id="@+id/BtnChangeBusType"
android:layout_width="150dip"
android:layout_height="30dip"
android:layout_marginLeft="10dip"
android:background="@drawable/frame"
android:text="zzzzzzzz"
android:textColor="@color/white" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical|center_horizontal" >
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="yyyyy"
android:textAppearance="?android:attr/textAppearanceMedium" />
<Button
android:id="@+id/BtnChangeBusType"
android:layout_width="150dip"
android:layout_height="30dip"
android:layout_marginLeft="10dip"
android:background="@drawable/frame"
android:text="zzzzzzzz"
android:textColor="@color/white" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical|center_horizontal" >
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="yyyyy"
android:textAppearance="?android:attr/textAppearanceMedium" />
<Button
android:id="@+id/BtnChangeBusType"
android:layout_width="150dip"
android:layout_height="30dip"
android:layout_marginLeft="10dip"
android:background="@drawable/frame"
android:text="zzzzzzzz"
android:textColor="@color/white" />
</LinearLayout>
</LinearLayout>
</fwp.demo.panel.SlidingDrawerXpanel>
</LinearLayout>
主界面
<?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="#ffffffff"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:id="@+id/btnslidingdrawer"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:text="Button" />
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/black" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/black" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.24"
android:orientation="vertical" >
<ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/viewfinder_frame" >
</ListView>
</LinearLayout>
</LinearLayout>
attrs
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="Panel">
<!-- 需要展示的其他的layout -->
<attr name="otherhandle" format="reference"></attr>
<!-- Defines panel animation duration in ms. -->
<attr name="animationDurationpanel" format="integer" />
<attr name="animationDuration" format="integer" />
<!-- Defines panel position on the screen. -->
<attr name="position">
<!-- Panel placed at top of the screen. -->
<enum name="top" value="0" />
<!-- Panel placed at bottom of the screen. -->
<enum name="bottom" value="1" />
<!-- Panel placed at left of the screen. -->
<enum name="left" value="2" />
<!-- Panel placed at right of the screen. -->
<enum name="right" value="3" />
</attr>
<!-- Identifier for the child that represents the panel's handle. -->
<attr name="handle" format="reference" />
<!-- Identifier for the child that represents the panel's handle button. -->
<attr name="handlebtn" format="reference" />
<!-- Identifier for the child that represents the panel's content. -->
<attr name="content" format="reference" />
<!-- Defines if flying gesture forces linear interpolator in animation. -->
<attr name="linearFlying" format="boolean" />
<!-- Defines size relative to parent (must be in form: nn%p). -->
<attr name="weight" format="fraction" />
<!-- Defines opened handle (drawable/color). -->
<attr name="openedHandle" format="reference|color" />
<!-- Defines closed handle (drawable/color). -->
<attr name="closedHandle" format="reference|color" />
</declare-styleable>
</resources>