Dialogs
A dialog is a small window that prompts the user to make a decision or enter additonal infomation .Adialog does not fill the screen and is normally used for modal events that require users to take an action before they can proceed.
Dialog
The Dialog class is the base class for dialogs, but you should avoid instantiating Dialog directly. Instead , use one of the following subclasses.
1, AlertDialog
A dialog that can show title , up to three buttons,a list of selectable items,or a custom layout.
2, DatePickerDialog and TimePickerDialog
A dialog with a pre-defined UI that allows the user to select a date or time.
以上3個(gè)類定義了Dialog的樣式和結(jié)構(gòu),但是最好使用一個(gè)個(gè)DialogFragment來包裹Dialog對(duì)象.
DialogFragment 類提供了所有Dialog操作需要要的接口.可以創(chuàng)建和管理Dialog樣式.使用
DialogFragment 管理對(duì)話框確保他可以正確處理生命周期事件.
DialogFragment 可以將Dialog作為一個(gè)組件嵌入到更大的組件中.就像普通的Fragment那樣.
Creating a Dialog Fragment
You can accomplish a wide variety dialog designs - including custom layouts and those described in the Dialogs design guide - by extending DialogFragment and creating AlertDialog in the onCreateDialog() callback method.
你可以完成各式各樣的對(duì)話框設(shè)計(jì),包括自定義布局和通過DialogFragment的onCreateDialog()回調(diào)函數(shù)中來創(chuàng)建.
A basic AlertDialog that's managed within a DialogFragment
public static class FireMissilesDialogFragment extends android.support.v4.app.DialogFragment{
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the Builder class for convenient dialog construction
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage("測(cè)試對(duì)話框")
.setPositiveButton("Fire",new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
Log.d("---","===========fire");
}
})
.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Log.d("---","=========== cancel");
}
});
// Create the AlertDialog object and return it .
return builder.create();
}
}
直接創(chuàng)建類的對(duì)象調(diào)用 show() 方法.
new FireMissilesDialogFragment().show(getSupportFragmentManager(),"111");
Building an Alert Dialog
組成
1. Title : 該部分是可選的,只有當(dāng)內(nèi)容區(qū)域有內(nèi)容時(shí)才使用Title
2. Content area : 可以展示一個(gè)消息,列表,或者其他自定義布局 .
3. Action buttons : 最多3個(gè)按鈕.(確定,取消,其他)
AlertDialog.Builder 創(chuàng)建對(duì)話框.
// 1. Instantiate an AlertDialog.Builder with its constructor
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// 2. Chain together various setter methods to set the dialog charachteristics
builder.setMessage("Message")
.setTitle("Title");
// 3. Get the AlertDialog from create()
AlertDialog dialog = builder.create();
Adding buttons
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setPositiveButton("Fire",new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
Log.d("---","===========fire");
}
})
.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Log.d("---","=========== cancel");
}
});
// Set other Dialog properties
// Create the AlertDialog object and return it .
return builder.create();
Adding a list
A traditional single-choice list(普通列表)
// 使用 setItems()
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("列表")
.setItems(R.array.language, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// The 'which' argument contains the index position
// of selected item .
}
});
return builder.create();
A persistent single-choice list(radio buttons)
方法 : setSingleChoiceItems()
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Radio")
.setSingleChoiceItems(R.array.language, 0, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Log.d("TAG","選擇了 : " + which);
}
});
return builder.create();
A persistent multiple-choice list(checkboxes)
方法 : setMultiChoiceItems()
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
return builder.setTitle("CheckBoxes")
.setMultiChoiceItems(R.array.language,null, new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
Log.d("TAG","Index : " + which);
Log.d("TAG","OP : " + isChecked);
}
}).create();
Create a Custom Layout
創(chuàng)建自定義布局的Dialog.
1. 創(chuàng)建自定義布局.
2. 通過AlertDialog.Builder 的 setView()添加到Dialog中.
res/layout/dialog_signin.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:src="@drawable/logo"
android:scaleType="centerInside"
android:background="#FFFFBB33"
android:contentDescription="LOGO"
android:layout_width="match_parent"
android:layout_height="64dp"/>
<EditText
android:id="@+id/et_username"
android:inputType="textWebEmailAddress"
android:layout_marginTop="16dp"
android:layout_marginStart="4dp"
android:layout_marginEnd="4dp"
android:layout_marginBottom="4dp"
android:hint="username"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<EditText
android:id="@+id/et_password"
android:inputType="textPassword"
android:layout_marginTop="16dp"
android:layout_marginStart="4dp"
android:layout_marginEnd="4dp"
android:layout_marginBottom="4dp"
android:hint="password"
android:fontFamily="sans-serif"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
Tip : 設(shè)置 "textPassword" 會(huì)改變 fontFamily 為 monospace,
可以通過設(shè)置 "sans-serif" 來保持兩個(gè)框一致.
public static class CustomLayoutDialog extends DialogFragment{
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Get the layout inflater
LayoutInflater inflater = getActivity().getLayoutInflater();
// Inflate and set layout for the dialog
// Pass null as the parent view because its going in the dialog layout
builder.setView(inflater.inflate(R.layout.dialog_signin,null));
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
return builder.create();
}
}
Tip : 可以使用Activity來實(shí)現(xiàn)自定義Dialog的功能.
只需要將Activity主題設(shè)置如下 :
<activity android:theme="@android:style/Theme.Holo.Dialog">
Passing Events Back to the Dialog's Host
public static class NoticeDialogFragment extends DialogFragment{
/* The activity that creates an instance of this dialog fragment
* must implement this interface inorder to receive event callbacks.
* Each method passes the DialogFragment in case the host needs to query it.
*/
public interface NoticeDialogListener {
public void onDialogPositiveClick(DialogFragment dialog);
public void onDialogNegativeClick(DialogFragment dialog);
}
// Use this instance of the interface to deliver action events
NoticeDialogListener mListener;
// Override the Fragment.onAttach() method to instantiate the NoticeDialogListener
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// Verify that the host activity implements the callback interface
try{
mListener = (NoticeDialogListener) activity;
}catch (ClassCastException e){
throw new ClassCastException(activity.toString()+"must implement NoticeDialogListener");
}
}
}
Showing a Dialog
1. 創(chuàng)建一個(gè)DialogFragment實(shí)例對(duì)象
2. 調(diào)用 show()
3. FragmentManager獲取方式 :
3.1 getSupportFragmentManager() from the fragmentActivity.
3.2 getFragmentManager() from a Fragment .
Showing a Dialog Fullscreen or as an Embedded Fragment
DialogFragment 可以同時(shí)使用一下兩種情況:
1. 顯示為Dialog.
2. 顯示為Fragment.
注意 : 在這種情況下不能使用AlertDialog.Builder 或者其他的Dialog對(duì)象創(chuàng)建
需要在onCreateView() 中加載布局文件.
一下代碼實(shí)現(xiàn)了在小屏幕上顯示Fragment在大屏幕上顯示Dialog
public static class CustomEmDialogFragment extends DialogFragment {
/**
* The system calls this to get the DialogFragment's layout,regardless
* of whether it's being displayed as a dialog or an embedded fragment.
* */
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
// Inflate the layout to use as dialog or embedded fragment.
return inflater.inflate(R.layout.dialog_signin,container,false);
}
/** The system calls this only when creating the layout in a dialog */
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// The only reason you might override this method when using onCreateView() is
// to modify any dialog characteristics. For example , the dialog includes a
// title by default , but you custom layout might not need it. So here you can
// remove the dialog title , but you must call the superclass to get the Dialog.
Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
return dialog;
}
}
private boolean mIsLargeLayout = false;
public void showDialog(){
FragmentManager fragmentManager = getSupportFragmentManager();
CustomLayoutDialog newFragment = new CustomLayoutDialog();
if (mIsLargeLayout){
newFragment.show(fragmentManager,"dialog");
}else{
// the device is smaller, so show the fragment fullscreen.
FragmentTransaction transaction = fragmentManager.beginTransaction();
// For a little polish, specify a transition animation
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
transaction.add(android.R.id.content,newFragment)
.addToBackStack(null).commit();
}
}
res/values/bools.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="large_layout">false</bool>
</resources>
res/values-large/bools.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="large_layout">true</bool>
</resources>
Dismissing a Dialog
1. 每次onCancel() 被調(diào)用 都會(huì)調(diào)用 onDismiss().
2. Dialog.dismiss() 和 DialogFragment.dismiss() 會(huì)調(diào)用onDismiss .
不會(huì)調(diào)用onCancel().
3. 可以在onDismiss() 中進(jìn)行必要操作.