Dialog可以说是一个项目中的必用控件了,但是既然Google推荐用DialogFragment来替代Dialog,那我们就改用DialogFragment吧,话不多说,写一个最简单常见的屏幕中间弹出的DialogFragment,下面是java代码:
public class CenterTipDialogFragment extends DialogFragment {
@BindView(R.id.tv_title)
TextView tvTitle;
@BindView(R.id.tv_content)
TextView tvContent;
@BindView(R.id.tv_left)
TextView tvLeft;
@BindView(R.id.tv_right)
TextView tvRight;
private Unbinder unbinder;
private OnClickListener mOnClickListener;
private String mTitle;
private String mContent;
private String mLeftText;
private String mRightText;
private View mContentView;
public interface OnClickListener {
void onLeftBtnClick();
void onRightBtnClick();
}
public static CenterTipDialogFragment newInstance(String title,String content,String leftText,String rightText){
CenterTipDialogFragment fragment = new CenterTipDialogFragment();
Bundle bundle = new Bundle();
bundle.putString("title", title);
bundle.putString("content", content);
bundle.putString("leftText", leftText);
bundle.putString("rightText", rightText);
fragment.setArguments(bundle);
return fragment;
}
public CenterTipDialogFragment setClickListener(OnClickListener listener){
mOnClickListener = listener;
return this;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
mContentView = inflater.inflate(R.layout.dlg_center_tip, container, true);
unbinder = ButterKnife.bind(this, view);
return mContentView;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams();
layoutParams.width = (int) (getResources().getDisplayMetrics().widthPixels * 0.8);
initData();
}
private void initData() {
Bundle bundle = getArguments();
if (bundle != null){
mTitle = bundle.getString("title");
mContent = bundle.getString("content");
mLeftText = bundle.getString("leftText");
mRightText = bundle.getString("rightText");
}
if (TextUtils.isEmpty(mTitle)) {
tvTitle.setVisibility(View.GONE);
} else {
tvTitle.setVisibility(View.VISIBLE);
tvTitle.setText(mTitle);
}
if (TextUtils.isEmpty(mContent)) {
tvContent.setVisibility(View.GONE);
} else {
tvContent.setVisibility(View.VISIBLE);
tvContent.setText(mContent);
}
if (TextUtils.isEmpty(mLeftText)) {
tvLeft.setVisibility(View.GONE);
} else {
tvLeft.setVisibility(View.VISIBLE);
tvLeft.setText(mLeftText);
}
if (TextUtils.isEmpty(mRightText)) {
tvRight.setVisibility(View.GONE);
} else {
tvRight.setVisibility(View.VISIBLE);
tvRight.setText(mRightText);
}
tvLeft.setOnClickListener(v -> {
if (mOnClickListener != null) {
mOnClickListener.onLeftBtnClick();
CenterTipDialogFragment.this.dismiss();
}
});
tvRight.setOnClickListener(v -> {
if (mOnClickListener != null) {
mOnClickListener.onRightBtnClick();
CenterTipDialogFragment.this.dismiss();
}
});
}
@Override
public void onDestroy() {
unbinder.unbind();
super.onDestroy();
}
}
然后是xml文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/ll_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_radius_white"
android:divider="@drawable/horizontal_grey_line"
android:orientation="vertical"
android:showDividers="middle">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:gravity="center_horizontal"
android:orientation="vertical">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="30dp"
android:textColor="@color/color_222222"
android:textSize="16sp"
android:textStyle="bold"
tools:text="审核未通过" />
<TextView
android:id="@+id/tv_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="40dp"
android:textColor="@color/color_222222"
android:textSize="16sp"
tools:text="图片不清晰,审核未通过" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="@drawable/vertical_grey_line"
android:orientation="horizontal"
android:showDividers="middle">
<TextView
android:id="@+id/tv_left"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:paddingVertical="13dp"
android:textColor="@color/color_037CFF"
android:textSize="14sp"
tools:text="取消" />
<TextView
android:id="@+id/tv_right"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:paddingVertical="13dp"
android:textColor="@color/color_037CFF"
android:textSize="14sp"
tools:text="重新认证" />
</LinearLayout>
</LinearLayout>
代码很简单,和写fragment几乎一样,DialogFragment也是继承的Fragment,只不过加了Dialog的一些特性。运行代码,效果如下图:
嗯,是不是很简单?但是,当我换个手机运行,马上出现问题,换成vivo手机运行如下图:
What?上面多出来的部分和四个角的诡异圆角是什么鬼?马上换成Dialog试了一下,结果还是这样。然后我开始怀疑是我布局文件有问题,可能vivo系统的Dialog不能自适应宽高,那么就给布局文件固定宽高,试了好几种宽高值还是没解决,而且如果布局文件写死了宽高,那么如果标题或者内容字数多了就显示不下了,所以不能写死。因为对Dialog比DialogFragment熟悉,所以就开始现在Dialog中尝试解决,首先给Dialog加一个自定义的透明背景style,
<style name="TransparentDialog" parent="@android:style/Theme.Dialog">
<!-- 背景透明 -->
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowContentOverlay">@null</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>
</style>
运行,无效!代码中重新设置contentView的宽高:
ViewGroup.LayoutParams layoutParams = contentView.getLayoutParams();
layoutParams.width = (int) (activity.getResources().getDisplayMetrics().widthPixels * 0.8);
layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
contentView.setLayoutParams(layoutParams);
运行,依然无效!静下心来好好分析吧,看现象好像是我的contentView加入到Dialog中的时候,Dialog的最根布局针对contentView做了处理,导致我后面重新对contentView设置layoutParams无效,那把这段代码放到setContentView之前试试,结果会崩溃,因为contentView.getLayoutParams()会返回null。那自己new一个layoutParams,
ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams((int) (activity.getResources().getDisplayMetrics().widthPixels * 0.8),
ViewGroup.LayoutParams.WRAP_CONTENT);
contentView.setLayoutParams(layoutParams);
dialog.setContentView(contentView);
然后效果如下:
嗯,终于有所改变,看来快解决了,加油。看目前这个现象,既然对contentView设置layoutParams不行,那就对子控件设置,我先是对xml文件的根布局,就是上面xml里的最外层的Linearlayout设置layoutParams,无效!这样应该和对contentView设置是一样的。那就在外面再包一层FramLayout,运行,正常了!然后再试试之前本来就显示正常的手机,也是好的。到此,问题解决!然后把解决思路用回到DialogFragment,同样问题解决了。Dialog的代码就不贴了,下面是DialogFragment的完整的代码:
public class CenterTipDialogFragment extends DialogFragment {
@BindView(R.id.tv_title)
TextView tvTitle;
@BindView(R.id.tv_content)
TextView tvContent;
@BindView(R.id.tv_left)
TextView tvLeft;
@BindView(R.id.tv_right)
TextView tvRight;
@BindView(R.id.ll_main)
LinearLayout mRootLayout;
private Unbinder unbinder;
private OnClickListener mOnClickListener;
private String mTitle;
private String mContent;
private String mLeftText;
private String mRightText;
public interface OnClickListener {
void onLeftBtnClick();
void onRightBtnClick();
}
public static CenterTipDialogFragment newInstance(String title,String content,String leftText,String rightText){
CenterTipDialogFragment fragment = new CenterTipDialogFragment();
Bundle bundle = new Bundle();
bundle.putString("title", title);
bundle.putString("content", content);
bundle.putString("leftText", leftText);
bundle.putString("rightText", rightText);
fragment.setArguments(bundle);
return fragment;
}
public CenterTipDialogFragment setClickListener(OnClickListener listener){
mOnClickListener = listener;
return this;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dlg_center_tip, container, true);
//下面这两行代码是关键,和Dialog设置背景透明和无标题的自定义style是同样的效果
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
unbinder = ButterKnife.bind(this, view);
return view;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
//这里也是关键,mRootLayout是xml文件中倒数第二层的layout,而非最外层的layout
ViewGroup.LayoutParams layoutParams = mRootLayout.getLayoutParams();
layoutParams.width = (int) (getResources().getDisplayMetrics().widthPixels * 0.8);
initData();
}
private void initData() {
Bundle bundle = getArguments();
if (bundle != null){
mTitle = bundle.getString("title");
mContent = bundle.getString("content");
mLeftText = bundle.getString("leftText");
mRightText = bundle.getString("rightText");
}
if (TextUtils.isEmpty(mTitle)) {
tvTitle.setVisibility(View.GONE);
} else {
tvTitle.setVisibility(View.VISIBLE);
tvTitle.setText(mTitle);
}
if (TextUtils.isEmpty(mContent)) {
tvContent.setVisibility(View.GONE);
} else {
tvContent.setVisibility(View.VISIBLE);
tvContent.setText(mContent);
}
if (TextUtils.isEmpty(mLeftText)) {
tvLeft.setVisibility(View.GONE);
} else {
tvLeft.setVisibility(View.VISIBLE);
tvLeft.setText(mLeftText);
}
if (TextUtils.isEmpty(mRightText)) {
tvRight.setVisibility(View.GONE);
} else {
tvRight.setVisibility(View.VISIBLE);
tvRight.setText(mRightText);
}
tvLeft.setOnClickListener(v -> {
if (mOnClickListener != null) {
mOnClickListener.onLeftBtnClick();
CenterTipDialogFragment.this.dismiss();
}
});
tvRight.setOnClickListener(v -> {
if (mOnClickListener != null) {
mOnClickListener.onRightBtnClick();
CenterTipDialogFragment.this.dismiss();
}
});
}
@Override
public void onDestroy() {
unbinder.unbind();
super.onDestroy();
}
}
xml文件:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_radius_white">
<LinearLayout
android:id="@+id/ll_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="@drawable/horizontal_grey_line"
android:orientation="vertical"
android:showDividers="middle">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:gravity="center_horizontal"
android:orientation="vertical">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="30dp"
android:textColor="@color/color_222222"
android:textSize="16sp"
android:textStyle="bold"
tools:text="审核未通过" />
<TextView
android:id="@+id/tv_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="40dp"
android:textColor="@color/color_222222"
android:textSize="16sp"
tools:text="图片不清晰,审核未通过" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="@drawable/vertical_grey_line"
android:orientation="horizontal"
android:showDividers="middle">
<TextView
android:id="@+id/tv_left"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:paddingVertical="13dp"
android:textColor="@color/color_037CFF"
android:textSize="14sp"
tools:text="取消" />
<TextView
android:id="@+id/tv_right"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:paddingVertical="13dp"
android:textColor="@color/color_037CFF"
android:textSize="14sp"
tools:text="重新认证" />
</LinearLayout>
</LinearLayout>
</FrameLayout>
最后吐槽一下,android适配确实是件让人头疼的事。