前面是一个具体示例,总结/模板(暂无)看最后。
dialog就是指的这个:
主要分为以下三部分:
①:Title
②:View
③:Button
其中Title和Button需要通过Java代码直接设置,两者都强制为纯文本,而View需要一个布局文件。
所以如果想要自定义Title和Button,可以不设置他们而在View里面完成
注意这个View的范围(红框的范围),是很靠边的,所以如果想像图中这样让文字往中间靠,需要设置margin(亲测为24dp)。
下面是具体的实现。
首先要为这个dialog(实质上是一个fragment)建立一个类。
图中是一个备忘录(Memos)app,这是点了删除键之后出现的dialog,用这个举例。
(反正是我自己写的app,完全不怕侵权)
这个dialog类就叫DeleteDialogFragment.java
public class DeleteDialogFragment extends DialogFragment //v4支持包的类
{
@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
return new AlertDialog.Builder(getActivity()) //v7支持包的类
.create();
}
}
这样就是一个最简单的dialog了,但是这是一个完全空白的dialog。
接下来要为他加入标题:
return new AlertDialog.Builder(getActivity())
.setTitle("Warning") //此处均采用硬编码,最好放在string.xml中
.create();
然后加入两个按键。
可以看出,一个是确认的按键,一个是取消的按键。这两个分别用setPositiveButton(...)
与setNegativeButton(...)
来实现。
这两个方法均应传入两个参数:一个是名称(String),一个是点击监听器(DialogInterFace.OnClickListener()
(android.content包内的类))。后者不需要可以传入null,这样按下之后除了dialog消失以外什么也不会发生。
在这个示例中,明显按下cancel是什么也不会发生的,而按下delete后会删除当前备忘录。
先把这两个按钮加进去:
return new AlertDialog.Builder(getActivity())
.setTitle("Warning")
.setPositiveButton("Delete", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialogInterface, int i)
{
//相关代码
}
})
.setNegativeButton("Cancel", null)
.create();
(不得不说,这条return语句真的好长啊……)
接下来先把这个dialog的view部分完成。
增添一个layout布局文件delete_dialog_fragment:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:width="match_parent"
android:height="match_parent"
android:orientation="vertical"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="24dp"
android:text="Are you sure to delete this memo?"
android:textSize="16sp"
/>
</LinearLayout>
然后在DeleteDialogFragment中引用他:
@Override
public void Dialog onCreateDialog(...)
{
View v = LayoutInflater.from(getActivity()).inflate(R.layout.delete_dialog_fragment, null);
return ...
...
.setView(v)
...;
}
现在dialog的外观已经完成了,但是,这个dialog暂时还是没有用的,因为它的按钮还没有设置。
事实上,dialog最终实现的效果并不一定是由dialog本身来完成的,也可以由另一个fragment(一般都是创建dialog的fragment)完成。如果不需要调用另一个fragment中的成员,就可以在dialog的代码中实现(比如结束当前activity:getActivity().finish();
)。但是如果需要,那就要把一些信息传给那个fragment,告诉他:“这个按钮被按下了!”
在DeleteDialogFragment.java中添加下列代码:
//由于传回去的信息是以Intent作为载体
//所以需要一个键
public static final String EXTRA_IFDELETE = "com.company.memos.ifdelete";
private void sentResult(int resultCode, boolean ifDelete)
{
//为了防止下面出现空指针导致运行时错误
if (getTargetFragment() == null)
{
return;
}
Intent intent = new Intent();
intent.putExtra(EXTRA_IFDELETE, ifDelete);
getTargetFragment().onActivityResult(getTargetRequestCode(), resultCode, intent);
}
并且完善Delete按钮的监听器:
@Override
public void onClick(DialogInterface dialogInterface, int i)
{
//第一个参数表示按下的是一个positive button
//此外还有RESULT_CANCEL和RESULT_FIRST_USER
sentResult(Activity.RESULT_OK, true);
}
上面的代码中出现的TargetFragment需要在创建dialog的时候设定。
相关代码如下:
Fragment fm = getFragmentManager(); //v4包中的类
DeleteDialogFragment dialog = new DeleteDialogFragment();
//前一个参数指的是目标fragment
//由于在这个示例中它的名字无关紧要故略去
//后一个参数是(迷之)请求码(int)
//(估计是)为了验证是不是自己发出的请求
//这里设为0,具体代码不在此详述
dialog.setTargetFragment(XXXXXX.this, REQUEST_IFDELETE);
//后一个参数是这个dialog的标签(String)
dialog.show(fm, DIALOG_IFDELETE);
接着在这个类中重载onActivityResult(...)
方法:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
//确认是不是按下了positive button
if (resultCode != Activity.RESULT_OK)
{
return;
}
//确认是不是自己创建的dialog
if (requestCode == REQUEST_IFDELETE)
{
//下面是具体代码,并非通用
//如果提取出来的额外信息为真
//(之前放入了一个boolean值)
if (data.getBooleanExtra(DeleteDialogFragment.EXTRA_IFDELETE, false))
{
//“删除该备忘录”的相关代码
//然后结束这个activity
getActivity().finish();
}
}
}
至此,这个dialog就已经全部完成了。