GuideDialog.java 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841
  1. package com.kongzue.dialogx.dialogs;
  2. import android.app.Activity;
  3. import android.graphics.Bitmap;
  4. import android.graphics.Canvas;
  5. import android.graphics.Color;
  6. import android.graphics.Paint;
  7. import android.graphics.PorterDuff;
  8. import android.graphics.PorterDuffXfermode;
  9. import android.graphics.Rect;
  10. import android.graphics.RectF;
  11. import android.graphics.drawable.BitmapDrawable;
  12. import android.graphics.drawable.Drawable;
  13. import android.os.Build;
  14. import android.view.Gravity;
  15. import android.view.View;
  16. import android.view.ViewGroup;
  17. import android.widget.ImageView;
  18. import android.widget.RelativeLayout;
  19. import androidx.annotation.ColorInt;
  20. import com.kongzue.dialogx.DialogX;
  21. import com.kongzue.dialogx.R;
  22. import com.kongzue.dialogx.interfaces.DialogLifecycleCallback;
  23. import com.kongzue.dialogx.interfaces.DialogXAnimInterface;
  24. import com.kongzue.dialogx.interfaces.DialogXRunnable;
  25. import com.kongzue.dialogx.interfaces.DialogXStyle;
  26. import com.kongzue.dialogx.interfaces.OnBackPressedListener;
  27. import com.kongzue.dialogx.interfaces.OnBackgroundMaskClickListener;
  28. import com.kongzue.dialogx.interfaces.OnBindView;
  29. import com.kongzue.dialogx.interfaces.OnDialogButtonClickListener;
  30. import com.kongzue.dialogx.util.views.DialogXBaseRelativeLayout;
  31. import java.util.Arrays;
  32. import java.util.HashMap;
  33. /**
  34. * @author: Kongzue
  35. * @github: https://github.com/kongzue/
  36. * @homepage: http://kongzue.com/
  37. * @mail: myzcxhh@live.cn
  38. * @createTime: 2022/8/19 16:35
  39. */
  40. public class GuideDialog extends CustomDialog {
  41. public enum STAGE_LIGHT_TYPE {
  42. RECTANGLE, //矩形
  43. SQUARE_OUTSIDE, //方形(外围)
  44. SQUARE_INSIDE, //方形(内围)
  45. CIRCLE_OUTSIDE, //圆形(外围)
  46. CIRCLE_INSIDE, //圆形(内围)
  47. }
  48. protected STAGE_LIGHT_TYPE stageLightType = STAGE_LIGHT_TYPE.CIRCLE_OUTSIDE;
  49. protected Drawable tipImage;
  50. protected float stageLightFilletRadius; //舞台灯光部分的圆角
  51. protected Integer maskColor = null;
  52. protected OnDialogButtonClickListener<GuideDialog> onStageLightPathClickListener;
  53. protected int[] baseViewLocationCoordinateCompensation = new int[4];
  54. protected GuideDialog() {
  55. super();
  56. enterAnimResId = R.anim.anim_dialogx_alpha_enter;
  57. exitAnimResId = R.anim.anim_dialogx_default_exit;
  58. this.alignViewGravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
  59. }
  60. public static GuideDialog build() {
  61. return new GuideDialog();
  62. }
  63. public GuideDialog(View baseView, STAGE_LIGHT_TYPE stageLightType) {
  64. this();
  65. this.baseView(baseView);
  66. this.stageLightType = stageLightType;
  67. }
  68. public GuideDialog(View baseView, STAGE_LIGHT_TYPE stageLightType, OnBindView<CustomDialog> onBindView, int alignBaseViewGravity) {
  69. this();
  70. this.baseView(baseView);
  71. this.stageLightType = stageLightType;
  72. this.onBindView = onBindView;
  73. this.alignViewGravity = alignBaseViewGravity;
  74. }
  75. public GuideDialog(View baseView, STAGE_LIGHT_TYPE stageLightType, int tipImageResId, int alignBaseViewGravity) {
  76. this();
  77. this.baseView(baseView);
  78. this.tipImage = getResources().getDrawable(tipImageResId);
  79. this.stageLightType = stageLightType;
  80. this.alignViewGravity = alignBaseViewGravity;
  81. }
  82. public GuideDialog(View baseView, STAGE_LIGHT_TYPE stageLightType, Bitmap tipImage, int alignBaseViewGravity) {
  83. this();
  84. this.baseView(baseView);
  85. this.tipImage = new BitmapDrawable(getResources(), tipImage);
  86. this.stageLightType = stageLightType;
  87. this.alignViewGravity = alignBaseViewGravity;
  88. }
  89. public GuideDialog(View baseView, STAGE_LIGHT_TYPE stageLightType, Drawable tipImage, int alignBaseViewGravity) {
  90. this();
  91. this.baseView(baseView);
  92. this.tipImage = tipImage;
  93. this.stageLightType = stageLightType;
  94. this.alignViewGravity = alignBaseViewGravity;
  95. }
  96. public GuideDialog(int tipImageResId) {
  97. this();
  98. this.tipImage = getResources().getDrawable(tipImageResId);
  99. }
  100. public GuideDialog(Bitmap tipImage) {
  101. this();
  102. this.tipImage = new BitmapDrawable(getResources(), tipImage);
  103. }
  104. public GuideDialog(Drawable tipImage) {
  105. this();
  106. this.tipImage = tipImage;
  107. }
  108. public GuideDialog(int tipImageResId, ALIGN align) {
  109. this();
  110. this.tipImage = getResources().getDrawable(tipImageResId);
  111. this.align = align;
  112. }
  113. public GuideDialog(Bitmap tipImage, ALIGN align) {
  114. this();
  115. this.tipImage = new BitmapDrawable(getResources(), tipImage);
  116. this.align = align;
  117. }
  118. public GuideDialog(Drawable tipImage, ALIGN align) {
  119. this();
  120. this.tipImage = tipImage;
  121. this.align = align;
  122. }
  123. public GuideDialog(OnBindView<CustomDialog> onBindView) {
  124. this();
  125. this.onBindView = onBindView;
  126. }
  127. public GuideDialog(OnBindView<CustomDialog> onBindView, ALIGN align) {
  128. this();
  129. this.onBindView = onBindView;
  130. this.align = align;
  131. }
  132. public GuideDialog(View baseView, int tipImageResId) {
  133. this();
  134. this.baseView(baseView);
  135. this.tipImage = getResources().getDrawable(tipImageResId);
  136. }
  137. public GuideDialog(View baseView, Bitmap tipImage) {
  138. this();
  139. this.baseView(baseView);
  140. this.tipImage = new BitmapDrawable(getResources(), tipImage);
  141. }
  142. public GuideDialog(View baseView, Drawable tipImage) {
  143. this();
  144. this.baseView(baseView);
  145. this.tipImage = tipImage;
  146. }
  147. public GuideDialog(View baseView, STAGE_LIGHT_TYPE stageLightType, int tipImageResId) {
  148. this();
  149. this.baseView(baseView);
  150. this.stageLightType = stageLightType;
  151. this.tipImage = getResources().getDrawable(tipImageResId);
  152. }
  153. public GuideDialog(View baseView, STAGE_LIGHT_TYPE stageLightType, Bitmap tipImage) {
  154. this();
  155. this.baseView(baseView);
  156. this.stageLightType = stageLightType;
  157. this.tipImage = new BitmapDrawable(getResources(), tipImage);
  158. }
  159. public GuideDialog(View baseView, STAGE_LIGHT_TYPE stageLightType, Drawable tipImage) {
  160. this();
  161. this.baseView(baseView);
  162. this.stageLightType = stageLightType;
  163. this.tipImage = tipImage;
  164. }
  165. public GuideDialog(View baseView, int tipImageResId, int alignBaseViewGravity) {
  166. this();
  167. this.baseView(baseView);
  168. this.alignViewGravity = alignBaseViewGravity;
  169. this.tipImage = getResources().getDrawable(tipImageResId);
  170. }
  171. public GuideDialog(View baseView, Bitmap tipImage, int alignBaseViewGravity) {
  172. this();
  173. this.baseView(baseView);
  174. this.alignViewGravity = alignBaseViewGravity;
  175. this.tipImage = new BitmapDrawable(getResources(), tipImage);
  176. }
  177. public GuideDialog(View baseView, Drawable tipImage, int alignBaseViewGravity) {
  178. this();
  179. this.baseView(baseView);
  180. this.alignViewGravity = alignBaseViewGravity;
  181. this.tipImage = tipImage;
  182. }
  183. //静态方法
  184. public static GuideDialog show(OnBindView<CustomDialog> onBindView) {
  185. GuideDialog guideDialog = new GuideDialog(onBindView);
  186. guideDialog.show();
  187. return guideDialog;
  188. }
  189. public static GuideDialog show(OnBindView<CustomDialog> onBindView, ALIGN align) {
  190. GuideDialog guideDialog = new GuideDialog(onBindView);
  191. guideDialog.align = align;
  192. guideDialog.show();
  193. return guideDialog;
  194. }
  195. public static GuideDialog show(int tipImageResId) {
  196. return new GuideDialog(tipImageResId).show();
  197. }
  198. public static GuideDialog show(Bitmap tipImage) {
  199. return new GuideDialog(tipImage).show();
  200. }
  201. public static GuideDialog show(Drawable tipImage) {
  202. return new GuideDialog(tipImage).show();
  203. }
  204. public static GuideDialog show(int tipImageResId, ALIGN align) {
  205. GuideDialog guideDialog = new GuideDialog(tipImageResId, align);
  206. guideDialog.align = align;
  207. return guideDialog.show();
  208. }
  209. public static GuideDialog show(Bitmap tipImage, ALIGN align) {
  210. GuideDialog guideDialog = new GuideDialog(tipImage, align);
  211. guideDialog.align = align;
  212. return guideDialog.show();
  213. }
  214. public static GuideDialog show(Drawable tipImage, ALIGN align) {
  215. return new GuideDialog(tipImage, align).show();
  216. }
  217. public static GuideDialog show(View baseView, STAGE_LIGHT_TYPE stageLightType) {
  218. return new GuideDialog(baseView, stageLightType).show();
  219. }
  220. public static GuideDialog show(View baseView, STAGE_LIGHT_TYPE stageLightType, OnBindView<CustomDialog> onBindView, int alignBaseViewGravity) {
  221. return new GuideDialog(baseView, stageLightType, onBindView, alignBaseViewGravity).show();
  222. }
  223. public static GuideDialog show(View baseView, STAGE_LIGHT_TYPE stageLightType, int tipImageResId, int alignBaseViewGravity) {
  224. return new GuideDialog(baseView, stageLightType, tipImageResId, alignBaseViewGravity).show();
  225. }
  226. public static GuideDialog show(View baseView, STAGE_LIGHT_TYPE stageLightType, Bitmap tipImage, int alignBaseViewGravity) {
  227. return new GuideDialog(baseView, stageLightType, tipImage, alignBaseViewGravity).show();
  228. }
  229. public static GuideDialog show(View baseView, STAGE_LIGHT_TYPE stageLightType, Drawable tipImage, int alignBaseViewGravity) {
  230. return new GuideDialog(baseView, stageLightType, tipImage, alignBaseViewGravity).show();
  231. }
  232. public static GuideDialog show(View baseView, int tipImageResId) {
  233. return new GuideDialog(baseView, tipImageResId).show();
  234. }
  235. public static GuideDialog show(View baseView, Bitmap tipImage) {
  236. return new GuideDialog(baseView, tipImage).show();
  237. }
  238. public static GuideDialog show(View baseView, Drawable tipImage) {
  239. return new GuideDialog(baseView, tipImage).show();
  240. }
  241. public static GuideDialog show(View baseView, STAGE_LIGHT_TYPE stageLightType, int tipImageResId) {
  242. return new GuideDialog(baseView, stageLightType, tipImageResId).show();
  243. }
  244. public static GuideDialog show(View baseView, STAGE_LIGHT_TYPE stageLightType, Bitmap tipImage) {
  245. return new GuideDialog(baseView, stageLightType, tipImage).show();
  246. }
  247. public static GuideDialog show(View baseView, STAGE_LIGHT_TYPE stageLightType, Drawable tipImage) {
  248. return new GuideDialog(baseView, stageLightType, tipImage).show();
  249. }
  250. public static GuideDialog show(View baseView, int tipImageResId, int alignBaseViewGravity) {
  251. return new GuideDialog(baseView, tipImageResId, alignBaseViewGravity).show();
  252. }
  253. public static GuideDialog show(View baseView, Bitmap tipImage, int alignBaseViewGravity) {
  254. return new GuideDialog(baseView, tipImage, alignBaseViewGravity).show();
  255. }
  256. public static GuideDialog show(View baseView, Drawable tipImage, int alignBaseViewGravity) {
  257. return new GuideDialog(baseView, tipImage, alignBaseViewGravity).show();
  258. }
  259. //执行方法
  260. public GuideDialog show() {
  261. super.show();
  262. return this;
  263. }
  264. public GuideDialog show(Activity activity) {
  265. super.show(activity);
  266. return this;
  267. }
  268. @Override
  269. public String dialogKey() {
  270. return getClass().getSimpleName() + "(" + Integer.toHexString(hashCode()) + ")";
  271. }
  272. public GuideDialog setDialogLifecycleCallback(DialogLifecycleCallback<CustomDialog> dialogLifecycleCallback) {
  273. this.dialogLifecycleCallback = dialogLifecycleCallback;
  274. if (isShow) dialogLifecycleCallback.onShow(me);
  275. return this;
  276. }
  277. public GuideDialog setOnBackPressedListener(OnBackPressedListener<CustomDialog> onBackPressedListener) {
  278. this.onBackPressedListener = onBackPressedListener;
  279. refreshUI();
  280. return this;
  281. }
  282. public GuideDialog setStyle(DialogXStyle style) {
  283. this.style = style;
  284. return this;
  285. }
  286. public GuideDialog setTheme(DialogX.THEME theme) {
  287. this.theme = theme;
  288. return this;
  289. }
  290. public GuideDialog setCancelable(boolean cancelable) {
  291. this.privateCancelable = cancelable ? BOOLEAN.TRUE : BOOLEAN.FALSE;
  292. refreshUI();
  293. return this;
  294. }
  295. public GuideDialog.DialogImpl getDialogImpl() {
  296. return dialogImpl;
  297. }
  298. public GuideDialog setCustomView(OnBindView<CustomDialog> onBindView) {
  299. this.onBindView = onBindView;
  300. refreshUI();
  301. return this;
  302. }
  303. public GuideDialog removeCustomView() {
  304. this.onBindView.clean();
  305. refreshUI();
  306. return this;
  307. }
  308. public GuideDialog setEnterAnimResId(int enterAnimResId) {
  309. this.enterAnimResId = enterAnimResId;
  310. return this;
  311. }
  312. public GuideDialog setExitAnimResId(int exitAnimResId) {
  313. this.exitAnimResId = exitAnimResId;
  314. return this;
  315. }
  316. public GuideDialog setAnimResId(int enterAnimResId, int exitAnimResId) {
  317. this.enterAnimResId = enterAnimResId;
  318. this.exitAnimResId = exitAnimResId;
  319. return this;
  320. }
  321. public GuideDialog setAlign(ALIGN align) {
  322. this.align = align;
  323. return this;
  324. }
  325. public GuideDialog setAutoUnsafePlacePadding(boolean autoUnsafePlacePadding) {
  326. super.setAutoUnsafePlacePadding(autoUnsafePlacePadding);
  327. return this;
  328. }
  329. public GuideDialog setFullScreen(boolean fullscreen) {
  330. super.setFullScreen(fullscreen);
  331. return this;
  332. }
  333. public GuideDialog setMaskColor(@ColorInt int maskColor) {
  334. this.maskColor = maskColor;
  335. refreshUI();
  336. return this;
  337. }
  338. public GuideDialog setEnterAnimDuration(long enterAnimDuration) {
  339. this.enterAnimDuration = enterAnimDuration;
  340. return this;
  341. }
  342. public GuideDialog setExitAnimDuration(long exitAnimDuration) {
  343. this.exitAnimDuration = exitAnimDuration;
  344. return this;
  345. }
  346. public GuideDialog setDialogImplMode(DialogX.IMPL_MODE dialogImplMode) {
  347. this.dialogImplMode = dialogImplMode;
  348. return this;
  349. }
  350. public GuideDialog setBkgInterceptTouch(boolean bkgInterceptTouch) {
  351. this.bkgInterceptTouch = bkgInterceptTouch;
  352. return this;
  353. }
  354. public GuideDialog setAlignBaseViewGravity(View baseView, int alignGravity) {
  355. this.baseView(baseView);
  356. this.alignViewGravity = alignGravity;
  357. baseViewLoc = new int[4];
  358. baseView.getLocationInWindow(baseViewLoc);
  359. setFullScreen(true);
  360. return this;
  361. }
  362. public GuideDialog setAlignBaseViewGravity(View baseView) {
  363. this.baseView(baseView);
  364. baseViewLoc = new int[4];
  365. baseView.getLocationInWindow(baseViewLoc);
  366. setFullScreen(true);
  367. return this;
  368. }
  369. public GuideDialog setAlignBaseViewGravity(int alignGravity) {
  370. this.alignViewGravity = alignGravity;
  371. if (baseView() != null) {
  372. baseViewLoc = new int[4];
  373. baseView().getLocationInWindow(baseViewLoc);
  374. }
  375. setFullScreen(true);
  376. return this;
  377. }
  378. public GuideDialog setAlignBaseViewGravity(View baseView, int alignGravity, int marginLeft,
  379. int marginTop, int marginRight, int marginBottom) {
  380. this.marginRelativeBaseView = new int[]{marginLeft, marginTop, marginRight, marginBottom};
  381. return setAlignBaseViewGravity(baseView, alignGravity);
  382. }
  383. public GuideDialog setBaseViewMargin(int[] marginRelativeBaseView) {
  384. this.marginRelativeBaseView = marginRelativeBaseView;
  385. return this;
  386. }
  387. public GuideDialog setBaseViewMargin(int marginLeft, int marginTop,
  388. int marginRight, int marginBottom) {
  389. this.marginRelativeBaseView = new int[]{marginLeft, marginTop, marginRight, marginBottom};
  390. return this;
  391. }
  392. public GuideDialog setBaseViewMarginLeft(int marginLeft) {
  393. this.marginRelativeBaseView[0] = marginLeft;
  394. return this;
  395. }
  396. public GuideDialog setBaseViewMarginTop(int marginTop) {
  397. this.marginRelativeBaseView[1] = marginTop;
  398. return this;
  399. }
  400. public GuideDialog setBaseViewMarginRight(int marginRight) {
  401. this.marginRelativeBaseView[2] = marginRight;
  402. return this;
  403. }
  404. public GuideDialog setBaseViewMarginBottom(int marginBottom) {
  405. this.marginRelativeBaseView[3] = marginBottom;
  406. return this;
  407. }
  408. /**
  409. * 设置对话框 UI 宽度(单位:像素)
  410. *
  411. * @param width 宽度(像素)
  412. * @return CustomDialog实例
  413. */
  414. public GuideDialog setWidth(int width) {
  415. this.width = width;
  416. refreshUI();
  417. return this;
  418. }
  419. /**
  420. * 设置对话框 UI 高度(单位:像素)
  421. *
  422. * @param height 高度(像素)
  423. * @return CustomDialog实例
  424. */
  425. public GuideDialog setHeight(int height) {
  426. this.height = height;
  427. refreshUI();
  428. return this;
  429. }
  430. public GuideDialog setOnBackgroundMaskClickListener(OnBackgroundMaskClickListener<CustomDialog> onBackgroundMaskClickListener) {
  431. this.onBackgroundMaskClickListener = onBackgroundMaskClickListener;
  432. return this;
  433. }
  434. @Override
  435. protected void onDialogShow() {
  436. super.onDialogShow();
  437. if (baseView() == null) {
  438. super.setMaskColor(maskColor == null ? getColor(R.color.black50) : maskColor);
  439. }
  440. }
  441. View stageLightPathStub;
  442. @Override
  443. protected void onDialogRefreshUI() {
  444. super.onDialogRefreshUI();
  445. if (onBindView == null && tipImage != null) {
  446. getDialogImpl().boxCustom.setFocusable(false);
  447. getDialogImpl().boxCustom.setFocusableInTouchMode(false);
  448. getDialogImpl().boxCustom.setOnClickListener(null);
  449. getDialogImpl().boxCustom.setClickable(false);
  450. ImageView imageView = new ImageView(getOwnActivity());
  451. imageView.setImageDrawable(tipImage);
  452. imageView.setAdjustViewBounds(true);
  453. imageView.setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
  454. onBindView = new OnBindView<CustomDialog>(imageView) {
  455. @Override
  456. public void onBind(CustomDialog dialog, View v) {
  457. }
  458. };
  459. onBindView.bindParent(getDialogImpl().boxCustom, me);
  460. }
  461. if (getOnStageLightPathClickListener() != null && baseView() != null) {
  462. stageLightPathStub = new View(getOwnActivity());
  463. stageLightPathStub.setOnClickListener(new View.OnClickListener() {
  464. @Override
  465. public void onClick(View v) {
  466. if (!getOnStageLightPathClickListener().onClick(GuideDialog.this, v)) {
  467. dismiss();
  468. }
  469. }
  470. });
  471. getDialogImpl().boxRoot.addView(stageLightPathStub);
  472. } else {
  473. if (stageLightPathStub != null && stageLightPathStub.getParent() instanceof ViewGroup) {
  474. ((ViewGroup) stageLightPathStub.getParent()).removeView(stageLightPathStub);
  475. }
  476. }
  477. }
  478. int[] baseViewLocCache;
  479. @Override
  480. protected void onGetBaseViewLoc(int[] baseViewLoc) {
  481. if (Arrays.equals(baseViewLoc, baseViewLocCache)) {
  482. return;
  483. }
  484. if (getDialogImpl() == null) {
  485. return;
  486. }
  487. Bitmap bkg = Bitmap.createBitmap(getDialogImpl().boxRoot.getWidth(), getDialogImpl().boxRoot.getHeight(), Bitmap.Config.ARGB_8888);
  488. Canvas canvas = new Canvas(bkg);
  489. int x = baseViewLoc[0] + baseViewLocationCoordinateCompensation[0];
  490. int y = baseViewLoc[1] + baseViewLocationCoordinateCompensation[1];
  491. int w = baseViewLoc[2] + baseViewLocationCoordinateCompensation[2];
  492. int h = baseViewLoc[3] + baseViewLocationCoordinateCompensation[3];
  493. int hW = w / 2;
  494. int hH = h / 2;
  495. if (stageLightPathStub != null && (stageLightPathStub.getX() != x || stageLightPathStub.getY() != y)) {
  496. RelativeLayout.LayoutParams rLp = (RelativeLayout.LayoutParams) stageLightPathStub.getLayoutParams();
  497. if (rLp == null) {
  498. rLp = new RelativeLayout.LayoutParams(w, h);
  499. } else {
  500. rLp.width = w;
  501. rLp.height = h;
  502. }
  503. stageLightPathStub.setLayoutParams(rLp);
  504. stageLightPathStub.setX(x);
  505. stageLightPathStub.setY(y);
  506. }
  507. switch (stageLightType) {
  508. case CIRCLE_OUTSIDE: {
  509. int r = (int) Math.sqrt(hW * hW + hH * hH);
  510. canvas.drawCircle(x + hW, y + hH, r, getStageLightPaint());
  511. }
  512. break;
  513. case CIRCLE_INSIDE: {
  514. int r = Math.min(w, h) / 2;
  515. canvas.drawCircle(x + hW, y + hH, r, getStageLightPaint());
  516. }
  517. break;
  518. case RECTANGLE: {
  519. canvas.drawRoundRect(new RectF(x, y, x + w, y + h), stageLightFilletRadius, stageLightFilletRadius, getStageLightPaint());
  520. }
  521. break;
  522. case SQUARE_INSIDE: {
  523. int r = Math.min(w, h);
  524. canvas.drawRoundRect(new RectF(x + hW - r / 2, y + hH - r / 2, x + hW - r / 2 + r, y + hH - r / 2 + r), stageLightFilletRadius, stageLightFilletRadius, getStageLightPaint());
  525. }
  526. break;
  527. case SQUARE_OUTSIDE: {
  528. int r = Math.max(w, h);
  529. canvas.drawRoundRect(new RectF(x + hW - r / 2, y + hH - r / 2, x + hW - r / 2 + r, y + hH - r / 2 + r), stageLightFilletRadius, stageLightFilletRadius, getStageLightPaint());
  530. }
  531. break;
  532. }
  533. stageLightPaint.setXfermode(null);
  534. canvas.drawColor(maskColor == null ? getColor(R.color.black50) : maskColor, PorterDuff.Mode.SRC_OUT);
  535. BitmapDrawable bkgDrawable = new BitmapDrawable(getResources(), bkg);
  536. getDialogImpl().boxRoot.setBackground(bkgDrawable);
  537. baseViewLocCache = Arrays.copyOf(baseViewLoc, 4);
  538. }
  539. Paint stageLightPaint;
  540. private Paint getStageLightPaint() {
  541. if (stageLightPaint == null) {
  542. stageLightPaint = new Paint();
  543. stageLightPaint.setColor(Color.RED);
  544. stageLightPaint.setStyle(Paint.Style.FILL);
  545. stageLightPaint.setAntiAlias(true);
  546. }
  547. return stageLightPaint;
  548. }
  549. public STAGE_LIGHT_TYPE getStageLightType() {
  550. return stageLightType;
  551. }
  552. public GuideDialog setStageLightType(STAGE_LIGHT_TYPE stageLightType) {
  553. this.stageLightType = stageLightType;
  554. refreshUI();
  555. return this;
  556. }
  557. public Drawable getTipImage() {
  558. return tipImage;
  559. }
  560. public GuideDialog setTipImage(int tipImageResId) {
  561. this.tipImage = getResources().getDrawable(tipImageResId);
  562. refreshUI();
  563. return this;
  564. }
  565. public GuideDialog setTipImage(Bitmap tipImage) {
  566. this.tipImage = new BitmapDrawable(getResources(), tipImage);
  567. refreshUI();
  568. return this;
  569. }
  570. public GuideDialog setTipImage(Drawable tipImage) {
  571. this.tipImage = tipImage;
  572. refreshUI();
  573. return this;
  574. }
  575. public float getStageLightFilletRadius() {
  576. return stageLightFilletRadius;
  577. }
  578. public GuideDialog setStageLightFilletRadius(float stageLightFilletRadius) {
  579. this.stageLightFilletRadius = stageLightFilletRadius;
  580. refreshUI();
  581. return this;
  582. }
  583. public OnDialogButtonClickListener<GuideDialog> getOnStageLightPathClickListener() {
  584. return onStageLightPathClickListener;
  585. }
  586. public GuideDialog setOnStageLightPathClickListener(OnDialogButtonClickListener<GuideDialog> onStageLightPathClickListener) {
  587. this.onStageLightPathClickListener = onStageLightPathClickListener;
  588. refreshUI();
  589. return this;
  590. }
  591. public DialogXAnimInterface<CustomDialog> getDialogXAnimImpl() {
  592. return dialogXAnimImpl;
  593. }
  594. public GuideDialog setDialogXAnimImpl(DialogXAnimInterface<CustomDialog> dialogXAnimImpl) {
  595. this.dialogXAnimImpl = dialogXAnimImpl;
  596. return this;
  597. }
  598. public GuideDialog setRootPadding(int padding) {
  599. this.screenPaddings = new int[]{padding, padding, padding, padding};
  600. refreshUI();
  601. return this;
  602. }
  603. public GuideDialog setRootPadding(int paddingLeft, int paddingTop, int paddingRight, int paddingBottom) {
  604. this.screenPaddings = new int[]{paddingLeft, paddingTop, paddingRight, paddingBottom};
  605. refreshUI();
  606. return this;
  607. }
  608. public int[] getBaseViewLocationCoordinateCompensation() {
  609. return baseViewLocationCoordinateCompensation;
  610. }
  611. public GuideDialog setBaseViewLocationCoordinateCompensation(int[] baseViewLocationCoordinateCompensation) {
  612. this.baseViewLocationCoordinateCompensation = baseViewLocationCoordinateCompensation;
  613. return this;
  614. }
  615. public GuideDialog setBaseViewLocationCoordinateCompensation(int px) {
  616. this.baseViewLocationCoordinateCompensation = new int[]{px, px, px, px};
  617. refreshUI();
  618. return this;
  619. }
  620. public GuideDialog setBaseViewLocationCoordinateCompensation(int pxX, int pxY, int pxR, int pxB) {
  621. this.baseViewLocationCoordinateCompensation = new int[]{pxX, pxY, pxR, pxB};
  622. refreshUI();
  623. return this;
  624. }
  625. public GuideDialog setBaseViewLocationCoordinateCompensationLeft(int pxX) {
  626. this.baseViewLocationCoordinateCompensation[0] = pxX;
  627. refreshUI();
  628. return this;
  629. }
  630. public GuideDialog setBaseViewLocationCoordinateCompensationTop(int pxY) {
  631. this.baseViewLocationCoordinateCompensation[1] = pxY;
  632. refreshUI();
  633. return this;
  634. }
  635. public GuideDialog setBaseViewLocationCoordinateCompensationRight(int pxR) {
  636. this.baseViewLocationCoordinateCompensation[2] = pxR;
  637. refreshUI();
  638. return this;
  639. }
  640. public GuideDialog setBaseViewLocationCoordinateCompensationBottom(int pxB) {
  641. this.baseViewLocationCoordinateCompensation[3] = pxB;
  642. refreshUI();
  643. return this;
  644. }
  645. public int getBaseViewLocationCoordinateCompensationLeft() {
  646. return baseViewLocationCoordinateCompensation[0];
  647. }
  648. public int getBaseViewLocationCoordinateCompensationTop() {
  649. return baseViewLocationCoordinateCompensation[1];
  650. }
  651. public int getBaseViewLocationCoordinateCompensationRight() {
  652. return baseViewLocationCoordinateCompensation[2];
  653. }
  654. public int getBaseViewLocationCoordinateCompensationBottom() {
  655. return baseViewLocationCoordinateCompensation[3];
  656. }
  657. public GuideDialog setData(String key, Object obj) {
  658. if (data == null) data = new HashMap<>();
  659. data.put(key, obj);
  660. return this;
  661. }
  662. public GuideDialog onShow(DialogXRunnable<CustomDialog> dialogXRunnable) {
  663. onShowRunnable = dialogXRunnable;
  664. if (isShow() && onShowRunnable != null) {
  665. onShowRunnable.run(this);
  666. }
  667. return this;
  668. }
  669. public GuideDialog onDismiss(DialogXRunnable<CustomDialog> dialogXRunnable) {
  670. onDismissRunnable = dialogXRunnable;
  671. return this;
  672. }
  673. public GuideDialog setEnableImmersiveMode(boolean enableImmersiveMode) {
  674. this.enableImmersiveMode = enableImmersiveMode;
  675. refreshUI();
  676. return this;
  677. }
  678. public GuideDialog setThisOrderIndex(int orderIndex) {
  679. this.thisOrderIndex = orderIndex;
  680. if (getDialogView() != null) {
  681. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  682. getDialogView().setTranslationZ(orderIndex);
  683. } else {
  684. error("DialogX: " + dialogKey() + " 执行 .setThisOrderIndex("+orderIndex+") 失败:系统不支持此方法,SDK-API 版本必须大于 21(LOLLIPOP)");
  685. }
  686. }
  687. return this;
  688. }
  689. public GuideDialog bringToFront() {
  690. setThisOrderIndex(getHighestOrderIndex());
  691. return this;
  692. }
  693. public GuideDialog setActionRunnable(int actionId, DialogXRunnable<CustomDialog> runnable) {
  694. dialogActionRunnableMap.put(actionId, runnable);
  695. return this;
  696. }
  697. public GuideDialog cleanAction(int actionId){
  698. dialogActionRunnableMap.remove(actionId);
  699. return this;
  700. }
  701. public GuideDialog cleanAllAction(){
  702. dialogActionRunnableMap.clear();
  703. return this;
  704. }
  705. }