一个自定义的测评dialog动效小demo
#
- 博客园的第一篇博客,项目需求待确认的这段时间,有点小闲,把前两天写的一个测评提交的dialog效果先提上来,记录一下。
- pc端测评结束后有页面弹窗动效,所以android这边自己写了个小demo。首先贴dialog代码
- 实际效果图如下:
首先自定义了一个仿ios效果的dialog。代码如下:
1.因为需要一个粒子动画效果,引入了一个开源库:
github地址:https://github.com/jinatonic/confetti
添加依赖:
compile 'com.github.jinatonic.confetti:confetti:1.0.0'
初始化粒子效果:
1.设置粒子颜色
1 /**设置粒子颜色*/ 2 final Resources res = context.getResources(); 3 goldDark = res.getColor(R.color.gold_dark); 4 goldMed = res.getColor(R.color.gold_med); 5 gold = res.getColor(R.color.gold); 6 goldLight = res.getColor(R.color.gold_light); 7 goldLight1 = res.getColor(R.color.gold_light1); 8 goldLight2 = res.getColor(R.color.gold_light2); 9 goldLight3 = res.getColor(R.color.gold_light3); 10 goldLight4 = res.getColor(R.color.gold_light4); 11 goldLight5 = res.getColor(R.color.gold_light5); 12 goldLight6 = res.getColor(R.color.gold_light6); 13 goldLight7 = res.getColor(R.color.gold_light7); 14 goldLight8 = res.getColor(R.color.gold_light8); 15 goldLight9 = res.getColor(R.color.gold_light9); 16 colors = new int[]{goldDark, goldMed, gold, goldLight, goldLight1, goldLight2, goldLight3, goldLight4, goldLight5, goldLight6, goldLight7, goldLight8, goldLight9};
2.三种粒子实现效果
1 /**粒子效果时间——一次*/ 2 protected ConfettiManager generateOnce() { 3 return getCommonConfetti().oneShot(); 4 } 5 /**粒子效果时间——定义时长*/ 6 protected ConfettiManager generateStream() { 7 return getCommonConfetti().stream(1500); 8 } 9 /**粒子效果时间——持续*/ 10 protected ConfettiManager generateInfinite() { 11 return getCommonConfetti().infinite(); 12 } 13 /**粒子动画显示范围以及位置*/ 14 private CommonConfetti getCommonConfetti() { 15 WindowManager wm = (WindowManager) context 16 .getSystemService(Context.WINDOW_SERVICE); 17 18 int width = wm.getDefaultDisplay().getWidth()-120; 19 int height = wm.getDefaultDisplay().getHeight()-350; 20 final int centerX = width / 2; 21 final int centerY = height /2 ; 22 return CommonConfetti.explosion(container, centerX, centerY, colors); 23 }
2.定义了一个仿ios效果的dialog,代码如下:
package com.ydjy.test; import android.app.Dialog; import android.content.Context; import android.content.res.Resources; import android.view.Display; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.WindowManager; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.widget.Button; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.TextView; import com.github.jinatonic.confetti.CommonConfetti; import com.github.jinatonic.confetti.ConfettiManager; /*** * chenyen */ public class AlertDialog { private Context context; private Dialog dialog; private LinearLayout lLayout_bg; private TextView txt_title; private TextView txt_msg; private Button btn_neg; private Button btn_pos; private ImageView img_line; private Display display; private boolean showTitle = false; private boolean showMsg = false; private boolean showPosBtn = false; private boolean showNegBtn = false; private ImageView iv_icon_bg; private int goldDark; private int goldMed; private int gold; private int goldLight; private int[] colors; private int goldLight1; private int goldLight2; private int goldLight3; private int goldLight4; private int goldLight5; private int goldLight6; private int goldLight7; private int goldLight8; private int goldLight9; private RelativeLayout container; public AlertDialog(Context context) { this.context = context; WindowManager windowManager = (WindowManager) context .getSystemService(Context.WINDOW_SERVICE); display = windowManager.getDefaultDisplay(); } public AlertDialog builder() { // 获取Dialog布局 /**设置粒子颜色*/ final Resources res = context.getResources(); goldDark = res.getColor(R.color.gold_dark); goldMed = res.getColor(R.color.gold_med); gold = res.getColor(R.color.gold); goldLight = res.getColor(R.color.gold_light); goldLight1 = res.getColor(R.color.gold_light1); goldLight2 = res.getColor(R.color.gold_light2); goldLight3 = res.getColor(R.color.gold_light3); goldLight4 = res.getColor(R.color.gold_light4); goldLight5 = res.getColor(R.color.gold_light5); goldLight6 = res.getColor(R.color.gold_light6); goldLight7 = res.getColor(R.color.gold_light7); goldLight8 = res.getColor(R.color.gold_light8); goldLight9 = res.getColor(R.color.gold_light9); colors = new int[]{goldDark, goldMed, gold, goldLight, goldLight1, goldLight2, goldLight3, goldLight4, goldLight5, goldLight6, goldLight7, goldLight8, goldLight9}; View view = LayoutInflater.from(context).inflate( R.layout.view_alertdialog, null); // 获取自定义Dialog布局中的控件 lLayout_bg = (LinearLayout) view.findViewById(R.id.lLayout_bg); txt_title = (TextView) view.findViewById(R.id.txt_title); txt_title.setVisibility(View.GONE); txt_msg = (TextView) view.findViewById(R.id.txt_msg); txt_msg.setVisibility(View.GONE); btn_neg = (Button) view.findViewById(R.id.btn_neg); btn_neg.setVisibility(View.GONE); btn_pos = (Button) view.findViewById(R.id.btn_pos); btn_pos.setVisibility(View.GONE); img_line = (ImageView) view.findViewById(R.id.img_line); img_line.setVisibility(View.GONE); iv_icon_bg = (ImageView) view.findViewById(R.id.iv_icon_bg); container = (RelativeLayout) view.findViewById(R.id.container); // 定义Dialog布局和参数 dialog = new Dialog(context, R.style.AlertDialogStyle); dialog.setContentView(view); // 调整dialog背景大小 // lLayout_bg.setLayoutParams(new FrameLayout.LayoutParams((int) (display // .getWidth() * 0.85), LayoutParams.WRAP_CONTENT)); // setCancelable(false); return this; } /**设置标题*/ public AlertDialog setTitle(String title) { showTitle = true; if ("".equals(title)) { txt_title.setText(""); } else { txt_title.setText(title); } return this; } /**粒子效果时间——一次*/ protected ConfettiManager generateOnce() { return getCommonConfetti().oneShot(); } /**粒子效果时间——定义时长*/ protected ConfettiManager generateStream() { return getCommonConfetti().stream(1500); } /**粒子效果时间——持续*/ protected ConfettiManager generateInfinite() { return getCommonConfetti().infinite(); } /**粒子动画显示范围以及位置*/ private CommonConfetti getCommonConfetti() { WindowManager wm = (WindowManager) context .getSystemService(Context.WINDOW_SERVICE); int width = wm.getDefaultDisplay().getWidth()-120; int height = wm.getDefaultDisplay().getHeight()-350; final int centerX = width / 2; final int centerY = height /2 ; return CommonConfetti.explosion(container, centerX, centerY, colors); } /**标题字体大小*/ public AlertDialog setTitleSize(float size) { txt_title.setTextSize(size); return this; } /**设置内容字体大小*/ public AlertDialog setMessageSize(float size) { txt_msg.setTextSize(size); return this; } /**设置内容*/ public AlertDialog setMsg(CharSequence msg) { showMsg = true; if ("".equals(msg)) { txt_msg.setText(""); } else { txt_msg.setText(msg); } return this; } /**设置点击屏幕或物理返回键dialog是否消失*/ public AlertDialog setCancelable(boolean cancel) { dialog.setCancelable(cancel); return this; } public AlertDialog setPositiveButton(String text, final OnClickListener listener) { showPosBtn = true; if ("".equals(text)) { btn_pos.setText("确定"); } else { btn_pos.setText(text); } btn_pos.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { listener.onClick(v); dialog.dismiss(); } }); return this; } public AlertDialog setNegativeButton(String text, final OnClickListener listener) { showNegBtn = true; if ("".equals(text)) { btn_neg.setText("取消"); } else { btn_neg.setText(text); } btn_neg.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { listener.onClick(v); dialog.dismiss(); } }); return this; } private void setLayout() { if (!showTitle && !showMsg) { txt_title.setText("提示"); txt_title.setVisibility(View.VISIBLE); } if (showTitle) { txt_title.setVisibility(View.VISIBLE); } if (showMsg) { txt_msg.setVisibility(View.VISIBLE); } if (!showPosBtn && !showNegBtn) { btn_pos.setText("确定"); btn_pos.setVisibility(View.VISIBLE); btn_pos.setBackgroundResource(R.drawable.alertdialog_single_selector); btn_pos.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { dialog.dismiss(); } }); } if (showPosBtn && showNegBtn) { btn_pos.setVisibility(View.VISIBLE); btn_pos.setBackgroundResource(R.drawable.alertdialog_right_selector); btn_neg.setVisibility(View.VISIBLE); btn_neg.setBackgroundResource(R.drawable.alertdialog_left_selector); img_line.setVisibility(View.VISIBLE); } if (showPosBtn && !showNegBtn) { btn_pos.setVisibility(View.VISIBLE); btn_pos.setBackgroundResource(R.drawable.alertdialog_single_selector); } if (!showPosBtn && showNegBtn) { btn_neg.setVisibility(View.VISIBLE); btn_neg.setBackgroundResource(R.drawable.alertdialog_single_selector); } } public void show() { setLayout(); dialog.show(); } }
3.实现背景灯光效果,布局代码如下:
1 <?xml version="1.0" encoding="utf-8"?> 2 <RelativeLayout 3 xmlns:android="http://schemas.android.com/apk/res/android" 4 android:id="@+id/container" 5 android:layout_width="match_parent" 6 android:layout_height="match_parent" 7 > 8 9 10 11 <ImageView 12 android:id="@+id/iv_icon_bg" 13 android:layout_width="wrap_content" 14 android:layout_height="wrap_content" 15 android:layout_centerInParent="true" 16 android:src="@mipmap/light_bg2" 17 android:scaleType="centerCrop" 18 android:visibility="gone" 19 /> 20 21 <LinearLayout 22 android:id="@+id/lLayout_bg" 23 android:layout_width="match_parent" 24 android:layout_height="wrap_content" 25 android:layout_centerInParent="true" 26 android:background="@drawable/alert_bg" 27 android:orientation="vertical"> 28 29 <TextView 30 android:id="@+id/txt_title" 31 android:layout_width="match_parent" 32 android:layout_height="wrap_content" 33 android:layout_marginBottom="5dp" 34 android:layout_marginTop="15dp" 35 android:gravity="center" 36 android:textColor="#000000" 37 android:textSize="17sp" 38 android:textStyle="bold"/> 39 40 <TextView 41 android:id="@+id/txt_msg" 42 android:layout_width="match_parent" 43 android:layout_height="wrap_content" 44 android:layout_marginBottom="15dp" 45 android:layout_marginLeft="15dp" 46 android:layout_marginRight="15dp" 47 android:gravity="center" 48 android:textColor="#000000" 49 android:textSize="17sp"/> 50 51 <ImageView 52 android:layout_width="match_parent" 53 android:layout_height="0.5dp" 54 android:layout_marginTop="10dp" 55 android:background="#c6c6c6"/> 56 57 <LinearLayout 58 android:layout_width="match_parent" 59 android:layout_height="wrap_content" 60 android:orientation="horizontal"> 61 62 <Button 63 android:id="@+id/btn_neg" 64 android:layout_width="wrap_content" 65 android:layout_height="43dp" 66 android:layout_weight="1" 67 android:background="@drawable/alertdialog_left_selector" 68 android:gravity="center" 69 android:textColor="#000000" 70 android:textSize="16sp"/> 71 72 <ImageView 73 android:id="@+id/img_line" 74 android:layout_width="0.5dp" 75 android:layout_height="43dp" 76 android:background="#c6c6c6"/> 77 78 <Button 79 android:id="@+id/btn_pos" 80 android:layout_width="wrap_content" 81 android:layout_height="43dp" 82 android:layout_weight="1" 83 android:background="@drawable/alertdialog_right_selector" 84 android:gravity="center" 85 android:textColor="#000000" 86 android:textSize="16sp"/> 87 </LinearLayout> 88 </LinearLayout> 89 90 91 </RelativeLayout>
1.首先需要一个旋转以及渐隐动画,很简单:
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <rotate android:duration="2000" android:fromDegrees="0" android:pivotX="50.0%" android:pivotY="50.0%" android:repeatCount="0" android:fillAfter="true" android:toDegrees="359"/> <alpha android:duration="2000" android:fromAlpha="1.0" android:toAlpha="0" /> </set>
2.定义一个动画开启方法:
给背景图片设置一个动画,动画开启时,同时启动粒子效果,同时设置动画监听,动画结束后隐藏背景图片
/**开启动画*/ public AlertDialog setAnim(boolean cancel) { if (cancel) { generateStream(); iv_icon_bg.setVisibility(View.VISIBLE); Animation mAnimation = AnimationUtils.loadAnimation(context, R.anim.cart_anim); iv_icon_bg.startAnimation(mAnimation); mAnimation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { iv_icon_bg.setVisibility(View.INVISIBLE); } @Override public void onAnimationRepeat(Animation animation) { } }); } return this; }
4.最后完整代码,很简单:
1 package com.ydjy.test; 2 3 4 import android.app.Dialog; 5 import android.content.Context; 6 import android.content.res.Resources; 7 import android.view.Display; 8 import android.view.LayoutInflater; 9 import android.view.View; 10 import android.view.View.OnClickListener; 11 import android.view.WindowManager; 12 import android.view.animation.Animation; 13 import android.view.animation.AnimationUtils; 14 import android.widget.Button; 15 import android.widget.ImageView; 16 import android.widget.LinearLayout; 17 import android.widget.RelativeLayout; 18 import android.widget.TextView; 19 20 import com.github.jinatonic.confetti.CommonConfetti; 21 import com.github.jinatonic.confetti.ConfettiManager; 22 23 /*** 24 * chenyen 25 */ 26 public class AlertDialog { 27 private Context context; 28 private Dialog dialog; 29 private LinearLayout lLayout_bg; 30 private TextView txt_title; 31 private TextView txt_msg; 32 private Button btn_neg; 33 private Button btn_pos; 34 private ImageView img_line; 35 private Display display; 36 private boolean showTitle = false; 37 private boolean showMsg = false; 38 private boolean showPosBtn = false; 39 private boolean showNegBtn = false; 40 private ImageView iv_icon_bg; 41 private int goldDark; 42 private int goldMed; 43 private int gold; 44 private int goldLight; 45 private int[] colors; 46 private int goldLight1; 47 private int goldLight2; 48 private int goldLight3; 49 private int goldLight4; 50 private int goldLight5; 51 private int goldLight6; 52 private int goldLight7; 53 private int goldLight8; 54 private int goldLight9; 55 private RelativeLayout container; 56 57 public AlertDialog(Context context) { 58 this.context = context; 59 WindowManager windowManager = (WindowManager) context 60 .getSystemService(Context.WINDOW_SERVICE); 61 display = windowManager.getDefaultDisplay(); 62 } 63 64 public AlertDialog builder() { 65 // 获取Dialog布局 66 /**设置粒子颜色*/ 67 final Resources res = context.getResources(); 68 goldDark = res.getColor(R.color.gold_dark); 69 goldMed = res.getColor(R.color.gold_med); 70 gold = res.getColor(R.color.gold); 71 goldLight = res.getColor(R.color.gold_light); 72 goldLight1 = res.getColor(R.color.gold_light1); 73 goldLight2 = res.getColor(R.color.gold_light2); 74 goldLight3 = res.getColor(R.color.gold_light3); 75 goldLight4 = res.getColor(R.color.gold_light4); 76 goldLight5 = res.getColor(R.color.gold_light5); 77 goldLight6 = res.getColor(R.color.gold_light6); 78 goldLight7 = res.getColor(R.color.gold_light7); 79 goldLight8 = res.getColor(R.color.gold_light8); 80 goldLight9 = res.getColor(R.color.gold_light9); 81 colors = new int[]{goldDark, goldMed, gold, goldLight, goldLight1, goldLight2, goldLight3, goldLight4, goldLight5, goldLight6, goldLight7, goldLight8, goldLight9}; 82 83 View view = LayoutInflater.from(context).inflate( 84 R.layout.view_alertdialog, null); 85 86 // 获取自定义Dialog布局中的控件 87 lLayout_bg = (LinearLayout) view.findViewById(R.id.lLayout_bg); 88 txt_title = (TextView) view.findViewById(R.id.txt_title); 89 txt_title.setVisibility(View.GONE); 90 txt_msg = (TextView) view.findViewById(R.id.txt_msg); 91 txt_msg.setVisibility(View.GONE); 92 btn_neg = (Button) view.findViewById(R.id.btn_neg); 93 btn_neg.setVisibility(View.GONE); 94 btn_pos = (Button) view.findViewById(R.id.btn_pos); 95 btn_pos.setVisibility(View.GONE); 96 img_line = (ImageView) view.findViewById(R.id.img_line); 97 img_line.setVisibility(View.GONE); 98 iv_icon_bg = (ImageView) view.findViewById(R.id.iv_icon_bg); 99 container = (RelativeLayout) view.findViewById(R.id.container); 100 // 定义Dialog布局和参数 101 dialog = new Dialog(context, R.style.AlertDialogStyle); 102 dialog.setContentView(view); 103 104 // 调整dialog背景大小 105 // lLayout_bg.setLayoutParams(new FrameLayout.LayoutParams((int) (display 106 // .getWidth() * 0.85), LayoutParams.WRAP_CONTENT)); 107 // setCancelable(false); 108 return this; 109 } 110 /**设置标题*/ 111 public AlertDialog setTitle(String title) { 112 showTitle = true; 113 if ("".equals(title)) { 114 txt_title.setText(""); 115 } else { 116 txt_title.setText(title); 117 } 118 return this; 119 } 120 /**粒子效果时间——一次*/ 121 protected ConfettiManager generateOnce() { 122 return getCommonConfetti().oneShot(); 123 } 124 /**粒子效果时间——定义时长*/ 125 protected ConfettiManager generateStream() { 126 return getCommonConfetti().stream(1500); 127 } 128 /**粒子效果时间——持续*/ 129 protected ConfettiManager generateInfinite() { 130 return getCommonConfetti().infinite(); 131 } 132 /**粒子动画显示范围以及位置*/ 133 private CommonConfetti getCommonConfetti() { 134 WindowManager wm = (WindowManager) context 135 .getSystemService(Context.WINDOW_SERVICE); 136 137 int width = wm.getDefaultDisplay().getWidth()-120; 138 int height = wm.getDefaultDisplay().getHeight()-350; 139 final int centerX = width / 2; 140 final int centerY = height /2 ; 141 return CommonConfetti.explosion(container, centerX, centerY, colors); 142 } 143 /**标题字体大小*/ 144 public AlertDialog setTitleSize(float size) { 145 146 txt_title.setTextSize(size); 147 148 return this; 149 } 150 /**开启动画*/ 151 public AlertDialog setAnim(boolean cancel) { 152 153 if (cancel) { 154 generateStream(); 155 iv_icon_bg.setVisibility(View.VISIBLE); 156 Animation mAnimation = AnimationUtils.loadAnimation(context, R.anim.cart_anim); 157 iv_icon_bg.startAnimation(mAnimation); 158 mAnimation.setAnimationListener(new Animation.AnimationListener() { 159 @Override 160 public void onAnimationStart(Animation animation) { 161 162 } 163 164 @Override 165 public void onAnimationEnd(Animation animation) { 166 iv_icon_bg.setVisibility(View.INVISIBLE); 167 } 168 169 @Override 170 public void onAnimationRepeat(Animation animation) { 171 172 } 173 }); 174 } 175 176 return this; 177 } 178 /**设置内容字体大小*/ 179 public AlertDialog setMessageSize(float size) { 180 181 txt_msg.setTextSize(size); 182 183 return this; 184 } 185 /**设置内容*/ 186 public AlertDialog setMsg(CharSequence msg) { 187 showMsg = true; 188 if ("".equals(msg)) { 189 txt_msg.setText(""); 190 } else { 191 txt_msg.setText(msg); 192 } 193 return this; 194 } 195 /**设置点击屏幕或物理返回键dialog是否消失*/ 196 public AlertDialog setCancelable(boolean cancel) { 197 dialog.setCancelable(cancel); 198 return this; 199 } 200 201 public AlertDialog setPositiveButton(String text, 202 final OnClickListener listener) { 203 showPosBtn = true; 204 if ("".equals(text)) { 205 btn_pos.setText("确定"); 206 } else { 207 btn_pos.setText(text); 208 } 209 btn_pos.setOnClickListener(new OnClickListener() { 210 @Override 211 public void onClick(View v) { 212 listener.onClick(v); 213 dialog.dismiss(); 214 } 215 }); 216 return this; 217 } 218 219 public AlertDialog setNegativeButton(String text, final OnClickListener listener) { 220 showNegBtn = true; 221 if ("".equals(text)) { 222 btn_neg.setText("取消"); 223 } else { 224 btn_neg.setText(text); 225 } 226 btn_neg.setOnClickListener(new OnClickListener() { 227 @Override 228 public void onClick(View v) { 229 listener.onClick(v); 230 dialog.dismiss(); 231 } 232 }); 233 return this; 234 } 235 236 private void setLayout() { 237 if (!showTitle && !showMsg) { 238 txt_title.setText("提示"); 239 txt_title.setVisibility(View.VISIBLE); 240 } 241 242 if (showTitle) { 243 txt_title.setVisibility(View.VISIBLE); 244 } 245 246 if (showMsg) { 247 txt_msg.setVisibility(View.VISIBLE); 248 } 249 250 if (!showPosBtn && !showNegBtn) { 251 btn_pos.setText("确定"); 252 btn_pos.setVisibility(View.VISIBLE); 253 btn_pos.setBackgroundResource(R.drawable.alertdialog_single_selector); 254 btn_pos.setOnClickListener(new OnClickListener() { 255 @Override 256 public void onClick(View v) { 257 dialog.dismiss(); 258 } 259 }); 260 } 261 262 if (showPosBtn && showNegBtn) { 263 btn_pos.setVisibility(View.VISIBLE); 264 btn_pos.setBackgroundResource(R.drawable.alertdialog_right_selector); 265 btn_neg.setVisibility(View.VISIBLE); 266 btn_neg.setBackgroundResource(R.drawable.alertdialog_left_selector); 267 img_line.setVisibility(View.VISIBLE); 268 } 269 270 if (showPosBtn && !showNegBtn) { 271 btn_pos.setVisibility(View.VISIBLE); 272 btn_pos.setBackgroundResource(R.drawable.alertdialog_single_selector); 273 } 274 275 if (!showPosBtn && showNegBtn) { 276 btn_neg.setVisibility(View.VISIBLE); 277 btn_neg.setBackgroundResource(R.drawable.alertdialog_single_selector); 278 } 279 } 280 281 public void show() { 282 setLayout(); 283 dialog.show(); 284 } 285 }
大功告成。