- AlertDialog 實現(xiàn)
- 從屏幕底部彈出對話框
- 自定義效果
- Activity 仿 Dialog 效果
部分參考 android 底部彈出提示框的實現(xiàn)方式
基礎(chǔ)方法
構(gòu)造方法
很好幾個览露,要特別說的是這里的第二個养匈,可以加載一個 style 勒叠,
是實現(xiàn) dialog 寬度全屏的關(guān)鍵
Dialog(@NonNull Context context)
Dialog(@NonNull Context context, @StyleRes int themeResId)
設(shè)置寬高:
也可以直接使用數(shù)值
Window window = dialog.getWindow();
WindowManager.LayoutParams params = window.getAttributes();
params.width = WindowManager.LayoutParams.MATCH_PARENT;
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
window.setAttributes(params);//設(shè)置 dialog 的寬高
設(shè)置動畫
style 文件朝抖,下面會介紹
window.setWindowAnimations(R.style.dialog_anim);//設(shè)置動畫效果
其他的方法
setTitle(@Nullable CharSequence title) //使用默認的標題
setCustomTitle(@Nullable View customTitleView) //傳入一個布局挎峦,自定義樣式
setIcon(@Nullable Drawable icon) //使用圖標做標題
setMessage(@Nullable CharSequence message) // 在標題下按鈕上的說明文字
setPositiveButton(CharSequence text, final OnClickListener listener) // 常用于"確定"按鈕
setNegativeButton(CharSequence text, final OnClickListener listener) //常用于"取消"按鈕
setCancelable(boolean cancelable) // 設(shè)置點擊框外是否可以關(guān)閉,默認為可以
setItems(CharSequence[] items, final OnClickListener listener) //用這個實現(xiàn)簡單的列表
setView(View view) //實現(xiàn)自定義的一個布局
監(jiān)聽事件
setOnCancelListener(OnCancelListener onCancelListener)
setOnDismissListener(OnDismissListener onDismissListener)
setOnKeyListener(OnKeyListener onKeyListener)
AlertDialog 基礎(chǔ)實現(xiàn)
一個不怎么標準的例子:
因為例子中是在 Fragment 中缺亮,通過 LayoutInflater 獲取布局澈侠。
調(diào)用這個 openDialog() 方法即彈出對話框。
private void openDialog() {
LinearLayout linearLayout = (LinearLayout) LayoutInflater.from(getContext()).inflate(R.layout.change_password_dialog, null);
final EditText originPasswordEt = (EditText) linearLayout.findViewById(R.id.origin_password);
TextView forgetPassword = (TextView) linearLayout.findViewById(R.id.forget_password);
final AlertDialog dialog = new AlertDialog.Builder(getContext())
.setTitle("輸入密碼")
.setView(linearLayout)
.setPositiveButton("確定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String originPassword = originPasswordEt.getText().toString().trim();
//傳到后臺
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.create();
dialog.show();
forgetPassword.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showToast("忘記密碼");
dialog.dismiss();
}
});
}
布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:orientation="horizontal">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/origin_password"
android:textColor="@color/black_primary_dark"
android:textSize="16sp"/>
<EditText android:id="@+id/origin_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginStart="32dp"
android:hint="@string/origin_password_hint"
android:inputType="textPassword"
android:lines="1"/>
</LinearLayout>
<TextView android:id="@+id/forget_password" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginStart="24dp"
android:layout_marginTop="16dp"
android:text="@string/forget_password"
android:textColor="@color/small_text_color"
android:textSize="16sp"/>
</LinearLayout>
出現(xiàn)的位置铅辞,與相應動畫
彈出框出現(xiàn)在屏幕下方
Window window = dialog.getWindow();
window.setGravity(Gravity.BOTTOM); //設(shè)置框的位置
彈出框會出現(xiàn)在屏幕下方藻治,但屏幕的左右和下方都有一個小的空隙
要使彈出框布不留有間隙,只改變布局的 layout_width 是不夠的巷挥,這個是主題 style 導致的
新建一個 style:
<style name="Dialog_Full">
<item name="android:windowFullscreen">true</item>
<!-- 背景透明 -->
<item name="android:windowBackground">@android:color/transparent</item>
<!-- activity變暗 -->
<item name="android:backgroundDimEnabled">true</item>
</style>
并讓 dialog 引用這個 style
//在構(gòu)造函數(shù)中引用 style
AlertDialog dialog = new AlertDialog.Builder(getContext(),R.style.Dialog_Full).create();
Window window = dialog.getWindow();
window.setGravity(Gravity.BOTTOM);
//設(shè)置橫向滿屏桩卵,縱向自適應,沒有這里彈出框會完全布滿屏幕
window.setLayout(WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.WRAP_CONTENT);
彈出的動畫和縮回的動畫:
//pop_in.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="@android:integer/config_shortAnimTime"
android:fromYDelta="100%p"
android:toYDelta="0" />
<alpha
android:duration="@android:integer/config_shortAnimTime"
android:fromAlpha="0.0"
android:toAlpha="1.0" />
</set>
//pop_out.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromYDelta="0"
android:toYDelta="100%p" />
</set>
還有一個 style:
<style name="dialog_anim" parent="android:Animation">
<item name="android:windowEnterAnimation">@anim/pop_in</item>
<item name="android:windowExitAnimation">@anim/pop_out</item>
</style>
設(shè)置引用這個 style:
Window window = dialog.getWindow();
window.setGravity(Gravity.BOTTOM);
window.setWindowAnimations(R.style.dialog_anim);//動畫效果
window.setLayout(WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.WRAP_CONTENT);
dialog.show();//show 必須在 set 后面
效果圖就不上了..
自定義效果
將這個控件封裝好利于復用倍宾,并且可以自定義不同數(shù)目的 item 而不需要重寫布局雏节。
依然是參考 android 底部彈出提示框的實現(xiàn)方式,添加了一些改動
- 支持放任意多個 Item高职,但只有文字內(nèi)容
- 選擇是否左右無間隙
- 選擇是否有“取消”按鈕
- 選擇是否可以點擊外部關(guān)閉
- 文字居中或者靠左
核心代碼:
public static Dialog showItemSelectDialog() {
final Dialog dialog;
if (isFull){
dialog = new Dialog(context,R.style.Dialog_Full);//傳入布局改變主題
}else {
dialog = new Dialog(context);
}
View rootView = LayoutInflater.from(context).inflate(R.layout.layout_choice,null);
LinearLayout contentsView = (LinearLayout) rootView.findViewById(R.id.dialog_content);
//逐個添加 TextView
for(int i = 0;i < contents.length;i++){
View centerView = LayoutInflater.from(context).inflate(R.layout.dialog_center_item,null);
TextView centerText = (TextView) centerView.findViewById(R.id.dialog_center_item);
final int finali = i;
centerText.setText(contents[finali]);
centerText.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
dialog.dismiss();
if (listener != null){
listener.getSelectedItem(contents[finali]);
}
}
});
if (isTextCenter){
centerText.setGravity(Gravity.CENTER);//水平和垂直居中
}else{
centerText.setPadding(20,0,0,0);
centerText.setGravity(Gravity.CENTER_VERTICAL);//垂直居中
}
contentsView.addView(centerView);
}
Button CancleBtn = (Button) rootView.findViewById(R.id.dialog_cancel);
if (isBtnCancle){
CancleBtn.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
}else {
CancleBtn.setVisibility(View.GONE);
}
dialog.setContentView(rootView);
if (isCancelable){
dialog.setCancelable(true);
dialog.setCanceledOnTouchOutside(true);
}else {
dialog.setCancelable(false);
dialog.setCanceledOnTouchOutside(false);
}
Window window = dialog.getWindow();
WindowManager.LayoutParams params = window.getAttributes();
if (!(isCenter)){
params.gravity = Gravity.BOTTOM;
}
params.width = WindowManager.LayoutParams.MATCH_PARENT;
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
window.setAttributes(params);//設(shè)置 dialog 的寬高
window.setWindowAnimations(R.style.dialog_anim);//設(shè)置動畫效果
dialog.show();
return dialog;
}
只是很粗糙的實現(xiàn)钩乍,很多可以改進的地方。
但如果再繼續(xù)折騰下去可能不還如直接用 popupwidow怔锌。
用 Activity 實現(xiàn)類似 Dialog 的效果
參考 Android中使用Dialog風格彈出框的Activity
在 style 新建:
<style name="dialogstyle">
<!--設(shè)置dialog的背景-->
<item name="android:windowBackground">@android:color/transparent</item>
<!--設(shè)置Dialog的windowFrame框為無-->
<item name="android:windowFrame">@null</item>
<!--設(shè)置無標題-->
<item name="android:windowNoTitle">true</item>
<!--是否浮現(xiàn)在activity之上-->
<item name="android:windowIsFloating">true</item>
<!--是否半透明-->
<item name="android:windowIsTranslucent">true</item>
<!--設(shè)置窗口內(nèi)容不覆蓋-->
<item name="android:windowContentOverlay">@null</item>
<!--設(shè)置動畫寥粹,在這里使用讓它繼承系統(tǒng)的Animation.Dialog-->
<item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
<!--背景是否模糊顯示-->
<item name="android:backgroundDimEnabled">true</item>
</style>
然后在 AndroidManifest.xml 中設(shè)置 DialogActivity 的 theme