更好用的DialogFragment

工作中总是要用到各式各样的对话框,通常我们首先会想到的就是Dialog。在以前的时候我通常都会自定义一个Dialog,然后在里面写一个接口,让需要创建这个Dialog的界面继承这个接口,实现点击事件的监听。其中大概代码是这样的:

/**
 * @date 创建时间: 2017/11/22  22:25
 * @author zh_legendd
 * @Description 自定义的dialog
 * @Email code_legend@163.com
 * @Version 1.0
 */
public class SureExitDialog extends Dialog {


    private Button btn_cancel, btn_sure;

    private SureListener mSureListener;



    public interface SureListener {
        void sureExit();
    }

    public void setSureListener(SureListener mSureListener){
        this.mSureListener=mSureListener;
    }

    public SureExitDialog(Context context) {
        super(context, R.style.PayDialog);
        initWindow();
        show();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fragment_dialog);
        btn_sure = (Button) findViewById(R.id.btn_sure);
        btn_cancel = (Button) findViewById(R.id.btn_cancel);
        btn_cancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                dismiss();
            }
        });
        btn_sure.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mSureListener.sureExit();
                dismiss();
            }
        });
    }

    /**
     * 初始化window参数
     */
    private void initWindow() {
        Window dialogWindow = getWindow();
        dialogWindow.getDecorView().setPadding(0, 0, 0, 0);
                dialogWindow.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        dialogWindow.setBackgroundDrawableResource(android.R.color.transparent);
                        dialogWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
        WindowManager.LayoutParams lp = dialogWindow.getAttributes();
        lp.width = WindowManager.LayoutParams.MATCH_PARENT;
        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
        lp.gravity = Gravity.CENTER;
        dialogWindow.setAttributes(lp);
    }
}
  • 其实感觉这样写也并没有什么不好的,以前我也看到过其他人写的文章说现在官方推荐使用DialogFragment,但是看了几篇文章并没有感觉有多好用。直到我看了《Android编程权威指南》之后,我觉得真的有必要的使用一下DialogFragment了。现在基本上都会在Activity里面放很多fragment。因此接下来我们要做的一个DialogFragment的场景也是在镶嵌到Activity的Fragment中调起的Fragment的并且不通过设置接口来传递数据,而是通过Fragment中特有的属性设置Tag,来辨别不同的Fragment(这也许就是DialogFragment的精华所在吧),take is cheap show me the code。
  • 首先创建一个承载Fragment的Activity
/**
 * @date 创建时间: 2017/11/22 0022 22:32
 * @author zh_legendd
 * @Description 承载Fragment的Activity
 * @Email code_legend@163.com
 * @Version 1.0
 */
public class FDActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fd);
       //替换fragment
        initView();
    }
    public void initView(){
        FragmentManager supportFragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = supportFragmentManager.beginTransaction();
        transaction.add(R.id.fl_context,TrFragment.newInstance());
        transaction.commit();
//        transaction.add()
    }
}
  • 然后创建一个镶嵌在Activity里面的Fragment,在这个Fragment的布局中只有一个按钮所以就不贴布局的代码了,一会可以看源码。这里注意的主要有两点:
  • 1 调起DialogFragment :因为DialogFragment的父类也是Fragment,所以我们首先也是需要得到FragmentManager ,但是又有和Fragment不同的是显示DialogFragment的时候需要调用show方法。在这里还需要设置一个返回值的tag,用于在onActivityResult回调的时候得到DialogFragment回传过来的信息。相当与我们自定义的Dialog中使用接口一样。但是后面的show方法里面的Tag好像是现在没有什么用。
  • 2 一般情况下我们调起Dialog无非就是一些提示语,然后让用户选择确认或者取消。接下来说的就是在DialogFragment中当用户点击确定或取消之后,怎么回传用户行为,我想看过上面一段话肯定就已经知道了,那就是在onActivityResult中进行。
  • 3 在DialogFragment中并没有设置接口监听,却能在Fragment直接相互传递数据主要还是应用的我上一篇讲的在onActivityResult中进行回调。
  • 4 因为在Fragment中调起DialogFragment的时候,Fragment中有一个可以设置Tag的属性,所以不需要设置回调监听,直接使用onActivityResult回调监听就可以。但是在Activity就不同了,反正我是找了好久,就必须要设置接口监听。
/**
 * @date 创建时间: 2017/11/22 0022 22:34
 * @author zh_legendd
 * @Description 镶嵌在Activity的Fragment
 * @Email code_legend@163.com
 * @Version 1.0
 */
public class TrFragment extends Fragment {

    private static final int REQUEST_DATE=0;
    //fragment的TAG
    private static final String DIALOG_DATE="DialogDate";

    private Button bt_jump;

    public static TrFragment newInstance(){
        //fargment与Activity之间传递数据
//        Bundle args =new Bundle();
//        args.putString();
        TrFragment trFragment=new TrFragment();
//        trFragment.setArguments(args);
        return trFragment;
    }

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

        View inflate = inflater.inflate(R.layout.fragment_tr, null);

        bt_jump=(Button)inflate.findViewById(R.id.bt_jump);
        bt_jump.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//                MyToast.showText("点击了");
                FragmentManager fragmentManager = getFragmentManager();
                TestDialogFragment dialog = TestDialogFragment.newInstance("test");
                dialog.setTargetFragment(TrFragment.this,REQUEST_DATE);
                dialog.show(fragmentManager,DIALOG_DATE);
            }
        });

        return inflate;
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(resultCode!= Activity.RESULT_OK){
            return;
        }
        if(requestCode==REQUEST_DATE){
            MyToast.showText(data.getStringExtra(TestDialogFragment.EXTRA_STR));
        }
    }
}
  • 接下来就是在我们的DialogFragment中让我们正式的显示自己想要样式的Dialog。自定义的话,当时我心里面是有二个疑惑的首先就是怎么设置样式,然后就是怎么设置布局:
  • 第一个疑惑:这可能是有点麻烦了,需要谷歌一下。最后被我找到了,只要在这里设置属性就OK,这样你的DialogFragment就可以引用自定义的样式了。
@Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setStyle(STYLE_NO_TITLE,R.style.PayDialog);
    }
  • 第二个的话,很多文章里面都写的有直接在onCreateView里面设置布局就可以,当然自定义的话需要把标题给去掉,只用调用这一句方法就行getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);然后在onStart方法里面设置就像我们自定义的Dialog一样初始化window,就这么简单就可以实现和自定义Dialog一样的布局了。
/**
 * @date 创建时间: 2017/11/22 0022 22:44
 * @author zh_legendd
 * @Description 在DialogFragment布局
 * @Email code_legend@163.com
 * @Version 1.0
 */
public class TestDialogFragment extends DialogFragment {

    private static final String ARG_TEST="test";

    public  static final String EXTRA_STR="extra_str";


    private Button btn_cancel, btn_sure;

    public static TestDialogFragment newInstance(String str){
        Bundle bundle=new Bundle();
        bundle.putString(ARG_TEST,str);
        TestDialogFragment testDialogFragment=new TestDialogFragment();
        testDialogFragment.setArguments(bundle);
        return testDialogFragment;
    }

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

    }
    /**
     * 初始化window参数
     */
    private void initWindow() {
        Window dialogWindow = getDialog().getWindow();
        dialogWindow.getDecorView().setPadding(0, 0, 0, 0);
        dialogWindow.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        dialogWindow.setBackgroundDrawableResource(android.R.color.transparent);
        dialogWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
        WindowManager.LayoutParams lp = dialogWindow.getAttributes();
        lp.width = WindowManager.LayoutParams.MATCH_PARENT;
        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
        lp.gravity= Gravity.CENTER;
        dialogWindow.setAttributes(lp);
    }

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

        getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);

        View inflate = inflater.inflate(R.layout.fragment_dialog, null);
        btn_sure = (Button) inflate.findViewById(R.id.btn_sure);
        btn_cancel = (Button) inflate.findViewById(R.id.btn_cancel);
        btn_sure.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sendResult(Activity.RESULT_OK,"str");
            }
        });
        return inflate;
    }


    private void sendResult(int resultCode,String str){
        if(getTargetFragment()==null){
            return;
        }
        Intent intent=new Intent();
        intent.putExtra(EXTRA_STR,str);
        getTargetFragment().onActivityResult(getTargetRequestCode(),resultCode,intent);
    }


}

总结一下,我感觉DialogFragment中主要有两点相对应Dialog来说有点难。第一个是数据传递,第二个就自定义布局。感觉我上面说的还比较清楚吧(┬_┬)。Demo下载地址

DialogFragment

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 223,507评论 6 521
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 95,626评论 3 401
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 170,466评论 0 366
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 60,456评论 1 300
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 69,473评论 6 398
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 53,016评论 1 314
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,409评论 3 426
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 40,370评论 0 278
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,909评论 1 322
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,960评论 3 343
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 41,102评论 1 354
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,754评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,428评论 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,917评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 34,036评论 1 275
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,582评论 3 380
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 46,126评论 2 362

推荐阅读更多精彩内容