来自:https://github.com/shuaijia/JsHeadline/
参考
自定义Notification和Toast
Android用建造者模式实现一个新功能引导页
定义:
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
AlertDialog、okhttp 中都使用了构造者模式。
优点:
良好的封装性,使得客户端不需要知道产品内部实现的细节
建造者独立,扩展性强
缺点:
产生多余的Builder对象、Director对象,消耗内存
示例一:对popupWindow的封装
使用
JsPopupWindow popup = new JsPopupWindow.Builder()
.setContentViewId(R.layout.popup_news_list)
.setContext(itemView.getContext())
.setOutSideCancle(true)
.setFouse(false)
.setWidth((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 100,
itemView.getContext().getResources().getDisplayMetrics()))
.setHeight((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 40,
itemView.getContext().getResources().getDisplayMetrics()))
.setAnimation(R.style.anim_pop)
.build();
定义:
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.PopupWindow;
/**
* Description: 对popupWindow的封装
* Created by jia on 2017/7/10.
* 人之所以能,是相信能
*/
public class JsPopupWindow {
private PopupWindow mPopupWindow;
private View mContentView;
private Context mContext;
public JsPopupWindow(Builder builder) {
mContext = builder.getContext();
// 创建view
mContentView = LayoutInflater.from(mContext).inflate(builder.getContentViewId(), null);
// 创建popupWindow
mPopupWindow = new PopupWindow(mContentView, builder.getWidth(),
builder.getHeight(), builder.isFouse());
mPopupWindow.setOutsideTouchable(builder.isOutSideCancle());
mPopupWindow.setFocusable(true);
mPopupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
mPopupWindow.setAnimationStyle(builder.getAnimation());
}
/**
* 消失
*/
public void dismiss() {
if (mPopupWindow != null && mPopupWindow.isShowing()) {
mPopupWindow.dismiss();
}
}
/**
* 获取控件
*
* @param itemId
* @return
*/
public View getItemView(@NonNull int itemId) {
if (mPopupWindow != null && mContentView != null) {
return mContentView.findViewById(itemId);
}
return null;
}
/**
* 在父布局特定位置显示
*
* @param rootViewId
* @param gravity
* @param x
* @param y
* @return
*/
public JsPopupWindow showAtLocation(int rootViewId, int gravity, int x, int y) {
if (mPopupWindow != null) {
View rootView = LayoutInflater.from(mContext).inflate(rootViewId, null);
mPopupWindow.showAtLocation(rootView, gravity, x, y);
}
return this;
}
public JsPopupWindow showAsLocation(int targetViewId, int gravity, int offx, int offy) {
if (mPopupWindow != null) {
View targetview = LayoutInflater.from(mContext).inflate(targetViewId, null);
mPopupWindow.showAsDropDown(targetview, offx, offy, gravity);
}
return this;
}
public JsPopupWindow showAsLocation(View targetView, int gravity, int offx, int offy) {
if (mPopupWindow != null) {
mPopupWindow.showAsDropDown(targetView, offx, offy, gravity);
}
return this;
}
/**
* 根据id设置焦点监听
*
* @param viewid
* @param listener
*/
public void setOnFocusListener(int viewid, View.OnFocusChangeListener listener) {
View view = getItemView(viewid);
view.setOnFocusChangeListener(listener);
}
/**
* 在父布局特定位置显示
*
* @param gravity
* @param x
* @param y
* @return
*/
public JsPopupWindow showAtLocation(View rootView, int gravity, int x, int y) {
if (mPopupWindow != null) {
mPopupWindow.showAtLocation(rootView, gravity, x, y);
}
return this;
}
public static class Builder {
private Context context;
private int contentViewId;
private int width;
private int height;
private boolean fouse;
private boolean outSideCancle;
private int animation;
public Context getContext() {
return context;
}
public Builder setContext(Context context) {
this.context = context;
return this;
}
public int getContentViewId() {
return contentViewId;
}
public Builder setContentViewId(int contentViewId) {
this.contentViewId = contentViewId;
return this;
}
public int getWidth() {
return width;
}
public Builder setWidth(int width) {
this.width = width;
return this;
}
public int getHeight() {
return height;
}
public Builder setHeight(int height) {
this.height = height;
return this;
}
public boolean isFouse() {
return fouse;
}
public Builder setFouse(boolean fouse) {
this.fouse = fouse;
return this;
}
public boolean isOutSideCancle() {
return outSideCancle;
}
public Builder setOutSideCancle(boolean outSideCancle) {
this.outSideCancle = outSideCancle;
return this;
}
public int getAnimation() {
return animation;
}
public Builder setAnimation(int animation) {
this.animation = animation;
return this;
}
/**
* 构建
*
* @return
*/
public JsPopupWindow build() {
return new JsPopupWindow(this);
}
}
}
Builder模式可以称为建造者模式,它将一个复杂对象的构建和表示分离,同样的构建过程可以创建不同的表示。
示例二:
public class Student {
private String name;
private Integer age;
private String sex;
public Student() {
}
public Student(Builder builder) {
this.name = builder.name;
this.age = builder.age;
this.sex = builder.sex;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
'}';
}
// 构造者
public static class Builder {
private String name;
private Integer age;
private String sex;
public Builder setName(String name) {
this.name = name;
return this;
}
public Builder setAge(Integer age) {
this.age = age;
return this;
}
public Builder setSex(String sex) {
this.sex = sex;
return this;
}
public Student build() {
return new Student(this);
}
}
//测试如下: 可以任意构造
public static void main(String[] args) {
Student student1 = new Student(new Builder().setAge(20).setSex("男"));//没有姓名
System.out.println(student1);
Student student2 = new Student.Builder().setName("吴奇隆").setAge(18).build();//没有性别
System.out.println(student2);
}
}