安卓低版本的效果很难看,高版本的dialog虽然好看,但还是和公司UI给的效果图有些差距.
于是乎就想办法能不能dialog的布局也能自定义.好了先看效果图:
是不是感觉效果也很好,好了下边看看步骤:
1.首先我们看一下这个自定义的Dialog类
/**
* 自定义带两个button的dialog
*
* @author Haipeng
*
* 2016-7-28
*/
public class DefindedDialog extends Dialog {
public DefindedDialog(Context context, int theme) {
super(context, theme);
}
public DefindedDialog(Context context) {
super(context);
}
public static class Builder {
private Context context;
private String title;
private String message;
private String positiveButtonText;
private String negativeButtonText;
private OnDedindedClickedListener onDedindedClickedListener;
/**
*
* @param context
* @param title
* 标题
* @param message
* 提示内容
* @param positiveButtonText
* 确定按钮的文本
* @param negativeButtonText
* 取消按钮
* @param onDedindedClickedListener
* 两个按钮的监听
*/
public Builder(Context context, String title, String message,
String positiveButtonText, String negativeButtonText,
OnDedindedClickedListener onDedindedClickedListener) {
super();
this.context = context;
this.title = title;
this.message = message;
this.positiveButtonText = positiveButtonText;
this.negativeButtonText = negativeButtonText;
this.onDedindedClickedListener = onDedindedClickedListener;
}
/**
* Create the custom dialog
*/
public DefindedDialog create() {
final DefindedDialog dialog = new DefindedDialog(context,
R.style.TwoButtonDialog);// 设置dialog的风格
// 设置dialog不可取消 点击其他地方不能隐藏
dialog.setCanceledOnTouchOutside(false);
dialog.setCancelable(false);
View layout = View.inflate(context, R.layout.two_button_dialog,
null);
// 设置内容
TextView tv_content = (TextView) layout
.findViewById(R.id.two_btn_desc);
if (TextUtils.isEmpty(message)) {
tv_content.setVisibility(View.GONE);
} else {
tv_content.setVisibility(View.VISIBLE);
tv_content.setText(message);
tv_content.setMovementMethod(new ScrollingMovementMethod());
}
// 设置标题
TextView tv_title = (TextView) layout
.findViewById(R.id.two_btn_title);
// View view = layout.findViewById(R.id.view);
if (TextUtils.isEmpty(title)) {
tv_title.setVisibility(View.GONE);
// view.setVisibility(View.GONE);
} else {
// 间隔线
// view.setVisibility(View.VISIBLE);
tv_title.setVisibility(View.VISIBLE);
tv_title.setText(title);
}
// 将自定义的布局设置上去
dialog.setContentView(layout);
// 设置确定按钮的文字以及点击事件
Button confirm_btn = ((Button) layout
.findViewById(R.id.confirm_btn));
if (TextUtils.isEmpty(positiveButtonText)) {
confirm_btn.setText("确定");
} else {
confirm_btn.setText(positiveButtonText);
}
confirm_btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
onDedindedClickedListener.onPositiveButtonClieked(dialog);
dialog.dismiss();
}
});
// 设置取消按钮
Button cancle_btn = ((Button) layout.findViewById(R.id.cancle_btn));
if (TextUtils.isEmpty(negativeButtonText)) {
cancle_btn.setText("取消");
} else {
cancle_btn.setText(negativeButtonText);
}
cancle_btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
onDedindedClickedListener.onNegativeButtonClieked(dialog);
dialog.dismiss();
}
});
// 设置dialog的宽度
WindowManager.LayoutParams params = dialog.getWindow()
.getAttributes();
params.width = getScreenWidth(context) - dp2px(context, 50);
dialog.getWindow().setAttributes(params);
return dialog;
}
/**
* 获得屏幕宽度
*
* @param context
* @return
*/
public int getScreenWidth(Context context) {
WindowManager wm = (WindowManager) context
.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
return outMetrics.widthPixels;
}
/**
* dp转px
*
* @param context
* @param val
* @return
*/
public int dp2px(Context context, float dpVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
dpVal, context.getResources().getDisplayMetrics());
}
}
/**
* 当点击确定的时候会调用onPositiveButtonClieked 当点击取消的时候会调用onPositiveButtonClieked
*
* @author Haipeng
*
* 2016-7-28
*/
public interface OnDedindedClickedListener {
void onPositiveButtonClieked(DefindedDialog dialog);
void onNegativeButtonClieked(DefindedDialog dialog);
}
}
注意:
首先,这个类继承Dialog 关于dialog的设置都在内部类Builder中设置
在Dialog的builder中的create()方法中创建dialog的实例
接着 在Buider的构造方法中,部所有的构造方法中所需要的参数都传递过来
包括确定和取消按钮的监听
然后 OnDedindedClickedListener接口中的两个方法分别在两个按钮点击的时候调用
最后 在Oncreate中设置了Dialog 的布局 这也就是说 dialog的大小可以由我们去设置
灵活性也更大 比如说我们需要三个按钮的Dialog 我们只需要在布局文件中
添加一个按钮,代码稍作修改就好
2.下边贴出Dialog的布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="20dp"
android:background="@drawable/dialog_shape"
android:orientation="vertical" >
<!-- 标题 -->
<TextView
android:id="@+id/two_btn_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:text="更新"
android:textSize="19sp" />
<!-- 分割线 -->
<!--
<View
android:id="@+id/view"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#eeeeee"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="10dp" />
-->
<!-- 内容 -->
<TextView
android:id="@+id/two_btn_desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:layout_marginTop="20dp"
android:ellipsize="end"
android:gravity="center"
android:lineSpacingExtra="3dp"
android:maxHeight="300dp"
android:scrollbars="vertical"
android:textSize="15sp" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#eee" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:orientation="horizontal" >
<Button
android:id="@+id/cancle_btn"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@null"
android:text=""
android:textColor="#FF6601"
android:textSize="13sp" />
<View
android:id="@+id/button_devide_line"
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="#f7f7f7" />
<Button
android:id="@+id/confirm_btn"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@null"
android:text=""
android:textColor="#FF6601"
android:textSize="13sp" />
</LinearLayout>
</LinearLayout>
3.Builder的create()中需要一个风格
<style name="TwoButtonDialog" parent="android:style/Theme.Dialog">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">true</item>
</style>
注意:
首先 这个风格是去掉dialog默认的背景 设置没有标题
接着 windowIsFloating属性设置为false, 默认将Window设置成全屏大小,设置为true,则window大小为wrap_content。
这个属性的作用参考这篇文章
4.下边看这个自定义Dialog的封装
/**
* 创建Dialog的工具类
*
* @author Haipeng
*
* 2016-7-28
*/
public class DialogUtils {
/**
* 只要内容的dialog 两个按钮的文字设置为默认 不要标题
*
* @param context
* @param content
* @param listener
* @return
*/
public static Dialog commonDialogTwoBtn(Context context, String content,
DefindedDialog.OnDedindedClickedListener listener) {
return commonDialogTwoBtn(context, null, content, "确定", "取消", listener);
}
/**
* 只要内容的dialog 两个按钮的文字设置为不默认
*
* @param context
* @param content
* @param positiveName
* @param negativeName
* @param listener
* @return
*/
public static Dialog commonDialogTwoBtn(Context context, String content,
String positiveName, String negativeName,
DefindedDialog.OnDedindedClickedListener listener) {
return commonDialogTwoBtn(context, null, content, positiveName,
negativeName, listener);
}
/**
* 既要内容 又要标题的dialog 并且两个按钮的文字设置为默认
*
* @param context
* @param title
* @param content
* @param listener
* @return
*/
public static Dialog commonDialogTwoBtn(Context context, String title,
String content, DefindedDialog.OnDedindedClickedListener listener) {
return commonDialogTwoBtn(context, title, content, "确定", "取消", listener);
}
/**
* 既要内容 又要标题的dialog 并且两个按钮的文字不默认
*
* @param context
* @param title
* @param content
* @param positiveName
* @param negativeName
* @param listener
* @return
*/
public static Dialog commonDialogTwoBtn(Context context, String title,
String content, String positiveName, String negativeName,
DefindedDialog.OnDedindedClickedListener listener) {
if (TextUtils.isEmpty(content)) {
return null;
}
if (listener == null) {
return null;
}
DefindedDialog.Builder alert = new DefindedDialog.Builder(context,
title, content, positiveName, negativeName, listener);
DefindedDialog dialog = alert.create();
dialog.show();
return dialog;
}
}
注意 这里边的两个按钮的文案一般默认为确认和取消 当然你也可以传别的 标题可有可无
5.在MainActivity中调用下看看效果
private Button warming;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
warming = (Button) findViewById(R.id.warming);
warming.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.warming:
OnDedindedClickedListener onDedindedClickedListener = new DefindedDialog.OnDedindedClickedListener() {
@Override
public void onPositiveButtonClieked(DefindedDialog dialog) {
Toast.makeText(MainActivity.this, "确定", Toast.LENGTH_SHORT)
.show();
}
@Override
public void onNegativeButtonClieked(DefindedDialog dialog) {
Toast.makeText(MainActivity.this, "取消", Toast.LENGTH_SHORT)
.show();
}
};
DialogUtils.commonDialogTwoBtn(this, "你确定要删除该商品吗?",
onDedindedClickedListener);
DialogUtils.commonDialogTwoBtn(this, "删除", "你确定要删除该商品吗?",
onDedindedClickedListener);
DialogUtils.commonDialogTwoBtn(this, "你确定要删除该商品吗?", "确定", "取消",
onDedindedClickedListener);
DialogUtils.commonDialogTwoBtn(this, "删除", "你确定要删除该商品吗?", "确定",
"取消", onDedindedClickedListener);
break;
}
}
布局文件中就一个按钮 为了方便大家看效果 这里第一下按钮直接弹出了四个Dialog