android 自定义dialog的实现方法
最近一直在做 java 相关的东西, 虽然一直在看 Android 但感觉有点留于理论,总这样毕竟不行,写的多不一定懂得多,但要想懂得多就一
定要写的多,于是今天动手写了一下 Dialog 有关的东西,算是对 Dialog 的一个整理吧。
AlertDialog 的使用就不说了,随便百度一下就能找到,这里要说的,主要就是自定义的 Dialog。
然后还是先上代码吧:
public class CustomDialog extends AlertDialog {
protected CustomDialog(Context context) {
super(context);
}
protected CustomDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
super(context, cancelable, cancelListener);
}
protected CustomDialog(Context context, @StyleRes int themeResId) {
super(context, themeResId);
}
public static class Builder {
private Context mContext;
private CustomDialog dialog;
private View layout;
private int mIcon = -1;
private String mText;
private String mContent;
private String mPoiBtn;
private View.OnClickListener mPoiListener;
private String mNegBtn;
private View.OnClickListener mNegListener;
private int animateType = -1;
public static final int LOW_DISAPPEAR_ANIMATION = 1;
public static final int ROTATE_DISAPPEAR_ANIMATION = 2;
public Builder(Context context) {
mContext = context;
dialog = new CustomDialog(context, R.style.Theme_AppCompat_Dialog_Alert);
layout = View.inflate(mContext, R.layout.custom_dialog1, null);
}
public Builder setTitleIcon(int iconRes) {
mIcon = iconRes;
return this;
}
public Builder setTitle(CharSequence text) {
mText = (String) text;
return this;
}
public Builder setContent(CharSequence text) {
mContent = (String) text;
return this;
}
public Builder setPositiveButton(CharSequence text, @NonNull View.OnClickListener
clickListener) {
mPoiBtn = (String) text;
mPoiListener = clickListener;
return this;
}
public Builder setNegativeButton(CharSequence text, @NonNull View.OnClickListener
clickListener) {
mNegBtn = (String) text;
mNegListener = clickListener;
return this;
}
public Builder create() {
ImageView titleIcon = (ImageView) layout.findViewById(R.id.title_icon);
TextView contentView = (TextView) layout.findViewById(R.id.custom_content);
TextView titleView = (TextView) layout.findViewById(R.id.title);
TextView poiBtn = (TextView) layout.findViewById(R.id.custom_confirm);
TextView negBtn = (TextView) layout.findViewById(R.id.custom_cancel);
poiBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
if (mIcon != -1) {
titleIcon.setImageBitmap(BitmapFactory.decodeResource(mContext.getResources(),
mIcon));
}
if (!TextUtils.isEmpty(mText)) {
titleView.setText(mText);
}
if (!TextUtils.isEmpty(mContent)) {
contentView.setText(mContent);
}
if (!TextUtils.isEmpty(mPoiBtn)) {
poiBtn.setText(mPoiBtn);
poiBtn.setOnClickListener(mPoiListener);
} else {
poiBtn.setVisibility(View.GONE);
}
if (!TextUtils.isEmpty(mNegBtn)) {
negBtn.setText(mNegBtn);
negBtn.setOnClickListener(mNegListener);
} else {
negBtn.setVisibility(View.GONE);
}
dialog.setCancelable(true);
dialog.setCanceledOnTouchOutside(true);
return this;
}
int i = 0;
public CustomDialog show(){
Window mWin = dialog.getWindow();
dialog.show();
dialog.setContentView(layout, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ActionBar.LayoutParams.WRAP_CONTENT));
switch (animateType){
case LOW_DISAPPEAR_ANIMATION:
mWin.setWindowAnimations(R.style.dialog_Low_appear_animation);
break;
case ROTATE_DISAPPEAR_ANIMATION:
mWin.setWindowAnimations(R.style.dialog_rotate_appear_animation);
break;
}
return dialog;
}
public Builder setDisappearAnimator(int animateType){
this.animateType = animateType;
return this;
}
}
}
代码算不上多,做个分类的话,主要是有 3 部分: Builder 的构建,内容的设置,Dilalog的显示
首先说一下 Builder 的构建, 构建方法主要完成了 2 个功能, CustomDialog 的实例化 和 布局的填充,这里需要注意的有一点,不要急着吧
填充的布局添加到 dialog 实例中去, 在 dialog 的 show 方法之前调用 setContentView 或是 addContentView ,这样都会导致报错 RequestFeature must be called before adding content;
内容设置的代码,主要就是采用了一种链式的设计方法,每个方法都可以返回 Builder 类本身, 这样就可以一条直线的调用方法了,这样写起来 比较简洁;
最后,就是 dialog 的显示了, 记住在 show 之后调用 setContentView 或是 addContentView 就可以了, 置于 setCancelable() 和 setCancelableOnTouchOutside() 这个是对 dialog 消失时的设置,主要就两个 boolean 值,可以自己看一下;
下面是 R.layout.custom_dialog1 的布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/shape_custom_bg_grey">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:gravity="center">
<ImageView
android:id="@+id/title_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这里放置默认的标题"
android:textSize="20sp"/>
</LinearLayout>
<TextView
android:id="@+id/custom_content"
android:layout_width="match_parent"
android:layout_height="120dp"
android:padding="10dp"
android:text="这里可以放置正文内容"
android:textAlignment="center"
android:textSize="16sp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp">
<TextView
android:id="@+id/custom_cancel"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="取消"
android:textSize="18sp"
android:gravity="center"
android:background="@color/cancelBtn"
/>
<TextView
android:id="@+id/custom_confirm"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="确定"
android:textSize="18sp"
android:gravity="center"
android:background="@color/confirmBtn"
/>
</LinearLayout>
</LinearLayout>
最最后, 补充一下 Dialog 的入场动画和出场动画的定义方法
Dialog 主要是依附于一个 Window 对象来进行显示隐藏的,Window 对象的获取可以通过 dialog.getWindow 获得, 所以,dialog的出入场 动画其实就是 Window 的出入场动画,那么就简单了,通过 xml 来定义;
首先是 res/values/style.xml 文件
<style name="dialog_Low_appear_animation" parent="android:Animation">
<item name="android:windowEnterAnimation">@anim/dialog_low_enter_animation</item>
<item name="android:windowExitAnimation">@anim/dialog_low_exit_animation</item>
</style>
然后,显然后是 res/anim 下新建 dialog_low_enter_animation 和 dialog_low_exit_animation 的 Resource 文件;
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0" android:toXDelta="0" android:fromYDelta="100%" android:toYDelta="0"
android:duration="500"/>
<alpha android:fromAlpha="0" android:toAlpha="1" android:duration="500"/>
</set>
入场和出场的参数自己看着怎么定义合适,也就不多说了。
附上使用方法
CustomDialog dialog = new CustomDialog.Builer().setTitle("").setContent("")
.setPositiveButton("确定", new View.OnclickListerner(){
@override
public void onClick(View view){
dialog.dismiss();
}
})
.setNegativeButton("取消", new View.OnClickListener(){
@override
public void onClick(View view){
dialog.dismiss();
}
})
.setDisappearAnimation(CustomDialog.Builder.LOW_DISAPPEAR_ANIMATION)
.creat().show();
写到这里,好吧,dialog 的用法基本就写完了,关于原理方面的东西现在还没有涉及,以后涉猎了再来接着补充。