本文主要介绍如何利用PopupWindow实现在屏幕底部弹出分享菜单.
先来看一下效果图吧.点击分享按钮,从下方弹出分享菜单
布局
第一步是要实现菜单的布局popup_menu_share.xml
<?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="wrap_content"
android:layout_gravity="bottom"
android:background="@color/popup_bg"
android:divider="@drawable/divider"
android:orientation="vertical"
android:showDividers="middle">
<RelativeLayout
android:id="@+id/rl_wechat"
style="@style/menu_item"
android:layout_marginTop="@dimen/menu_layout_margin">
<TextView
android:id="@+id/tv_wechat"
style="@style/menu_textView"
android:text="@string/share_to_wechat" />
<ImageView
style="@style/menu_img"
android:layout_toLeftOf="@id/tv_wechat"
android:src="@drawable/ic_wechat" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/rl_wechat_mm"
style="@style/menu_item">
<TextView
android:id="@+id/tv_wechat_mm"
style="@style/menu_textView"
android:text="@string/share_to_wechat_mm" />
<ImageView
style="@style/menu_img"
android:layout_toLeftOf="@id/tv_wechat_mm"
android:src="@drawable/ic_wechat_mm" />
</RelativeLayout>
<Button
android:id="@+id/btn_cancle"
style="@style/menu_item"
android:layout_marginBottom="@dimen/menu_view_margin"
android:text="@string/share_cancel"
android:textColor="@color/white" />
</LinearLayout>
资源引用
res/values/color.xml
<color name="white">#FFFFFFFF</color>
<color name="popup_bg">#f2f2f2</color>
<color name="light_black">#a8a8a8</color>
res/values/dimen.xml
<dimen name="menu_item_height">45dp</dimen>
<dimen name="menu_img_width">30dp</dimen>
<dimen name="menu_img_height">30dp</dimen>
<dimen name="menu_text_size">16sp</dimen>
<dimen name="menu_view_margin">15dp</dimen>
<dimen name="menu_layout_margin">20dp</dimen>
res/values/styles.xml
<style name="menu_item">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">@dimen/menu_item_height</item>
<item name="android:layout_gravity">center_horizontal</item>
<item name="android:layout_marginLeft">@dimen/menu_layout_margin</item>
<item name="android:layout_marginRight">@dimen/menu_layout_margin</item>
<item name="android:background">@color/light_black</item>
</style>
<style name="menu_img">
<item name="android:layout_width">@dimen/menu_img_width</item>
<item name="android:layout_height">@dimen/menu_img_height</item>
<item name="android:layout_centerVertical">true</item>
</style>
<style name="menu_textView">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_centerInParent">true</item>
<item name="android:layout_marginLeft">@dimen/menu_view_margin</item>
<item name="android:textSize">@dimen/menu_text_size</item>
<item name="android:textColor">@color/white</item>
</style>
res/drawable/divider.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<solid android:color="@color/popup_bg"/>
<size android:height="1dp" />
</shape>
</item>
</selector>
实现
关于菜单的显示主要在initPopupWindow()
函数中
private void initPopupWindow() {
View menuView = View.inflate(mContext, R.layout.popup_menu_share, null);
menuView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mPopupWindow.dismiss();
}
});
// share to wechat
menuView.findViewById(R.id.rl_wechat).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(mContext, getString(R.string.share_to_wechat), Toast.LENGTH_LONG).show();
}
});
// share to wechat_mm
menuView.findViewById(R.id.rl_wechat_mm).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(mContext, getString(R.string.share_to_wechat_mm), Toast.LENGTH_LONG).show();
}
});
// cancel
menuView.findViewById(R.id.btn_cancle).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mPopupWindow.dismiss();
}
});
mPopupWindow = new PopupWindow(this);
mPopupWindow.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
mPopupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
mPopupWindow.setBackgroundDrawable(new ColorDrawable(0x000000));
mPopupWindow.setFocusable(true);
mPopupWindow.setOutsideTouchable(true);
mPopupWindow.setContentView(menuView);
mPopupWindow.showAtLocation(cancelBtn, Gravity.BOTTOM, 0, 0);
mPopupWindow.update();
}
需要注意的是popupWindow的宽和高一定要设置,否则无法显示.
如果没有意外的话,点击按钮,就能看到这样的效果了
等一下,细心的朋友可能会发现这个结果和上面效果图不一样啊.效果图中菜单外的地方背景变暗了,而我们实现的效果并没有这样的效果.别急,下面就来实现
改变背景
让背景变暗其实很简单,只需要改变窗口的透明度即可.
private void setWindowAlpha(float alpha) {
WindowManager.LayoutParams lp=getWindow().getAttributes();
lp.alpha = alpha;
getWindow().setAttributes(lp);
}
然后在initPopupWindow()
中添加
// 弹出菜单后设置透明度
setWindowAlpha(0.3f);
// 菜单消失后取消透明效果
mPopupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
@Override
public void onDismiss() {
setWindowAlpha(1f);
}
});
好了,这样就可以看到最上面的效果图了.
改进
你以为这样就结束了吗?还没有呢!添加完上面的代码之后虽然虽然结果一样了,但是过程很痛苦啊.想一想,一点击按钮就突然给你冒出个菜单出来,这交互太不友好了.所以接下来是要向菜单添加动画效果.这里要实现的主要是平移动画.
res/anim/menu_bottom_in.xml
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="300"
android:fromYDelta="100%"
android:interpolator="@android:anim/decelerate_interpolator"
android:toYDelta="0" />
res/anim/menu_bottom_out.xml
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="300"
android:fromYDelta="0"
android:interpolator="@android:anim/decelerate_interpolator"
android:toYDelta="100.0%" />
res/values/styles.xml
<style name="anim_menu_bottombar">
<item name="android:windowEnterAnimation">@anim/menu_bottombar_in</item>
<item name="android:windowExitAnimation">@anim/menu_bottombar_out</item>
</style>
最后在initPopupWindow()
中添加
mPopupWindow.setAnimationStyle(R.style.anim_menu_bottombar);
好了,现在再次点击按钮就可以看到动画效果了~
希望以上内容可以帮到你.