经常做Android开发的小伙伴,应该会需要自定义dialog,毕竟Android源生的new AlertDialog.Builder()在不同的Android版本上有不同的显示风格,而且未必适合公司App的界面风格。而且很多公司的UI设计师都是以苹果的界面风格来写Android的UI界面。。。
为了做出这样的苹果风格Dialog,在网上研究了一段时间,写了一个简单的demo
Demo下载地址https://github.com/linqinen708/MyDialogDemo
my_dialog.xml 的布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:background="@drawable/shape_background_my_dialog_white"
android:orientation="vertical"
>
<TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="50dp"
android:gravity="center"
android:text="温馨提示"
android:textColor="@color/black_333333"
android:textSize="17sp"
android:textStyle="bold"
/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/grey_efeff4"
/>
<TextView
android:id="@+id/tv_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:padding="10dp"
android:gravity="center"
android:text="是否放弃当前操作?"
android:textColor="@color/black_333333"
android:textSize="15sp"
/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/grey_efeff4"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal"
>
<TextView
android:id="@+id/tv_negativeButton"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@drawable/selector_background_my_dialog_left"
android:clickable="true"
android:gravity="center"
android:text="取消"
android:textColor="@color/selector_text_black_to_grey"
android:textSize="16sp"
/>
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="@color/grey_efeff4"
/>
<TextView
android:id="@+id/tv_positiveButton"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@drawable/selector_background_my_dialog_right"
android:clickable="true"
android:gravity="center"
android:text="确定"
android:textColor="@color/selector_text_orange_to_grey"
android:textSize="16sp"
/>
</LinearLayout>
</LinearLayout>
想要实现圆角效果,实际上就是使用shape属性,做过Android开发的一定不会陌生
@drawable/shape_background_my_dialog_white 代码
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<corners android:radius="8dp"/>
<solid android:color="@android:color/white"/>
</shape>
使用selector属性,给“取消”和“确定”按钮增加点击效果
@drawable/selector_background_my_dialog_left 代码
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/shape_background_my_dialog_grey_left" android:state_pressed="true"/>
<item android:drawable="@drawable/shape_background_my_dialog_white" android:state_pressed="false"/>
</selector>
点击的按压效果
@drawable/shape_background_my_dialog_grey_left
其中“取消”按钮因为在左边,所以使用bottomLeftRadius属性,只设置左下角为圆角,同理“确定”按钮在右边使用bottomRightRadius属性
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<corners android:bottomLeftRadius="8dp"/>
<solid android:color="@color/grey_efefef"/>
</shape>
非点击的效果
@drawable/shape_background_my_dialog_white
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<corners android:radius="8dp"/>
<solid android:color="@android:color/white"/>
</shape>
MyDialog 代码
import android.app.Dialog;
import android.content.Context;
import android.view.View;
import android.widget.TextView;
import butterknife.BindView;
import butterknife.ButterKnife;
/**
* Created by 林 on 2017/5/2.
*/
public class MyDialog extends Dialog {
@BindView(R.id.tv_message)
TextView mTvMessage;
@BindView(R.id.tv_negativeButton)
TextView mTvNegativeButton;
@BindView(R.id.tv_positiveButton)
TextView mTvPositiveButton;
@BindView(R.id.tv_title)
TextView mTvTitle;
private Context mContext;
//在构造方法里预加载我们的样式,这样就不用每次创建都指定样式了
public MyDialog(Context context) {
this(context, R.style.MyDialog);
}
public MyDialog(Context context, int themeResId) {
super(context, themeResId);
mContext = context;
setContentView(R.layout.my_dialog);
ButterKnife.bind(this);
}
/**
* 设置标题栏
*/
public MyDialog setTitle(String title) {
if (title != null) {
mTvTitle.setText(title);
}
return this;
}
/**
* 设置内容
*/
public MyDialog setMessage(String msg) {
if (msg != null) {
mTvMessage.setText(msg);
mTvMessage.setVisibility(View.VISIBLE);
}
return this;
}
/**
* 设置内容,当内容比较多时,需要设置gravity为Gravity.START属性
*/
public MyDialog setMessage(String msg, int gravity) {
if (msg != null) {
mTvMessage.setText(msg);
mTvMessage.setGravity(gravity);
mTvMessage.setVisibility(View.VISIBLE);
}
return this;
}
/**
* 设置右边确定点击按钮
*
* @param text 按钮上的显示字
* @param listener 点击事件监听
*/
public MyDialog setPositiveButton(final String text, final OnMyDialogButtonClickListener listener) {
if (text != null) {
mTvPositiveButton.setText(text);
}
mTvPositiveButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (listener != null) {
listener.onClick();
}
dismiss();
}
});
return this;
}
public interface OnMyDialogButtonClickListener {
void onClick();
}
/**
* 设置右边确定点击按钮
* 默认 点击 字体 为 确定
*
* @param listener 点击事件监听
*/
public MyDialog setPositiveButton(final OnMyDialogButtonClickListener listener) {
return setPositiveButton(null, listener);
}
/**
* 设置左边取消点击按钮
*
* @param text 按钮上的显示字
* @param listener 点击事件监听
*/
public MyDialog setNegativeButton(String text, final OnMyDialogButtonClickListener listener) {
if (text != null) {
mTvNegativeButton.setText(text);
}
mTvNegativeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (listener != null) {
listener.onClick();
}
dismiss();
}
});
return this;
}
/**
* 设置右边取消点击按钮
* 默认 点击 字体 为 取消
*
* @param listener 点击事件监听
*/
public MyDialog setNegativeButton(final OnMyDialogButtonClickListener listener) {
return setNegativeButton(null, listener);
}
/**设置是否可以取消dialog,由于直接使用setCancelable返回的是Dialog,所以自定义方法*/
public MyDialog setDialogCancelable(boolean flag) {
setCancelable(flag);
return this;
}
}
设置R.style.MyDialog的风格
<style name="MyDialog" parent="android:Theme.Dialog">
<!-- 背景颜色及透明程度 -->
<item name="android:windowBackground">@android:color/transparent</item>
<!-- 是否半透明 -->
<item name="android:windowIsTranslucent">true</item>
<!-- 是否没有标题 -->
<item name="android:windowNoTitle">true</item>
<!-- 是否浮现在activity之上 -->
<item name="android:windowIsFloating">true</item>
<!-- 是否背景模糊 -->
<item name="android:backgroundDimEnabled">true</item>
<!-- 设置背景模糊的透明度-->
<!--<item name="android:backgroundDimAmount">0.5</item>-->
</style>
具体使用
new MyDialog(this)
.setPositiveButton(new MyDialog.OnMyDialogButtonClickListener() {
@Override
public void onClick() {
Toast.makeText(getBaseContext(),"确定",Toast.LENGTH_SHORT).show();
}
})
.setNegativeButton(null)//如果只是取消dialog,可以不用写监听,但是要写setNegativeButton方法
.show();
详细使用方式
new MyDialog(this)
.setTitle("这个是标题")
.setMessage("这个是内容")
.setPositiveButton("自定义确定", new MyDialog.OnMyDialogButtonClickListener() {
@Override
public void onClick() {
Toast.makeText(getBaseContext(),"自定义确定",Toast.LENGTH_SHORT).show();
}
})
.setNegativeButton("自定义取消", new MyDialog.OnMyDialogButtonClickListener() {
@Override
public void onClick() {
Toast.makeText(getBaseContext(),"自定义取消",Toast.LENGTH_SHORT).show();
}
})
.show();