Android 自定义PopupWindow
程序员文章站
2022-05-31 10:55:26
...
封装一个通用PopupWindow,避免重复造*,简化代码,方便管理。
自定义PopupWindow:详情看注释
public class CommonPopWindow {
private static PopupWindow mPopupWindow;
private static Builder mBuilder;
private static View mContentView;
private static Window mWindow;
public interface ViewClickListener {
void getChildView(PopupWindow mPopupWindow, View view, int mLayoutResId);
}
private CommonPopWindow() {
mBuilder = new Builder();
}
public static Builder newBuilder() {
if (mBuilder == null) {
mBuilder = new Builder();
}
return mBuilder;
}
/**
* 获取PopupWindow宽度
*
* @return
*/
public int getWidth() {
if (mPopupWindow != null) {
return mContentView.getMeasuredWidth();
}
return 0;
}
/**
* 获取PopupWindow高度
*
* @return
*/
public int getHeight() {
if (mPopupWindow != null) {
return mContentView.getMeasuredHeight();
}
return 0;
}
/**
* 显示在控件的下方
*/
public CommonPopWindow showDownPop(View parent) {
if (parent.getVisibility() == View.GONE) {
mPopupWindow.showAtLocation(parent, Gravity.NO_GRAVITY, 0, 0);
} else {
int[] location = new int[2];
parent.getLocationOnScreen(location);
if (mPopupWindow != null) {
mPopupWindow.showAtLocation(parent, Gravity.NO_GRAVITY, location[0], location[1] + parent.getHeight());
}
}
return this;
}
/**
* 显示在控件的上方
*/
public CommonPopWindow showAsUp(View view) {
if (view.getVisibility() == View.GONE) {
mPopupWindow.showAtLocation(view, Gravity.NO_GRAVITY, 0, 0);
} else {
int[] location = new int[2];
view.getLocationOnScreen(location);
if (mPopupWindow != null) {
mPopupWindow.showAtLocation(view, Gravity.NO_GRAVITY, location[0], location[1] - view.getHeight());
//方式二
// mPopupWindow.showAsDropDown(view, 0, -(getHeight() + view.getMeasuredHeight()));
}
}
return this;
}
/**
* 显示在控件的左边
*/
public CommonPopWindow showAsLeft(View view) {
if (view.getVisibility() == View.GONE) {
mPopupWindow.showAtLocation(view, Gravity.NO_GRAVITY, 0, 0);
} else {
int[] location = new int[2];
view.getLocationOnScreen(location);
if (mPopupWindow != null) {
mPopupWindow.showAtLocation(view, Gravity.NO_GRAVITY, location[0] - getWidth(), location[1]);
}
}
return this;
}
/**
* 显示在控件右边
*/
public CommonPopWindow showAsRight(View view) {
if (view.getVisibility() == View.GONE) {
mPopupWindow.showAtLocation(view, Gravity.NO_GRAVITY, 0, 0);
} else {
int[] location = new int[2];
view.getLocationOnScreen(location);
if (mPopupWindow != null) {
mPopupWindow.showAtLocation(view, Gravity.NO_GRAVITY, location[0] + view.getWidth(), location[1]);
}
}
return this;
}
/**
* 显示控件下方
*
* @param view
* @return
*/
public CommonPopWindow showAsDown(View view) {
if (mPopupWindow != null) {
mPopupWindow.showAsDropDown(view);
}
return this;
}
/**
* 全屏弹出
*/
public CommonPopWindow showAsBottom(View view) {
if (view.getVisibility() == View.GONE) {
mPopupWindow.showAtLocation(view, Gravity.NO_GRAVITY, 0, 0);
} else {
int[] location = new int[2];
view.getLocationOnScreen(location);
if (mPopupWindow != null) {
mPopupWindow.showAtLocation(view, Gravity.BOTTOM, 0, 0);
}
}
return this;
}
public CommonPopWindow showAtLocation(View anchor, int gravity, int x, int y) {
if (mPopupWindow != null) {
mPopupWindow.showAtLocation(anchor, gravity, x, y);
}
return this;
}
/**
* 取消
*/
public static void dismiss() {
if (mWindow != null) {
WindowManager.LayoutParams params = mWindow.getAttributes();
params.alpha = 1.0f;
mWindow.setAttributes(params);
}
if (mPopupWindow != null && mPopupWindow.isShowing())
mPopupWindow.dismiss();
}
/*
* ---------------------Builder-------------------------
*/
public static class Builder implements PopupWindow.OnDismissListener {
private Context mContext;
private int mLayoutResId;//布局ID
private int mWidth, mHeight;//弹窗宽高
private int mAnimationStyle;//动画样式
private ViewClickListener mListener;//子View监听回调
private Drawable mDrawable;//背景Drawable
private boolean mTouchable = true;//是否相应touch事件
private boolean mFocusable = true;//是否获取焦点
private boolean mOutsideTouchable = true;//设置外部是否点击
private boolean mBackgroundDarkEnable = false;//是否背景窗体变暗
private float mDarkAlpha = 1.0f;//透明值
public CommonPopWindow build(Context context) {
this.mContext = context;
CommonPopWindow popWindow = new CommonPopWindow();
apply();
if (mListener != null && mLayoutResId != 0) {
mListener.getChildView(mPopupWindow, mContentView, mLayoutResId);
}
return popWindow;
}
private void apply() {
if (mLayoutResId != 0) {
mContentView = LayoutInflater.from(mContext).inflate(mLayoutResId, null);
}
if (mWidth != 0 && mHeight != 0) {
mPopupWindow = new PopupWindow(mContentView, mWidth, mHeight);
} else {
mPopupWindow = new PopupWindow(mContentView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
}
mPopupWindow.setTouchable(mTouchable);
mPopupWindow.setFocusable(mFocusable);
mPopupWindow.setOutsideTouchable(mOutsideTouchable);
if (mDrawable != null) {
mPopupWindow.setBackgroundDrawable(mDrawable);
} else {
mPopupWindow.setBackgroundDrawable(new ColorDrawable());
}
if (mAnimationStyle != -1) {
mPopupWindow.setAnimationStyle(mAnimationStyle);
}
if (mWidth == 0 || mHeight == 0) {
measureWidthAndHeight(mContentView);
//如果没有设置高度的情况下,设置宽高并赋值
mWidth = mPopupWindow.getContentView().getMeasuredWidth();
mHeight = mPopupWindow.getContentView().getMeasuredHeight();
}
Activity activity = (Activity) mContext;
if (activity != null && mBackgroundDarkEnable) {
float alpha = (mDarkAlpha >= 0f || mDarkAlpha <= 1f) ? mDarkAlpha : 0.7f;
mWindow = activity.getWindow();
WindowManager.LayoutParams params = mWindow.getAttributes();
params.alpha = alpha;
mWindow.setAttributes(params);
}
mPopupWindow.setOnDismissListener(this);
mPopupWindow.update();
}
@Override
public void onDismiss() {
dismiss();
}
/**
* 测量View的宽高
*
* @param mContentView
*/
private void measureWidthAndHeight(View mContentView) {
int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec((1 << 30) - 1, View.MeasureSpec.AT_MOST);
int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec((1 << 30) - 1, View.MeasureSpec.AT_MOST);
mContentView.measure(widthMeasureSpec, heightMeasureSpec);
}
/**
* 设置布局ID
*
* @param layoutResId
* @return
*/
public Builder setView(@LayoutRes int layoutResId) {
mContentView = null;
this.mLayoutResId = layoutResId;
return this;
}
/**
* 设置宽高
*
* @param width
* @param height
* @return
*/
public Builder setSize(int width, int height) {
mWidth = width;
mHeight = height;
return this;
}
/**
* 设置背景
*
* @param drawable
* @return
*/
public Builder setBackgroundDrawable(Drawable drawable) {
mDrawable = drawable;
return this;
}
/**
* 设置背景是否变暗
*
* @param darkEnable
* @return
*/
public Builder setBackgroundDarkEnable(boolean darkEnable) {
mBackgroundDarkEnable = darkEnable;
return this;
}
/**
* 设置背景透明度
*
* @param dackAlpha
* @return
*/
public Builder setBackgroundAlpha(@FloatRange(from = 0.0, to = 1.0) float dackAlpha) {
mDarkAlpha = dackAlpha;
return this;
}
/**
* 是否点击Outside消失
*
* @param touchable
* @return
*/
public Builder setOutsideTouchable(boolean touchable) {
mOutsideTouchable = touchable;
return this;
}
/**
* 是否设置Touch事件
*
* @param touchable
* @return
*/
public Builder setTouchable(boolean touchable) {
mTouchable = touchable;
return this;
}
/**
* 设置动画
*
* @param animationStyle
* @return
*/
public Builder setAnimationStyle(@StyleRes int animationStyle) {
mAnimationStyle = animationStyle;
return this;
}
/**
* 是否设置获取焦点
*
* @param focusable
* @return
*/
public Builder setFocusable(boolean focusable) {
mFocusable = focusable;
return this;
}
/**
* 设置子View点击事件回调
*
* @param listener
* @return
*/
public Builder setViewOnClickListener(ViewClickListener listener) {
this.mListener = listener;
return this;
}
}
}
使用PopupWindow
public class MainActivity extends AppCompatActivity implements CommonPopWindow.ViewClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//向上弹出
public void showUpPopClick(View view) {
CommonPopWindow.newBuilder()
.setView(R.layout.pop_right_or_left)
.setViewOnClickListener(this)
.build(this)
.showAsUp(view);
}
//向下弹出
public void showDownPopClick(View view) {
CommonPopWindow.newBuilder()
.setView(R.layout.pop_right_or_left)
.setViewOnClickListener(this)
.build(this)
.showAsDown(view);
}
//向左弹出
public void showLeftPopClick(View view) {
CommonPopWindow.newBuilder()
.setView(R.layout.pop_right_or_left)
.setAnimationStyle(R.style.AnimRightToLeft)
.setViewOnClickListener(this)
.build(this)
.showAsLeft(view);
}
//向右弹出
public void showRightPopClick(View view) {
CommonPopWindow.newBuilder()
.setView(R.layout.pop_right_or_left)
.setAnimationStyle(R.style.AnimRightToLeft)
.setViewOnClickListener(this)
.build(this)
.showAsRight(view);
}
//底部弹出
public void showBottomPopClick(View view) {
CommonPopWindow.newBuilder()
.setView(R.layout.pop_bottom)
.setAnimationStyle(R.style.AnimUp)
.setBackgroundDrawable(new BitmapDrawable())
.setSize(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
.setViewOnClickListener(this)
.setBackgroundDarkEnable(true)
.setBackgroundAlpha(0.7f)
.build(this)
.showAsBottom(view);
}
@Override
public void getChildView(final PopupWindow mPopupWindow, View view, int layoutResId) {
switch (layoutResId) {
case R.layout.pop_right_or_left:
ImageView good = (ImageView) view.findViewById(R.id.good);
ImageView collection = (ImageView) view.findViewById(R.id.collection);
good.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
toast("点赞");
Log.e("Tag", "onClick");
mPopupWindow.dismiss();
}
});
collection.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
toast("收藏");
mPopupWindow.dismiss();
}
});
break;
case R.layout.pop_bottom:
Button btnTakePhoto = (Button) view.findViewById(R.id.btn_take_photo);
Button btnSelectPhoto = (Button) view.findViewById(R.id.btn_select_photo);
Button btnCancel = (Button) view.findViewById(R.id.btn_cancel);
btnTakePhoto.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
toast("拍照");
mPopupWindow.dismiss();
}
});
btnSelectPhoto.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
toast("相册选取");
mPopupWindow.dismiss();
}
});
btnCancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
toast("取消");
mPopupWindow.dismiss();
}
});
break;
}
}
private void toast(String str) {
Toast.makeText(this, str, Toast.LENGTH_SHORT).show();
}
}
推荐阅读
-
Android kotlin上传头像实现
-
Android Studio笔记之webview ——实现app本身打开网页而不跳转到其他浏览器(内置浏览器)
-
javascript自定义in_array()函数实现方法_javascript技巧
-
Android Studio 需要掌握的Debug技巧
-
从7点到9点写的小程序(用了模块导入,python终端颜色显示,用了点局部和全局可变和不可变作用域,模块全是自定义)
-
PHP采用自定义函数实现遍历目录下所有文件的方法_PHP
-
mysql-Mysql存储过程中怎么判断传入参数与自定义字符串的值相等(新人求助)
-
Android进阶学习:移动端开发重点学习的十点,不能再得过且过的写业务代码了
-
JSP自定义标签:带标签体(body)的标签
-
对微信Android版的交互协议和加密模式的进一步分析及修复方案