Android PopupWindow usage summary, androidpopupwindow
I used PopupWindow a few days ago. I couldn't remember how to use it. I checked it online, wrote a demo, and recorded the usage of PopupWindow here.
Use Cases
PopupWindow, as its name implies, is a pop-up window, which can be seen in many scenarios. For example, the option pop-up window of ActionBar/Toolbar, the container of a group of options, or the window of a set such as list.
Basic usage
Using PopupWindow is simple and can be summarized into three steps:
The second step is optional (but the second step is basically required ). The following is a simple example:
1 // View 2 View contentView = LayoutInflater for PopupWindow. from (context ). inflate (layoutRes, null, false); 3 // create a PopupWindow object, where: 4 // The first parameter is used for View in PopupWindow, and the second parameter is the width of PopupWindow, 5 // The third parameter is the height of the PopupWindow, and the fourth parameter specifies whether PopupWindow can obtain focus 6 PopupWindow window = new PopupWindow (contentView, 100,100, true ); 7 // set the background of PopupWindow. setBackgroundDrawable (new ColorDrawable (Color. TRANSPARENT); 9 // set whether PopupWindow can respond to the external click event 10 window. setOutsideTouchable (true); 11 // sets whether PopupWindow can respond to the click event 12 window. setTouchable (true); 13 // display PopupWindow, where: 14 // The first parameter is the anchpoint of PopupWindow, the second and third parameters are respectively the x and y offsets of PopupWindow relative to the anchpoint 15 windows. showAsDropDown (anchor, xoff, yoff); 16 // or you can call this method to display PopupWindow, where: 17 // The first parameter is the parent View of PopupWindow, the second parameter is the position of PopupWindow relative to the parent View, 18 // The third and fourth parameters are respectively the x and y offsets of PopupWindow relative to the parent View 19 // window. showAtLocation (parent, gravity, x, y );
The role of each method is written in the annotation. I believe everyone can understand it. However, pay attention to the following two lines:
1 window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));2 window.setOutsideTouchable(true);
Only when the background of PopupWindow is set at the same time and the external click event can be responded can it "truly" respond to the external click event. That is, PopupWindow disappears only when you click the outside of PopupWindow or press the "Back" key.
Use the showAsDropDown method to display PopupWindow
Generally, after the showAsDropDown method is called, PopupWindow is displayed in the lower left of the anchor (drop down ). However, if you want to display the PopupWindow above the anchor in the middle of the anchor, you need to use the xoff and yoff parameters of the showAsDropDown method.
The purpose here is not only to include the two situations mentioned above (above the anchor center of the anchor), but to include 5 display modes in both the horizontal and vertical directions:
- Horizontal Direction:
- ALIGN_LEFT: left inside the anchor;
- ALIGN_RIGHT: Right side of the anchor;
- CENTER_HORI: In the central horizontal area of the anchor;
- TO_RIGHT: Right of the outside of the anchor;
- TO_LEFT: left outside the anchor.
- Vertical direction:
- Align_abve: above the inside of the anchor;
- ALIGN_BOTTOM: lower inside the anchor;
- CENTER_VERT: in the vertical center of the anchor;
- TO_BOTTOM: Outside the anchor;
- To_abve: above the outside of the anchor.
See the figure below:
First, we define a class for simple encapsulation of PopupWindow:
1 public abstract class CommonPopupWindow { 2 protected Context context; 3 protected View contentView; 4 protected PopupWindow mInstance; 5 6 public CommonPopupWindow(Context c, int layoutRes, int w, int h) { 7 context=c; 8 contentView=LayoutInflater.from(c).inflate(layoutRes, null, false); 9 initView();10 initEvent();11 mInstance=new PopupWindow(contentView, w, h, true);12 initWindow();13 }14 15 public View getContentView() { return contentView; }16 public PopupWindow getPopupWindow() { return mInstance; }17 18 protected abstract void initView();19 protected abstract void initEvent();20 21 protected void initWindow() {22 mInstance.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));23 mInstance.setOutsideTouchable(true);24 mInstance.setTouchable(true);25 }26 27 public void showBashOfAnchor(View anchor, LayoutGravity layoutGravity, int xmerge, int ymerge) {28 int[] offset=layoutGravity.getOffset(anchor, mInstance);29 mInstance.showAsDropDown(anchor, offset[0]+xmerge, offset[1]+ymerge);30 }31 32 public void showAsDropDown(View anchor, int xoff, int yoff) {33 mInstance.showAsDropDown(anchor, xoff, yoff);34 }35 36 public void showAtLocation(View parent, int gravity, int x, int y) {37 mInstance.showAtLocation(parent, gravity, x, y);38 }39 }
Here we need to implement the "showBashOfAnchor" method. There is a "LayoutGravity" type parameter, which is the object that controls the position of PopupWindow relative to the anchpoint. The following defines "LayoutGravity ":
1 public static class LayoutGravity { 2 private int layoutGravity; 3 // waring, don't change the order of these constants! 4 public static final int ALIGN_LEFT=0x1; 5 public static final int ALIGN_ABOVE=0x2; 6 public static final int ALIGN_RIGHT=0x4; 7 public static final int ALIGN_BOTTOM=0x8; 8 public static final int TO_LEFT=0x10; 9 public static final int TO_ABOVE=0x20;10 public static final int TO_RIGHT=0x40;11 public static final int TO_BOTTOM=0x80;12 public static final int CENTER_HORI=0x100;13 public static final int CENTER_VERT=0x200;14 15 public LayoutGravity(int gravity) {16 layoutGravity=gravity;17 }18 19 public int getLayoutGravity() { return layoutGravity; }20 public void setLayoutGravity(int gravity) { layoutGravity=gravity; }21 22 public void setHoriGravity(int gravity) {23 layoutGravity&=(0x2+0x8+0x20+0x80+0x200);24 layoutGravity|=gravity;25 }26 public void setVertGravity(int gravity) {27 layoutGravity&=(0x1+0x4+0x10+0x40+0x100);28 layoutGravity|=gravity;29 }30 31 public boolean isParamFit(int param) {32 return (layoutGravity & param) > 0;33 }34 35 public int getHoriParam() {36 for(int i=0x1; i<=0x100; i=i<<2)37 if(isParamFit(i))38 return i;39 return ALIGN_LEFT;40 }41 42 public int getVertParam() {43 for(int i=0x2; i<=0x200; i=i<<2)44 if(isParamFit(i))45 return i;46 return TO_BOTTOM;47 }48 49 public int[] getOffset(View anchor, PopupWindow window) {50 int anchWidth=anchor.getWidth();51 int anchHeight=anchor.getHeight();52 53 int winWidth=window.getWidth();54 int winHeight=window.getHeight();55 View view=window.getContentView();56 if(winWidth<=0)57 winWidth=view.getWidth();58 if(winHeight<=0)59 winHeight=view.getHeight();60 61 int xoff=0;62 int yoff=0;63 64 switch (getHoriParam()) {65 case ALIGN_LEFT:66 xoff=0; break;67 case ALIGN_RIGHT:68 xoff=anchWidth-winWidth; break;69 case TO_LEFT:70 xoff=-winWidth; break;71 case TO_RIGHT:72 xoff=anchWidth; break;73 case CENTER_HORI:74 xoff=(anchWidth-winWidth)/2; break;75 default:break;76 }77 switch (getVertParam()) {78 case ALIGN_ABOVE:79 yoff=-anchHeight; break;80 case ALIGN_BOTTOM:81 yoff=-winHeight; break;82 case TO_ABOVE:83 yoff=-anchHeight-winHeight; break;84 case TO_BOTTOM:85 yoff=0; break;86 case CENTER_VERT:87 yoff=(-winHeight-anchHeight)/2; break;88 default:break;89 }90 return new int[]{ xoff, yoff };91 }92 }
The main method here is "getOffset", which determines the position of the PopupWindow relative to the anchpoint based on the gravity in the horizontal and vertical directions.
When "LayoutGravity" is used, you can use the "setHoriGravity" and "setVertGravity" methods to set gravity in both the horizontal and vertical directions, or create a new "LayoutGravity" object.
The following is a demo:
Use setAnimationStyle to add an animation
As we mentioned above, we set the background for PopupWindow and register the event listener. Now let's add an animation for PopupWindow.
The animation here refers to the animation when the PopupWindow appears and disappears. By default, pop-up and disappear are displayed directly, which makes the user feel abrupt. If the PopupWindow is able to "slide" the screen and "slide out" the screen (or in other ways), the user experience will be better.
You can call the 'setanimationstyle' method to add an animation to a PopupWindow. This method has only one parameter, that is, to specify the animation style. Therefore, we need to define the animation resources and style resources.
Below is an animation of "slide in and out:
1 <!-- res/anim/translate_in.xml --> 2 <?xml version="1.0" encoding="utf-8"?> 3 <set xmlns:android="http://schemas.android.com/apk/res/android"> 4 <translate 5 android:fromXDelta="0" 6 android:toXDelta="0" 7 android:fromYDelta="100%" 8 android:toYDelta="0" 9 android:duration="200" >10 </translate>11 </set>
1 <!-- res/anim/translate_out.xml --> 2 <?xml version="1.0" encoding="utf-8"?> 3 <set xmlns:android="http://schemas.android.com/apk/res/android"> 4 <translate 5 android:fromXDelta="0" 6 android:toXDelta="0" 7 android:fromYDelta="0" 8 android:toYDelta="100%" 9 android:duration="200" >10 </translate>11 </set>
Then define the sliding animation style:
1 <!-- res/values/styles.xml -->2 <style name="animTranslate">3 <item name="android:windowEnterAnimation">@anim/translate_in</item>4 <item name="android:windowExitAnimation">@anim/translate_out</item>5 </style>
Now we can add a "slide" animation for the PopupWindow:
1 window.setAnimationStyle(R.style.animTranslate);
Let's take a look at the effect:
PS: Because the animation time is too short (200 ms), in addition, the screenshot frequency may be a little low during GIF conversion, resulting in the slide effect is not very obvious. You are advised to run the demo to view it.
Now the appearance/disappearance of PopupWindow is not so abrupt. However, when a pop-up window appears, it is not easy to distinguish the pop-up window from the background. If the pop-up window background can be dimmed.
No problem. After the pop-up window appears, we can darken the background and restore the background after the pop-up window disappears:
1 window.setOnDismissListener(new PopupWindow.OnDismissListener() { 2 @Override 3 public void onDismiss() { 4 WindowManager.LayoutParams lp=getWindow().getAttributes(); 5 lp.alpha=1.0f; 6 getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); 7 getWindow().setAttributes(lp); 8 } 9 });10 11 window.showAtLocation(activityPopup, Gravity.BOTTOM, 0, 0);12 WindowManager.LayoutParams lp=getWindow().getAttributes();13 lp.alpha=0.3f;14 getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);15 getWindow().setAttributes(lp);
Now let's take a look at the effect:
Now PopupWindow is more obvious.
In addition, we have also implemented three animation styles: transparency, scaling, and rotation. The implementation method is similar to the above, so we will not repeat them here.
Source code
All the above Code (including the Code not provided) has been uploaded to GitHub:
Https://github.com/jzyhywxz/PopupWindow