DialogFragment 的使用和一些坑点

最近在使用 DialogFragment 的时候踩了一些坑,所以写个博客记录一下。

DialogFragment 使用起来和普通的 fragment 差不多,在普通 fragment 的基础上 DialogFragment 可以通过 show() 和 dismiss() 方法来控制显示和消失,并且自带显示的效果,相对与普通的 dialog,DialogFragment 可以支持自定义布局,使用起来非常方便。

话不多说,直接上代码。

package com.example.chen.test;

import android.app.DialogFragment;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;



public class NoticeDialogFragment extends DialogFragment {

    private TextView noticeTitle;
    private TextView noticeBody;
    private TextView noticeTime;
    private TextView btnKnow;
    private View mRootView;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        //对话框的布局
        if(mRootView==null){
            mRootView = inflater.inflate(R.layout.dialog_group_notice, container,false);
        }
        noticeTitle = mRootView.findViewById(R.id.group_notice_title);
        noticeBody = mRootView.findViewById(R.id.group_notice_body);
        noticeTime = mRootView.findViewById(R.id.group_notice_time);
        btnKnow = mRootView.findViewById(R.id.btn_know);

        //绑定监听事件
        btnKnow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dismiss();
            }
        });
        return mRootView;
    }
}

这里的 DialogFragment 内控件的点击事件的处理有两种,上面那种是直接在 DialogFragment 内处理,另一种是在 DialogFragment 里面写个接口,然后在 activity 里面做处理。 
如:

package com.example.chen.test;

import android.app.DialogFragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;


/**
 * Created by chen on 2018/8/3.
 */
public class NoticeDialogFragment extends DialogFragment {

    private TextView noticeTitle;
    private TextView noticeBody;
    private TextView noticeTime;
    private TextView btnKnow;
    private View mRootView;
    private onItemClickListener onItemClickListener;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        //对话框的布局
        if(mRootView==null){
            mRootView = inflater.inflate(R.layout.dialog_group_notice, container,false);
        }
        noticeTitle = mRootView.findViewById(R.id.group_notice_title);
        noticeBody = mRootView.findViewById(R.id.group_notice_body);
        noticeTime = mRootView.findViewById(R.id.group_notice_time);
        btnKnow = mRootView.findViewById(R.id.btn_know);

        //绑定监听事件
        btnKnow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //在activity里面处理点击事件
                onItemClickListener.onItemClick(v);
            }
        });
        return mRootView;
    }

    //监听事件接口
    public interface onItemClickListener {
        void onItemClick(View v);
    }

    public void setOnItemClickListener(NoticeDialogFragment.onItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }
}

然后在activity里面处理监听事件

package com.example.chen.test;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity implements
        NoticeDialogFragment.onItemClickListener{

    NoticeDialogFragment fragment;
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button = findViewById(R.id.btn_show);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //实例化对象
                fragment = new NoticeDialogFragment();
                //绑定监听事件
                fragment.setOnItemClickListener(MainActivity.this);
                fragment.show(getFragmentManager(), "dialog");
            }
        });
    }

    @Override
    public void onItemClick(View v) {
        fragment.dismiss();
        Toast.makeText(this, "我知道了", Toast.LENGTH_SHORT).show();
    }
}

这样,一个简单的Dialog就完成了,来看一下运行效果。 
 
可以说是非常的不尽人意了,我们想要的效果是让我们写的布局显示在中间并且不要旁边的边框,但 DialogFragment 并不能读懂我们的想法,所以我们需要写一个 style 来告诉 DialogFragment 这个布局应该如何显示。

<style name="NoticeDialogStyle" parent="android:Theme.Holo.Light.Dialog">
       <item name="android:windowNoTitle">true</item>
       <item name="android:windowBackground">@null</item>
</style>

然后在 DialogFragment 的 onCreate 方法里面调用 setStyle 来设置我们写好的 style,一定是在onCreate 里面设置 style,在 onCreateView 里面设置是没有效果的。

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setStyle(DialogFragment.STYLE_NORMAL,R.style.NoticeDialogStyle);
}

这两句代码很简单,就是告诉 DialogFragment 我的 dialog 没有标题栏,并且背景也是空的,实际上如果只是想去掉边框的话,只需要设置 windowNoTitle 为 true 就可以了,但是考虑到默认的背景有点黑,设置背景为空,下面是运行效果。 
 
新的问题又出现了,我们设置的圆角布局出现了黑角,实际上是因为我们把 DialogFragment 的背景设置为空,所以才会出现黑角,我们需要在 DialogFragment 的 onCreateView 里面设置背景为透明。

getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));

到此,大功告成,来看效果图。 
 
这篇博客只是记录我在使用 DialogFragment 中遇到的问题,有些言辞可能不太准确,欢迎指正。
 

猜你喜欢

转载自blog.csdn.net/weixin_37734988/article/details/89303842