DialogFragment的使用

  • Post author:
  • Post category:其他


可以参考另一个博主的文章


Android 必知必会 – DialogFragment 使用总结



**

背景

Android 官方推荐使用 DialogFragment 来代替 Dialog ,可以让它具有更高的可复用性(降低耦合)和更好的便利性(很好的处理屏幕翻转的情况)。

而创建 DialogFragment 有两种方式:

覆写其 onCreateDialog 方法 — ①

覆写其 onCreateView 方法 — ②

虽然这两种方式都能实现相同的效果,但是它们各有自己适合的应用场景:

方法 ①,一般用于创建替代传统的 Dialog 对话框的场景,UI 简单,功能单一。
方法 ②,一般用于创建复杂内容弹窗或全屏展示效果的场景,UI 复杂,功能复杂,一般有网络请求等异步操作。


DialogFragment不像Dialog使用的时候,例如横竖屏的切换(Activity的生命周期会改变),就造成了dialog会消失 ,DialogFragment则不会,只有Activity消失他才会消失。

使用DialogFragment的时候可以使用onCreateView自定义布局,也可以在onCreateDialog方法中使用以前传统的方式书写。

在onCreateDialog中实现

public class UpdateMoneyDialog extends DialogFragment {
    private Activity activity;
    private Context context;
    private LayoutInflater inflater;
    private Dialog dialog;
    private View view;
    private TextView tvCancel;
    private TextView tvConfirm;
    private EditText etMoney;
    private int position;
    private TextView tvName;


    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        this.context = context;
        this.activity = (Activity) context;
    }

    public static UpdateMoneyDialog getInstance(String money,int postion,String name){
        UpdateMoneyDialog imgShowDialog = new UpdateMoneyDialog();
        Bundle bundle = new Bundle();
        bundle.putString("money",money);
        bundle.putInt("pos",postion);
        bundle.putString("name",name);
        //传入值,跟Fragment传值方法一样
        imgShowDialog.setArguments(bundle);
        return imgShowDialog;
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        inflater = LayoutInflater.from(context);
        dialog = new Dialog(context, R.style.bran_online_supervise_dialog);
        view = inflater.inflate(R.layout.update_money_dialog_layout, null);
        tvCancel = (TextView) view.findViewById(R.id.tv_cancel);
        tvConfirm = (TextView) view.findViewById(R.id.tv_confirm);
        tvName = (TextView) view.findViewById(R.id.tv_name);
        etMoney = (EditText) view.findViewById(R.id.et_money);

        //设置取消标题
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        //设置点击外部不可以消失
        dialog.setCanceledOnTouchOutside(true);
        //设置即使点击返回键也不会退出
        setCancelable(true);
        dialog.setContentView(view);

    //将值取出来
        Bundle bundle = getArguments();
        if(null != bundle){
            position = bundle.getInt("pos");
            String money = bundle.getString("money");
            etMoney.setText(money);
            String name = bundle.getString("name");
            tvName.setText(name);
        }

        tvCancel.setOnClickListener(onClickListener);
        tvConfirm.setOnClickListener(onClickListener);

        //获取当前Activity所在的窗体
        Window dialogWindow = dialog.getWindow();
        //设置软键盘弹出模式
        dialogWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
        //获得窗体的属性
        WindowManager.LayoutParams lp = dialogWindow.getAttributes();
        lp.gravity = Gravity.BOTTOM;
        //设置Dialog宽度匹配屏幕宽度
        lp.width = WindowManager.LayoutParams.MATCH_PARENT;
        //设置Dialog高度自适应
        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
        //将属性设置给窗体
        dialogWindow.setAttributes(lp);
        return dialog;
    }

    /**
     * View的点击事件
     */
    View.OnClickListener onClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            switch (v.getId()){
                case R.id.tv_cancel:
                    KeyboardUtils.hideSoftInput(activity,tvCancel);
                    dialog.dismiss();
                    break;
                case R.id.tv_confirm:
                    String money = etMoney.getText().toString().trim();
                    if(!TextUtils.isEmpty(money)){
                        listener.onObtainValue(position,money);
                        KeyboardUtils.hideSoftInput(activity,tvConfirm);
                        dialog.dismiss();
                    }else{
                        listener.onObtainValue(position,"0");
                        KeyboardUtils.hideSoftInput(activity,tvConfirm);
                        dialog.dismiss();
                    }
                    break;
                default:
                    break;
            }
        }
    };

    public interface OnUpdateMoneyListener{
        void onObtainValue(int position,String data);
    }
    private OnUpdateMoneyListener listener = null;
    public void setOnUpdateMoneyListener(OnUpdateMoneyListener listener){
        this.listener = listener;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        KeyboardUtils.hideSoftInput(activity);
        if(dialog != null){
            dialog.dismiss();
            dialog = null;
        }
    }
}

DialogFragment的一下窗口属性

<style name="bran_online_supervise_dialog" parent="@android:style/Theme.Dialog">
        <!-- 背景透明 -->
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:windowContentOverlay">@null</item>
        <!--透明度40%-->
        <item name="android:backgroundDimAmount">0.4</item>
        <!-- 浮于Activity之上 -->
        <item name="android:windowIsFloating">true</item>
        <!-- 边框 -->
        <item name="android:windowFrame">@null</item>
        <!-- Dialog以外的区域模糊效果 -->
        <item name="android:backgroundDimEnabled">true</item>
        <!-- 无标题 -->
        <item name="android:windowNoTitle">true</item>
        <!-- 半透明 -->
        <!--<item name="android:windowIsTranslucent">true</item>-->
        <!-- Dialog进入及退出动画 -->
        <item name="android:windowAnimationStyle">@style/bran_online_supervise_animation</item>
    </style>
    <!-- Dialog从底部进出动画 -->
    <style name="bran_online_supervise_animation" parent="@android:style/Animation.Dialog">
        <item name="android:windowEnterAnimation">@anim/dialog_enter_anim</item>
        <item name="android:windowExitAnimation">@anim/dialog_exit_anim</item>
    </style>

进入动画dialog_enter_anim

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="false"
    >
    <translate
        android:fromYDelta="100%p"
        android:toYDelta="0"
        android:duration="500"
        />
    <alpha
        android:fromAlpha="0"
        android:toAlpha="1.0"
        android:duration="500"
        />
</set>

退出动画dialog_exit_anim

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="false"
    >
    <translate
        android:fromYDelta="0"
        android:toYDelta="100%p"
        android:duration="500"
        />
    <alpha
        android:fromAlpha="1.0"
        android:toAlpha="0"
        android:duration="500"
        />
</set>
在onCreateView中实现自定义
public class CustomDiaFrag extends DialogFragment {

    @BindView(R.id.tv_title)
    TextView tvTitle;
    @BindView(R.id.tv_content)
    TextView tvContent;
    @BindView(R.id.tv_comfirm)
    TextView tvComfirm;
    @BindView(R.id.tv_cancel)
    TextView tvCancel;
    Unbinder unbinder;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setStyle(DialogFragment.STYLE_NO_TITLE,R.style.AppTheme);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.custom_dia_frag_layout, container, false);
        unbinder = ButterKnife.bind(this, view);

        Window window = getDialog().getWindow();
        window.setBackgroundDrawable(new ColorDrawable(0x80000000));
        WindowManager.LayoutParams params = window.getAttributes();
        params.gravity = Gravity.CENTER;
        params.width = WindowManager.LayoutParams.WRAP_CONTENT;
        params.height = WindowManager.LayoutParams.WRAP_CONTENT;
        window.setAttributes(params);

        tvComfirm.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        });
        tvCancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        });
        return view;
    }

    public static CustomDiaFrag newInstance() {
        return new CustomDiaFrag();
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        unbinder.unbind();
    }
}


<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <android.support.constraint.ConstraintLayout
        android:layout_width="300dp"
        android:layout_height="200dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        android:background="#55000000"
        >
        <TextView
            android:id="@+id/tv_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="标题"
            android:textColor="#0da38c"
            android:textSize="18sp"
            android:layout_marginTop="20dp"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            />
        <TextView
            android:id="@+id/tv_content"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="你原来是内容"
            android:textSize="15sp"
            android:textColor="#192c9c"
            app:layout_constraintTop_toBottomOf="@id/tv_title"
            android:layout_marginTop="20dp"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            />
        <TextView
            android:id="@+id/tv_comfirm"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="确定"
            android:textSize="18sp"
            android:textColor="#FF8B3D"
            app:layout_constraintBottom_toBottomOf="parent"
            android:padding="5dp"
            app:layout_constraintHorizontal_weight="1"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toLeftOf="@+id/tv_cancel"
            android:gravity="center"
            android:layout_marginBottom="20dp"
            />
        <TextView
            android:id="@+id/tv_cancel"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="取消"
            android:textSize="18sp"
            android:textColor="#FF8B3D"
            app:layout_constraintBottom_toBottomOf="parent"
            android:padding="5dp"
            app:layout_constraintHorizontal_weight="1"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintLeft_toRightOf="@id/tv_comfirm"
            android:gravity="center"
            android:layout_marginBottom="20dp"
            />

    </android.support.constraint.ConstraintLayout>

</android.support.constraint.ConstraintLayout>

下面补充一下DialogFragment的第二种用法(onCreateView),使用方式跟我们的Fragment相同,跟Fragment一样一般使用V4包的类

public class CustomDialog extends DialogFragment {
    @BindView(R.id.tv_title)
    TextView tvTitle;
    @BindView(R.id.tv_content)
    TextView tvContent;
    @BindView(R.id.bt_cancel)
    Button btCancel;
    @BindView(R.id.bt_confirm)
    Button btConfirm;
    Unbinder unbinder;
    private Activity activity;

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        activity = (Activity) context;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setStyle(DialogFragment.STYLE_NO_TITLE, R.style.custom_dialog);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.custom_dialog_layout, null);
        unbinder = ButterKnife.bind(this, view);
        init();
        return view;
    }

    private void init() {
        Dialog dialog = getDialog();
        dialog.setCanceledOnTouchOutside(true);
        dialog.setCancelable(true);

        Window window = dialog.getWindow();
        //设置dialog的背景颜色,我们可以直接在XML中给dialog加一个背景色,如果不设置背景颜色就会造成背景是透明的
        //window.setBackgroundDrawable(new ColorDrawable(0x00000000));
        window.getDecorView().setPadding(0, 0, 0, 0);
        //获得窗体的属性
        WindowManager.LayoutParams lp = window.getAttributes();
        lp.gravity = Gravity.CENTER;
        //设置Dialog宽度匹配屏幕宽度
        lp.width = WindowManager.LayoutParams.MATCH_PARENT;
        //设置Dialog高度自适应
        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
        //将属性设置给窗体
        window.setAttributes(lp);
    }

    @OnClick(R.id.bt_cancel)
    public void toCancel(){
        dismiss();
    }

    @OnClick(R.id.bt_confirm)
    public void toConfirm(){

    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        unbinder.unbind();
    }
}

^_^,还有个小东西,不知道你们发现没有,经常使用UC浏览器就会发现它经常弹出让我们给评价的dialog,动画效果是从顶部下来的,改成下面的动画进入方式就可以了

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="false"
    >
    <translate
        android:fromYDelta="-100%p"
        android:toYDelta="0"
        android:duration="500"
        />
<!--
    <translate
        android:fromYDelta="100%p"
        android:toYDelta="0"
        android:duration="500"
        />
-->
    <alpha
        android:fromAlpha="0"
        android:toAlpha="1.0"
        android:duration="500"
        />
</set>



版权声明:本文为u013855006原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。