最近在使用 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 这个布局应该如何显示。
然后在 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 中遇到的问题,有些言辞可能不太准确,欢迎指正。