因app需求问题,需要实现如图这种dialog
看到这里,你可能会说如此easy的事情,还说什么! 那么继续往下看!
场景1:
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
public class AlertDialogFragmentActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_alert_dialog_fragment);
findViewById(R.id.show).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showDialog();
}
});
}
public static class MyAlertDialogFragment extends DialogFragment {
public static MyAlertDialogFragment newInstance(int title) {
MyAlertDialogFragment frag = new MyAlertDialogFragment();
Bundle args = new Bundle();
args.putInt("title", title);
frag.setArguments(args);
return frag;
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
int title = getArguments().getInt("title");
// AlertDialog 的内容区
View contentView = LayoutInflater.from(getActivity()).inflate(R.layout.basic_dialog_fragment, null);
return new AlertDialog.Builder(getActivity())
.setIcon(R.drawable.ic_about)
.setTitle(title)
.setView(contentView)
.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) {
}
})
.create();
}
}
void showDialog() {
DialogFragment newFragment = MyAlertDialogFragment.newInstance(R.string.two_buttons_title);
newFragment.show(getSupportFragmentManager(), "dialog");
}
}
实际效果图成了这样
title区的内容不是纵横向居中的,button区完全走样右对齐了,如上图所示,只有绿色内容区是自定义内容,(title和button样式都是Android内置)
这是什么原因造成的?
这是因为当前这个AlertDialogFragmentActivity的theme属性的原因,它继承自AppCompatActivity要求使用 Theme.AppCompat.xxx 系列theme
代码中(AppCompatActivity,DialogFragment,AlertDialog)都是support library中的类,这些的类是配套使用的,你不能在Activity中直接使用support library中的DialogFragment和AlertDialog
尝试在AndroidManifest.xml中将AppCompatActivity的android:theme属性改成"@android:style/Theme.Holo"等,后续得到一个以下异常
Caused by: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.
Theme.AppCompat.xxx 系列theme可以用于非support library包中的类,反过来Theme.Holo.xxx 或者 Theme.Light.xxx 等系列则无法用于support library包中的类
尝试修改 MyAlertDialogFragment的onCreateDialog 中的AlertDialog.Builder()代码
new AlertDialog.Builder(getActivity(),android.R.style.Theme_Holo_Dialog)
得到的效果图如下,反而更差
场景2:
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
public class AlertDialogFragmentActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_alert_dialog_fragment);
findViewById(R.id.show).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showDialog();
}
});
}
public static class MyAlertDialogFragment extends DialogFragment {
public static MyAlertDialogFragment newInstance(int title) {
MyAlertDialogFragment frag = new MyAlertDialogFragment();
Bundle args = new Bundle();
args.putInt("title", title);
frag.setArguments(args);
return frag;
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
int title = getArguments().getInt("title");
// AlertDialog 的内容区
View contentView = LayoutInflater.from(getActivity()).inflate(R.layout.basic_dialog_fragment, null);
return new AlertDialog.Builder(getActivity())
.setIcon(R.drawable.ic_about)
.setTitle(title)
.setView(contentView)
.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) {
}
})
.create();
}
}
void showDialog() {
DialogFragment newFragment = MyAlertDialogFragment.newInstance(R.string.two_buttons_title);
newFragment.show(getFragmentManager(), "dialog");
}
}
得到的效果图基本理想:
场景2中没有使用support library中类,而且Theme.AppCompat.xxx系列theme可以兼容低版本API,但是你的App的最小API也要11以上。
鉴于以上原因,最好自定义Dialog的内容区(在你自定义时,模仿将title和button都定义到你的布局中),然后不设置Dialog的title,button属性,只调用AlertDialog.Builder#setView(view),或者Dialog#setContentView(View view)
来源:oschina
链接:https://my.oschina.net/u/945251/blog/465638