Android中PopupWindow使用詳解

David的專欄發表於2014-09-13

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 popupDialognull;

@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());

}

popupDialognewPopupDialog(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();

popupDialognull;

}

}

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 fragmentnull;

@Override

protectedvoidonCreate(Bundle bundle){

super.onCreate(bundle);

requestWindowFeature(Window.FEATURE_NO_TITLE);

setContentView(R.layout.activity_base_main);

if(null== bundle){

FragmentTransactionft =getSupportFragmentManager().beginTransaction();

fragmentnewViewUtilsFragment();

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);

}

好了,到這裡我們的工作就完成啦,可以欣賞自己的作品了。

相關文章