建造者模式实例之PopupView

上一次简单分析了链式编程,爽感今犹在,今天接上次,模仿android原生AlertDialog做一个PopupView。
这里借鉴了 :

下一个丶奇迹 http://blog.csdn.net/pangpang123654/article/details/52254803

的分享,倍感倾谢。


开始说正题。
先上上一次的效果图,其展现出的效果,是建造者模式的思想精髓。

这里写图片描述

关注建造产品的共性,其细节的个性则让其自由定义(是否显示,显示的内容);


今天要做的PopupView也很简单,

顶部是一个Title
中间是一个Content
底部是左右两个按钮
通过建造者模式,实现可自定义的PopupView。(自定义顶部、中部、底部)


以下是PopupView的XML布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="320dp"
    android:layout_height="400dp"
    android:layout_marginTop="200dp"
    android:background="#cccccc"
    android:gravity="center"
    android:orientation="vertical">

    <TextView
        android:id="@+id/txt_title"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:gravity="center"
        android:text="title"
        android:textSize="18sp" />

    <TextView
        android:id="@+id/txt_info"
        android:layout_width="match_parent"

        android:layout_height="40dp"
        android:gravity="center"
        android:text="msg" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="80dp"

        android:orientation="horizontal">

        <Button
            android:id="@+id/btn_left"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

        <Button
            android:id="@+id/btn_right"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1" />
    </LinearLayout>

</LinearLayout>

MainActivity中,动态加载一个LinearLayout,居中布置两个横向排列的Button。
左边一个Button点击后出现第一种形式的PopupView
右边一个Button点击后出现第二种形式的PopupView,
MainActivity代码如下:

package com.lebang.lmuseum;

import android.app.Activity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(mainview());
    }

    /**
     * 动态加载主布局
     *
     * @return
     */
    private View mainview() {
        //LinearLayout的参数及布局
        LinearLayout mLinearLayout = new LinearLayout(this);
        LinearLayout.LayoutParams mParams = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
        mLinearLayout.setOrientation(LinearLayout.HORIZONTAL);
        mLinearLayout.setGravity(Gravity.CENTER_HORIZONTAL);
        mLinearLayout.setLayoutParams(mParams);

        //动态创建Button的params,mBtnOne和mBtnTwo使用
        LinearLayout.LayoutParams mBtn_params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT);

        //创建第一个Button,该Button弹出的PopupView是不带title,带content,带一个Button的
        Button mBtnOne = new Button(this);
        mBtn_params.gravity = Gravity.CENTER_VERTICAL;
        mBtnOne.setLayoutParams(mBtn_params);
        mBtnOne.setText("弹出单按钮提示");
        mBtnOne.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new PopupView.Builder(MainActivity.this)
                        .setContent("真的要删除历史记录吗?").setRightText("确定")
                        .setListenRight(new ImplRightClick() {
                            @Override
                            public void rightClick() {
                                Toast.makeText(MainActivity.this, "点击了右侧,左侧的按钮被我隐藏了,这世界只要我一个按钮就好",
                                        Toast.LENGTH_LONG).show();
                            }
                        }).build().showPopupView();
            }
        });

        //创建第二个Button,该Button弹出的PopupView是带title,带content,带两个Button的
        Button mBtnTwo = new Button(this);
        mBtnTwo.setLayoutParams(mBtn_params);
        mBtnTwo.setText("弹出双按钮提示");
        mBtnTwo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new PopupView.Builder(MainActivity.this)
                        .setTitle("提示")
                        .setContent("真的要删除历史记录吗?")
                        .setLeftText("取消")
                        .setListenLeft(new ImplLeftClick() {
                            @Override
                            public void leftClick() {
                                Toast.makeText(MainActivity.this, "点击了左侧",
                                        Toast.LENGTH_LONG).show();
                            }
                        }).setRightText("确定")
                        .setListenRight(new ImplRightClick() {
                            @Override
                            public void rightClick() {
                                Toast.makeText(MainActivity.this, "点击了右侧",
                                        Toast.LENGTH_LONG).show();
                            }
                        }).build().showPopupView();
            }
        });

        mLinearLayout.addView(mBtnOne);
        mLinearLayout.addView(mBtnTwo);
        return mLinearLayout;
    }
}

主要看点从new PopupView.Builder(MainActivity.this) 开始。
是不是和安卓中的new AlertDialog.Builder(this),如出一辙?

那么我们来看看PopupView内部是如何封装的,
PopupView代码如下:

package com.lebang.lmuseum;

import android.content.Context;
import android.graphics.drawable.BitmapDrawable;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.PopupWindow;
import android.widget.TextView;

/**
 * Created by Administrator on 2016/9/12.
 * 通过建造者模式构建一个popupwindow
 */
public class PopupView extends PopupWindow {
    private final Context context;
    private final String title;
    private final String content;
    private final ImplLeftClick iListenLeft;
    private final ImplRightClick iListenRight;
    private final String leftText;
    private final String rightText;

    /**
     *  内部类Builder
     *  外部调用时的代码就可以写new PopupView.Builder()
     */
    public static class Builder {
        private final Context context;
        private String title;
        private String content;
        private ImplLeftClick iListenLeft;
        private ImplRightClick iListenRight;
        private String leftText;
        private String rightText;

        public Builder(Context context) {
            this.context = context;
        }

        public Builder setTitle(String title) {
            this.title = title;
            return this;
        }

        public Builder setContent(String content) {
            this.content = content;
            return this;
        }

        public Builder setListenLeft(ImplLeftClick iListenLeft) {
            this.iListenLeft = iListenLeft;
            return this;
        }

        public Builder setLeftText(String leftText) {
            this.leftText = leftText;
            return this;
        }

        public Builder setListenRight(ImplRightClick iListenRight) {
            this.iListenRight = iListenRight;
            return this;
        }

        public Builder setRightText(String rightText) {
            this.rightText = rightText;
            return this;
        }

        public PopupView build() {
            return new PopupView(this);
        }
    }

    public PopupView(Builder builder) {
        this.context = builder.context;
        this.title = builder.title;
        this.content = builder.content;
        this.iListenLeft = builder.iListenLeft;
        this.iListenRight = builder.iListenRight;
        this.leftText = builder.leftText;
        this.rightText = builder.rightText;
        initPopupView();
    }

    private PopupWindow popupWindow;
    private View popView;
    private TextView txt_title;
    private TextView txt_info;

    private void initPopupView() {
        popView = LayoutInflater.from(context).inflate(R.layout.popup_common_view, null);
        //获取屏幕尺寸
        DisplayMetrics dm = new DisplayMetrics();
        WindowManager windowManager = (WindowManager) context
                .getSystemService(Context.WINDOW_SERVICE);
        windowManager.getDefaultDisplay().getMetrics(dm);
        //将PopupView 的尺寸设为宽满屏,高半屏
        popupWindow = new PopupWindow(popView, dm.widthPixels, dm.heightPixels/2);
        //设为可点击
        popupWindow.setFocusable(true);
        //设为屏外可点击
        popupWindow.setOutsideTouchable(true);
        //设置背景图片
        popupWindow.setBackgroundDrawable(new BitmapDrawable());
        txt_title = (TextView) popView.findViewById(R.id.txt_title);
        if (TextUtils.isEmpty(title)) {
            txt_title.setVisibility(View.GONE);
        } else {
            txt_title.setText(title);
        }
        txt_info = (TextView) popView.findViewById(R.id.txt_info);
        if (TextUtils.isEmpty(content)) {
            txt_info.setVisibility(View.GONE);
        } else {
            txt_info.setText(content);
        }
        Button btn_right = (Button) popView.findViewById(R.id.btn_right);
        if (!TextUtils.isEmpty(rightText)) {
            btn_right.setText(rightText);
            btn_right.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    popupWindow.dismiss();
                    if (iListenRight != null) {
                        iListenRight.rightClick();
                    }
                }
            });
        } else {
            btn_right.setVisibility(View.GONE);
        }
        Button btn_left = (Button) popView.findViewById(R.id.btn_left);
        if (!TextUtils.isEmpty(leftText)) {
            btn_left.setText(leftText);
            btn_left.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    popupWindow.dismiss();
                    if (iListenLeft != null) {
                        iListenLeft.leftClick();
                    }
                }
            });
        } else {
            btn_left.setVisibility(View.GONE);
        }
    }

   public void showPopupView() {
        if (popupWindow == null) {
            initPopupView();
        }
       //指定展示的位置
        popupWindow.showAtLocation(popView, Gravity.CENTER_VERTICAL, 0, 0);
    }
}

外部是一个PopupView, 内部有一个Builder的内部类,两者的属性变量基本相同
PopupView中最主要的两个方法是initPopupView()和showPopup(),

Builder中最主要的方法则是build(),返回一个PopupView实例,并将Build中所有属性的值赋给PopupView。
然后在PopupView的showPopup()中判断该实例是否为空,不为空则show()出来..

左右两个按钮的接口代码

public interface ImplLeftClick {
    void leftClick();
}

public interface ImplRightClick {
    void rightClick();
}

案例到此为止,
附上简单的效果图

这里写图片描述

源码点击此处下载
http://download.csdn.net/detail/lebang08/9628601

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值