当前位置:网站首页>Popupwindow utility class
Popupwindow utility class
2022-06-26 03:37:00 【kingsley1212】
PopupWindow Tool class , Quick realization of spring frame function
The following code is Java Version ofpublic PopwindowJavaUtil(Context context) {
this.mContext = context;
}
/**
* Position relative to a control With offset
*
* @param anchor Specify the relative position of which control it is located
* @param x
* @param y
* @return
*/
public PopwindowJavaUtil showAsDropDown(View anchor, int x, int y) {
mPopupWindow.showAsDropDown(anchor, x, y);
return this;
}
public PopwindowJavaUtil showAsDropDown(View anchor) {
mPopupWindow.showAsDropDown(anchor);
return this;
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public PopwindowJavaUtil showAsDropDown(View anchor, int xOff, int yOff, int gravity) {
mPopupWindow.showAsDropDown(anchor, xOff, yOff, gravity);
return this;
}
/**
* Position relative to parent control
*
* @param parent
* @param gravity
* @param x
* @param y
* @return
*/
public PopwindowJavaUtil showAtLocation(View parent, int x, int y, int gravity) {
mPopupWindow.showAtLocation(parent, x, y, gravity);
return this;
}
/**
* Set a shaded background
*/
public PopwindowJavaUtil showAtLocation(View parent, int x, int y, int gravity, final float bgAlpha) {
backgroundAlpha(bgAlpha, true);
mPopupWindow.showAtLocation(parent, gravity, x, y);
mPopupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
@Override
public void onDismiss() {
backgroundAlpha(bgAlpha, false);
}
});
return this;
}
public PopwindowJavaUtil showAtLocation(View root) {
int[] windowPos = calculatePopWindowPos(root, mContentView);
int xOff = 10;// You can adjust the offset by yourself
windowPos[0] -= xOff;
mPopupWindow.showAtLocation(root, Gravity.TOP | Gravity.START,
windowPos[0], windowPos[1]);
return this;
}
/**
* Add attribute
*
* @param popupWindow
*/
private void apply(PopupWindow popupWindow) {
popupWindow.setClippingEnabled(mClippEnable);
if (mIgnoreCheekPress) {
popupWindow.setIgnoreCheekPress();
}
if (mInputMode != -1) {
popupWindow.setInputMethodMode(mInputMode);
}
if (mSoftInputMode != -1) {
popupWindow.setSoftInputMode(mSoftInputMode);
}
if (mOnDismissListener != null) {
popupWindow.setOnDismissListener(mOnDismissListener);
}
if (mOnTouchListener != null) {
popupWindow.setTouchInterceptor(mOnTouchListener);
}
popupWindow.setTouchable(mTouchable);
}
private PopupWindow build() {
if (mContentView == null) {
mContentView = LayoutInflater.from(mContext).inflate(mResLayoutId, null);
}
if (mWidth != 0f && mHeight != 0f) {
mPopupWindow = new PopupWindow(mContentView, (int) mWidth, (int) mHeight);
} else {
mPopupWindow = new PopupWindow(mContentView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
}
if (mAninationStyle != -1) {
mPopupWindow.setAnimationStyle(mAninationStyle);
}
if (mElevation != 0f) {
mPopupWindow.setElevation(mElevation);
}
apply(mPopupWindow);// Set some properties
mPopupWindow.setFocusable(mIsFocusable);
if (null != mBackgroundDrawable) {
mPopupWindow.setBackgroundDrawable(mBackgroundDrawable);
}
mPopupWindow.setOutsideTouchable(mIsOutside);
if (mWidth == 0f || mHeight == 0f) {
mPopupWindow.getContentView().measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
mWidth = mPopupWindow.getContentView().getMeasuredWidth();
mHeight = mPopupWindow.getContentView().getMinimumHeight();
}
mPopupWindow.update();
return mPopupWindow;
}
public View getView(int resId) {
View view = sparseArray.get(resId);
if (mContentView == null) {
Log.i("PopwindowJavaUtil", "mContentView is null!");
return null;
}
if (view == null) {
view = mContentView.findViewById(resId);
sparseArray.put(resId, view);
}
return view;
}
public void setText(int resId, String text) {
TextView textView = (TextView) getView(resId);
textView.setText(text);
}
public void dissmiss() {
if (mPopupWindow != null) {
mPopupWindow.dismiss();
}
}
public static class PopupWindowBuilder {
private PopwindowJavaUtil mCustomPopWindow;
public PopupWindowBuilder(Context context) {
mCustomPopWindow = new PopwindowJavaUtil(context);
}
public PopupWindowBuilder size(float width, float height) {
mCustomPopWindow.mWidth = width;
mCustomPopWindow.mHeight = height;
return this;
}
public PopupWindowBuilder setFocusable(boolean focusable) {
mCustomPopWindow.mIsFocusable = focusable;
return this;
}
public PopupWindowBuilder setView(int resLayoutId) {
mCustomPopWindow.mResLayoutId = resLayoutId;
mCustomPopWindow.mContentView = null;
return this;
}
public PopupWindowBuilder setView(View view) {
mCustomPopWindow.mContentView = view;
mCustomPopWindow.mResLayoutId = -1;
return this;
}
public PopupWindowBuilder setElevation(Float elevation) {
mCustomPopWindow.mElevation = elevation;
return this;
}
public PopupWindowBuilder setOutsideTouchable(Boolean outsideTouchable) {
mCustomPopWindow.mIsOutside = outsideTouchable;
return this;
}
/**
* Set pop-up animation
*
* @param animationStyle
* @return
*/
public PopupWindowBuilder setAnimationStyle(int animationStyle) {
mCustomPopWindow.mAninationStyle = animationStyle;
return this;
}
public PopupWindowBuilder setClippingEnable(Boolean enable) {
mCustomPopWindow.mClippEnable = enable;
return this;
}
public PopupWindowBuilder setIgnoreCheekPress(Boolean ignoreCheekPress) {
mCustomPopWindow.mIgnoreCheekPress = ignoreCheekPress;
return this;
}
public PopupWindowBuilder setInputMethodMode(int mode) {
mCustomPopWindow.mInputMode = mode;
return this;
}
public PopupWindowBuilder setOnDissmissListener(PopupWindow.OnDismissListener onDissmissListener) {
mCustomPopWindow.mOnDismissListener = onDissmissListener;
return this;
}
public PopupWindowBuilder setSoftInputMode(int softInputMode) {
mCustomPopWindow.mSoftInputMode = softInputMode;
return this;
}
public PopupWindowBuilder setTouchable(Boolean touchable) {
mCustomPopWindow.mTouchable = touchable;
return this;
}
public PopupWindowBuilder setTouchIntercepter(View.OnTouchListener touchIntercepter) {
mCustomPopWindow.mOnTouchListener = touchIntercepter;
return this;
}
public PopupWindowBuilder setBackgroundDrawable(Drawable drawable) {
mCustomPopWindow.mBackgroundDrawable = drawable;
return this;
}
public PopwindowJavaUtil create() {
mCustomPopWindow.build();
return mCustomPopWindow;
}
}
private int[] calculatePopWindowPos(View anchorView, View contentView) {
int[] windowPos = new int[2];
int[] anchorLoc = new int[2];
// Get anchors View Coordinate position in the upper left corner of the screen
anchorView.getLocationOnScreen(anchorLoc);
int anchorHeight = anchorView.getHeight();
// Get the height and width of the screen
int screenHeight = getScreenHeight(anchorView.getContext());
int screenWidth = getScreenWidth(anchorView.getContext());
contentView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
// Calculation contentView Height and width of
int windowHeight = contentView.getMeasuredHeight();
int windowWidth = contentView.getMeasuredWidth();
// Determine whether you need to pop up or pop down
boolean isNeedShowUp = screenHeight - anchorLoc[1] - anchorHeight < windowHeight;
if (isNeedShowUp) {
windowPos[0] = screenWidth - windowWidth;
windowPos[1] = anchorLoc[1] - windowHeight;
} else {
windowPos[0] = screenWidth - windowWidth;
windowPos[1] = anchorLoc[1] + anchorHeight;
}
return windowPos;
}
private int getScreenWidth(Context context) {
return context.getResources().getDisplayMetrics().heightPixels;
}
private int getScreenHeight(Context context) {
return context.getResources().getDisplayMetrics().widthPixels;
}
private boolean isStarted = false;
float mCurrentAlpha;
ValueAnimator animation;
private void backgroundAlpha(float bgAlpha, boolean show) {
if (isStarted) {
return;
}
isStarted = true;
ValueAnimator animator = null;
if (show) {
animator = ValueAnimator.ofFloat(1f, bgAlpha).setDuration(500);
} else {
animator = ValueAnimator.ofFloat(bgAlpha, 1f).setDuration(500);
}
ValueAnimator.AnimatorUpdateListener updateListener = new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation1) {
mCurrentAlpha = (float) animation1.getAnimatedValue();
animation = animation1;
WindowManager.LayoutParams lp = ((Activity) mContext).getWindow().getAttributes();
lp.alpha = mCurrentAlpha;
((Activity) mContext).getWindow().setAttributes(lp);
}
};
Animator.AnimatorListener animatorListener = new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
// The animation is over
isStarted = false;
}
};
animator.addUpdateListener(updateListener);
animator.addListener(animatorListener);
animator.start();
}
}
kotlin Version as follows
class PopwindowUtil private constructor(private val mContext: Context) {
var mWidth = 0f
var mHeight = 0f
private var mIsFocusable = true
private var mIsOutside = true
private var mResLayoutId = -1
var mContentView: View? = null
private var mPopupWindow: PopupWindow? = null
private var mAnimationStyle = -1
private var mElevation :Float = 0f
private var mClippEnable = true//default is true
private var mIgnoreCheekPress = false
private var mInputMode = -1
private var mOnDismissListener: PopupWindow.OnDismissListener? = null
private var mSoftInputMode = -1
private var mTouchable = true//default is ture
private var mOnTouchListener: View.OnTouchListener? = null
private var mBackgroundDrawable: Drawable? = null
private val sparseArray = SparseArray<View>()
/**
* Position relative to a control With offset
* @param anchor Specify the relative position of which control it is located
* @param x
* @param y
* @return
*/
fun showAsDropDown(anchor: View, x: Int, y: Int): PopwindowUtil {
mPopupWindow?.showAsDropDown(anchor, x, y)
return this
}
fun showAsDropDown(anchor: View): PopwindowUtil {
mPopupWindow?.showAsDropDown(anchor)
return this
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
fun showAsDropDown(anchor: View, xOff: Int, yOff: Int, gravity: Int): PopwindowUtil {
mPopupWindow?.showAsDropDown(anchor, xOff, yOff, gravity)
return this
}
/**
* Position relative to parent control
* @param parent
* @param gravity
* @param x
* @param y
* @return
*/
fun showAtLocation(parent: View, x: Int, y: Int ,gravity: Int): PopwindowUtil {
mPopupWindow?.showAtLocation(parent, gravity, x, y)
return this
}
/**
* Set a shaded background
*/
fun showAtLocation(parent: View, x: Int, y: Int ,gravity: Int,bgAlpha: Float): PopwindowUtil {
backgroundAlpha(bgAlpha,true)
mPopupWindow?.let {
it.showAtLocation(parent, gravity, x, y)
it.setOnDismissListener {
backgroundAlpha(bgAlpha,false)
}
}
return this
}
fun showAtLocation(root: View): PopwindowUtil {
val windowPos = calculatePopWindowPos(root, mContentView!!)
val xOff = 10// You can adjust the offset by yourself
windowPos[0] -= xOff
mPopupWindow?.showAtLocation(
root, Gravity.TOP or Gravity.START,
windowPos[0], windowPos[1]
)
return this
}
/**
* Add attribute
* @param popupWindow
*/
private fun apply(popupWindow: PopupWindow) {
popupWindow.isClippingEnabled = mClippEnable
if (mIgnoreCheekPress) {
popupWindow.setIgnoreCheekPress()
}
if (mInputMode != -1) {
popupWindow.inputMethodMode = mInputMode
}
if (mSoftInputMode != -1) {
popupWindow.softInputMode = mSoftInputMode
}
if (mOnDismissListener != null) {
popupWindow.setOnDismissListener(mOnDismissListener)
}
if (mOnTouchListener != null) {
popupWindow.setTouchInterceptor(mOnTouchListener)
}
popupWindow.isTouchable = mTouchable
}
private fun build(): PopupWindow {
if (mContentView == null) {
mContentView = LayoutInflater.from(mContext).inflate(mResLayoutId, null)
}
if (mWidth != 0f && mHeight != 0f) {
mPopupWindow = PopupWindow(mContentView, mWidth.toInt(), mHeight.toInt())
} else {
mPopupWindow =
PopupWindow(mContentView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
}
if (mAnimationStyle != -1) {
mPopupWindow!!.animationStyle = mAnimationStyle
}
if (mElevation != 0f){
mPopupWindow!!.elevation = mElevation;
}
apply(mPopupWindow!!)// Set some properties
mPopupWindow!!.isFocusable = mIsFocusable
if (null != mBackgroundDrawable) {
mPopupWindow!!.setBackgroundDrawable(mBackgroundDrawable)
}
mPopupWindow!!.isOutsideTouchable = mIsOutside
if (mWidth == 0f || mHeight == 0f) {
mPopupWindow!!.contentView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
// If no width or height is set outside , Calculate the width and height and assign values
mWidth = mPopupWindow!!.contentView.measuredWidth.toFloat()
mHeight = mPopupWindow!!.contentView.measuredHeight.toFloat()
}
mPopupWindow!!.update()
return mPopupWindow!!
}
fun <T : View> getView(resId: Int): T? {
var view: View? = sparseArray.get(resId)
if (mContentView == null) {
Log.i("PopwindowUtil", "mContentView is null!")
return null
}
if (view == null) {
view = mContentView!!.findViewById(resId)
sparseArray.put(resId, view)
}
return view as T?
}
fun setText(resId: Int, text: String) {
val textView = getView<TextView>(resId)
textView!!.text = text
}
fun dissmiss() {
if (mPopupWindow != null) {
mPopupWindow!!.dismiss()
}
}
class PopupWindowBuilder(context: Context) {
private val mCustomPopWindow: PopwindowUtil
init {
mCustomPopWindow = PopwindowUtil(context)
}
fun size(width: Float, height: Float): PopupWindowBuilder {
mCustomPopWindow.mWidth = width
mCustomPopWindow.mHeight = height
return this
}
fun setFocusable(focusable: Boolean): PopupWindowBuilder {
mCustomPopWindow.mIsFocusable = focusable
return this
}
fun setView(resLayoutId: Int): PopupWindowBuilder {
mCustomPopWindow.mResLayoutId = resLayoutId
mCustomPopWindow.mContentView = null
return this
}
fun setView(view: View): PopupWindowBuilder {
mCustomPopWindow.mContentView = view
mCustomPopWindow.mResLayoutId = -1
return this
}
fun setElevation(elevation :Float): PopupWindowBuilder {
mCustomPopWindow.mElevation = elevation
return this
}
fun setOutsideTouchable(outsideTouchable: Boolean): PopupWindowBuilder {
mCustomPopWindow.mIsOutside = outsideTouchable
return this
}
/**
* Set pop-up animation
* @param animationStyle
* @return
*/
fun setAnimationStyle(animationStyle: Int): PopupWindowBuilder {
mCustomPopWindow.mAnimationStyle = animationStyle
return this
}
fun setClippingEnable(enable: Boolean): PopupWindowBuilder {
mCustomPopWindow.mClippEnable = enable
return this
}
fun setIgnoreCheekPress(ignoreCheekPress: Boolean): PopupWindowBuilder {
mCustomPopWindow.mIgnoreCheekPress = ignoreCheekPress
return this
}
fun setInputMethodMode(mode: Int): PopupWindowBuilder {
mCustomPopWindow.mInputMode = mode
return this
}
fun setOnDissmissListener(onDissmissListener: PopupWindow.OnDismissListener): PopupWindowBuilder {
mCustomPopWindow.mOnDismissListener = onDissmissListener
return this
}
fun setSoftInputMode(softInputMode: Int): PopupWindowBuilder {
mCustomPopWindow.mSoftInputMode = softInputMode
return this
}
fun setTouchable(touchable: Boolean): PopupWindowBuilder {
mCustomPopWindow.mTouchable = touchable
return this
}
fun setTouchIntercepter(touchIntercepter: View.OnTouchListener): PopupWindowBuilder {
mCustomPopWindow.mOnTouchListener = touchIntercepter
return this
}
fun setBackgroundDrawable(drawable: Drawable): PopupWindowBuilder {
mCustomPopWindow.mBackgroundDrawable = drawable
return this
}
fun create(): PopwindowUtil {
// structure PopWindow
mCustomPopWindow.build()
return mCustomPopWindow
}
}
companion object {
/**
* Calculated position ,y The direction is anchorView Align the top and bottom of the display ,x The direction is aligned with the right side of the screen
* If anchorView The position of the has changed , You can properly add an additional offset to correct
* @param anchorView Exhale window Of view
* @param contentView window The content layout of
* @return window In the upper left corner of the display xOff,yOff coordinate
*/
private fun calculatePopWindowPos(anchorView: View, contentView: View): IntArray {
val windowPos = IntArray(2)
val anchorLoc = IntArray(2)
// Get anchors View Coordinate position in the upper left corner of the screen
anchorView.getLocationOnScreen(anchorLoc)
val anchorHeight = anchorView.height
// Get the height and width of the screen
val screenHeight = getScreenHeight(anchorView.context)
val screenWidth = getScreenWidth(anchorView.context)
contentView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
// Calculation contentView Height and width of
val windowHeight = contentView.measuredHeight
val windowWidth = contentView.measuredWidth
// Determine whether you need to pop up or pop down
val isNeedShowUp = screenHeight - anchorLoc[1] - anchorHeight < windowHeight
if (isNeedShowUp) {
windowPos[0] = screenWidth - windowWidth
windowPos[1] = anchorLoc[1] - windowHeight
} else {
windowPos[0] = screenWidth - windowWidth
windowPos[1] = anchorLoc[1] + anchorHeight
}
return windowPos
}
/**
* Get screen height (px)
*/
fun getScreenHeight(context: Context): Int {
return context.resources.displayMetrics.heightPixels
}
/**
* Get screen width (px)
*/
fun getScreenWidth(context: Context): Int {
return context.resources.displayMetrics.widthPixels
}
}
var isStarted = false
fun backgroundAlpha(bgAlpha:Float,show:Boolean) {
if (isStarted){
return
}
isStarted = true
var animator:ValueAnimator
if (show)
animator = ValueAnimator.ofFloat(1f, bgAlpha).setDuration(500)
else
animator = ValueAnimator.ofFloat(bgAlpha, 1f).setDuration(500)
getActivityFromContext(mContext)?.let {
var updateListener = ValueAnimator.AnimatorUpdateListener { animation ->
var mCurrentAlpha = (animation.animatedValue as Float)
val lp = it.getWindow().getAttributes()
lp.alpha = mCurrentAlpha
it.getWindow().setAttributes(lp)
}
var animatorListener = object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
super.onAnimationEnd(animation)
// The animation is over
isStarted = false
}
}
animator.addUpdateListener(updateListener)
animator.addListener(animatorListener)
animator.start()
}
}
/**
* Judge context
*/
private fun getActivityFromContext(context: Context?): Activity? {
var context = context
if (null != context) {
while (context is ContextWrapper) {
if (context is Activity) {
return context
}else if (context is Fragment){
return context.activity
}
context = context.baseContext
}
}
return null
}
}
Usage method , Call the following methods when necessary
val popwindowUtil = PopwindowJavaUtil.PopupWindowBuilder(activity!!)
.setView(R.layout.pop_detail_menu)// This is what you need to pop up view
.size(LinearLayout.LayoutParams.MATCH_PARENT.toFloat(), LinearLayout.LayoutParams.WRAP_CONTENT.toFloat())
.setAnimationStyle(R.style.contextMenuAnim)
.setFocusable(true)
.setTouchable(true)
.setOutsideTouchable(true)
.create()
val rootview = LayoutInflater.from(activity)
.inflate(R.layout.frag_home, null)// This is your current page view
popwindowUtil.showAtLocation(rootview,0,0, Gravity.BOTTOM,0.6f)
Pop up pop up animation
<style name="contextMenuAnim" parent="@android:style/Animation.Activity">
<item name="android:windowEnterAnimation">@anim/pop_show</item>
<item name="android:windowExitAnimation">@anim/pop_hide</item>
</style>
pop_show.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="@android:integer/config_mediumAnimTime"
android:shareInterpolator="true"
>
<translate
android:fromXDelta="0"
android:fromYDelta="100%p"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:toXDelta="0"
android:toYDelta="0"/>
<alpha
android:fromAlpha="0"
android:toAlpha="1"
/>
</set>
pop_hide.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="@android:integer/config_mediumAnimTime"
android:shareInterpolator="true"
>
<translate
android:fromXDelta="0"
android:fromYDelta="0"
android:interpolator="@android:anim/linear_interpolator"
android:toXDelta="0"
android:toYDelta="100%p" />
<alpha
android:fromAlpha="1"
android:toAlpha="0"
/>
</set>
边栏推荐
- Upload file / text / picture, box shadow
- 关于#sql#的问题:SQL问题--账号多地登录的SQL代码
- 点击事件
- Analysis of the multiple evaluation system of children's programming
- XGBoost, lightGBM, CatBoost——尝试站在巨人的肩膀上
- Notes on the 3rd harmonyos training in the studio
- 论文回顾:Unmixing-Based Soft Color Segmentation for Image Manipulation
- Plug in installation and shortcut keys of jupyter notebook
- 工业机器人之“慧眼”——机器视觉
- Todolist incomplete, completed
猜你喜欢

MySQL开发环境

数字孪生智慧水务,突破海绵城市发展困境

类图

Google recommends using kotlin flow in MVVM architecture

Inkscape如何将png图片转换为svg图片并且不失真

【论文笔记】Learning to Grasp with Primitive Shaped Object Policies

Lumen Analysis and Optimization of ue5 global Lighting System

The role of children's programming in promoting traditional disciplines in China

progress bar

MySQL增删查改(初阶)
随机推荐
Is it safe to open an account in flush online? How to open a brokerage account online
The "eye" of industrial robot -- machine vision
USB driver -debug
Hardware creation principle of campus maker space
Request object, send request
进度条
Qt编译出错ERROR: Unknown module(s) in QT: script
Record a torture bug caused by restcontrol and controller
【哈希表】改进,拉链法哈希结构——直接用两个索引查找,不用每次都hash和%一遍
usb peripheral 驱动 - 枚举
Partition, column, list
国信金太阳靠谱吗?开证券账户安全吗?
Review of the paper: unmixing based soft color segmentation for image manipulation
经典模型——AlexNet
XGBoost, lightGBM, CatBoost——尝试站在巨人的肩膀上
显卡、GPU、CPU、CUDA、显存、RTX/GTX及查看方式
[hash table] a very simple zipper hash structure, so that the effect is too poor, there are too many conflicts, and the linked list is too long
云计算基础-0
Analysis and optimization of ue5 global illumination system lumen
Is it safe to open a fund account? How to apply