上一次簡單分析了鏈式編程,爽感今猶在,今天接上次,模仿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();
}
案例到此爲止,
附上簡單的效果圖