项目中遇到一个需求,需要在 Service
中弹出 Dialog
以显示消费信息,但是 Dialog
需要依附于一个 Activity
,但是当用户退出应用之后,该应用的 Activity
就已全部销毁,所以在 Service
中弹出的 Dialog
也就没有了可以依附的 Activity
了。
网上普遍是将这个应用的 Dialog
设置成一个系统级的 Dialog
,即一个全局性质的提示框,这样,无论它现在处于何种界面之下,只要调用 show()
就可以弹出提示框了。
该方法由于配置起来相对麻烦,而且各大厂商的权限管理各不相同,于是我改用了一种更为简单粗暴的方法——直接从 Service
中弹出 Activity
,Activity
为我们提供了多种主题,我们只需选择一个弹窗类型的主题即可。
首先创建一个新的 Activity
,然后在「AndroidManifest.xml」中修改这个 Activity
的主题:
<activity
android:name=".DialogActivity"
android:theme="@style/Theme.AppCompat.Light.Dialog.Alert" />
其实 Dialog
主题也挺多的,有美有丑,得益于 IDE 的智能提醒,输入“Dialog”就列出了一大堆,我也懒得一个个试了,挑了两三个看下效果,发现最好看就是上面这个,所以就选它了。
然后开始写布局文件,虽然是 Dialog
样式,但只需按照平常写 Activity
布局的习惯来写即可。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="10dp"
tools:context=".DialogActivity">
<TextView
android:id="@+id/dialog_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="15dp" />
<Button
android:id="@+id/dialog_positive_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="@color/colorPrimary"
android:text="确定"
android:textColor="#FFFFFF" />
</LinearLayout>
布局十分简单,一个纵向线性布局,里面就一个文本显示框和一个按钮,宽度都填满父视图,高度则包裹该组件,这应该是多年 Windows 系统以及多种操作系统和应用达成的一种不成文的共识,使我们作为用户也形成了固有的印象。
最后就是逻辑代码实现了,同样极其简单,就像平常写 Activity
的逻辑一样。
public class DialogActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dialog);
TextView dialogMessage = (TextView) findViewById(R.id.dialog_message);
String details = getIntent().getStringExtra("dialogMessage");
dialogMessage.setText(details);
Button dialogPositiveButton = (Button) findViewById(R.id.dialog_positive_button);
dialogPositiveButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
});
}
}
获取到 TextView
和 Button
的实例,TextView
通过 getIntent()
获取 Service
中传过来的内容并显示,而 Button
则负责关闭这个 Activity
。
实际效果如下: