PopMenu.java 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308
  1. package com.kongzue.dialogx.dialogs;
  2. import static android.view.View.GONE;
  3. import static android.view.View.OVER_SCROLL_NEVER;
  4. import static android.view.View.VISIBLE;
  5. import android.animation.ValueAnimator;
  6. import android.graphics.Outline;
  7. import android.graphics.drawable.GradientDrawable;
  8. import android.os.Build;
  9. import android.text.TextUtils;
  10. import android.view.Gravity;
  11. import android.view.View;
  12. import android.view.ViewGroup;
  13. import android.view.ViewOutlineProvider;
  14. import android.view.ViewTreeObserver;
  15. import android.view.animation.AccelerateInterpolator;
  16. import android.view.animation.Animation;
  17. import android.view.animation.AnimationUtils;
  18. import android.view.animation.DecelerateInterpolator;
  19. import android.view.animation.Transformation;
  20. import android.widget.AdapterView;
  21. import android.widget.RelativeLayout;
  22. import android.widget.TextView;
  23. import androidx.annotation.Nullable;
  24. import androidx.lifecycle.Lifecycle;
  25. import com.kongzue.dialogx.DialogX;
  26. import com.kongzue.dialogx.R;
  27. import com.kongzue.dialogx.interfaces.BaseDialog;
  28. import com.kongzue.dialogx.interfaces.BlurViewType;
  29. import com.kongzue.dialogx.interfaces.DialogConvertViewInterface;
  30. import com.kongzue.dialogx.interfaces.DialogLifecycleCallback;
  31. import com.kongzue.dialogx.interfaces.DialogXAnimInterface;
  32. import com.kongzue.dialogx.interfaces.DialogXStyle;
  33. import com.kongzue.dialogx.interfaces.MenuItemLayoutRefreshCallback;
  34. import com.kongzue.dialogx.interfaces.OnBackPressedListener;
  35. import com.kongzue.dialogx.interfaces.OnBackgroundMaskClickListener;
  36. import com.kongzue.dialogx.interfaces.OnBindView;
  37. import com.kongzue.dialogx.interfaces.OnIconChangeCallBack;
  38. import com.kongzue.dialogx.interfaces.OnMenuItemClickListener;
  39. import com.kongzue.dialogx.util.DialogXViewLoc;
  40. import com.kongzue.dialogx.util.PopMenuArrayAdapter;
  41. import com.kongzue.dialogx.util.TextInfo;
  42. import com.kongzue.dialogx.util.views.DialogXBaseRelativeLayout;
  43. import com.kongzue.dialogx.util.views.MaxRelativeLayout;
  44. import com.kongzue.dialogx.util.views.PopMenuListView;
  45. import java.lang.ref.WeakReference;
  46. import java.util.ArrayList;
  47. import java.util.Arrays;
  48. import java.util.List;
  49. /**
  50. * @author: Kongzue
  51. * @github: https://github.com/kongzue/
  52. * @homepage: http://kongzue.com/
  53. * @mail: myzcxhh@live.cn
  54. * @createTime: 2021/8/18 14:27
  55. */
  56. public class PopMenu extends BaseDialog {
  57. public static long overrideEnterDuration = -1;
  58. public static long overrideExitDuration = -1;
  59. protected PopMenu me = this;
  60. protected boolean bkgInterceptTouch = true;
  61. protected OnBindView<PopMenu> onBindView; //自定义布局
  62. protected DialogLifecycleCallback<PopMenu> dialogLifecycleCallback; //对话框生命周期
  63. protected OnBackgroundMaskClickListener<PopMenu> onBackgroundMaskClickListener;
  64. protected List<CharSequence> menuList;
  65. protected DialogImpl dialogImpl;
  66. protected WeakReference<View> baseViewWeakReference;
  67. protected boolean overlayBaseView = true; //允许菜单覆盖在 baseView 上
  68. protected OnMenuItemClickListener<PopMenu> onMenuItemClickListener;
  69. protected OnIconChangeCallBack<PopMenu> onIconChangeCallBack; //设置图标
  70. protected int width = -1; //指定菜单宽度
  71. protected int height = -1; //指定菜单高度
  72. protected TextInfo menuTextInfo;
  73. protected boolean offScreen = false; //超出屏幕
  74. protected float backgroundRadius = -1;
  75. protected DialogXAnimInterface<PopMenu> dialogXAnimImpl;
  76. protected OnBackPressedListener<PopMenu> onBackPressedListener;
  77. protected MenuItemLayoutRefreshCallback<PopMenu> menuMenuItemLayoutRefreshCallback;
  78. protected int pressedIndex = -1;
  79. protected int alignGravity = -1; //指定菜单相对 baseView 的位置
  80. //记录 baseView 位置
  81. protected DialogXViewLoc baseViewLoc = new DialogXViewLoc();
  82. private int selectIndex;
  83. public PopMenu() {
  84. super();
  85. }
  86. public PopMenu(View baseView, List<CharSequence> menuList) {
  87. this.menuList = new ArrayList<>();
  88. this.menuList.addAll(menuList);
  89. this.baseView(baseView);
  90. }
  91. public PopMenu(View baseView, CharSequence[] menuList) {
  92. this.menuList = new ArrayList<>();
  93. this.menuList.addAll(Arrays.asList(menuList));
  94. this.baseView(baseView);
  95. }
  96. public PopMenu(List<CharSequence> menuList) {
  97. this.menuList = new ArrayList<>();
  98. this.menuList.addAll(menuList);
  99. }
  100. public PopMenu(CharSequence[] menuList) {
  101. this.menuList = new ArrayList<>();
  102. this.menuList.addAll(Arrays.asList(menuList));
  103. }
  104. public PopMenu(OnBindView<PopMenu> onBindView) {
  105. this.onBindView = onBindView;
  106. }
  107. public PopMenu(View baseView, OnBindView<PopMenu> onBindView) {
  108. this.baseView(baseView);
  109. this.onBindView = onBindView;
  110. }
  111. public PopMenu(View baseView, List<CharSequence> menuList, OnBindView<PopMenu> onBindView) {
  112. this.baseView(baseView);
  113. this.menuList = new ArrayList<>();
  114. this.menuList.addAll(menuList);
  115. this.onBindView = onBindView;
  116. }
  117. public PopMenu(View baseView, CharSequence[] menuList, OnBindView<PopMenu> onBindView) {
  118. this.baseView(baseView);
  119. this.menuList = new ArrayList<>();
  120. this.menuList.addAll(Arrays.asList(menuList));
  121. this.onBindView = onBindView;
  122. }
  123. public PopMenu(List<CharSequence> menuList, OnBindView<PopMenu> onBindView) {
  124. this.menuList = new ArrayList<>();
  125. this.menuList.addAll(menuList);
  126. this.onBindView = onBindView;
  127. }
  128. public PopMenu(CharSequence[] menuList, OnBindView<PopMenu> onBindView) {
  129. this.menuList = new ArrayList<>();
  130. this.menuList.addAll(Arrays.asList(menuList));
  131. this.onBindView = onBindView;
  132. }
  133. public static PopMenu build() {
  134. return new PopMenu();
  135. }
  136. public static PopMenu build(DialogXStyle style) {
  137. return new PopMenu().setStyle(style);
  138. }
  139. public static PopMenu show(CharSequence[] menus) {
  140. PopMenu popMenu = new PopMenu(menus);
  141. popMenu.show();
  142. return popMenu;
  143. }
  144. public static PopMenu show(List<CharSequence> menuList) {
  145. PopMenu popMenu = new PopMenu(menuList);
  146. popMenu.show();
  147. return popMenu;
  148. }
  149. public static PopMenu show(View baseView, CharSequence[] menus) {
  150. PopMenu popMenu = new PopMenu(baseView, menus);
  151. popMenu.show();
  152. return popMenu;
  153. }
  154. public static PopMenu show(View baseView, List<CharSequence> menuList) {
  155. PopMenu popMenu = new PopMenu(baseView, menuList);
  156. popMenu.show();
  157. return popMenu;
  158. }
  159. public static PopMenu show(View baseView, CharSequence[] menus, OnBindView<PopMenu> onBindView) {
  160. PopMenu popMenu = new PopMenu(baseView, menus, onBindView);
  161. popMenu.show();
  162. return popMenu;
  163. }
  164. public static PopMenu show(View baseView, List<CharSequence> menuList, OnBindView<PopMenu> onBindView) {
  165. PopMenu popMenu = new PopMenu(baseView, menuList, onBindView);
  166. popMenu.show();
  167. return popMenu;
  168. }
  169. public static PopMenu show(CharSequence[] menus, OnBindView<PopMenu> onBindView) {
  170. PopMenu popMenu = new PopMenu(menus, onBindView);
  171. popMenu.show();
  172. return popMenu;
  173. }
  174. public static PopMenu show(List<CharSequence> menuList, OnBindView<PopMenu> onBindView) {
  175. PopMenu popMenu = new PopMenu(menuList, onBindView);
  176. popMenu.show();
  177. return popMenu;
  178. }
  179. private ViewTreeObserver viewTreeObserver;
  180. private ViewTreeObserver.OnDrawListener baseViewDrawListener;
  181. public PopMenu show() {
  182. if (isHide && getDialogView() != null && isShow) {
  183. if (hideWithExitAnim && getDialogImpl() != null) {
  184. getDialogImpl().boxBody.clearAnimation();
  185. getDialogView().setVisibility(View.VISIBLE);
  186. getDialogImpl().boxRoot.animate().alpha(1f);
  187. getDialogImpl().getDialogXAnimImpl().doShowAnim(me, getDialogImpl().boxBody);
  188. } else {
  189. getDialogView().setVisibility(View.VISIBLE);
  190. }
  191. return this;
  192. }
  193. super.beforeShow();
  194. if (getDialogView() == null) {
  195. int layoutId = isLightTheme() ? R.layout.layout_dialogx_popmenu_material : R.layout.layout_dialogx_popmenu_material_dark;
  196. if (getStyle().popMenuSettings() != null) {
  197. if (getStyle().popMenuSettings().layout(isLightTheme()) != 0) {
  198. layoutId = getStyle().popMenuSettings().layout(isLightTheme());
  199. }
  200. }
  201. View dialogView = createView(layoutId);
  202. dialogImpl = new DialogImpl(dialogView);
  203. if (dialogView != null) {
  204. dialogView.setTag(me);
  205. }
  206. show(dialogView);
  207. } else {
  208. show(getDialogView());
  209. }
  210. if (baseView() != null) {
  211. viewTreeObserver = baseView().getViewTreeObserver();
  212. viewTreeObserver.addOnDrawListener(baseViewDrawListener = new ViewTreeObserver.OnDrawListener() {
  213. @Override
  214. public void onDraw() {
  215. int[] baseViewLocCache = new int[2];
  216. if (baseView() != null) {
  217. baseView().getLocationInWindow(baseViewLocCache);
  218. if (getDialogImpl() != null && !baseViewLoc.isSameLoc(baseViewLocCache)) {
  219. baseViewLoc.set(baseViewLocCache);
  220. refreshMenuLoc();
  221. }
  222. } else {
  223. if (viewTreeObserver != null) {
  224. removeDrawListener(viewTreeObserver, this);
  225. viewTreeObserver = null;
  226. baseViewDrawListener = null;
  227. }
  228. }
  229. }
  230. });
  231. }
  232. return this;
  233. }
  234. private void refreshMenuLoc() {
  235. if (getDialogImpl() == null || getDialogImpl().boxRoot == null) {
  236. return;
  237. }
  238. getDialogImpl().boxBody.setTag(null);
  239. DialogXViewLoc loc = getMenuLoc();
  240. getDialogImpl().boxBody.setTag(loc);
  241. if (!isEnterAnimRunning) {
  242. if (loc.getX() != getDialogImpl().boxBody.getX()) {
  243. getDialogImpl().boxBody.setX(loc.getX());
  244. }
  245. if (loc.getY() != getDialogImpl().boxBody.getY()) {
  246. getDialogImpl().boxBody.setY(loc.getY());
  247. }
  248. }
  249. if (getDialogImpl().boxBody.getWidth() != loc.getW()) {
  250. RelativeLayout.LayoutParams rLp = new RelativeLayout.LayoutParams((int) loc.getW(), ViewGroup.LayoutParams.WRAP_CONTENT);
  251. getDialogImpl().boxBody.setLayoutParams(rLp);
  252. }
  253. }
  254. protected DialogXViewLoc getMenuLoc() {
  255. if (getDialogImpl().boxBody.getTag() instanceof DialogXViewLoc) {
  256. return (DialogXViewLoc) getDialogImpl().boxBody.getTag();
  257. }
  258. DialogXViewLoc result = new DialogXViewLoc();
  259. MaxRelativeLayout boxBody = getDialogImpl().boxBody;
  260. DialogXBaseRelativeLayout boxRoot = getDialogImpl().boxRoot;
  261. //菜单位置计算逻辑
  262. int baseViewLeft = (int) baseViewLoc.getX();
  263. int baseViewTop = (int) baseViewLoc.getY();
  264. int calX = 0, calY = 0;
  265. if (alignGravity != -1) {
  266. if (isAlignGravity(Gravity.CENTER_VERTICAL)) {
  267. calY = (Math.max(0, baseViewTop + baseView().getMeasuredHeight() / 2 - boxBody.getHeight() / 2));
  268. }
  269. if (isAlignGravity(Gravity.CENTER_HORIZONTAL)) {
  270. calX = (Math.max(0, baseViewLeft + (
  271. getWidth() > 0 ? baseView().getMeasuredWidth() / 2 - getWidth() / 2 : 0
  272. )));
  273. }
  274. if (isAlignGravity(Gravity.CENTER)) {
  275. calX = (Math.max(0, baseViewLeft + (
  276. getWidth() > 0 ? (baseView().getMeasuredWidth() / 2 - getWidth() / 2) : 0
  277. )));
  278. calY = (Math.max(0, baseViewTop + baseView().getMeasuredHeight() / 2 - boxBody.getHeight() / 2));
  279. }
  280. if (overlayBaseView) {
  281. //菜单覆盖在 baseView 上时
  282. if (isAlignGravity(Gravity.TOP)) {
  283. calY = (baseViewTop + baseView().getMeasuredHeight() - boxBody.getHeight());
  284. if (calX == 0) {
  285. calX = (Math.max(0, baseViewLeft + (
  286. getWidth() > 0 ? baseView().getMeasuredWidth() / 2 - getWidth() / 2 : 0
  287. )));
  288. }
  289. }
  290. if (isAlignGravity(Gravity.LEFT)) {
  291. calX = Math.max(0, (baseViewLeft + baseView().getMeasuredWidth() - boxBody.getWidth()));
  292. if (calY == 0) {
  293. calY = (Math.max(0, baseViewTop + baseView().getMeasuredHeight() / 2 - boxBody.getHeight() / 2));
  294. }
  295. }
  296. if (isAlignGravity(Gravity.RIGHT)) {
  297. calX = baseViewLeft;
  298. if (calY == 0) {
  299. calY = (Math.max(0, baseViewTop + baseView().getMeasuredHeight() / 2 - boxBody.getHeight() / 2));
  300. }
  301. }
  302. if (isAlignGravity(Gravity.BOTTOM)) {
  303. calY = baseViewTop;
  304. if (calX == 0) {
  305. calX = (Math.max(0, baseViewLeft + (
  306. getWidth() > 0 ? baseView().getMeasuredWidth() / 2 - getWidth() / 2 : 0
  307. )));
  308. }
  309. }
  310. } else {
  311. if (isAlignGravity(Gravity.TOP)) {
  312. calY = (Math.max(0, baseViewTop - boxBody.getHeight()));
  313. if (calX == 0) {
  314. calX = (Math.max(0, baseViewLeft + (
  315. getWidth() > 0 ? baseView().getMeasuredWidth() / 2 - getWidth() / 2 : 0
  316. )));
  317. }
  318. }
  319. if (isAlignGravity(Gravity.LEFT)) {
  320. calX = Math.max(0, (baseViewLeft - boxBody.getWidth()));
  321. if (calY == 0) {
  322. calY = (Math.max(0, baseViewTop + baseView().getMeasuredHeight() / 2 - boxBody.getHeight() / 2));
  323. }
  324. }
  325. if (isAlignGravity(Gravity.RIGHT)) {
  326. calX = (Math.max(0, baseViewLeft + baseView().getWidth()));
  327. if (calY == 0) {
  328. calY = (Math.max(0, baseViewTop + baseView().getMeasuredHeight() / 2 - boxBody.getHeight() / 2));
  329. }
  330. }
  331. if (isAlignGravity(Gravity.BOTTOM)) {
  332. calY = (Math.max(0, baseViewTop + baseView().getHeight()));
  333. if (calX == 0) {
  334. calX = (Math.max(0, baseViewLeft + (
  335. getWidth() > 0 ? baseView().getMeasuredWidth() / 2 - getWidth() / 2 : 0
  336. )));
  337. }
  338. }
  339. }
  340. if (!offScreen) {
  341. if (calX < 0) {
  342. calX = 0;
  343. }
  344. if ((calX + boxBody.getWidth()) > boxRoot.getUseAreaWidth()) {
  345. calX = boxRoot.getUseAreaWidth() - boxBody.getWidth();
  346. }
  347. if (calY < 0) {
  348. calY = 0;
  349. }
  350. if ((calY + boxBody.getHeight()) > boxRoot.getUseAreaHeight()) {
  351. calY = boxRoot.getUseAreaHeight() - boxBody.getHeight();
  352. }
  353. }
  354. result.setX(calX).setY(calY);
  355. } else {
  356. int mHeight = PopMenu.this.height == -1 ? baseView().getHeight() : PopMenu.this.height;
  357. int left = (int) baseViewLoc.getX();
  358. int top = (int) (baseViewLoc.getY() + (overlayBaseView ? 0 : mHeight) + selectItemYDeviation);
  359. if (!offScreen) {
  360. if (left < 0) {
  361. left = 0;
  362. }
  363. if ((left + boxBody.getWidth()) > boxRoot.getUseAreaWidth()) {
  364. left = boxRoot.getUseAreaWidth() - boxBody.getWidth();
  365. }
  366. if (top < 0) {
  367. top = 0;
  368. }
  369. if ((top + boxBody.getHeight()) > boxRoot.getUseAreaHeight()) {
  370. top = boxRoot.getUseAreaHeight() - boxBody.getHeight();
  371. }
  372. }
  373. result.setX(left).setY(top);
  374. }
  375. int mWidth = PopMenu.this.width == -1 ? baseView().getWidth() : PopMenu.this.width;
  376. int mHeight = PopMenu.this.height == -1 ? baseView().getHeight() : PopMenu.this.height;
  377. result.setW(mWidth).setH(mHeight);
  378. return result;
  379. }
  380. protected PopMenuArrayAdapter menuListAdapter;
  381. protected int selectItemYDeviation; //如果找到了选中菜单,这里记录的是其位置的 Y 偏差值
  382. protected boolean isEnterAnimRunning;
  383. public class DialogImpl implements DialogConvertViewInterface {
  384. private List<View> blurViews;
  385. public DialogXBaseRelativeLayout boxRoot;
  386. public MaxRelativeLayout boxBody;
  387. public RelativeLayout boxCustom;
  388. public PopMenuListView listMenu;
  389. public DialogImpl(View convertView) {
  390. if (convertView == null) return;
  391. setDialogView(convertView);
  392. boxRoot = convertView.findViewById(R.id.box_root);
  393. boxBody = convertView.findViewById(R.id.box_body);
  394. boxCustom = convertView.findViewById(R.id.box_custom);
  395. listMenu = convertView.findViewById(R.id.listMenu);
  396. boxBody.setVisibility(View.INVISIBLE);
  397. blurViews = findAllBlurView(convertView);
  398. //先设置为 -1 表示未初始化位置
  399. boxBody.setX(-1);
  400. boxBody.setY(-1);
  401. init();
  402. }
  403. @Override
  404. public void init() {
  405. closing = false;
  406. if (menuListAdapter == null) {
  407. menuListAdapter = new PopMenuArrayAdapter(me, getOwnActivity(), menuList);
  408. }
  409. boxRoot.setParentDialog(me);
  410. boxRoot.setOnLifecycleCallBack(new DialogXBaseRelativeLayout.OnLifecycleCallBack() {
  411. @Override
  412. public void onShow() {
  413. isShow = true;
  414. preShow = false;
  415. setLifecycleState(Lifecycle.State.CREATED);
  416. onDialogShow();
  417. getDialogLifecycleCallback().onShow(me);
  418. PopMenu.this.onShow(me);
  419. refreshUI();
  420. }
  421. @Override
  422. public void onDismiss() {
  423. isShow = false;
  424. getDialogLifecycleCallback().onDismiss(me);
  425. PopMenu.this.onDismiss(me);
  426. menuListAdapter = null;
  427. dialogImpl = null;
  428. baseView(null);
  429. dialogLifecycleCallback = null;
  430. setLifecycleState(Lifecycle.State.DESTROYED);
  431. System.gc();
  432. }
  433. });
  434. boxRoot.setOnBackPressedListener(new DialogXBaseRelativeLayout.PrivateBackPressedListener() {
  435. @Override
  436. public boolean onBackPressed() {
  437. if (onBackPressedListener != null) {
  438. if (onBackPressedListener.onBackPressed(me)) {
  439. dismiss();
  440. }
  441. } else {
  442. if (isCancelable()) {
  443. dismiss();
  444. }
  445. }
  446. return true;
  447. }
  448. });
  449. listMenu.setMaxHeight(getRootFrameLayout() == null ? dip2px(500) : getRootFrameLayout().getMeasuredHeight() - dip2px(150));
  450. boxBody.setVisibility(View.INVISIBLE);
  451. boxBody.post(new Runnable() {
  452. @Override
  453. public void run() {
  454. getDialogXAnimImpl().doShowAnim(me, boxBody);
  455. setLifecycleState(Lifecycle.State.RESUMED);
  456. Integer blurFrontColor = null;
  457. Float dialogXRadius = null;
  458. if (style.popMenuSettings() != null && style.popMenuSettings().blurBackgroundSettings() != null) {
  459. blurFrontColor = getColorNullable(getIntStyleAttr(style.popMenuSettings().blurBackgroundSettings().blurForwardColorRes(isLightTheme())));
  460. dialogXRadius = getFloatStyleAttr((float) style.popMenuSettings().blurBackgroundSettings().blurBackgroundRoundRadiusPx());
  461. }
  462. if (blurViews != null) {
  463. for (View blurView : blurViews) {
  464. ((BlurViewType) blurView).setOverlayColor(backgroundColor == null ? blurFrontColor : backgroundColor);
  465. ((BlurViewType) blurView).setRadiusPx(dialogXRadius);
  466. }
  467. }
  468. }
  469. });
  470. int dividerDrawableResId = 0;
  471. int dividerHeight = 0;
  472. if (style.popMenuSettings() != null) {
  473. dividerDrawableResId = style.popMenuSettings().overrideMenuDividerDrawableRes(isLightTheme());
  474. dividerHeight = style.popMenuSettings().overrideMenuDividerHeight(isLightTheme());
  475. }
  476. if (dividerDrawableResId == 0) {
  477. dividerDrawableResId = isLightTheme() ? R.drawable.rect_dialogx_material_menu_split_divider : R.drawable.rect_dialogx_material_menu_split_divider_night;
  478. }
  479. listMenu.setOverScrollMode(OVER_SCROLL_NEVER);
  480. listMenu.setVerticalScrollBarEnabled(false);
  481. listMenu.setDivider(getResources().getDrawable(dividerDrawableResId));
  482. listMenu.setDividerHeight(dividerHeight);
  483. listMenu.setOnItemClickListener(new AdapterView.OnItemClickListener() {
  484. @Override
  485. public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
  486. selectIndex = position;
  487. if (!closing) {
  488. if (!getOnMenuItemClickListener().onClick(me, menuList.get(position), position)) {
  489. dismiss();
  490. }
  491. }
  492. }
  493. });
  494. onDialogInit();
  495. }
  496. @Override
  497. public void refreshView() {
  498. if (boxRoot == null || getOwnActivity() == null) {
  499. return;
  500. }
  501. boxRoot.setRootPadding(screenPaddings[0], screenPaddings[1], screenPaddings[2], screenPaddings[3]);
  502. if (listMenu.getAdapter() == null) {
  503. listMenu.setAdapter(menuListAdapter);
  504. } else {
  505. if (menuListAdapter.getMenuList() != menuList) {
  506. menuListAdapter = new PopMenuArrayAdapter(me, getOwnActivity(), menuList);
  507. listMenu.setAdapter(menuListAdapter);
  508. } else {
  509. menuListAdapter.notifyDataSetChanged();
  510. }
  511. }
  512. if (bkgInterceptTouch) {
  513. if (isCancelable()) {
  514. boxRoot.setOnClickListener(new View.OnClickListener() {
  515. @Override
  516. public void onClick(View v) {
  517. if (onBackgroundMaskClickListener == null || !onBackgroundMaskClickListener.onClick(me, v)) {
  518. doDismiss(v);
  519. }
  520. }
  521. });
  522. } else {
  523. boxRoot.setOnClickListener(null);
  524. }
  525. } else {
  526. boxRoot.setClickable(false);
  527. }
  528. if (backgroundRadius > -1) {
  529. GradientDrawable gradientDrawable = (GradientDrawable) boxBody.getBackground();
  530. if (gradientDrawable != null) gradientDrawable.setCornerRadius(backgroundRadius);
  531. if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
  532. boxBody.setOutlineProvider(new ViewOutlineProvider() {
  533. @Override
  534. public void getOutline(View view, Outline outline) {
  535. outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), backgroundRadius);
  536. }
  537. });
  538. boxBody.setClipToOutline(true);
  539. }
  540. if (blurViews != null) {
  541. for (View blurView : blurViews) {
  542. ((BlurViewType) blurView).setRadiusPx(backgroundRadius);
  543. }
  544. }
  545. }
  546. if (onBindView != null && onBindView.getCustomView() != null) {
  547. onBindView.bindParent(boxCustom, me);
  548. boxCustom.setVisibility(View.VISIBLE);
  549. } else {
  550. boxCustom.setVisibility(View.GONE);
  551. }
  552. if (width != -1) {
  553. boxBody.setMaxWidth(width);
  554. boxBody.setMinimumWidth(width);
  555. }
  556. if (height != -1) {
  557. boxBody.setMaxHeight(height);
  558. boxBody.setMinimumHeight(height);
  559. }
  560. if (backgroundColor != null) {
  561. tintColor(boxBody, backgroundColor);
  562. if (blurViews != null) {
  563. for (View blurView : blurViews) {
  564. ((BlurViewType) blurView).setOverlayColor(backgroundColor);
  565. }
  566. }
  567. }
  568. onDialogRefreshUI();
  569. }
  570. @Override
  571. public void doDismiss(View v) {
  572. if (v != null) {
  573. v.setEnabled(false);
  574. }
  575. if (!dismissAnimFlag && boxRoot != null) {
  576. dismissAnimFlag = true;
  577. boxRoot.post(new Runnable() {
  578. @Override
  579. public void run() {
  580. getDialogXAnimImpl().doExitAnim(me, boxBody);
  581. runOnMainDelay(new Runnable() {
  582. @Override
  583. public void run() {
  584. if (baseViewDrawListener != null) {
  585. if (viewTreeObserver != null) {
  586. removeDrawListener(viewTreeObserver, baseViewDrawListener);
  587. } else {
  588. if (baseView() != null) {
  589. removeDrawListener(baseView().getViewTreeObserver(), baseViewDrawListener);
  590. }
  591. }
  592. baseViewDrawListener = null;
  593. viewTreeObserver = null;
  594. }
  595. dismiss(getDialogView());
  596. }
  597. }, getExitAnimationDuration(null));
  598. }
  599. });
  600. }
  601. }
  602. protected DialogXAnimInterface<PopMenu> getDialogXAnimImpl() {
  603. if (dialogXAnimImpl == null) {
  604. dialogXAnimImpl = new DialogXAnimInterface<PopMenu>() {
  605. int selectMenuIndex = -1;
  606. @Override
  607. public void doShowAnim(PopMenu dialog, ViewGroup dialogBodyView) {
  608. long enterAnimDurationTemp = getEnterAnimationDuration(null);
  609. if (baseView() != null) {
  610. //有绑定按钮的情况下
  611. int targetHeight = getBodyRealHeight();
  612. boxBody.getLayoutParams().height = 1;
  613. if (overlayBaseView && !listMenu.isCanScroll()) {
  614. if (baseView() instanceof TextView) {
  615. String baseText = ((TextView) baseView()).getText().toString();
  616. for (CharSequence c : menuList) {
  617. if (TextUtils.equals(c.toString(), baseText)) {
  618. selectMenuIndex = menuList.indexOf(c);
  619. break;
  620. }
  621. }
  622. }
  623. //找到已选中的项目
  624. if (selectMenuIndex != -1) {
  625. int[] viewLoc = new int[2];
  626. if (listMenu.getChildAt(selectMenuIndex) != null) {
  627. int itemHeight = listMenu.getChildAt(selectMenuIndex).getMeasuredHeight();
  628. listMenu.getChildAt(selectMenuIndex).getLocationInWindow(viewLoc);
  629. selectItemYDeviation = (int) ((baseView().getMeasuredHeight() / 2f) - (viewLoc[1] - boxBody.getY()) - (itemHeight / 2f));
  630. }
  631. }
  632. }
  633. refreshMenuLoc();
  634. selectItemYDeviation = (int) (getMenuLoc().getY() - baseViewLoc.getY());
  635. //展开动画
  636. ValueAnimator enterAnim = ValueAnimator.ofFloat(0f, 1f);
  637. enterAnim.setInterpolator(new DecelerateInterpolator());
  638. enterAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
  639. @Override
  640. public void onAnimationUpdate(ValueAnimator animation) {
  641. if (!isShow || getDialogImpl() == null || getDialogImpl().boxBody == null)
  642. return;
  643. float animatedValue = (float) animation.getAnimatedValue();
  644. isEnterAnimRunning = !(animatedValue == 1f);
  645. DialogXViewLoc loc = getMenuLoc();
  646. int aimHeight = animatedValue == 1f ? ViewGroup.LayoutParams.WRAP_CONTENT : (int) (targetHeight * animatedValue);
  647. boxBody.getLayoutParams().height = aimHeight;
  648. boxBody.getLayoutParams().width = getWidth() == -1 ? baseView().getWidth() : getWidth();
  649. if ((boxBody.getY() + aimHeight) > boxRoot.getSafeHeight()) {
  650. boxBody.setY(boxRoot.getSafeHeight() - aimHeight);
  651. }
  652. float calX = loc.getX() != -1 ? loc.getX() : baseViewLoc.getX();
  653. float calY = baseViewLoc.getY() + selectItemYDeviation * animatedValue;
  654. if (!offScreen) {
  655. if (calX < 0) {
  656. calX = 0;
  657. }
  658. if (calY < 0) {
  659. calY = 0;
  660. }
  661. if ((calX + boxBody.getWidth()) > boxRoot.getUseAreaWidth()) {
  662. calX = boxRoot.getUseAreaWidth() - boxBody.getWidth();
  663. }
  664. if ((calY + boxBody.getHeight()) > boxRoot.getUseAreaHeight()) {
  665. calY = boxRoot.getUseAreaHeight() - boxBody.getHeight();
  666. }
  667. }
  668. boxBody.setX(calX);
  669. boxBody.setY(calY);
  670. boxBody.requestLayout();
  671. if (boxBody.getVisibility() != VISIBLE) {
  672. boxBody.setVisibility(View.VISIBLE);
  673. }
  674. if (isUseBlurBackground()) {
  675. boxRoot.setBkgAlpha((Float) animation.getAnimatedValue());
  676. }
  677. }
  678. });
  679. enterAnim.setInterpolator(new DecelerateInterpolator(2f));
  680. enterAnim.setDuration(enterAnimDurationTemp);
  681. enterAnim.start();
  682. } else {
  683. //无绑定按钮的情况下
  684. RelativeLayout.LayoutParams rLp = (RelativeLayout.LayoutParams) boxBody.getLayoutParams();
  685. rLp.addRule(RelativeLayout.CENTER_IN_PARENT);
  686. rLp.width = getWidth() == -1 ? RelativeLayout.LayoutParams.MATCH_PARENT : getWidth();
  687. rLp.leftMargin = dip2px(50);
  688. rLp.rightMargin = dip2px(50);
  689. boxBody.setLayoutParams(rLp);
  690. boxBody.setAlpha(0f);
  691. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && !isUseBlurBackground()) {
  692. boxBody.setElevation(dip2px(20));
  693. }
  694. boxBody.setVisibility(View.VISIBLE);
  695. boxBody.animate().alpha(1f).setDuration(enterAnimDurationTemp);
  696. ValueAnimator bkgAlpha = ValueAnimator.ofFloat(0f, 1f);
  697. bkgAlpha.setDuration(enterAnimDurationTemp);
  698. bkgAlpha.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
  699. @Override
  700. public void onAnimationUpdate(ValueAnimator animation) {
  701. boxRoot.setBkgAlpha((Float) animation.getAnimatedValue());
  702. }
  703. });
  704. bkgAlpha.start();
  705. }
  706. }
  707. @Override
  708. public void doExitAnim(PopMenu dialog, ViewGroup dialogBodyView) {
  709. Animation exitAnim = AnimationUtils.loadAnimation(getOwnActivity() == null ? boxRoot.getContext() : getOwnActivity(), R.anim.anim_dialogx_default_exit);
  710. long exitAnimDuration = getExitAnimationDuration(exitAnim);
  711. exitAnim.setDuration(exitAnimDuration);
  712. boxBody.startAnimation(exitAnim);
  713. boxRoot.animate()
  714. .alpha(0f)
  715. .setInterpolator(new AccelerateInterpolator())
  716. .setDuration(exitAnimDuration);
  717. ValueAnimator bkgAlpha = ValueAnimator.ofFloat(1, 0f);
  718. bkgAlpha.setDuration(exitAnimDuration);
  719. bkgAlpha.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
  720. @Override
  721. public void onAnimationUpdate(ValueAnimator animation) {
  722. if (boxRoot != null && baseView() == null) {
  723. boxRoot.setBkgAlpha((Float) animation.getAnimatedValue());
  724. }
  725. }
  726. });
  727. bkgAlpha.start();
  728. }
  729. };
  730. }
  731. return dialogXAnimImpl;
  732. }
  733. private boolean isUseBlurBackground() {
  734. return style.popMenuSettings() != null && style.popMenuSettings().blurBackgroundSettings() != null && style.popMenuSettings().blurBackgroundSettings().blurBackground();
  735. }
  736. public long getExitAnimationDuration(@Nullable Animation defaultExitAnim) {
  737. if (defaultExitAnim == null && boxBody.getAnimation() != null) {
  738. defaultExitAnim = boxBody.getAnimation();
  739. }
  740. long exitAnimDurationTemp = (defaultExitAnim == null || defaultExitAnim.getDuration() == 0) ? 150 : defaultExitAnim.getDuration();
  741. if (overrideExitDuration >= 0) {
  742. exitAnimDurationTemp = overrideExitDuration;
  743. }
  744. if (exitAnimDuration != -1) {
  745. exitAnimDurationTemp = exitAnimDuration;
  746. }
  747. return exitAnimDurationTemp;
  748. }
  749. public long getEnterAnimationDuration(@Nullable Animation defaultEnterAnim) {
  750. if (defaultEnterAnim == null && boxBody.getAnimation() != null) {
  751. defaultEnterAnim = boxBody.getAnimation();
  752. }
  753. long enterAnimDurationTemp = (defaultEnterAnim == null || defaultEnterAnim.getDuration() == 0) ? 150 : defaultEnterAnim.getDuration();
  754. if (overrideEnterDuration >= 0) {
  755. enterAnimDurationTemp = overrideEnterDuration;
  756. }
  757. if (enterAnimDuration >= 0) {
  758. enterAnimDurationTemp = enterAnimDuration;
  759. }
  760. return enterAnimDurationTemp;
  761. }
  762. }
  763. private void removeDrawListener(ViewTreeObserver viewTreeObserver, ViewTreeObserver.OnDrawListener listener) {
  764. if (viewTreeObserver == null || listener == null || !viewTreeObserver.isAlive()) {
  765. return;
  766. }
  767. try {
  768. viewTreeObserver.removeOnDrawListener(listener);
  769. } catch (Exception e) {
  770. }
  771. }
  772. private int getBodyRealHeight() {
  773. if (getDialogImpl() == null) {
  774. return 0;
  775. }
  776. int matchParentMeasureSpec = View.MeasureSpec.makeMeasureSpec(((View) getDialogImpl().boxBody.getParent()).getWidth(), View.MeasureSpec.EXACTLY);
  777. int wrapContentMeasureSpec = View.MeasureSpec.makeMeasureSpec(((View) getDialogImpl().boxBody.getParent()).getHeight(), View.MeasureSpec.AT_MOST);
  778. getDialogImpl().boxBody.measure(matchParentMeasureSpec, wrapContentMeasureSpec);
  779. return getDialogImpl().boxBody.getMeasuredHeight();
  780. }
  781. private boolean closing;
  782. public void dismiss() {
  783. closing = true;
  784. runOnMain(new Runnable() {
  785. @Override
  786. public void run() {
  787. if (dialogImpl == null) {
  788. return;
  789. }
  790. dialogImpl.doDismiss(null);
  791. }
  792. });
  793. }
  794. @Override
  795. public void restartDialog() {
  796. if (getDialogView() != null) {
  797. if (baseViewDrawListener != null) {
  798. if (viewTreeObserver != null) {
  799. removeDrawListener(viewTreeObserver, baseViewDrawListener);
  800. } else {
  801. if (baseView() != null) {
  802. removeDrawListener(baseView().getViewTreeObserver(), baseViewDrawListener);
  803. }
  804. }
  805. baseViewDrawListener = null;
  806. }
  807. dismiss(getDialogView());
  808. isShow = false;
  809. }
  810. if (getDialogImpl().boxCustom != null) {
  811. getDialogImpl().boxCustom.removeAllViews();
  812. }
  813. show();
  814. }
  815. @Override
  816. protected void shutdown() {
  817. }
  818. public List<CharSequence> getMenuList() {
  819. return menuList;
  820. }
  821. public PopMenu setMenuList(List<CharSequence> menuList) {
  822. this.menuList = new ArrayList<>();
  823. this.menuList.addAll(menuList);
  824. refreshUI();
  825. return this;
  826. }
  827. public PopMenu setMenuList(String[] menuList) {
  828. this.menuList = new ArrayList<>();
  829. this.menuList.addAll(Arrays.asList(menuList));
  830. refreshUI();
  831. return this;
  832. }
  833. public PopMenu setMenuList(CharSequence[] menuList) {
  834. this.menuList = new ArrayList<>();
  835. this.menuList.addAll(Arrays.asList(menuList));
  836. refreshUI();
  837. return this;
  838. }
  839. public void refreshUI() {
  840. if (getDialogImpl() == null) {
  841. return;
  842. }
  843. runOnMain(new Runnable() {
  844. @Override
  845. public void run() {
  846. if (dialogImpl != null) {
  847. dialogImpl.refreshView();
  848. }
  849. }
  850. });
  851. }
  852. @Override
  853. public boolean isCancelable() {
  854. return true;
  855. }
  856. public DialogImpl getDialogImpl() {
  857. return dialogImpl;
  858. }
  859. @Override
  860. public String dialogKey() {
  861. return getClass().getSimpleName() + "(" + Integer.toHexString(hashCode()) + ")";
  862. }
  863. public DialogLifecycleCallback<PopMenu> getDialogLifecycleCallback() {
  864. return dialogLifecycleCallback == null ? new DialogLifecycleCallback<PopMenu>() {
  865. } : dialogLifecycleCallback;
  866. }
  867. public PopMenu setDialogLifecycleCallback(DialogLifecycleCallback<PopMenu> dialogLifecycleCallback) {
  868. this.dialogLifecycleCallback = dialogLifecycleCallback;
  869. if (isShow) {
  870. dialogLifecycleCallback.onShow(me);
  871. }
  872. return this;
  873. }
  874. public boolean isOverlayBaseView() {
  875. return overlayBaseView;
  876. }
  877. public PopMenu setOverlayBaseView(boolean overlayBaseView) {
  878. this.overlayBaseView = overlayBaseView;
  879. refreshUI();
  880. return this;
  881. }
  882. public OnMenuItemClickListener<PopMenu> getOnMenuItemClickListener() {
  883. return onMenuItemClickListener == null ? new OnMenuItemClickListener<PopMenu>() {
  884. @Override
  885. public boolean onClick(PopMenu dialog, CharSequence text, int index) {
  886. return false;
  887. }
  888. } : onMenuItemClickListener;
  889. }
  890. public PopMenu setOnMenuItemClickListener(OnMenuItemClickListener<PopMenu> onMenuItemClickListener) {
  891. this.onMenuItemClickListener = onMenuItemClickListener;
  892. return this;
  893. }
  894. public OnIconChangeCallBack<PopMenu> getOnIconChangeCallBack() {
  895. return onIconChangeCallBack;
  896. }
  897. public PopMenu setOnIconChangeCallBack(OnIconChangeCallBack<PopMenu> onIconChangeCallBack) {
  898. this.onIconChangeCallBack = onIconChangeCallBack;
  899. return this;
  900. }
  901. public PopMenu setCustomView(OnBindView<PopMenu> onBindView) {
  902. this.onBindView = onBindView;
  903. refreshUI();
  904. return this;
  905. }
  906. public View getCustomView() {
  907. if (onBindView == null) {
  908. return null;
  909. }
  910. return onBindView.getCustomView();
  911. }
  912. public PopMenu removeCustomView() {
  913. this.onBindView.clean();
  914. refreshUI();
  915. return this;
  916. }
  917. public int getWidth() {
  918. return width;
  919. }
  920. /**
  921. * 设置菜单 UI 宽度(单位:像素)
  922. *
  923. * @param width 宽度(像素)
  924. * @return PopMenu实例
  925. */
  926. public PopMenu setWidth(int width) {
  927. this.width = width;
  928. refreshUI();
  929. return this;
  930. }
  931. public int getHeight() {
  932. return height;
  933. }
  934. /**
  935. * 设置菜单 UI 高度(单位:像素)
  936. *
  937. * @param height 高度(像素)
  938. * @return PopMenu实例
  939. */
  940. public PopMenu setHeight(int height) {
  941. this.height = height;
  942. refreshUI();
  943. return this;
  944. }
  945. public int getAlignGravity() {
  946. return alignGravity;
  947. }
  948. /**
  949. * 判断是否有设置对应的位置关系
  950. *
  951. * @param gravity 位置关系
  952. * @return 是否具备位置关系
  953. */
  954. public boolean isAlignGravity(int gravity) {
  955. return (alignGravity & gravity) == gravity;
  956. }
  957. public PopMenu setAlignGravity(int alignGravity) {
  958. this.alignGravity = alignGravity;
  959. refreshMenuLoc();
  960. return this;
  961. }
  962. public PopMenu setDialogImplMode(DialogX.IMPL_MODE dialogImplMode) {
  963. this.dialogImplMode = dialogImplMode;
  964. return this;
  965. }
  966. public TextInfo getMenuTextInfo() {
  967. if (menuTextInfo == null) {
  968. return DialogX.menuTextInfo;
  969. }
  970. return menuTextInfo;
  971. }
  972. public PopMenu setMenuTextInfo(TextInfo menuTextInfo) {
  973. this.menuTextInfo = menuTextInfo;
  974. return this;
  975. }
  976. public boolean isOffScreen() {
  977. return offScreen;
  978. }
  979. /**
  980. * 是否允许超出屏幕显示
  981. * PopMenu 默认位置显示在屏幕内,开启后将无视屏幕范围限制。
  982. *
  983. * @param offScreen 超出屏幕
  984. * @return PopMenu实例
  985. */
  986. public PopMenu setOffScreen(boolean offScreen) {
  987. this.offScreen = offScreen;
  988. return this;
  989. }
  990. public boolean isBkgInterceptTouch() {
  991. return bkgInterceptTouch;
  992. }
  993. public PopMenu setBkgInterceptTouch(boolean bkgInterceptTouch) {
  994. this.bkgInterceptTouch = bkgInterceptTouch;
  995. return this;
  996. }
  997. public OnBackgroundMaskClickListener<PopMenu> getOnBackgroundMaskClickListener() {
  998. return onBackgroundMaskClickListener;
  999. }
  1000. public PopMenu setOnBackgroundMaskClickListener(OnBackgroundMaskClickListener<PopMenu> onBackgroundMaskClickListener) {
  1001. this.onBackgroundMaskClickListener = onBackgroundMaskClickListener;
  1002. refreshUI();
  1003. return this;
  1004. }
  1005. public PopMenu setStyle(DialogXStyle style) {
  1006. this.style = style;
  1007. return this;
  1008. }
  1009. public PopMenu setTheme(DialogX.THEME theme) {
  1010. this.theme = theme;
  1011. return this;
  1012. }
  1013. public PopMenu setRadius(float radiusPx) {
  1014. backgroundRadius = radiusPx;
  1015. refreshUI();
  1016. return this;
  1017. }
  1018. public float getRadius() {
  1019. return backgroundRadius;
  1020. }
  1021. private boolean isHide;
  1022. public void hide() {
  1023. isHide = true;
  1024. hideWithExitAnim = false;
  1025. if (getDialogView() != null) {
  1026. getDialogView().setVisibility(View.GONE);
  1027. }
  1028. }
  1029. protected boolean hideWithExitAnim;
  1030. public void hideWithExitAnim() {
  1031. hideWithExitAnim = true;
  1032. isHide = true;
  1033. if (getDialogImpl() != null) {
  1034. getDialogImpl().getDialogXAnimImpl().doExitAnim(me, getDialogImpl().boxBody);
  1035. runOnMainDelay(new Runnable() {
  1036. @Override
  1037. public void run() {
  1038. if (getDialogView() != null) {
  1039. getDialogView().setVisibility(View.GONE);
  1040. }
  1041. }
  1042. }, getDialogImpl().getExitAnimationDuration(null));
  1043. }
  1044. }
  1045. public DialogXAnimInterface<PopMenu> getDialogXAnimImpl() {
  1046. return dialogXAnimImpl;
  1047. }
  1048. public PopMenu setDialogXAnimImpl(DialogXAnimInterface<PopMenu> dialogXAnimImpl) {
  1049. this.dialogXAnimImpl = dialogXAnimImpl;
  1050. return this;
  1051. }
  1052. public OnBackPressedListener<PopMenu> getOnBackPressedListener() {
  1053. return onBackPressedListener;
  1054. }
  1055. public PopMenu setOnBackPressedListener(OnBackPressedListener<PopMenu> onBackPressedListener) {
  1056. this.onBackPressedListener = onBackPressedListener;
  1057. return this;
  1058. }
  1059. public View getBaseView() {
  1060. return baseView();
  1061. }
  1062. public PopMenu setBaseView(View baseView) {
  1063. baseView(baseView);
  1064. refreshUI();
  1065. return this;
  1066. }
  1067. public PopMenu setRootPadding(int padding) {
  1068. this.screenPaddings = new int[]{padding, padding, padding, padding};
  1069. refreshUI();
  1070. return this;
  1071. }
  1072. public PopMenu setRootPadding(int paddingLeft, int paddingTop, int paddingRight, int paddingBottom) {
  1073. this.screenPaddings = new int[]{paddingLeft, paddingTop, paddingRight, paddingBottom};
  1074. refreshUI();
  1075. return this;
  1076. }
  1077. public int getPressedIndex() {
  1078. return pressedIndex;
  1079. }
  1080. //设置已选择的菜单项(菜单背景会有选中状态的显示)
  1081. public PopMenu setPressedIndex(int pressedIndex) {
  1082. this.pressedIndex = pressedIndex;
  1083. refreshUI();
  1084. return this;
  1085. }
  1086. public int getSelectIndex() {
  1087. return selectIndex;
  1088. }
  1089. public CharSequence getSelectMenuText() {
  1090. if (menuList == null) return "";
  1091. return menuList.get(selectIndex);
  1092. }
  1093. /**
  1094. * 用于使用 new 构建实例时,override 的生命周期事件
  1095. * 例如:
  1096. * new PopMenu() {
  1097. *
  1098. * @param dialog self
  1099. * @Override public void onShow(PopMenu dialog) {
  1100. * //...
  1101. * }
  1102. * }
  1103. */
  1104. public void onShow(PopMenu dialog) {
  1105. }
  1106. /**
  1107. * 用于使用 new 构建实例时,override 的生命周期事件
  1108. * 例如:
  1109. * new PopMenu() {
  1110. *
  1111. * @param dialog self
  1112. * @Override public boolean onDismiss(PopMenu dialog) {
  1113. * WaitDialog.show("Please Wait...");
  1114. * if (dialog.getButtonSelectResult() == BUTTON_SELECT_RESULT.BUTTON_OK) {
  1115. * //点击了OK的情况
  1116. * //...
  1117. * } else {
  1118. * //其他按钮点击、对话框dismiss的情况
  1119. * //...
  1120. * }
  1121. * return false;
  1122. * }
  1123. * }
  1124. */
  1125. //用于使用 new 构建实例时,override 的生命周期事件
  1126. public void onDismiss(PopMenu dialog) {
  1127. }
  1128. public MenuItemLayoutRefreshCallback<PopMenu> getMenuMenuItemLayoutRefreshCallback() {
  1129. return menuMenuItemLayoutRefreshCallback;
  1130. }
  1131. public PopMenu setMenuMenuItemLayoutRefreshCallback(MenuItemLayoutRefreshCallback<PopMenu> menuMenuItemLayoutRefreshCallback) {
  1132. this.menuMenuItemLayoutRefreshCallback = menuMenuItemLayoutRefreshCallback;
  1133. return this;
  1134. }
  1135. protected PopMenu baseView(View view) {
  1136. if (view == null && baseViewWeakReference != null) {
  1137. baseViewWeakReference.clear();
  1138. baseViewWeakReference = null;
  1139. } else {
  1140. baseViewWeakReference = new WeakReference<>(view);
  1141. }
  1142. return this;
  1143. }
  1144. protected View baseView() {
  1145. return baseViewWeakReference == null ? null : baseViewWeakReference.get();
  1146. }
  1147. }