1.来源
DialogFragment类最初是通过Android3.0(API级别11)添加的,官方推荐您应该将 DialogFragment 用作对话框的容器。DialogFragment 类提供您创建对话框和管理其外观所需的所有控件,而不是调用 Dialog 对象上的方法。
2.好处
使用 DialogFragment 管理对话框可确保它能正确处理生命周期事件,如用户按“返回”按钮或旋转屏幕时。 此外,DialogFragment 类还允许您将对话框的 UI 作为嵌入式组件在较大 UI 中重复使用,就像传统 Fragment 一样(例如,当您想让对话框 UI 在大屏幕和小屏幕上具有不同外观时)。
3.注意事项
注:由于 DialogFragment 类最初是通过 Android 3.0(API 级别 11)添加的,因此本文描述的是如何使用支持库附带的 DialogFragment 类。 通过将该库添加到您的应用,您可以在运行 Android 1.6 或更高版本的设备上使用 DialogFragment 以及各种其他 API。如果您的应用支持的最低版本是 API 级别 11 或更高版本,则可使用 DialogFragment 的框架版本,但请注意,本文中的链接适用于支持库 API。 使用支持库时,请确保您导入的是 android.support.v4.app.DialogFragment 类,而不是 android.app.DialogFragment。
4.使用
1.如何显示一个dialog出来
onCreateDialog中可以通过AlertDialogAPl创建多种列表(传统单选列表,永久性单选列表(单选按钮),永久性多选列表(复选框)),也可以自定义布局.... 至于具体用法读者可以自行百度
class FireMissilesDialogFragment : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val builder = AlertDialog.Builder(activity) //import android.app.Dialog
val inflater = activity!!.layoutInflater
builder.setView(inflater.inflate(R.layout.dialog_signin, null))
.setPositiveButton("确定", DialogInterface.OnClickListener() { dialog, id ->
})
.setNegativeButton("取消", DialogInterface.OnClickListener() { dialog, id ->
})
return builder.create()
}
}
在Activity中使用
val dialogFragment = FireMissilesDialogFragment()
dialogFragment.show(supportFragmentManager, "1")
//or val sfb = supportFragmentManager.beginTransaction()
sfb.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE )
dialogFragment.show(sfb,"1")
2.将事件传递回对话框的宿主
当用户触摸对话框的某个操作按钮或从列表中选择某一项时,您的 DialogFragment 可能会自行执行必要的操作,但通常您想将事件传递给打开该对话框的 Activity 或片段。 为此,请定义一个界面,为每种点击事件定义一种方法。然后在从该对话框接收操作事件的宿主组件中实现该界面。
class FireMissilesDialogFragment : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val builder = AlertDialog.Builder(activity) //import android.app.Dialog
val inflater = activity!!.layoutInflater
builder.setView(inflater.inflate(R.layout.dialog_signin, null))
.setPositiveButton("确定", DialogInterface.OnClickListener() { dialog, id ->
mListener!!.onDialogPositiveClick(this)
})
.setNegativeButton("取消", DialogInterface.OnClickListener() { dialog, id ->
mListener!!.onDialogNegativeClick(this)
})
return builder.create()
}
}
interface NoticeDialogListener {
fun onDialogPositiveClick(dialog: DialogFragment)
fun onDialogNegativeClick(dialog: DialogFragment)
}
var mListener: NoticeDialogListener? = null
override fun onAttach(context: Context?) {
super.onAttach(context)
try {
// Instantiate the NoticeDialogListener so we can send events to the host
mListener = activity as NoticeDialogListener
} catch (e: ClassCastException) {
// The activity doesn't implement the interface, throw exception
throw ClassCastException(activity.toString() + " must implement NoticeDialogListener")
}
}
由于宿主 Activity 会实现 NoticeDialogListener—由以上显示的 onAttach() 回调方法强制执行 — 因此对话框片段可以使用界面回调方法向 Activity 传递点击事件
3.某些特殊情况下
您可能采用以下 UI 设计:您想让一部分 UI 在某些情况下显示为对话框,但在其他情况下全屏显示或显示为嵌入式片段(也许取决于设备使用大屏幕还是小屏幕)。DialogFragment 类便具有这种灵活性,因为它仍然可以充当嵌入式 Fragment。
但在这种情况下,您不能使用 AlertDialog.Builder 或其他 Dialog 对象来构建对话框。如果您想让 DialogFragment 具有嵌入能力,则必须在布局中定义对话框的 UI,然后在 onCreateView() 回调中加载布局
1.使用
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val dialog = super.onCreateDialog(savedInstanceState)
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
return dialog
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.dialog_signin, container, false)
}
if (mIsLargeLayout) {
dialogFragment.show(supportFragmentManager, "1")
} else {
val sfb = supportFragmentManager.beginTransaction()
sfb.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
sfb.add(android.R.id.content, dialogFragment)
.addToBackStack(null).commit()
}
2.判断大屏幕
在本示例中,mIsLargeLayout 布尔值指定当前设备是否应该使用应用的大布局设计(进而将此片段显示为对话框,而不是全屏显示)。 设置这种布尔值的最佳方法是声明一个布尔资源值,其中包含适用于不同屏幕尺寸的备用资源值。 例如,以下两个版本的布尔资源适用于不同的屏幕尺寸:
res/values/bools.xml
false
res/values-large/bools.xml
true
然后,您可以在 Activity 的 onCreate() 方法执行期间初始化 mIsLargeLayout 值:
var mIsLargeLayout = resources.getBoolean(R.bool.large_layout)