转载

PopupWindow的基本使用一

PopupWindow在开发中也是很常见的一个控件,由于多数情况下PopupWindow都是弹出一个列表框,从Android3.0开始官方提供了两个专门用于弹出列表的弹框ListPopupWindow和PopupMenu,如果想要支持更低的版本可以使用support v7中相应的类。

创建PopupWindow

创建PopupWindow有两种类型的构造方法,一种是传统方式创建View的方式,另外一种是直接传进一个View的构造方式。

//方式一
PopupWindow(Contextcontext)
PopupWindow(Contextcontext, AttributeSetattrs)
PopupWindow(Contextcontext, AttributeSetattrs, int defStyleAttr)
PopupWindow(Contextcontext, AttributeSetattrs, int defStyleAttr, int defStyleRes)
//方式二
PopupWindow(ViewcontentView)
PopupWindow(int width, int height)
PopupWindow(ViewcontentView, int width, int height)
PopupWindow(ViewcontentView, int width, int height, boolean focusable)

PopupWindow更类似与一个工具类,在工具类中存入一个View,在操作的时候弹出或销毁该View。查看源码我们也可以看出来PopupWindow并没有继承自View,因此在使用的时候与View还是有很显著差别的,View可以定义子在布局文件中,但是没有哪个开发者将PopupWindow放在布局文件中。在传入上下文Context的时候跟创建View类似,如果创建一个View需要传入一个Context实例,方式一不用多说了,在方式二中只要传入一个View同样可以通过View中getContext方法获取一个Context实例。

在创建一个PopupWindow的时候有三个最基本的属性必须设置,contentView、width和height,这里具体的为什么后面再做分析,虽然已经传入了View,但是View的高度是由父控件决定的,在创建的时候是不知道它的父控件是谁的,因此宽高都是未知的,如果不设置是显示不出来PopupWindow的。

Viewview=View.inflate(context, R.layout.layout_popup,null);
popupWindow.setWidth(width);
popupWindow.setHeight(height);
popupWindow.setContentView(view);

这里用了三行代码才设置完毕所必须的属性,事实上使用方式二中的第3个和第4个构造方法可以直接构造出需要显示的PopupWindow,focusable这个属性不是必须的,但是在交互的时候缺少该属性也会引发很奇葩的问题,在后面也会介绍。

设置PopupWindow显示位置

设置PopupWindow显示位置主要有两种类型showAsDropDown和showAtLocation:

showAsDropDown(Viewanchor)
showAsDropDown(Viewanchor, int xoff, int yoff)
showAsDropDown(Viewanchor, int xoff, int yoff, int gravity)//API 19新增
showAtLocation (Viewparent, int gravity, int x, int y)
showAsDropDown(Viewanchor, int xoff, int yoff, int gravity)

该方法是设置相对于anchor的位置,如果showAsDropDown只有一个参数,就是相对于anchor左下方,xoff和yoff是相对anchor左下方为基点在x方向移动xoff像素,在y方向移动yoff像素,gravity与showAtLocation中gravity属性是有本质区别的,该方法的gravity是相对于anchor方位。

showAtLocation (View parent, int gravity, int x, int y)

该方法是相对于屏幕位置,位置展示跟parent基本没有关系,parent只是为了获取一个WindowToken,用于检索出该View所处的Window窗体,然后设置PopupWindow的布局参数到WindowManager.LayoutParams上面。

public void showAtLocation(Viewparent, int gravity, int x, int y) {
 showAtLocation(parent.getWindowToken(), gravity, x, y);
}
public void showAtLocation(IBindertoken, int gravity, int x, int y) {
 //...
 final WindowManager.LayoutParams p = createPopupLayoutParams(token);
 preparePopup(p);
 
 // Only override the default if some gravity was specified.
 if (gravity != Gravity.NO_GRAVITY) {
 p.gravity = gravity;
 }
 
 p.x = x;
 p.y = y;
 
 invokePopup(p);
}
 
//下面方法来自View中方法
/**
* Retrieve a unique token identifying the window this view is attached to.
* @return Return the window's token for use in
* {@link WindowManager.LayoutParams#token WindowManager.LayoutParams.token}.
*/
public IBindergetWindowToken() {
 return mAttachInfo != null ? mAttachInfo.mWindowToken : null;
}

其它常用方法

dismiss ()
setAnimationStyle(int animationStyle)
setOutsideTouchable(boolean touchable)
setBackgroundDrawable(Drawablebackground)
setFocusable(boolean focusable)

比较常用的方法也就这么多了,接下来介绍Popup简单使用。

PopupWindow简单使用

PopupWindow的基本使用一

本文实例只是为了演示PopupWindow基本使用,布局都是使用较简单的方式呈现。

showAsDropDown(View anchor)

先看一下布局文件,非常简单内部仅有一个View设置一个背景色。

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <Viewandroid:layout_height="match_parent"
        android:background="#ff4081"
        android:layout_width="match_parent"/>
</LinearLayout>

下面创建一个PopupWindow,这里使用两种创建方式,究竟使用哪一种方式看个人习惯而定。

Viewview=View.inflate(this,R.layout.layout_popup,null);
 
//方式一
popupWindow=new PopupWindow(this);
popupWindow.setContentView(view);
popupWindow.setWidth(400);
popupWindow.setHeight(200);
popupWindow.setFocusable(true);
 
//方式二
popupWindow=new PopupWindow(view, 400, 200, true);
 
popupWindow.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#00000000")));
popupWindow.showAsDropDown(btn);

showAsDropDown(View anchor, int xoff, int yoff)

showAsDropDown(View anchor)已经显示在了左下方,其实该方法中X方向位移xoff和Y方向位移yoff都是0,PopupWindow中实现源代码如下:

/**
* Display the content view in a popup window anchored to the bottom-left
* corner of the anchor view. If there is not enough room on screen to show
* the popup in its entirety, this method tries to find a parent scroll
* view to scroll. If no parent scroll view can be scrolled, the
* bottom-left corner of the popup is pinned at the top left corner of the
* anchor view.
*
* @param anchor the view on which to pin the popup window
*
* @see #dismiss()
*/
public void showAsDropDown(Viewanchor) {
 showAsDropDown(anchor, 0, 0);
}

想要距离anchor View在X方向和Y方向平移,只需要将xoff和yoff传入具体的数值即可。

showAtLocation (View parent, int gravity, int x, int y)

该方法是设置PopupWindow相对于窗口位置,通过gravity参数设置。有部分开发者使用PopupWindow来设计弹出框或者仿写类似QQ弹出菜单都是借助于该方法,然后使用setAnimationStyle设置炫酷的动画。例如从窗口下侧显示使用Gravity.BOTTOM或者显示在屏幕中央使用Gravity.CENTER。

setAnimationStyle(int animationStyle)

PopupWindow设置动画跟设置普通View的动画不同,PopupWindow直译弹出窗体,所以使用动画使用是转场动画windowAnimation,进入动画android:windowEnterAnimation和退出动画android:windowExitAnimation。

设置底部进入动画

<?xmlversion="1.0" encoding="utf-8"?>
<setxmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="200"
        android:fromYDelta="100%"
        android:toYDelta="0%"/>
</set>

设置底部退出动画

<?xmlversion="1.0" encoding="utf-8"?>
<setxmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="200"
        android:fromYDelta="0%"
        android:toYDelta="100%"/>
</set>

然后在style.xml文件中设置转场动画

<stylename="CustomPopAnim">
 <itemname="android:windowEnterAnimation">@anim/slide_from_bottom</item>
 <itemname="android:windowExitAnimation">@anim/slide_to_bottom</item>
</style>

PopupWindow隐藏

PopupWindow隐藏调用的是dismiss方法,如果想在PopupWindow隐藏的时候处理其它事件可以设置事件监听器。

popupWindow.setOnDismissListener(new OnDismissListener() {
 @Override
 public void onDismiss() {
 //TODO
 }
});

小结

这篇文章先完成到这里,有关其它几个常用的方法在随后的文章继续,同样ListPopupWindow和PopupMenu以及与Dialog的区别也在下一篇文章介绍。

原文  http://www.sunnyang.com/624.html
正文到此结束
Loading...