弹窗之一: dialogFragment的使用

参考:
Android 官方推荐 : DialogFragment 创建对话框

1、 概述

DialogFragment在android 3.0时被引入。是一种特殊的Fragment,用于在Activity的内容之上展示一个模态的对话框。典型的用于:展示警告框,输入框,确认框等等。
在DialogFragment产生之前,我们创建对话框:一般采用AlertDialog和Dialog。注:官方不推荐直接使用Dialog创建对话框。

2、 好处与用法

使用DialogFragment来管理对话框,当旋转屏幕和按下后退键时可以更好的管理其声明周期,它和Fragment有着基本一致的声明周期。且DialogFragment也允许开发者把Dialog作为内嵌的组件进行重用,类似Fragment(可以在大屏幕和小屏幕显示出不同的效果)。上面会通过例子展示这些好处~
使用DialogFragment至少需要实现onCreateView或者onCreateDIalog方法。onCreateView即使用定义的xml布局文件展示Dialog。onCreateDialog即利用AlertDialog或者Dialog创建出Dialog。

3、使用方法:

a)布局文件,我们创建一个设置dialogFragment的布局文件:

<?xml version="1.0" encoding="utf-8"?>  
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="wrap_content"  
    android:layout_height="wrap_content" >  

    <TextView  
        android:id="@+id/id_label_your_name"  
        android:layout_width="wrap_content"  
        android:layout_height="32dp"  
        android:gravity="center_vertical"  
        android:text="Your name:" />  

    <EditText  
        android:id="@+id/id_txt_your_name"  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content"  
        android:layout_toRightOf="@id/id_label_your_name"  
        android:imeOptions="actionDone"  
        android:inputType="text" />  

    <Button  
        android:id="@+id/id_sure_edit_name"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:layout_alignParentRight="true"  
        android:layout_below="@id/id_txt_your_name"  
        android:text="ok" />  

</RelativeLayout>  

b)继承DialogFragment,重写onCreateView方法

public class EditNameDialogFragment extends DialogFragment  
{  


    @Override  
    public View onCreateView(LayoutInflater inflater, ViewGroup container,  
            Bundle savedInstanceState)  
    {  
        View view = inflater.inflate(R.layout.fragment_edit_name, container);  
        return view;  
    }  

} 

c)activity中调用:

public void showEditDialog(View view)  
    {  
        EditNameDialogFragment editNameDialog = new EditNameDialogFragment();  
        editNameDialog.show(getFragmentManager(), "EditNameDialog");  
    }  

效果图:

可以看到,对话框成功创建并显示出来,不过默认对话框有个讨厌的标题,我们怎么去掉呢:可以在onCreateView中调用getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);即可去掉。

一、去除标题栏

在DialogFragment的onCreateView方法中添加

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        //去除标题栏
        Dialog dialog = getDialog();
        if (dialog != null) {
            dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        }

        View view = inflater.inflate(R.layout.dialog_layout, container, false);

        TextView mTvConfirm = ((TextView) view.findViewById(R.id.dialog_positive));
        mTvConfirm.setOnClickListener(this);

        return view;
    }

二、设置宽度撑满屏幕、位置、动画等属性

在DialogFragment的onStart方法中添加

  @Override
    public void onStart() {
        super.onStart();

        //设置动画、位置、宽度等属性(注意一:必须放在onStart方法中)
        Window window = getDialog().getWindow();
        if (window != null) {
            // 注意二:一定要设置Background,如果不设置,window属性设置无效
            window.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.white)));
            WindowManager.LayoutParams layoutParams = window.getAttributes();

            layoutParams.windowAnimations = R.style.MusicDialog;//动画
            layoutParams.gravity = Gravity.BOTTOM; // 位置
            layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;//宽度满屏

            window.setAttributes(layoutParams);
        }

    }

注意:

设置宽度撑满屏幕、位置、动画等属性:在onCreateView中设置与onStart中不设置Background一样的效果:全屏未实现。

示例如下:

onStart中不设置Background

public class MyDialogFrag2 extends DialogFragment implements View.OnClickListener {

    @Override
    public void onStart() {
        super.onStart();

        //设置动画、位置、宽度等属性(注意一:必须放在onStart和onResume()中设置才有效)
        Window window = getDialog().getWindow();
        if (window != null) {
            // 注意二:一定要设置Background,如果不设置,window属性设置无效
//            window.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.white)));
            WindowManager.LayoutParams layoutParams = window.getAttributes();

            layoutParams.windowAnimations = R.style.MusicDialog;//动画
            layoutParams.gravity = Gravity.BOTTOM; // 位置
            layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;//宽度满屏

            window.setAttributes(layoutParams);
        }

    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Dialog dialog = getDialog();
        if (dialog != null) {
            dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        }

        View view = inflater.inflate(R.layout.dialog_layout, container, false);

        TextView mTvConfirm = ((TextView) view.findViewById(R.id.dialog_positive));
        mTvConfirm.setOnClickListener(this);

        return view;
    }


    @Override
    public void onClick(View v) {

        switch (v.getId()) {
            case R.id.dialog_positive:
                dismiss();
                break;
        }
    }
}

onCreateView中设置:

public class MyDialogFrag3 extends DialogFragment implements View.OnClickListener {

    @Override
    public void onStart() {
        super.onStart();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        //设置动画、位置、宽度等属性(注意一:必须放在onStart方法中)
        Window window = getDialog().getWindow();
        if (window != null) {
            // 注意二:一定要设置Background,如果不设置,window属性设置无效
            window.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.white)));
            WindowManager.LayoutParams layoutParams = window.getAttributes();

            layoutParams.windowAnimations = R.style.MusicDialog;//动画
            layoutParams.gravity = Gravity.BOTTOM; // 位置
            layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;//宽度满屏

            window.setAttributes(layoutParams);
        }

        Dialog dialog = getDialog();
        if (dialog != null) {
            dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        }

        View view = inflater.inflate(R.layout.dialog_layout, container, false);

        TextView mTvConfirm = ((TextView) view.findViewById(R.id.dialog_positive));
        mTvConfirm.setOnClickListener(this);

        return view;
    }


    @Override
    public void onClick(View v) {

        switch (v.getId()) {
            case R.id.dialog_positive:
                dismiss();
                break;
        }
    }
}

效果如图:

这里写图片描述

三、设置透明度

    // 0~1 , 1表示完全昏暗
            dialog.getWindow().setDimAmount(0.5f);

四、点击外部不消失

 //点击外部不消失
            dialog.setCanceledOnTouchOutside(false);

五、点击返回键不消失

 //点击返回键不消失,需要监听OnKeyListener:
            dialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
                @Override
                public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                    if (keyCode == KeyEvent.KEYCODE_BACK) {
                        return true;
                    }
                    return false;
                }
            });

六、Enter和Exit动画 (飞入飞出)

//在style.xml中引入自定义动画,动画自定义
<style name="CustomDialog" parent="@android:style/Theme.Dialog">
    <item name="android:windowEnterAnimation">@anim/popwin_show_anim</item>
    <item name="android:windowExitAnimation">@anim/popwin_hide_anim</item>
</style>

java代码中引用:

//在Java代码中设置窗口动画
getDialog().getWindow().getAttributes().windowAnimations = R.style.CustomDialog;  

七、设置全屏及解决状态栏变黑的问题

    @SuppressWarnings("deprecation")
    @Override
    public void onStart() {
        super.onStart();

        Window window = getDialog().getWindow();
        if (window != null) {
            window.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.theme_color)));
            WindowManager.LayoutParams layoutParams = window.getAttributes();

            layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;// 宽度满屏
            layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT;// 高度满屏

            window.setAttributes(layoutParams);
        }
    }

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Dialog dialog = getDialog();
        if (dialog != null) {
            dialog.getWindow().setDimAmount(0f);// 透明

            dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);// 无标题栏
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);// 解决全屏时状态栏变黑
        }

        View view = inflater.inflate(R.layout.main_dialog_layout, container, false);
        mWebView = (WebView) view.findViewById(R.id.wv_main_dialog);

        initWebSettings();

        return view;
    }

八、activity传值到dialogfragment

MainActivity传值:

MainDialogFrag mainDialogFrag = new MainDialogFrag();

Bundle bundle = new Bundle();
bundle.putString("url", mainWebDataModel.url);
bundle.putString("title", mainWebDataModel.title);
bundle.putString("msgtype", mainWebDataModel.msgtype);

mainDialogFrag.setArguments(bundle);
mainDialogFrag.show(getFragmentManager(), "MainDialogFrag");

MainDialogFrag中获取值:

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        Bundle bundle = getArguments();
        if (bundle != null) {
            url = bundle.getString("url");

            if (!TextUtils.isEmpty(url)) {
                mWebView.loadUrl(url);
                // mWebView.loadUrl("https://www.baidu.com/");
                // mWebView.loadUrl("http://www.oschina.net/");
            }
        }
    }

参考: Activity 与 DialogFragment 之间的数据传递

标准版:

package com.example.lenovo.mydialogfrag;

import android.app.Dialog;
import android.content.DialogInterface;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.DialogFragment;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;


public class MyDialogFrag extends DialogFragment implements View.OnClickListener {

    @Override
    public void onStart() {
        super.onStart();

        //设置动画、位置、宽度等属性(注意一:必须放在onStart方法中)
        Window window = getDialog().getWindow();
        if (window != null) {
            // 注意二:一定要设置Background,如果不设置,window属性设置无效
            window.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.white)));
            WindowManager.LayoutParams layoutParams = window.getAttributes();

            layoutParams.windowAnimations = R.style.MusicDialog;//动画
            layoutParams.gravity = Gravity.BOTTOM; // 位置
            layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;//宽度满屏

            window.setAttributes(layoutParams);
        }

    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        //去除标题栏
        Dialog dialog = getDialog();
        if (dialog != null) {
            dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);

            // 0~1 , 1表示完全昏暗
            dialog.getWindow().setDimAmount(0.5f);

            //点击外部不消失
//            dialog.setCanceledOnTouchOutside(false);

            //点击返回键不消失,需要监听OnKeyListener:
//            dialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
//                @Override
//                public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
//                    if (keyCode == KeyEvent.KEYCODE_BACK) {
//                        return true;
//                    }
//                    return false;
//                }
//            });
        }


        View view = inflater.inflate(R.layout.dialog_layout, container, false);

        TextView mTvConfirm = ((TextView) view.findViewById(R.id.dialog_positive));
        mTvConfirm.setOnClickListener(this);

        return view;
    }


    @Override
    public void onClick(View v) {

        switch (v.getId()) {
            case R.id.dialog_positive:
                dismiss();
                break;
        }
    }
}

dialogfragment的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/experience_confirm_dialog_container"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:orientation="vertical">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="13dp"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:layout_marginTop="13dp">

        <TextView
            android:id="@+id/experience_confirm_dialog_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:gravity="center"
            android:text="确认消息"
            android:textColor="#333333"
            android:textSize="15sp" />
    </RelativeLayout>


    <View
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:background="#e6e6e6" />


    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingBottom="20dp"
        android:paddingTop="20dp">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <TextView
                android:id="@+id/experience_confirm_dialog_msg1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:text="15000"
                android:textColor="#ff7612"
                android:textSize="18sp" />

            <TextView
                android:id="@+id/experience_confirm_dialog_msg2"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:paddingTop="7dp"
                android:text="体验金投资额(元)"
                android:textColor="#999999"
                android:textSize="12sp" />
        </LinearLayout>

    </RelativeLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:background="#e6e6e6" />

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:paddingLeft="20dp"
        android:paddingRight="20dp">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="预期收益(元)"
            android:textColor="#999999"
            android:textSize="12sp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_alignParentRight="true"
            android:gravity="center"
            android:text="1,000"
            android:textColor="#333333"
            android:textSize="12sp" />
    </RelativeLayout>

    <TextView
        android:id="@+id/dialog_positive"
        android:layout_width="match_parent"
        android:layout_height="43dp"
        android:background="#ff7612"
        android:gravity="center"
        android:padding="5dp"
        android:text="确定投资"
        android:textColor="#ffffff"
        android:textSize="18sp" />

</LinearLayout>

res/value/styles

    <style name="MusicDialog">
        <item name="android:windowEnterAnimation">@anim/push_top_in</item>
        <item name="android:windowExitAnimation">@anim/push_bottom_out</item>
    </style>

动画

push_top_in.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <rotate
        android:duration="10"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toDegrees="-3" />
    <translate
        android:duration="@android:integer/config_shortAnimTime"
        android:fromYDelta="-150%"
        android:interpolator="@android:interpolator/decelerate_quint"
        android:toYDelta="0" />
    <rotate
        android:duration="10"
        android:pivotX="50%"
        android:pivotY="50%"
        android:startOffset="150"
        android:toDegrees="0" />
</set>

push_bottom_out.xml

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="@android:integer/config_shortAnimTime"
    android:fromYDelta="0"
    android:interpolator="@android:interpolator/accelerate_quint"
    android:toYDelta="100%" />

效果图:

这里写图片描述

参考:

DialogFragment去除默认标题栏并横向充满屏幕

DialogFragment中上下文空指针问题

空指针:

java.lang.NullPointerException: 

Attempt to invoke virtual method 
'java.lang.String android.content.Context.getPackageName()' on a null object reference

DialogFragment中直接使用getActivity返回的确是空的。

在Fragment中获取context:

@Override
public void onAttach(Activity activity) {
    mContext = activity;
    super.onAttach(activity);
}
  • 6
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值