类SldingDrawer的实现

来自海涛给的例子,谢谢海涛一直的指导!

系统的slidingDrawer貌似只能从下往上,或者从右往左!

这个例子是 实现 任意方向,当然你可以将布局改为相对布局将其放在任何地方

其实就是一个自定义组件,然后将其放在 你的主程序的布局中,类似slidingDrawer那样:

一个handler,一个content布局

自定义组件的class:

public class PanelView extends LinearLayout {
private int mDuration;
private int mPosition;
private Boolean isAnimation;
private int mOrientation;
private int BOTTOM = 1;
private int TOP = 0;
private int LEFT = 2;
private int RIGHT = 3;
private Drawable mOpenedHandle;
private Drawable mClosedHandle;
private Button mHandle;
private LinearLayout mContent;

public PanelView(Context context, AttributeSet attrs) {
super(context, attrs);

TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Panel);

mDuration = a.getInteger(R.styleable.Panel_animationDuration, 750);
mPosition = a.getInteger(R.styleable.Panel_position, BOTTOM);
isAnimation = a.getBoolean(R.styleable.Panel_animationEnable, true);
a.recycle();

// 根据mPosition 决定LinearLayout的android:orientation属性
mOrientation = (mPosition == TOP || mPosition == BOTTOM) ? VERTICAL
: HORIZONTAL;
setOrientation(mOrientation);

initialHandlerBg();
}

// 设置mHandle所用背景图
private void initialHandlerBg() {

if (mPosition == LEFT) {
mOpenedHandle = getResources().getDrawable(
R.drawable.right_switcher_expanded_background);
mClosedHandle = getResources().getDrawable(
R.drawable.left_switcher_expanded_background);

} else if(mPosition == TOP){
mOpenedHandle = getResources().getDrawable(
R.drawable.top_switcher_collapsed_background);
mClosedHandle = getResources().getDrawable(
R.drawable.top_switcher_expanded_background);
} else {
mOpenedHandle = getResources().getDrawable(
R.drawable.left_switcher_collapsed_background);
mClosedHandle = getResources().getDrawable(
R.drawable.right_switcher_expanded_background);

}
}

// 回调函数 界面初始化快结束时调用 用于得到 mHandle/mContent
protected void onFinishInflate() {
super.onFinishInflate();
// 得到mHandle实例
mHandle = (Button) this.getChildAt(0);

if (mHandle == null) {
throw new RuntimeException("Your Panel must have a View - mHandle");
}
mHandle.setOnClickListener(clickListener);

mContent = (LinearLayout) this.getChildAt(1);
if (mContent == null) {
throw new RuntimeException("Your Panel must have a View - mContent");
}

// 先移除mHandle/mContent 然后根据position决定二者的添加次序
removeView(mHandle);
removeView(mContent);

if (mPosition == TOP || mPosition == LEFT) {
addView(mContent);
addView(mHandle);
} else {
addView(mHandle);
addView(mContent);
}

if (mClosedHandle != null) {
mHandle.setBackgroundDrawable(mClosedHandle);
}

// 隐藏 mContent
mContent.setVisibility(GONE);

}

private int mContentWidth=200;
private int mContentHeight=100;
private int paddingTop;
private int paddingLeft;
private Boolean isContentExpand = false;

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

paddingTop = this.getPaddingTop();
paddingLeft = this.getPaddingLeft();

}

// 定义mHandle监听器 用于开合mContent
OnClickListener clickListener = new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (!isContentExpand) {
open();
} else {
close();
}

// 置反 即:开-合-开-合-开-...
isContentExpand = !isContentExpand;

}
};

// 回调函数 用于监听 Panel 的开合 效果见:setOnClickLstener(OnClickListener listener)
public static interface OnPanelListener {
// - open
public void onPanelOpened(PanelView panel);

// - close
public void onPanelClosed(PanelView panel);
}

public void open() {
if (isAnimation) {
doAnimationOpen();
} else {
doOpen();
}

}

public void doOpen() {
mContent.setVisibility(VISIBLE);

}

public void doAnimationOpen() {

post(aOpen);

}

Runnable aOpen = new Runnable() {
public void run() {
TranslateAnimation animation;
int fromXDelta = 0, toXDelta = 0, fromYDelta = 0, toYDelta = 0;
int calculatedDuration = 0;

if (mPosition == TOP) {
fromYDelta = -1 * mContentHeight;
toXDelta = 0;

calculatedDuration = mDuration
* Math.abs(toYDelta - fromYDelta) / mContentHeight;
} else if (mPosition == BOTTOM) {
fromYDelta = paddingTop;
toYDelta = fromYDelta + 1 * mContentHeight;

calculatedDuration = mDuration
* Math.abs(toYDelta - fromYDelta) / mContentHeight;
} else if (mPosition == LEFT) {
fromXDelta = -1 * mContentWidth;
toXDelta= 0;

calculatedDuration = mDuration
* Math.abs(toXDelta - fromXDelta) / mContentWidth;
} else if (mPosition == RIGHT) {
fromXDelta = paddingLeft;
toXDelta = fromYDelta + 1 * mContentHeight;

calculatedDuration = mDuration
* Math.abs(toYDelta - fromYDelta) / mContentHeight;
}

animation = new TranslateAnimation(fromXDelta, toXDelta,
fromYDelta, toYDelta);
animation.setDuration(calculatedDuration);
animation.setAnimationListener(new AnimationListener() {

@Override
public void onAnimationStart(Animation animation) {
mContent.setVisibility(VISIBLE);
}

@Override
public void onAnimationRepeat(Animation animation) {

}

@Override
public void onAnimationEnd(Animation animation) {
postProcess();
}
});
startAnimation(animation);

}
};

public void close() {
if (isAnimation) {
doAnimationClose();
} else {
doClose();
}
}

public void doClose() {
mContent.setVisibility(GONE);

}

public void doAnimationClose() {
post(aClose);

}

Runnable aClose = new Runnable() {
public void run() {
TranslateAnimation animation;
int fromXDelta = 0, toXDelta = 0, fromYDelta = 0, toYDelta = 0;
int calculatedDuration = 0;

if (mPosition == TOP) {
toYDelta = -1 * mContentHeight;

calculatedDuration = mDuration
* Math.abs(toYDelta - fromYDelta) / mContentHeight;
} else if (mPosition == BOTTOM) {
fromYDelta = 1 * mContentHeight;
toYDelta = paddingTop;

calculatedDuration = mDuration
* Math.abs(toYDelta - fromYDelta) / mContentHeight;
} else if (mPosition == LEFT) {

toXDelta = -1 * mContentWidth;

calculatedDuration = mDuration
* Math.abs(toXDelta - fromXDelta) / mContentWidth;
} else if (mPosition == RIGHT) {

}

animation = new TranslateAnimation(fromXDelta, toXDelta,
fromYDelta, toYDelta);
animation.setDuration(calculatedDuration);
animation.setAnimationListener(new AnimationListener() {

@Override
public void onAnimationStart(Animation animation) {

}

@Override
public void onAnimationRepeat(Animation animation) {

}

@Override
public void onAnimationEnd(Animation animation) {
mContent.setVisibility(View.GONE);
postProcess();
}
});
startAnimation(animation);
}
};
private OnPanelListener panelListener;

// 善后工作 比如:改变mHandle背景图 通知开合监听器
private void postProcess() {
if (!isContentExpand) {
mHandle.setBackgroundDrawable(mClosedHandle);
} else {
mHandle.setBackgroundDrawable( mOpenedHandle);
}

if (panelListener != null) {
if (isContentExpand) {
panelListener.onPanelOpened(PanelView.this);

} else {
panelListener.onPanelClosed(PanelView.this);

}
}
}

}


图片自己去搞定咯,随便找个做个测试就可以!

主程序的布局里面 此组件的例子:

<com.SildingDrawPanel.PanelView
android:id="@+id/leftPanel" android:layout_width="wrap_content"
android:layout_height="wrap_content" panel:position="left"
panel:animationDuration="500" panel:animationEnable="true"
android:layout_gravity="left">
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<LinearLayout android:orientation="vertical"
android:layout_width="wrap_content" android:layout_height="wrap_content">
//content
</LinearLayout>
</com.SildingDrawPanel.PanelView>


组件里面用到的attrs

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="Panel">
<attr name="animationDuration" format="integer" />
<attr name="position">
<enum name="top" value="0" />
<enum name="bottom" value="1" />
<enum name="left" value="2" />
<enum name="right" value="3" />

</attr>
<attr name="animationEnable" format="boolean" />
</declare-styleable>
</resources>


好了 附上工程
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值