首页 > 代码库 > PopupWindow在android中的使用分析

PopupWindow在android中的使用分析

PopupWindowandroid中的使用分析

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中的使用分析