編輯:關於Android編程
開始說正題。
先上上一次的效果圖,其展現出的效果,是建造者模式的思想精髓。
關注建造產品的共性,其細節的個性則讓其自由定義(是否顯示,顯示的內容);
今天要做的PopupView也很簡單,
頂部是一個Title
中間是一個Content
底部是左右兩個按鈕
通過建造者模式,實現可自定義的PopupView。(自定義頂部、中部、底部)
以下是PopupView的XML布局文件:
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(); }
案例到此為止,
附上簡單的效果圖
有時候利用android的TextView顯示中文跟數字的組合會對不齊,如下面截圖,文字還沒有到達屏幕右邊就開始換行了為了解決這個文字,自己子定義了一個TextView的
Buzz桌面安裝好之後,是不會自動將已安裝的手機應用程序圖標添加到桌面上的,需要我們手動添加或拖動應用程序圖標到桌面,下面就讓我們來看看如何將已經安裝的應用
以前寫過2篇關於相冊選取、裁剪的demo,今天我們來學習下github上一款開源的相冊裁剪開源庫開源庫地址 https://github.com/ArthurHub/An
Android Toolbar:ToolBar是Android 5.0(API Level 21)之後用來取代ActionBar的ToolBar的優勢:Toolbar本身