PopupWindow在android中的使用分析
PopupWindow是应用开发中经常用到的组建,使用它可以在当前屏幕的上层显示一个弹窗,同时也可以指定弹窗的位置以及背景色等特性,大大提高用户体验,那么这里我就以下几点介绍它的使用:
1
从指定的位置弹出这个窗口(淡入淡出动画)
2
从屏幕底部弹出这个窗口(带有透明度背景,自定义触摸其他位置自动关闭弹窗)
我的效果图如下:
下面直接上代码,具体如下所示(按开发顺序排列)
1
自定义一个继承自PopupWindow的类
publicclassPopupDialog
extendsPopupWindow {
publicPopupDialog(View
view,intwidth,intheight)
{
super(view,width,height);
}
}
2自定义一个负责设定PopupWindow特性的属性类
publicclassPopup
{
privateintxPos;
//弹出窗口的x方向位置
privateintyPos;
//弹出窗口的y方向位置
privateintvWidth;
//窗口显示内容的视图宽度
privateintvHeight;
//窗口显示内容的视图高度
privateintanimFadeInOut;
//窗口显示动画
privateintcontentView;
//潜入在窗口的视图
privateView
customView;
//潜入的窗口视图view
privatebooleanisClickable;
//视图外部是否可以点击
privateOnDismissListener
listener;
//监听弹窗是否dismiss
privateOnTouchListener
touchListener;
//监听触摸位置
privatefloatbgAlpha;
//背景遮罩的透明度
publicintgetxPos()
{
returnxPos;
}
publicvoidsetxPos(intxPos)
{
this.xPos=
xPos;
}
publicintgetyPos()
{
returnyPos;
}
publicvoidsetyPos(intypos)
{
this.yPos=
ypos;
}
publicintgetvWidth()
{
returnvWidth;
}
publicvoidsetvWidth(intvWidth)
{
this.vWidth=
vWidth;
}
publicintgetvHeight()
{
returnvHeight;
}
publicvoidsetvHeight(intvHeight)
{
this.vHeight=
vHeight;
}
publicintgetAnimFadeInOut()
{
returnanimFadeInOut;
}
publicvoidsetAnimFadeInOut(intanimFadeInOut){
this.animFadeInOut=
animFadeInOut;
}
publicintgetContentView()
{
returncontentView;
}
publicvoidsetContentView(intcontentView){
this.contentView=
contentView;
}
publicbooleanisClickable()
{
returnisClickable;
}
publicvoidsetClickable(booleanisClickable){
this.isClickable=
isClickable;
}
publicView getCustomView() {
returncustomView;
}
publicvoidsetCustomView(View
customView){
this.customView=
customView;
}
publicOnDismissListener getListener()
{
returnlistener;
}
publicvoidsetListener(OnDismissListener
listener){
this.listener=
listener;
}
publicfloatgetBgAlpha()
{
returnbgAlpha;
}
publicvoidsetBgAlpha(floatbgAlpha)
{
this.bgAlpha=
bgAlpha;
}
publicOnTouchListener getTouchListener()
{
returntouchListener;
}
publicvoidsetTouchListener(OnTouchListener
touchListener){
this.touchListener=
touchListener;
}
3
自定义一个用来管理PopupWindow的工具类
publicclassPopupUtils
{
privatestaticPopupDialog
popupDialog=
null;
@SuppressLint("NewApi")
publicstaticPopupDialog
createPopupDialog(Context context,Popupdialog) {
dismissPopupDialog();
Viewview =null;
if(ValueUtils.isEmpty(dialog.getCustomView())){
LayoutInflaterinflater =LayoutInflater.from(context);
view=
inflater.inflate(dialog.getContentView(),null);
}else{
view=
dialog.getCustomView();
}
view.setOnTouchListener(dialog.getTouchListener());
if(0!=
dialog.getBgAlpha()){
view.setAlpha(dialog.getBgAlpha());
}
popupDialog=
newPopupDialog(view,dialog.getvWidth(),dialog.getvHeight());
ColorDrawabledw =
newColorDrawable(Color.TRANSPARENT);
//follow two lines is used for back key -00000
popupDialog.setBackgroundDrawable(dw);
popupDialog.setAnimationStyle(dialog.getAnimFadeInOut());
popupDialog.setOutsideTouchable(dialog.isClickable());
popupDialog.setFocusable(true);
//not allow user click popupwindowbackground event or not permit
popupDialog.setOnDismissListener(dialog.getListener());
popupDialog.update();
returnpopupDialog;
}
publicstaticvoiddismissPopupDialog()
{
if(ValueUtils.isNotEmpty(popupDialog)&&
popupDialog.isShowing()){
popupDialog.dismiss();
popupDialog=
null;
}
}
publicstaticbooleanisPopupShowing()
{
if(ValueUtils.isNotEmpty(popupDialog)&&
popupDialog.isShowing()){
returntrue;
}else{
returnfalse;
}
}
}
接下来,我们需要准备相关的资源文件了,比如:导航按钮页面,采购清单弹窗页面以,选择美图窗口页面以及需要用到的动画文件和圆角背景文件,具体如下:
导航按钮页面xml:
<ScrollViewxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/main"
android:background="#f2f3f4">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<Button
android:id="@+id/btnDropDownPopupDialog"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_gravity="center_horizontal"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp"
android:background="#FFFFFF"
android:textColor="#5084FE"
android:text="采购清单"
/>
<Button
android:id="@+id/btnDownUpPopupDialog"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_gravity="center_horizontal"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp"
android:background="#FFFFFF"
android:textColor="#5084FE"
android:text="选择美图"
/>
</LinearLayout>
</ScrollView>
采购清单弹窗页面xml:
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#c9cbce"
android:gravity="center"
>
<TextView
android:id="@+id/tvbillTypeYc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="粤菜"
android:textColor="#5084FE"
android:padding="10dp"
android:layout_margin="10dp"
android:gravity="center"
android:background="@drawable/corners_bk_gray2"
/>
<TextView
android:id="@+id/tvbillTypeCc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="川菜"
android:textColor="#5084FE"
android:padding="10dp"
android:layout_margin="10dp"
android:gravity="center"
android:layout_below="@id/tvbillTypeYc"
android:background="@drawable/corners_bk_gray2"
/>
<TextView
android:id="@+id/tvbillTypeXc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="湘菜"
android:textColor="#5084FE"
android:padding="10dp"
android:layout_margin="10dp"
android:gravity="center"
android:layout_below="@id/tvbillTypeCc"
android:background="@drawable/corners_bk_gray2"
/>
<TextView
android:id="@+id/tvbillTypeMore"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="..."
android:textColor="#5084FE"
android:padding="10dp"
android:layout_margin="10dp"
android:gravity="center"
android:layout_below="@id/tvbillTypeXc"
android:background="@drawable/corners_bk_gray2"
/>
</RelativeLayout>
选择美图弹窗页面xml:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00000000"
>
<FrameLayout
android:id="@+id/flMaskLayer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
/>
<LinearLayout
android:id="@+id/llHeader"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:orientation="vertical"
android:layout_alignParentBottom="true"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="81.0dp"
android:background="@drawable/corners_bk_white"
>
<TextView
android:id="@+id/tvTakeHeader"
android:layout_width="match_parent"
android:layout_height="40dp"
android:text="拍照"
android:textColor="#5084FE"
android:gravity="center"
/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/gray"
android:layout_centerVertical="true"
/>
<TextView
android:id="@+id/tvHeaderFromSD"
android:layout_width="match_parent"
android:layout_height="40dp"
android:text="从相册中选"
android:textColor="#5084FE"
android:gravity="center"
android:layout_below="@id/tvTakeHeader"
/>
</RelativeLayout>
<TextView
android:id="@+id/tvCancel"
android:layout_width="match_parent"
android:layout_height="40dp"
android:text="取消"
android:textColor="#5084FE"
android:background="@drawable/corners_bk_white"
android:gravity="center"
android:layout_marginTop="18dp"
/>
</LinearLayout>
</RelativeLayout>
淡入淡出动画文件xml:
淡入动画:
<?xmlversion="1.0"encoding="utf-8"standalone="no"?>
<setxmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/decelerate_interpolator">
<alpha
android:duration="500"
android:fromAlpha="0.0"
android:toAlpha="1.0"/>
</set>
淡出动画:
<?xmlversion="1.0"encoding="utf-8"standalone="no"?>
<setxmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/decelerate_interpolator">
<alpha
android:duration="300"
android:fromAlpha="1.0"
android:toAlpha="0.0"/>
</set>
圆角背景文件xml:
采购清单背景:
<?xmlversion="1.0"encoding="utf-8"?>
<shapexmlns:android="http://schemas.android.com/apk/res/android">
<solidandroid:color="#efece0"/>
<corners
android:radius="4dp"/>
<padding
android:bottom="5dp"
android:left="10dp"
android:right="10dp"
android:top="5dp"/>
<stroke
android:width="1dp"
android:color="#efece0"/>
</shape>
底部弹窗:
<?xmlversion="1.0"encoding="utf-8"?>
<shapexmlns:android="http://schemas.android.com/apk/res/android">
<solidandroid:color="#FFFFFF"/>
<corners
android:bottomLeftRadius="6dp"
android:bottomRightRadius="6dp"
android:topLeftRadius="6dp"
android:topRightRadius="6dp"/>
</shape>
到这里,我们已经准备了所有需要的工作,接下来就是在我们的前段页面中调用即可。主要是通过参数对象包装参数,并调用上面的工具类进行展示和隐藏我们需要的PopupWindow即可,具体如下:
publicclassViewUtilsActivity
extendsFragmentActivity {
privatestaticViewUtilsFragment
fragment=
null;
@Override
protectedvoidonCreate(Bundle
bundle){
super.onCreate(bundle);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_base_main);
if(null==
bundle){
FragmentTransactionft =getSupportFragmentManager().beginTransaction();
fragment=
newViewUtilsFragment();
ft.add(R.id.container,fragment);
ft.commit();
}
}
publicclassViewUtilsFragment
extendsFragment
implementsView.OnClickListener {
privatePopupDialog
popupDialog=
null;
privateButton
btnDropDownPopupDialog=
null;
privateButton
btnDownUpPopupDialog=
null;
@Override
publicView onCreateView(LayoutInflater
inflater,ViewGroup
container,
BundlesavedInstanceState){
ViewrootView =(View)
inflater.inflate(R.layout.fragment_viewutils,container,false);
btnDropDownPopupDialog= (Button)rootView.findViewById(R.id.btnDropDownPopupDialog);
btnDropDownPopupDialog.setOnClickListener(this);
btnDownUpPopupDialog= (Button)
rootView.findViewById(R.id.btnDownUpPopupDialog);
btnDownUpPopupDialog.setOnClickListener(this);
returnrootView;
}
@Override
publicvoidonClick(View
v){
switch(v.getId()){
caseR.id.btnDropDownPopupDialog:
showDropDownPopupDialog();
break;
caseR.id.btnDownUpPopupDialog:
showDownUpPopupDialog();
break;
default:
break;
}
}
privatevoidshowDropDownPopupDialog()
{
Popuppopup =
newPopup();
//这里是获得屏幕宽度使弹窗水平居中
intxPos
=(AppUtils.getScreenWidth(getActivity())-
btnDropDownPopupDialog.getWidth())/ 2;
popup.setxPos(xPos);
popup.setyPos(0);
popup.setvWidth(LayoutParams.WRAP_CONTENT);
popup.setvHeight(LayoutParams.WRAP_CONTENT);
popup.setClickable(true);
popup.setAnimFadeInOut(R.style.AnimationFade);
popup.setContentView(R.layout.view_popup_dialog);
popupDialog= ViewUtils.createPopupDialog(getActivity(),popup);
popupDialog.showAsDropDown(btnDropDownPopupDialog,popup.getxPos(),popup.getyPos());
}
@SuppressLint({"NewApi","ClickableViewAccessibility"})
privatevoidshowDownUpPopupDialog()
{
Popuppopup =
newPopup();
popup.setvWidth(LayoutParams.MATCH_PARENT);
popup.setvHeight(LayoutParams.MATCH_PARENT);
popup.setClickable(true);
popup.setContentView(R.layout.view_userheader_modifydetail);
//设置触摸其他位置时关闭窗口
OnTouchListenerlistener =newOnTouchListener()
{
@Override
publicbooleanonTouch(View
view,MotionEvent
event){
intheight
=view.findViewById(R.id.llHeader).getTop();
inty
= (int)event.getY();
if(event.getAction()==MotionEvent.ACTION_UP){
if(y<height){
ViewUtils.dismissPopupDialog();
}
}
returntrue;
}
};
popup.setTouchListener(listener);
popupDialog= ViewUtils.createPopupDialog(getActivity(),popup);
popupDialog.showAtLocation(getActivity().findViewById(R.id.main),
Gravity.BOTTOM|Gravity.CENTER_HORIZONTAL,popup.getxPos(),popup.getyPos());
Viewview =popupDialog.getContentView();
//背景透明度设置
view.findViewById(R.id.flMaskLayer).setAlpha(0.75f);
View.OnClickListenerl =
newView.OnClickListener() {
@Override
publicvoidonClick(View
v){
if(v.getId()==
R.id.tvCancel){
ViewUtils.dismissPopupDialog();
}
elseif(v.getId()==
R.id.tvTakeHeader){
//take phone
Toast.makeText(getActivity(),"拍照",Toast.LENGTH_SHORT).show();
ViewUtils.dismissPopupDialog();
}
elseif(v.getId()==
R.id.tvHeaderFromSD){
//pick picture from
sd
Toast.makeText(getActivity(),"从相册中选",Toast.LENGTH_SHORT).show();
ViewUtils.dismissPopupDialog();
}
}
};
view.findViewById(R.id.tvCancel).setOnClickListener(l);
view.findViewById(R.id.tvTakeHeader).setOnClickListener(l);
view.findViewById(R.id.tvHeaderFromSD).setOnClickListener(l);
}
publicPopupDialog getPopupDialog()
{
returnpopupDialog;
}
}
//监听返回按钮
@Override
publicbooleanonKeyDown(intkeyCode,KeyEvent
event){
switch(keyCode){
caseKeyEvent.KEYCODE_BACK:
{
booleanflag
=ViewUtils.isPopupShowing();
if(flag){
ViewUtils.dismissPopupDialog();
returnfalse;
}
}
break;
default:
break;
}
returnsuper.onKeyDown(keyCode,event);
}
好了,到这里我们的工作就完成啦,可以欣赏自己的作品了。
如果有问题,可以在评论中或群(179914858)进行讨论,谢谢。