Android 自定义PopupWindow技巧
2015-12-25 14:46
525 查看
Android 自定义PopupWindow技巧
前言
PopupWindow的宽高
PopupWindow定位在下左位置
PopupWindow定位在下中位置
PopupWindow定位在下右位置
PopupWindow动画
自定义PopupWindow
效果图
其实PopupWindow自定义过程是很简单的,唯一头疼的是:PopupWindow显示的定位问题。
定位问题尤为恶心一点:有时候要涉及到PopupWindow的宽高问题。我们都知道,在没show之前是拿不到宽高的,show的时候定位需要宽高,如此矛盾。以下,都给予回答。
其次的问题也有:PopupWindow的显示、消失动画设计问题。
以下也在我自定义的PopupWindow中提供了三个简单的定位方法:
显示在控件的下左位置
显示在控件的下中位置
显示在控件的下右位置
我们可以在PopupWindow初始化的时候,强制绘制Layout,而拿到PopupWindow的宽高。
设计一个从PopWindow开始的时候右上角逐步展示,然后结束的时候往右上角逐步收起的动画:
styles.xml
popwindow_in.xml
popwindow_out.xml
前言
PopupWindow的宽高
PopupWindow定位在下左位置
PopupWindow定位在下中位置
PopupWindow定位在下右位置
PopupWindow动画
自定义PopupWindow
效果图
前言
其实PopupWindow自定义过程是很简单的,唯一头疼的是:PopupWindow显示的定位问题。定位问题尤为恶心一点:有时候要涉及到PopupWindow的宽高问题。我们都知道,在没show之前是拿不到宽高的,show的时候定位需要宽高,如此矛盾。以下,都给予回答。
其次的问题也有:PopupWindow的显示、消失动画设计问题。
以下也在我自定义的PopupWindow中提供了三个简单的定位方法:
显示在控件的下左位置
显示在控件的下中位置
显示在控件的下右位置
PopupWindow的宽高
我们可以在PopupWindow初始化的时候,强制绘制Layout,而拿到PopupWindow的宽高。// 用于保存PopupWindow的宽度 private int width; // 用于保存PopupWindow的高度 private int height; public CustomPopupWindow(Activity activity) { super(activity); this.activity = activity; this.initPopupWindow(); } private void initPopupWindow() { LayoutInflater inflater = (LayoutInflater) activity .getSystemService(Context.LAYOUT_INFLATER_SERVICE); this.contentView = inflater.inflate(R.layout.popupwindow_custom, null); this.setContentView(contentView); // 设置弹出窗体的宽 this.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT); // 设置弹出窗体的高 this.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT); // 设置弹出窗体可点击 this.setTouchable(true); this.setFocusable(true); // 设置点击是否消失 this.setOutsideTouchable(true); //设置弹出窗体动画效果 this.setAnimationStyle(R.style.PopupAnimation); //实例化一个ColorDrawable颜色为半透明 ColorDrawable background = new ColorDrawable(0x4f000000); //设置弹出窗体的背景 this.setBackgroundDrawable(background); // 绘制 this.mandatoryDraw(); } /** * 强制绘制popupWindowView,并且初始化popupWindowView的尺寸 */ private void mandatoryDraw() { this.contentView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); /** * 强制刷新后拿到PopupWindow的宽高 */ this.width = this.contentView.getMeasuredWidth(); this.height = this.contentView.getMeasuredHeight(); }
PopupWindow定位在下左位置
/** * 显示在控件的下左方 * * @param parent parent */ public void showAtDropDownLeft(View parent) { if (parent.getVisibility() == View.GONE) { this.showAtLocation(parent, 0, 0, 0); } else { // x y int[] location = new int[2]; //获取在整个屏幕内的绝对坐标 parent.getLocationOnScreen(location); this.showAtLocation(parent, 0, location[0], location[1] + parent.getHeight()); } }
PopupWindow定位在下中位置
/** * 显示在控件的下中方 * * @param parent parent */ public void showAtDropDownCenter(View parent) { if (parent.getVisibility() == View.GONE) { this.showAtLocation(parent, 0, 0, 0); } else { // x y int[] location = new int[2]; //获取在整个屏幕内的绝对坐标 parent.getLocationOnScreen(location); this.showAtLocation(parent, 0, location[0] / 2 + parent.getWidth() / 2 - this.width / 6, location[1] + parent.getHeight()); } }
PopupWindow定位在下右位置
/** * 显示在控件的下右方 * * @param parent parent */ public void showAtDropDownRight(View parent) { if (parent.getVisibility() == View.GONE) { this.showAtLocation(parent, 0, 0, 0); } else { // x y int[] location = new int[2]; //获取在整个屏幕内的绝对坐标 parent.getLocationOnScreen(location); this.showAtLocation(parent, 0, location[0] + parent.getWidth() - this.width, location[1] + parent.getHeight()); } }
PopupWindow动画
设计一个从PopWindow开始的时候右上角逐步展示,然后结束的时候往右上角逐步收起的动画:styles.xml
<style name="PopupAnimation" parent="android:Animation" mce_bogus="1"> <item name="android:windowEnterAnimation">@anim/popwindow_in</item> <item name="android:windowExitAnimation">@anim/popwindow_out</item> </style>
popwindow_in.xml
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/decelerate_interpolator"> <!-- 时间 0.2秒 开始的时候 x y 全是0 没有大小 结束的时候 x y 全是1 实际大小 pivotX 100% 表示最右边 pivotY 0% 表示最顶边 以上定位右上角 缩放时不变位置 --> <scale android:duration="200" android:fromXScale="0.0" android:fromYScale="0.0" android:pivotX="100%" android:pivotY="0%" android:toXScale="1.0" android:toYScale="1.0" /> <!-- 时间 0.2秒 开始全透明 结束一点都不透明 --> <alpha android:duration="200" android:fromAlpha="0.0" android:toAlpha="1.0" /> </set>
popwindow_out.xml
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/decelerate_interpolator"> <!-- 时间 0.2秒 开始的时候 x y 全是1 实际大小 结束的时候 x y 全是0 没有大小 pivotX 100% 表示最右边 pivotY 0% 表示最顶边 以上定位右上角 缩放时不变位置 --> <scale android:duration="200" android:fromXScale="1.0" android:fromYScale="1.0" android:pivotX="100%" android:pivotY="0%" android:toXScale="0.0" android:toYScale="0.0" /> <!-- 时间 0.2秒 开始一点都不透明 结束全透明 --> <alpha android:duration="200" android:fromAlpha="1.0" android:toAlpha="0.0" /> </set>
自定义PopupWindow
public class CustomPopupWindow extends android.widget.PopupWindow { private Activity activity; private View contentView; // 用于保存PopupWindow的宽度 private int width; // 用于保存PopupWindow的高度 private int height; public CustomPopupWindow(Activity activity) { super(activity); this.activity = activity; this.initPopupWindow(); } private void initPopupWindow() { LayoutInflater inflater = (LayoutInflater) activity .getSystemService(Context.LAYOUT_INFLATER_SERVICE); this.contentView = inflater.inflate(R.layout.popupwindow_custom, null); this.setContentView(contentView); // 设置弹出窗体的宽 this.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT); // 设置弹出窗体的高 this.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT); // 设置弹出窗体可点击 this.setTouchable(true); this.setFocusable(true); // 设置点击是否消失 this.setOutsideTouchable(true); //设置弹出窗体动画效果 this.setAnimationStyle(R.style.PopupAnimation); //实例化一个ColorDrawable颜色为半透明 ColorDrawable background = new ColorDrawable(0x4f000000); //设置弹出窗体的背景 this.setBackgroundDrawable(background); // 绘制 this.mandatoryDraw(); } /** * 强制绘制popupWindowView,并且初始化popupWindowView的尺寸 */ private void mandatoryDraw() { this.contentView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); /** * 强制刷新后拿到PopupWindow的宽高 */ this.width = this.contentView.getMeasuredWidth(); this.height = this.contentView.getMeasuredHeight(); } /** * 显示在控件的下右方 * * @param parent parent */ public void showAtDropDownRight(View parent) { if (parent.getVisibility() == View.GONE) { this.showAtLocation(parent, 0, 0, 0); } else { // x y int[] location = new int[2]; //获取在整个屏幕内的绝对坐标 parent.getLocationOnScreen(location); this.showAtLocation(parent, 0, location[0] + parent.getWidth() - this.width, location[1] + parent.getHeight()); } } /** * 显示在控件的下左方 * * @param parent parent */ public void showAtDropDownLeft(View parent) { if (parent.getVisibility() == View.GONE) { this.showAtLocation(parent, 0, 0, 0); } else { // x y int[] location = new int[2]; //获取在整个屏幕内的绝对坐标 parent.getLocationOnScreen(location); this.showAtLocation(parent, 0, location[0], location[1] + parent.getHeight()); } } /** * 显示在控件的下中方 * * @param parent parent */ public void showAtDropDownCenter(View parent) { if (parent.getVisibility() == View.GONE) { this.showAtLocation(parent, 0, 0, 0); } else { // x y int[] location = new int[2]; //获取在整个屏幕内的绝对坐标 parent.getLocationOnScreen(location); this.showAtLocation(parent, 0, location[0] / 2 + parent.getWidth() / 2 - this.width / 6, location[1] + parent.getHeight()); } } public static class PopupWindowBuilder { private static String activityHashCode; private static CustomPopupWindow popupWindow; public static PopupWindowBuilder ourInstance; public static PopupWindowBuilder getInstance(Activity activity) { if (ourInstance == null) ourInstance = new PopupWindowBuilder(); String hashCode = String.valueOf(activity.hashCode()); /** * 不同一个Activity */ if (!hashCode.equals(String.valueOf(activityHashCode))) { activityHashCode = hashCode; popupWindow = new CustomPopupWindow(activity); } return ourInstance; } public PopupWindowBuilder setTouchable(boolean touchable) { popupWindow.setTouchable(touchable); return this; } public PopupWindowBuilder setAnimationStyle(int animationStyle) { popupWindow.setAnimationStyle(animationStyle); return this; } public PopupWindowBuilder setBackgroundDrawable(Drawable background) { popupWindow.setBackgroundDrawable(background); return this; } public CustomPopupWindow getPopupWindow() { popupWindow.update(); return popupWindow; } } }
效果图
相关文章推荐
- android自定义视图开发利器ViewDragHelper源码解析
- Android Topbar(自定义组合控件)
- 基于Android实现桌面悬浮清内存app概述
- android 编程实战 学习 之一
- Android 获取屏幕的信息
- android安全
- Android实际分辨率(android:anyDensity="false"的情况下的获取方法)
- android ListView 九大重要属性详细分析
- 关于android 怎样安装 assets文件下的apk
- android-selector
- Android中Activity、Service和线程之间的通信
- Android Studio 代码混淆配置大全
- BroadcastReceiver应用详解
- Android 控件之GridView图片表格控件
- 初入android驱动开发之usb(一)
- Android View总结
- Android HorizontalScrollView 水平滑动 里面放listView 解决滑动冲突
- Android 5.x新特性之elevation(阴影),tinting(着色)以及clipping(剪裁)
- Android 图片Exif信息相关的获取与修改
- Android 系统编译 1