首页 > 代码库 > PopupWindow在android中的使用分析
PopupWindow在android中的使用分析
PopupWindow在android中的使用分析
PopupWindow是应用开发中经常用到的组建,使用它可以在当前屏幕的上层显示一个弹窗,同时也可以指定弹窗的位置以及背景色等特性,大大提高用户体验,那么这里我就以下几点介绍它的使用:
1从指定的位置弹出这个窗口(淡入淡出动画)
2从屏幕底部弹出这个窗口(带有透明度背景,自定义触摸其他位置自动关闭弹窗)
我的效果图如下:
下面直接上代码,具体如下所示(按开发顺序排列)
1自定义一个继承自PopupWindow的类
publicclassPopupDialogextendsPopupWindow {
publicPopupDialog(Viewview,intwidth,intheight) {
super(view,width,height);
}
}
2自定义一个负责设定PopupWindow特性的属性类
publicclassPopup {
privateintxPos;//弹出窗口的x方向位置
privateintyPos;//弹出窗口的y方向位置
privateintvWidth;//窗口显示内容的视图宽度
privateintvHeight;//窗口显示内容的视图高度
privateintanimFadeInOut;//窗口显示动画
privateintcontentView;//潜入在窗口的视图
privateViewcustomView;//潜入的窗口视图view
privatebooleanisClickable;//视图外部是否可以点击
privateOnDismissListenerlistener; //监听弹窗是否dismiss
privateOnTouchListenertouchListener;//监听触摸位置
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(ViewcustomView){
this.customView=customView;
}
publicOnDismissListener getListener() {
returnlistener;
}
publicvoidsetListener(OnDismissListenerlistener){
this.listener=listener;
}
publicfloatgetBgAlpha() {
returnbgAlpha;
}
publicvoidsetBgAlpha(floatbgAlpha) {
this.bgAlpha=bgAlpha;
}
publicOnTouchListener getTouchListener() {
returntouchListener;
}
publicvoidsetTouchListener(OnTouchListenertouchListener){
this.touchListener=touchListener;
}
3自定义一个用来管理PopupWindow的工具类
publicclassPopupUtils {
privatestaticPopupDialogpopupDialog=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:
<RelativeLayoutxmlns: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即可,具体如下:
publicclassViewUtilsActivityextendsFragmentActivity {
privatestaticViewUtilsFragmentfragment=null;
@Override
protectedvoidonCreate(Bundlebundle){
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();
}
}
publicclassViewUtilsFragmentextendsFragmentimplementsView.OnClickListener {
privatePopupDialogpopupDialog=null;
privateButtonbtnDropDownPopupDialog=null;
privateButtonbtnDownUpPopupDialog=null;
@Override
publicView onCreateView(LayoutInflaterinflater,ViewGroupcontainer,
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(Viewv){
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(Viewview,MotionEventevent){
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(Viewv){
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 fromsd
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,KeyEventevent){
switch(keyCode){
caseKeyEvent.KEYCODE_BACK: {
booleanflag =ViewUtils.isPopupShowing();
if(flag){
ViewUtils.dismissPopupDialog();
returnfalse;
}
}
break;
default:
break;
}
returnsuper.onKeyDown(keyCode,event);
}
好了,到这里我们的工作就完成啦,可以欣赏自己的作品了。
如果有问题,可以在评论中或群(179914858)进行讨论,谢谢。
PopupWindow在android中的使用分析