builder模式创建自定义popwindow

builder设计模式

将一个复杂的对象构建与它的表示分离,简化代码的使用方式。当对象有多个参数或多个零件同时初始化方法同时初始化方法有默认值时,采用此模式比较方便。

主要结构

  1. basepopwindow 产品类
  2. builder 产品类具体的构造类 basepopwindow的子类
  3. BasePopController 产品类控制类
  4. PopupParams 产品类参数类 basepopcontroller 的子类

代码实现

public class BasePopWindow extends PopupWindow {
final BasePopController controller; public BasePopWindow(Context context) {
this.controller = new BasePopController(context, this);
} public interface ViewInterface{
/**
* view 或布局id
* @param view
* @param viewResId
*/
void getChildView(View view,int viewResId);
}
@Override
public int getWidth() {
return controller.mPopWindowView.getMeasuredWidth();
}
@Override
public int getHeight() {
return controller.mPopWindowView.getMeasuredHeight();
} @Override
public void dismiss() {
super.dismiss();
controller.setAlpha(1.0f);
}
public static class Builder{
private final BasePopController.PopupParams popupParams;
private ViewInterface viewInterface; public Builder(Context context) {
this.popupParams = new BasePopController.PopupParams(context);
}
/*
返回this为链式调用
*/
public Builder setView(int layoutResId){
popupParams.mView=null;
popupParams.layoutResId=layoutResId;
return this;
}
public Builder setView(View mView){
popupParams.mView=mView;
popupParams.layoutResId=0;
return this;
}
public Builder setConstomViewClickListen(ViewInterface viewInterface){
this.viewInterface=viewInterface;
return this;
}
public Builder setAnimation(int animationResId){
popupParams.isAnimation=true;
popupParams.animationResId=animationResId;
return this;
}
public Builder setWidthHeight(int width,int height){
popupParams.mWidth=width;
popupParams.mHight=height;
return this;
}
public Builder setAlpha(float alpha){
popupParams.alpha=alpha;
popupParams.isShowBg=true;
return this;
}
public Builder setIsOutClick(boolean isOutClick){
popupParams.isOutside=isOutClick;
return this;
}
public BasePopWindow create(){
final BasePopWindow window=new BasePopWindow(popupParams.context);
popupParams.apply(window.controller);
if (viewInterface!=null&& popupParams.layoutResId!=0) {
viewInterface.getChildView(window.controller.mPopWindowView,popupParams.animationResId);
}
int widthMeasureSpec=View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
int heightMeasureSpec=View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
window.controller.mPopWindowView.measure(widthMeasureSpec,heightMeasureSpec);
return window;
}
}
}

basepopwindow 构造函数使用basepopcontroller完成,可以采用布局id或view两种参数之一,viewinterface 暴漏其中的子view,同时builder类设置参数的返回值均为this便于使用链式调用,

create方法组装basepopcontroller中的默认构造函数和popupparams中设置的参数,basepopcontroller代码如下:

public class BasePopController {
private int layoutResId;
private Context context;
private PopupWindow popupWindow;
View mPopWindowView;
private View mView;
private Window window; public BasePopController(Context context, PopupWindow popupWindow) {
this.context = context;
this.popupWindow = popupWindow;
}
public void setView(int layoutResId){
mView=null;
this.layoutResId=layoutResId;
installContent();
}
public void setView(View mView){
layoutResId=0;
this.mView=mView;
installContent();
} private void installContent() {
if (layoutResId != 0) {
mPopWindowView= LayoutInflater.from(context).inflate(layoutResId, null);
} else if (mView!=null){
mPopWindowView=mView;
}
popupWindow.setContentView(mPopWindowView);
}
private void setWidthHeight(int width,int height){
if (width==0) {
popupWindow.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
} else {
Log.e("popwindow", "setWidthHeight: "+width);
popupWindow.setWidth(width);
}
if (height==0) {
popupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
} else {
popupWindow.setHeight(height);
Log.e("popwindow", "setWidthHeight: "+height);
}
} void setAlpha(float alpha){
window= ((Activity)context).getWindow();
WindowManager.LayoutParams lp=window.getAttributes();
lp.alpha=alpha;
window.setAttributes(lp);
}
private void setAnimation(int animaResId){
popupWindow.setAnimationStyle(animaResId);
} /**
* 设置外部可点击
*/
private void setOutsideClick(boolean isClick){
popupWindow.setBackgroundDrawable(new ColorDrawable(context.getResources().getColor(R.color.transparent)));
popupWindow.setOutsideTouchable(isClick);
popupWindow.setFocusable(isClick);
}
static class PopupParams{
public int layoutResId;
public Context context;
public int mWidth,mHight;
public boolean isShowBg,isAnimation;
public float alpha;
public int animationResId;
public View mView;
public boolean isOutside; public PopupParams(Context context) {
this.context = context;
} public void apply(BasePopController controller){
if (mView != null) {
controller.setView(mView);
}else if (layoutResId!=0){
controller.setView(layoutResId);
}else {
throw new IllegalArgumentException("popwindow layout content no set");
}
controller.setWidthHeight(mWidth, mHight);
controller.setOutsideClick(isOutside);
if (isShowBg) {
controller.setAlpha(alpha);
}
if (isAnimation) {
controller.setAnimation(animationResId);
}
}
} }

具体使用方法如下:

  basePopWindow = new BasePopWindow.Builder(this)
.setView(R.layout.bg_pop_actpaymentchose)
.setWidthHeight((int) (point.x * 0.6), point.y / 4)
.setAnimation(R.style.pop_bottom_anim)
.setAlpha(0.5f)
.setIsOutClick(true)
.setConstomViewClickListen((view, viewResId) -> {
//此处获取子view
tvleft.setOnClickListener(v -> {
basePopWindow.dismiss();
});
tvRight.setOnClickListener(v -> {
try {
jsonObject.put("orderNum", orderNum);
} catch (JSONException e) {
e.printStackTrace();
}
mPresentser.getConfirmreceiving(jsonObject.toString());
basePopWindow.dismiss();
});
})
.create();
basePopWindow.showAtLocation(findViewById(R.id.rl_root), Gravity.CENTER, 0, 0);

showAtLocation 方法显示在组件某位置,showAsDropDown()方法可以设置于某一组件下方,一般在启动按钮。windowmanager的LayoutParams参数alpha可以设置灰度,弹出popwindow时可以设置背景变暗,范围是0 ~1f,

可以设置页面的根布局,point值是根据屏幕获取的实际大小百分比设置,避免布局出现错乱。方法如下:

Display display = getWindowManager().getDefaultDisplay();
Point point = new Point();
display.getSize(point);

Android 开发学习进程0.30 builder模式创建popwindow的更多相关文章

  1. Android 开发学习进程0.16 layout_weight属性 R文件关联XML Module

    layout_weight属性 layout_weight属性我们常常用到,但有时候会发现它还有一些奇怪的属性,比如大多数使用时会把宽度设置成0,但要是宽度不设置成0会有什么效果? layout_we ...

  2. Android 开发学习进程0.19 webview 的使用

    Android 中的webview android 中的webview是可以在app内部打开HTML等的网页,不必再打开浏览器,有两种实现方法,即webviewclient webChromeclie ...

  3. Android开发学习进程0.18 SharePreference的使用 AIDL

    SharePreference SharePreference是一种持久化存储手段,使用场景很多,如第一次打开时加载的用户协议等.适合小数据单进程的应用.将数据以键值对的形式存储在XML中. 使用方式 ...

  4. Android 开发学习进程0.17 Android资源文件selector textview显示两种不同字体

    selector 是安卓资源文件的一种,它可以使按钮等实现不同状态下的不同UI,不用在代码中实现,而使用方式有两种,一种在color文件下 创建.xml可以使按钮等字体在不同状态下的变化,其二是在dr ...

  5. Android 开发学习进程0.15 adb cardview framelayout 控件设置状态获取焦点

    Android设备调试桥 即adb 使用adb进行无线调试的一些常用命令 adb tcpip 5555 设置调试端口为5555 防止冲突 adb shell ifconfig wlan0 查询局域网中 ...

  6. Android 开发学习进程0.27 kotlin使用 和viewbinding的使用

    kotlin-android-extensions 插件被废弃 笔者曾经尝试写过一部分的kotlin代码 主要是项目中一些代码是kotlin完成的,其中我认为 kotlin的kotlin-androi ...

  7. Android 开发学习进程0.28 腾讯TBS接入和相关问题

    TBS 的接入和使用 TBS 的接入 腾讯TBS是X5内核的升级版,可以当作webview 来打开 网页,可以以用来打开docx doc pdf 等文件,这里主要使用的是文件功能. 依赖接入 api ...

  8. Android 开发学习进程0.32 dwonloadmanager使用

    downloadmanager时Android系统下载器,使用系统下载器可以避免用stream流读入内存可能导致的内存溢出问题.以下为downloadmanager初始化部分.apkurl为下载网络路 ...

  9. Android 开发学习进程0.14 Bindview recyclerview popwindow使用 window类属性使用

    BindView ButterKnife 优势 绑定组件方便,使用简单 处理点击事件方便,如adapter中的viewholder 同时父组件绑定后子组件无需绑定 注意 在setcontentview ...

随机推荐

  1. 007.NET5 Log4Net组件使用

    NET 5 Log4Net组件使用 1. Nuget引入程序集:log4net + Microsfot.Extensions.Logging.Log4Net.AspNetCore 2. 准备配置文件 ...

  2. 如何使用 js 实现tooltips 的 hover 时候坐标的自动计算

    如何使用 js 实现tooltips 的 hover 时候坐标的自动计算 js 监听 mouseover event https://developer.mozilla.org/zh-CN/docs/ ...

  3. vue 二级子路由跳转不了 bug

    vue 二级子路由跳转不了 bug @click.prevent 阻止原生事件的冒泡 <li class="tools-hover-box-list-item" v-for= ...

  4. vue 自动注册全局组件

    vue 自动注册全局组件 vue 注册全局组件的方式 const plugins = { install(Vue) { const requireComponent = require.context ...

  5. calendar time shaper

    calendar time shaper const dateObj = { "id": 191837, "productId": 13602, "a ...

  6. git & Angular git commit 规范

    git & Angular git commit 规范 https://github.com/angular/angular/commits/master https://github.com ...

  7. vue & template & v-else & v-for bug

    vue & template & v-else & v-for bug nested table bug https://codepen.io/xgqfrms/pen/wvaG ...

  8. “NGK公链+5G”——打造智慧城市

    智慧城市目前被全球各国当成城市建设的重点,旨在城市在智能化的同时,还能给民众带来幸福感和安全感.随着5G的到来,城市智能化又到了一个新的高度.比如无人驾驶.无人机等方面将会产生质的变化,因为5G的加入 ...

  9. m1款MacBook Air 使用3个月总结及原生运行于apple架构软件推荐

    前言 我之前一直是一个坚定的Windows/Android党,大学的时候用过几台iPhone,感觉也就那样.这次m1版本的Mac一发布我直接又转回apple阵营了,11月份的时候官网订了一台m1 版本 ...

  10. 将项目加载到tomcat中的时候报错:Tomcat version 6.0 only supports J2EE 1.2, 1.3, 1.4, and Java EE 5 Web modules

    转自:http://jingwang0523.blog.163.com/blog/static/9090710320113294551497/ 最近在用eclipse做项目,新建项目时什么都贪新,用最 ...