Android开发——官方推荐使用DialogFragment替换AlertDialog

0.  前言

DialogFragment是在Android3.0(API level 11)中引入,代替了已经不建议使用的AlertDialog

为什么不再建议使用AlertDialog了呢?我们先得清楚DialogFragment存在的意义。本文原创,转载请注明出处为SEU_Calvin的博客

1DialogFragmentFragment基本一致的生命周期,因此当旋转屏幕和按下后退键时便于Activity更好的管理其生命周期

2)比如当屏幕旋转时,AlertDialog会消失,更不会保存如EditText上的文字,如果处理不当很可能引发异常,因为Activity销毁前不允许对话框未关闭。而DialogFragment对话框会随之自动调整对话框大小。DialogFragment的出现完美的解决了横竖屏幕切换Dialog消失的问题,同时也有恢复数据的功能。

 

1.  AlertDialog的使用

这种方式是我以前使用的,既然不建议使用,那就尽量少用吧。但是感觉比DialogFragment要简单一些。代码直接在Activity中就能完成。下面是一个让用户输入密码的对话框例子。

 private AlertDialog dialog;
    private void showEnterDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
        View view = View.inflate(MainActivity.this, R.layout.fragment_login_dialog, null);
        ok = (Button) view.findViewById(R.id.ok);
        cancel = (Button) view.findViewById(R.id.cancel);
        cancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dialog.dismiss();
            }
        });
        ok.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //取出密码并验证的逻辑略
                dialog.dismiss();
            }
        });
        dialog = builder.create();
        dialog.setView(view, 0, 0, 0, 0);
        dialog.show();
}

效果如下所示,看起来还不错,但是旋转屏幕后对话框就消失了。针对这个问题,还是建议使用DialogFragment来做对话框。

2.  DialogFragment的使用——继承DialogFragment并实现onCreateDialog

DialogFragment有两种使用方式,第一种是写一个类继承DialogFragment并且实现它的onCreateDialog方法来创建一个DialogFragment,在onCreateDialog中一般使用AlertDialog创建并返回一个对话框。

public class AlertDialogFragment extends DialogFragment {
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        LayoutInflater inflater = getActivity().getLayoutInflater();
        //这里使用的布局文件和1中的一样,只是去掉了两个按钮
        View view = inflater.inflate(R.layout.fragment_login_dialog, null);
        builder.setView(view).setPositiveButton("OK", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int id) {}
           }).setNegativeButton("Cancel", null);
        return builder.create();
    }
}

接下来就是在Activity中使用它:

FragmentTransaction mFragTransaction = getFragmentManager().beginTransaction();
Fragment fragment =  getFragmentManager().findFragmentByTag("dialogFragment");
if(fragment!=null){
    //为了不重复显示dialog,在显示对话框之前移除正在显示的对话框
    mFragTransaction.remove(fragment);
}
AlertDialogFragment dialogFragment = new AlertDialogFragment();
//显示一个Fragment并且给该Fragment添加一个Tag,可通过findFragmentByTag找到该Fragment
dialogFragment.show(mFragTransaction, "dialogFragment");

效果如下所示,还是不错的,旋转屏幕后对话框也不会消失,如果有文字也会被保存:

3.  DialogFragment的使用——继承DialogFragment并实现它的onCreateView

DialogFragment的第二种使用方式是继承DialogFragment并且实现它的onCreateView方法来加载一个我们指定的xml布局从而提供对话框内容。这里需要注意的是如果没有调用下面的第四行代码,加载出来的对话框会默认出现一个标题,查看DialogFragment的源码可以发现它内部是mDialog.setContentView(view);把我们的xml布局加载到DialogContent内容区域。或许你不想去除标题,反而想要在标题区域显示你设置的标题,那么可以使用getDialog().setTitle("这是标题");本文原创,转载请注明出处为SEU_Calvin的博客

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        //去掉默认的标题
        getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);
        View view = inflater.inflate(R.layout.fragment_login_dialog, container);
        ok = (Button) view.findViewById(R.id.ok);
        cancel = (Button) view.findViewById(R.id.cancel);
        cancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getDialog().dismiss();
            }
        });
        ok.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getDialog().dismiss();
            }
        });
        return view;
    }

Activity中的简易使用如下,效果和1中的是一样的。但是屏幕的旋转丝毫不会影响到对话框。

AlertDialogFragment alertDialogFragment = new AlertDialogFragment();
alertDialogFragment.show(getFragmentManager(), "EditNameDialog");

4.  使用接口回调实现DialogFragmentActivity的通信

以第一种实现它的onCreateDialog方法为例,只需定一个如下的接口,并在点击OK的逻辑中,回调接口的方法传入获取用户输入,即可在实现了该接口的Activity中得到这些数据。

public interface LoginInputListener  {  
    void onLoginIn (String password);  
}  
LoginInputListener listener = (LoginInputListener) getActivity();  
listener. onLoginIn (mPassword.getText().toString()); 
//在Activity中
@Override  
public void onLoginIn (String password)  {
  //得到数据password
} 

至此关于使用Fragment创建对话框的介绍就到此结束了。

请大家多点赞支持一下~

### Android 对话框背景自定义 在 Android 中,可以通过多种方式实现对话框 (Dialog) 的背景定制化。以下是几种常见的方法: #### 方法一:通过 `setCanceledOnTouchOutside` 和 `Window setBackgroundDrawableResource` 可以创建一个透明的布局作为背景,并将其应用到 Dialog 上。 ```java AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setView(R.layout.custom_dialog); // 创建并显示对话框 final AlertDialog dialog = builder.create(); dialog.show(); // 设置背景颜色或图片 if (dialog.getWindow() != null) { dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent); // 自定义背景为透明[^1] } ``` 这种方法适用于希望完全移除默认灰色背景或者替换为其他资源的情况。 --- #### 方法二:使用 `DialogFragment` 并设置模糊效果 如果需要更复杂的视觉效果(如模糊),可以在后台添加一层带有高斯模糊处理的效果层。这通常涉及使用第三方库来简化操作过程。 例如,借助 [BlurView](https://github.com/Dimezis/BlurView),能够轻松实现毛玻璃风格的背景。 ```xml <!-- res/layout/dialog_fragment.xml --> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <!-- 添加 BlurView 或者其他视图组件 --> </FrameLayout> ``` 接着,在 Java/Kotlin 文件里初始化该 Fragment 及其样式属性。 ```java public class CustomDialogFragment extends DialogFragment { @Override public void onStart() { super.onStart(); if (getDialog() != null && getDialog().getWindow() != null){ getDialog().getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); // 应用模糊逻辑或其他特效... } } @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.dialog_fragment, container, false); } } ``` 上述代码片段展示了如何利用 `DialogFragment` 来构建更加灵活可控的内容区域。 --- #### 方法三:调整按钮文字颜色及其他细节优化 除了改变整体外观外,还可以单独修改某些 UI 部件的颜色参数,比如确认取消键上的字体色调等。 ```java AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setMessage("Sample Message"); // 定义正负向动作监听器以及对应的文字描述 builder.setPositiveButton("OK", ... ); builder.setNegativeButton("Cancel", ... ); // 获取内部控件实例进而施加个性化设定 AlertDialog alert = builder.create(); alert.setOnShowListener(dialogInterface -> { Button positiveButton = alert.getButton(AlertDialog.BUTTON_POSITIVE); Button negativeButton = alert.getButton(AlertDialog.BUTTON_NEGATIVE); if (positiveButton != null) { positiveButton.setTextColor(ContextCompat.getColor(context, R.color.your_custom_color)); // 更改颜色[^2] } }); ``` 此部分重点在于获取原始对象之后再做进一步装饰工作。 --- #### 使用适配器增强列表型数据展示能力 当涉及到复杂的数据集合呈现需求时,则可能需要用到专门设计过的 Adapter 类型解决方案。这里推荐一款非常强大的工具——[BaseRecyclerViewAdapterHelper](https://github.com/CymChad/BaseRecyclerViewAdapterHelper)[^3] ,它极大地降低了开发难度的同时还提供了丰富的扩展选项满足各类场景下的差异化表现形式要求。 综上所述,无论是简单的全局主题切换还是精细至每一个独立单元格级别的控制都可以找到合适的途径达成目标!
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值