版權聲明:本文出自阿鐘的博客,轉載請註明出處:http://blog.csdn.net/a_zhon
唉!最近一直忙碌着寫項目以至於都沒有空出點時間來總結近期的學習,記錄學習到的東西…現在正好有時間了就該好好記錄一下學習的過程了。今天就來談談開發中經常用的到的一個控件——Dialog,對話框一般我們就用來提示一些信息給用戶,讓用戶自主選擇,或者在一些操作不可逆的情況下我們提示用戶是否繼續操作,下面就讓我們一起來學習吧。老司機發車啦…
最簡單的對話框
AlertDialog dialog = new AlertDialog.Builder(this)
.setIcon(R.mipmap.icon)//設置標題的圖片
.setTitle("我是對話框")//設置對話框的標題
.setMessage("我是對話框的內容")//設置對話框的內容
//設置對話框的按鈕
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this, "點擊了取消按鈕", Toast.LENGTH_SHORT).show();
dialog.dismiss();
}
})
.setPositiveButton("確定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this, "點擊了確定的按鈕", Toast.LENGTH_SHORT).show();
dialog.dismiss();
}
}).create();
dialog.show();
AlertDialog類中有一個靜態內部類Builder。所以可以看出對話框使用了一個建造者模式在調用函數的時候就可以一直直點點點鏈式調用。 需要注意的是:NegativeButton這個按鈕是在對話框的左邊,PositiveButton在對話框的右邊;如果你還想再加一個按鈕也是可以的只需要在調用.setNeutralButton(“第三個按鈕”,listener)即可。
列表對話框
當給用戶的選擇就那麼幾條路的時候,就可在對話框上放置一個列表供用戶自己選擇
final String items[] = {"我是Item一", "我是Item二", "我是Item三", "我是Item四"};
AlertDialog dialog = new AlertDialog.Builder(this)
.setIcon(R.mipmap.icon)//設置標題的圖片
.setTitle("列表對話框")//設置對話框的標題
.setItems(items, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this, items[which], Toast.LENGTH_SHORT).show();
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.setPositiveButton("確定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}).create();
dialog.show();
源碼已經爲我們預留好了設置方法,所以我們只需要調用.setItems()即可,第一個參數即要顯示item的數組,第二個參數也就是點擊item後的監聽事件還是so easy的。
單選列表對話框
這個與列表對話框差不多是一樣的只是它是單選。
final String items[] = {"我是Item一", "我是Item二", "我是Item三", "我是Item四"};
AlertDialog dialog = new AlertDialog.Builder(this)
.setIcon(R.mipmap.icon)//設置標題的圖片
.setTitle("單選列表對話框")//設置對話框的標題
.setSingleChoiceItems(items, 1, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this, items[which], Toast.LENGTH_SHORT).show();
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.setPositiveButton("確定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}).create();
dialog.show();
.setSingleChoiceItems(items, 1, listener)第一個參數:設置單選的資源數組;第二個參數:設置默認選中哪一項。
多選列表
final String items[] = {"我是Item一", "我是Item二", "我是Item三", "我是Item四"};
final boolean checkedItems[] = {true, false, true, false};
AlertDialog dialog = new AlertDialog.Builder(this)
.setIcon(R.mipmap.icon)//設置標題的圖片
.setTitle("多選對話框")//設置對話框的標題
.setMultiChoiceItems(items, checkedItems, new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
checkedItems[which] = isChecked;
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.setPositiveButton("確定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
for (int i = 0; i < checkedItems.length; i++) {
if (checkedItems[i]) {
Toast.makeText(MainActivity.this, "選中了" + i, Toast.LENGTH_SHORT).show();
}
}
dialog.dismiss();
}
}).create();
dialog.show();
.setMultiChoiceItems(items, checkedItems, listener)//第一個參數:設置單選的資源;第二個參數:設置默認選中哪幾項(數組);
半自定義對話框
或許上面幾種對話框的款式都不是你需要或者喜歡的,那你肯定就需要開始自定義了;源碼爲我們提供了一個.setView()函數,這樣我們就可以自定義對話框顯示的內容了,如下代碼:
View view = getLayoutInflater().inflate(R.layout.half_dialog_view, null);
final EditText editText = (EditText) view.findViewById(R.id.dialog_edit);
AlertDialog dialog = new AlertDialog.Builder(this)
.setIcon(R.mipmap.icon)//設置標題的圖片
.setTitle("半自定義對話框")//設置對話框的標題
.setView(view)
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.setPositiveButton("確定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String content = editText.getText().toString();
Toast.makeText(MainActivity.this, content, Toast.LENGTH_SHORT).show();
dialog.dismiss();
}
}).create();
dialog.show();
上面代碼中half_dialog_view.xml中我就放置了一個EditText;在這裏好多人在找自己佈局中的控件時候經常報NullpointException,原因也很簡單就是沒有使用加載的佈局.findViewbyId()。到了這一步基本上就能滿足開發中80%的需求了,看官如果還不能滿足那別急慢慢往下看。
完全自定義的對話框
上面我們說了可以通過調用.setView(view)方法,自定義其顯示的內容;但是你會覺得這遠遠不夠我還想把他的標題或者底部按鈕給改了,那麼就需要來個完全自定義了,如下:
首先我們需要自定義Dialog的style,讓他自己本有的東西全部透明,然後在設置我們自己的內容就可以達到完全自定義的效果了。
<!--對話框的樣式-->
<style name="NormalDialogStyle">
<!--對話框背景 -->
<item name="android:windowBackground">@android:color/transparent</item>
<!--邊框 -->
<item name="android:windowFrame">@null</item>
<!--沒有標題 -->
<item name="android:windowNoTitle">true</item>
<!-- 是否浮現在Activity之上 -->
<item name="android:windowIsFloating">true</item>
<!--背景透明 -->
<item name="android:windowIsTranslucent">false</item>
<!-- 是否有覆蓋 -->
<item name="android:windowContentOverlay">@null</item>
<!--進出的顯示動畫 -->
<item name="android:windowAnimationStyle">@style/normalDialogAnim</item>
<!--背景變暗-->
<item name="android:backgroundDimEnabled">true</item>
</style>
<!--對話框動畫-->
<style name="normalDialogAnim" parent="android:Animation">
<item name="@android:windowEnterAnimation">@anim/normal_dialog_enter</item>
<item name="@android:windowExitAnimation">@anim/normal_dialog_exit</item>
</style>
接下來就可以爲對話框設置我們自定義的style了.
/**
* 自定義對話框
*/
private void customDialog() {
final Dialog dialog = new Dialog(this, R.style.NormalDialogStyle);
View view = View.inflate(this, R.layout.dialog_normal, null);
TextView cancel = (TextView) view.findViewById(R.id.cancel);
TextView confirm = (TextView) view.findViewById(R.id.confirm);
dialog.setContentView(view);
//使得點擊對話框外部不消失對話框
dialog.setCanceledOnTouchOutside(true);
//設置對話框的大小
view.setMinimumHeight((int) (ScreenSizeUtils.getInstance(this).getScreenHeight() * 0.23f));
Window dialogWindow = dialog.getWindow();
WindowManager.LayoutParams lp = dialogWindow.getAttributes();
lp.width = (int) (ScreenSizeUtils.getInstance(this).getScreenWidth() * 0.75f);
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
lp.gravity = Gravity.CENTER;
dialogWindow.setAttributes(lp);
cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
confirm.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
dialog.show();
}
同樣我門通過調用這個dialog.setContentView(view);就可以設置我們自己的佈局了。所以現在關鍵就是碼我們的佈局了一起來看看效果圖
既然是自定義對話框,那麼就肯定要來弄一弄他的方方面面;
這裏使用到了一個工具類用來計算手機屏幕的寬高,如下代碼:
public class ScreenSizeUtils {
private static ScreenSizeUtils instance = null;
private int screenWidth, screenHeight;
public static ScreenSizeUtils getInstance(Context mContext) {
if (instance == null) {
synchronized (ScreenSizeUtils.class) {
if (instance == null)
instance = new ScreenSizeUtils(mContext);
}
}
return instance;
}
private ScreenSizeUtils(Context mContext) {
WindowManager manager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics dm = new DisplayMetrics();
manager.getDefaultDisplay().getMetrics(dm);
screenWidth = dm.widthPixels;// 獲取屏幕分辨率寬度
screenHeight = dm.heightPixels;// 獲取屏幕分辨率高度
}
//獲取屏幕寬度
public int getScreenWidth() {
return screenWidth;
}
//獲取屏幕高度
public int getScreenHeight() {
return screenHeight;
}
}
Demo 底部選擇對話框
我們現在可以自定義對話框了,那麼我們就來實現一個經常用到的一個底部選擇對話框,來看下效果圖吧:
先來碼這個對話框的佈局,dialog_bottom.xml裏面就放置了三個按鈕。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent"
android:orientation="vertical">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/round_corner"
android:text="拍照" />
<TextView
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:background="#ddd" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/round_corner"
android:text="相冊" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="@drawable/round_corner"
android:text="取消" />
<View
android:layout_width="match_parent"
android:layout_height="15dp" />
</LinearLayout>
接下來就可以爲我們的對話框加載這個佈局了
Dialog dialog = new Dialog(this, R.style.NormalDialogStyle);
View view = View.inflate(this, R.layout.dialog_bottom, null);
dialog.setContentView(view);
dialog.setCanceledOnTouchOutside(true);
view.setMinimumHeight((int) (ScreenSizeUtils.getInstance(this).getScreenHeight() * 0.23f));
Window dialogWindow = dialog.getWindow();
WindowManager.LayoutParams lp = dialogWindow.getAttributes();
lp.width = (int) (ScreenSizeUtils.getInstance(this).getScreenWidth() * 0.9f);
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
lp.gravity = Gravity.BOTTOM;
dialogWindow.setAttributes(lp);
dialog.show();
上面這一段帶代碼的關鍵就是將Dialog放置在屏幕底部lp.gravity = Gravity.BOTTOM;並設置他的寬度爲屏幕的90%lp.width = (int) (ScreenSizeUtils.getInstance(this).getScreenWidth() * 0.9f);。相信大家之前都用的是popwindow來實現這個效果的,現在學會了這個是不是可以直接把他給替換了。哈哈……
進度條對話框(圓形、水平)
這個就相對比較簡單了
ProgressDialog dialog = new ProgressDialog(this);
dialog.setMessage("正在加載中");
dialog.show();
當然我們也可以設置一個水平的進度條並顯示當前進度,只需要把他的樣式設置爲ProgressDialog.STYLE_HORIZONTAL即可。
final ProgressDialog dialog = new ProgressDialog(this);
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setMessage("正在加載中");
dialog.setMax(100);
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
int progress = 0;
@Override
public void run() {
dialog.setProgress(progress += 5);
if (progress == 100) {
timer.cancel();
}
}
}, 0, 1000);
dialog.show();
BottomSheetDialog
一個可以上下拖動的對話框,使用方法和Dialog還是差不多的。
BottomSheetDialog dialog = new BottomSheetDialog(this);
View view = getLayoutInflater().inflate(R.layout.activity_main, null);
dialog.setContentView(view);//設置顯示的內容,我這爲了方便就直接把主佈局設置進去了。
dialog.show();
BottomSheetDialog會根據你設置的View大小來計算默認顯示出來的高度,內容越多顯示的越多反之則越少。當顯示的內容比較少的時候他默認顯示一點,這個時候就比較蛋疼了所以我們就要讓他一顯示就默認全部展開。
/**
* 默認展開對話框
*/
final FrameLayout frameLayout = (FrameLayout) dialog.findViewById(android.support.design.R.id.design_bottom_sheet);
frameLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
//獲得BottomSheetBehavior
BottomSheetBehavior behavior = BottomSheetBehavior.from(frameLayout);
//設置對話框的的狀態
behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
}
});
BottomSheetDialog的操作基本上都是通過Behavior來設置的,所以關鍵就是獲得他的Behavior;
這裏還有小坑就是:當你向下滑動讓他消失的時候,對話框是看不見了但是他卻並沒有dismiss需要在點擊一次屏幕才能完全消失。下面給出解決辦法:通過監聽他的狀態來手動dismiss();
behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
if (newState == BottomSheetBehavior.STATE_HIDDEN)
dialog.dismiss();
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
}
});
下載地址
Demo下載地址 https://download.csdn.net/download/a_zhon/9740905
題外話
說到這裏基本上一些常用的Dialog就講完了(ps:如有缺漏歡迎大家留言補充…),相信你也一定學習get到了。歡迎大家加入 QQ羣:555974449 一起來學習哦! (時不時有老司機開車哦….)