123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308 |
- package com.kongzue.dialogx.dialogs;
- import static android.view.View.GONE;
- import static android.view.View.OVER_SCROLL_NEVER;
- import static android.view.View.VISIBLE;
- import android.animation.ValueAnimator;
- import android.graphics.Outline;
- import android.graphics.drawable.GradientDrawable;
- import android.os.Build;
- import android.text.TextUtils;
- import android.view.Gravity;
- import android.view.View;
- import android.view.ViewGroup;
- import android.view.ViewOutlineProvider;
- import android.view.ViewTreeObserver;
- import android.view.animation.AccelerateInterpolator;
- import android.view.animation.Animation;
- import android.view.animation.AnimationUtils;
- import android.view.animation.DecelerateInterpolator;
- import android.view.animation.Transformation;
- import android.widget.AdapterView;
- import android.widget.RelativeLayout;
- import android.widget.TextView;
- import androidx.annotation.Nullable;
- import androidx.lifecycle.Lifecycle;
- import com.kongzue.dialogx.DialogX;
- import com.kongzue.dialogx.R;
- import com.kongzue.dialogx.interfaces.BaseDialog;
- import com.kongzue.dialogx.interfaces.BlurViewType;
- import com.kongzue.dialogx.interfaces.DialogConvertViewInterface;
- import com.kongzue.dialogx.interfaces.DialogLifecycleCallback;
- import com.kongzue.dialogx.interfaces.DialogXAnimInterface;
- import com.kongzue.dialogx.interfaces.DialogXStyle;
- import com.kongzue.dialogx.interfaces.MenuItemLayoutRefreshCallback;
- import com.kongzue.dialogx.interfaces.OnBackPressedListener;
- import com.kongzue.dialogx.interfaces.OnBackgroundMaskClickListener;
- import com.kongzue.dialogx.interfaces.OnBindView;
- import com.kongzue.dialogx.interfaces.OnIconChangeCallBack;
- import com.kongzue.dialogx.interfaces.OnMenuItemClickListener;
- import com.kongzue.dialogx.util.DialogXViewLoc;
- import com.kongzue.dialogx.util.PopMenuArrayAdapter;
- import com.kongzue.dialogx.util.TextInfo;
- import com.kongzue.dialogx.util.views.DialogXBaseRelativeLayout;
- import com.kongzue.dialogx.util.views.MaxRelativeLayout;
- import com.kongzue.dialogx.util.views.PopMenuListView;
- import java.lang.ref.WeakReference;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.List;
- /**
- * @author: Kongzue
- * @github: https://github.com/kongzue/
- * @homepage: http://kongzue.com/
- * @mail: myzcxhh@live.cn
- * @createTime: 2021/8/18 14:27
- */
- public class PopMenu extends BaseDialog {
- public static long overrideEnterDuration = -1;
- public static long overrideExitDuration = -1;
- protected PopMenu me = this;
- protected boolean bkgInterceptTouch = true;
- protected OnBindView<PopMenu> onBindView; //自定义布局
- protected DialogLifecycleCallback<PopMenu> dialogLifecycleCallback; //对话框生命周期
- protected OnBackgroundMaskClickListener<PopMenu> onBackgroundMaskClickListener;
- protected List<CharSequence> menuList;
- protected DialogImpl dialogImpl;
- protected WeakReference<View> baseViewWeakReference;
- protected boolean overlayBaseView = true; //允许菜单覆盖在 baseView 上
- protected OnMenuItemClickListener<PopMenu> onMenuItemClickListener;
- protected OnIconChangeCallBack<PopMenu> onIconChangeCallBack; //设置图标
- protected int width = -1; //指定菜单宽度
- protected int height = -1; //指定菜单高度
- protected TextInfo menuTextInfo;
- protected boolean offScreen = false; //超出屏幕
- protected float backgroundRadius = -1;
- protected DialogXAnimInterface<PopMenu> dialogXAnimImpl;
- protected OnBackPressedListener<PopMenu> onBackPressedListener;
- protected MenuItemLayoutRefreshCallback<PopMenu> menuMenuItemLayoutRefreshCallback;
- protected int pressedIndex = -1;
- protected int alignGravity = -1; //指定菜单相对 baseView 的位置
- //记录 baseView 位置
- protected DialogXViewLoc baseViewLoc = new DialogXViewLoc();
- private int selectIndex;
- public PopMenu() {
- super();
- }
- public PopMenu(View baseView, List<CharSequence> menuList) {
- this.menuList = new ArrayList<>();
- this.menuList.addAll(menuList);
- this.baseView(baseView);
- }
- public PopMenu(View baseView, CharSequence[] menuList) {
- this.menuList = new ArrayList<>();
- this.menuList.addAll(Arrays.asList(menuList));
- this.baseView(baseView);
- }
- public PopMenu(List<CharSequence> menuList) {
- this.menuList = new ArrayList<>();
- this.menuList.addAll(menuList);
- }
- public PopMenu(CharSequence[] menuList) {
- this.menuList = new ArrayList<>();
- this.menuList.addAll(Arrays.asList(menuList));
- }
- public PopMenu(OnBindView<PopMenu> onBindView) {
- this.onBindView = onBindView;
- }
- public PopMenu(View baseView, OnBindView<PopMenu> onBindView) {
- this.baseView(baseView);
- this.onBindView = onBindView;
- }
- public PopMenu(View baseView, List<CharSequence> menuList, OnBindView<PopMenu> onBindView) {
- this.baseView(baseView);
- this.menuList = new ArrayList<>();
- this.menuList.addAll(menuList);
- this.onBindView = onBindView;
- }
- public PopMenu(View baseView, CharSequence[] menuList, OnBindView<PopMenu> onBindView) {
- this.baseView(baseView);
- this.menuList = new ArrayList<>();
- this.menuList.addAll(Arrays.asList(menuList));
- this.onBindView = onBindView;
- }
- public PopMenu(List<CharSequence> menuList, OnBindView<PopMenu> onBindView) {
- this.menuList = new ArrayList<>();
- this.menuList.addAll(menuList);
- this.onBindView = onBindView;
- }
- public PopMenu(CharSequence[] menuList, OnBindView<PopMenu> onBindView) {
- this.menuList = new ArrayList<>();
- this.menuList.addAll(Arrays.asList(menuList));
- this.onBindView = onBindView;
- }
- public static PopMenu build() {
- return new PopMenu();
- }
- public static PopMenu build(DialogXStyle style) {
- return new PopMenu().setStyle(style);
- }
- public static PopMenu show(CharSequence[] menus) {
- PopMenu popMenu = new PopMenu(menus);
- popMenu.show();
- return popMenu;
- }
- public static PopMenu show(List<CharSequence> menuList) {
- PopMenu popMenu = new PopMenu(menuList);
- popMenu.show();
- return popMenu;
- }
- public static PopMenu show(View baseView, CharSequence[] menus) {
- PopMenu popMenu = new PopMenu(baseView, menus);
- popMenu.show();
- return popMenu;
- }
- public static PopMenu show(View baseView, List<CharSequence> menuList) {
- PopMenu popMenu = new PopMenu(baseView, menuList);
- popMenu.show();
- return popMenu;
- }
- public static PopMenu show(View baseView, CharSequence[] menus, OnBindView<PopMenu> onBindView) {
- PopMenu popMenu = new PopMenu(baseView, menus, onBindView);
- popMenu.show();
- return popMenu;
- }
- public static PopMenu show(View baseView, List<CharSequence> menuList, OnBindView<PopMenu> onBindView) {
- PopMenu popMenu = new PopMenu(baseView, menuList, onBindView);
- popMenu.show();
- return popMenu;
- }
- public static PopMenu show(CharSequence[] menus, OnBindView<PopMenu> onBindView) {
- PopMenu popMenu = new PopMenu(menus, onBindView);
- popMenu.show();
- return popMenu;
- }
- public static PopMenu show(List<CharSequence> menuList, OnBindView<PopMenu> onBindView) {
- PopMenu popMenu = new PopMenu(menuList, onBindView);
- popMenu.show();
- return popMenu;
- }
- private ViewTreeObserver viewTreeObserver;
- private ViewTreeObserver.OnDrawListener baseViewDrawListener;
- public PopMenu show() {
- if (isHide && getDialogView() != null && isShow) {
- if (hideWithExitAnim && getDialogImpl() != null) {
- getDialogImpl().boxBody.clearAnimation();
- getDialogView().setVisibility(View.VISIBLE);
- getDialogImpl().boxRoot.animate().alpha(1f);
- getDialogImpl().getDialogXAnimImpl().doShowAnim(me, getDialogImpl().boxBody);
- } else {
- getDialogView().setVisibility(View.VISIBLE);
- }
- return this;
- }
- super.beforeShow();
- if (getDialogView() == null) {
- int layoutId = isLightTheme() ? R.layout.layout_dialogx_popmenu_material : R.layout.layout_dialogx_popmenu_material_dark;
- if (getStyle().popMenuSettings() != null) {
- if (getStyle().popMenuSettings().layout(isLightTheme()) != 0) {
- layoutId = getStyle().popMenuSettings().layout(isLightTheme());
- }
- }
- View dialogView = createView(layoutId);
- dialogImpl = new DialogImpl(dialogView);
- if (dialogView != null) {
- dialogView.setTag(me);
- }
- show(dialogView);
- } else {
- show(getDialogView());
- }
- if (baseView() != null) {
- viewTreeObserver = baseView().getViewTreeObserver();
- viewTreeObserver.addOnDrawListener(baseViewDrawListener = new ViewTreeObserver.OnDrawListener() {
- @Override
- public void onDraw() {
- int[] baseViewLocCache = new int[2];
- if (baseView() != null) {
- baseView().getLocationInWindow(baseViewLocCache);
- if (getDialogImpl() != null && !baseViewLoc.isSameLoc(baseViewLocCache)) {
- baseViewLoc.set(baseViewLocCache);
- refreshMenuLoc();
- }
- } else {
- if (viewTreeObserver != null) {
- removeDrawListener(viewTreeObserver, this);
- viewTreeObserver = null;
- baseViewDrawListener = null;
- }
- }
- }
- });
- }
- return this;
- }
- private void refreshMenuLoc() {
- if (getDialogImpl() == null || getDialogImpl().boxRoot == null) {
- return;
- }
- getDialogImpl().boxBody.setTag(null);
- DialogXViewLoc loc = getMenuLoc();
- getDialogImpl().boxBody.setTag(loc);
- if (!isEnterAnimRunning) {
- if (loc.getX() != getDialogImpl().boxBody.getX()) {
- getDialogImpl().boxBody.setX(loc.getX());
- }
- if (loc.getY() != getDialogImpl().boxBody.getY()) {
- getDialogImpl().boxBody.setY(loc.getY());
- }
- }
- if (getDialogImpl().boxBody.getWidth() != loc.getW()) {
- RelativeLayout.LayoutParams rLp = new RelativeLayout.LayoutParams((int) loc.getW(), ViewGroup.LayoutParams.WRAP_CONTENT);
- getDialogImpl().boxBody.setLayoutParams(rLp);
- }
- }
- protected DialogXViewLoc getMenuLoc() {
- if (getDialogImpl().boxBody.getTag() instanceof DialogXViewLoc) {
- return (DialogXViewLoc) getDialogImpl().boxBody.getTag();
- }
- DialogXViewLoc result = new DialogXViewLoc();
- MaxRelativeLayout boxBody = getDialogImpl().boxBody;
- DialogXBaseRelativeLayout boxRoot = getDialogImpl().boxRoot;
- //菜单位置计算逻辑
- int baseViewLeft = (int) baseViewLoc.getX();
- int baseViewTop = (int) baseViewLoc.getY();
- int calX = 0, calY = 0;
- if (alignGravity != -1) {
- if (isAlignGravity(Gravity.CENTER_VERTICAL)) {
- calY = (Math.max(0, baseViewTop + baseView().getMeasuredHeight() / 2 - boxBody.getHeight() / 2));
- }
- if (isAlignGravity(Gravity.CENTER_HORIZONTAL)) {
- calX = (Math.max(0, baseViewLeft + (
- getWidth() > 0 ? baseView().getMeasuredWidth() / 2 - getWidth() / 2 : 0
- )));
- }
- if (isAlignGravity(Gravity.CENTER)) {
- calX = (Math.max(0, baseViewLeft + (
- getWidth() > 0 ? (baseView().getMeasuredWidth() / 2 - getWidth() / 2) : 0
- )));
- calY = (Math.max(0, baseViewTop + baseView().getMeasuredHeight() / 2 - boxBody.getHeight() / 2));
- }
- if (overlayBaseView) {
- //菜单覆盖在 baseView 上时
- if (isAlignGravity(Gravity.TOP)) {
- calY = (baseViewTop + baseView().getMeasuredHeight() - boxBody.getHeight());
- if (calX == 0) {
- calX = (Math.max(0, baseViewLeft + (
- getWidth() > 0 ? baseView().getMeasuredWidth() / 2 - getWidth() / 2 : 0
- )));
- }
- }
- if (isAlignGravity(Gravity.LEFT)) {
- calX = Math.max(0, (baseViewLeft + baseView().getMeasuredWidth() - boxBody.getWidth()));
- if (calY == 0) {
- calY = (Math.max(0, baseViewTop + baseView().getMeasuredHeight() / 2 - boxBody.getHeight() / 2));
- }
- }
- if (isAlignGravity(Gravity.RIGHT)) {
- calX = baseViewLeft;
- if (calY == 0) {
- calY = (Math.max(0, baseViewTop + baseView().getMeasuredHeight() / 2 - boxBody.getHeight() / 2));
- }
- }
- if (isAlignGravity(Gravity.BOTTOM)) {
- calY = baseViewTop;
- if (calX == 0) {
- calX = (Math.max(0, baseViewLeft + (
- getWidth() > 0 ? baseView().getMeasuredWidth() / 2 - getWidth() / 2 : 0
- )));
- }
- }
- } else {
- if (isAlignGravity(Gravity.TOP)) {
- calY = (Math.max(0, baseViewTop - boxBody.getHeight()));
- if (calX == 0) {
- calX = (Math.max(0, baseViewLeft + (
- getWidth() > 0 ? baseView().getMeasuredWidth() / 2 - getWidth() / 2 : 0
- )));
- }
- }
- if (isAlignGravity(Gravity.LEFT)) {
- calX = Math.max(0, (baseViewLeft - boxBody.getWidth()));
- if (calY == 0) {
- calY = (Math.max(0, baseViewTop + baseView().getMeasuredHeight() / 2 - boxBody.getHeight() / 2));
- }
- }
- if (isAlignGravity(Gravity.RIGHT)) {
- calX = (Math.max(0, baseViewLeft + baseView().getWidth()));
- if (calY == 0) {
- calY = (Math.max(0, baseViewTop + baseView().getMeasuredHeight() / 2 - boxBody.getHeight() / 2));
- }
- }
- if (isAlignGravity(Gravity.BOTTOM)) {
- calY = (Math.max(0, baseViewTop + baseView().getHeight()));
- if (calX == 0) {
- calX = (Math.max(0, baseViewLeft + (
- getWidth() > 0 ? baseView().getMeasuredWidth() / 2 - getWidth() / 2 : 0
- )));
- }
- }
- }
- if (!offScreen) {
- if (calX < 0) {
- calX = 0;
- }
- if ((calX + boxBody.getWidth()) > boxRoot.getUseAreaWidth()) {
- calX = boxRoot.getUseAreaWidth() - boxBody.getWidth();
- }
- if (calY < 0) {
- calY = 0;
- }
- if ((calY + boxBody.getHeight()) > boxRoot.getUseAreaHeight()) {
- calY = boxRoot.getUseAreaHeight() - boxBody.getHeight();
- }
- }
- result.setX(calX).setY(calY);
- } else {
- int mHeight = PopMenu.this.height == -1 ? baseView().getHeight() : PopMenu.this.height;
- int left = (int) baseViewLoc.getX();
- int top = (int) (baseViewLoc.getY() + (overlayBaseView ? 0 : mHeight) + selectItemYDeviation);
- if (!offScreen) {
- if (left < 0) {
- left = 0;
- }
- if ((left + boxBody.getWidth()) > boxRoot.getUseAreaWidth()) {
- left = boxRoot.getUseAreaWidth() - boxBody.getWidth();
- }
- if (top < 0) {
- top = 0;
- }
- if ((top + boxBody.getHeight()) > boxRoot.getUseAreaHeight()) {
- top = boxRoot.getUseAreaHeight() - boxBody.getHeight();
- }
- }
- result.setX(left).setY(top);
- }
- int mWidth = PopMenu.this.width == -1 ? baseView().getWidth() : PopMenu.this.width;
- int mHeight = PopMenu.this.height == -1 ? baseView().getHeight() : PopMenu.this.height;
- result.setW(mWidth).setH(mHeight);
- return result;
- }
- protected PopMenuArrayAdapter menuListAdapter;
- protected int selectItemYDeviation; //如果找到了选中菜单,这里记录的是其位置的 Y 偏差值
- protected boolean isEnterAnimRunning;
- public class DialogImpl implements DialogConvertViewInterface {
- private List<View> blurViews;
- public DialogXBaseRelativeLayout boxRoot;
- public MaxRelativeLayout boxBody;
- public RelativeLayout boxCustom;
- public PopMenuListView listMenu;
- public DialogImpl(View convertView) {
- if (convertView == null) return;
- setDialogView(convertView);
- boxRoot = convertView.findViewById(R.id.box_root);
- boxBody = convertView.findViewById(R.id.box_body);
- boxCustom = convertView.findViewById(R.id.box_custom);
- listMenu = convertView.findViewById(R.id.listMenu);
- boxBody.setVisibility(View.INVISIBLE);
- blurViews = findAllBlurView(convertView);
- //先设置为 -1 表示未初始化位置
- boxBody.setX(-1);
- boxBody.setY(-1);
- init();
- }
- @Override
- public void init() {
- closing = false;
- if (menuListAdapter == null) {
- menuListAdapter = new PopMenuArrayAdapter(me, getOwnActivity(), menuList);
- }
- boxRoot.setParentDialog(me);
- boxRoot.setOnLifecycleCallBack(new DialogXBaseRelativeLayout.OnLifecycleCallBack() {
- @Override
- public void onShow() {
- isShow = true;
- preShow = false;
- setLifecycleState(Lifecycle.State.CREATED);
- onDialogShow();
- getDialogLifecycleCallback().onShow(me);
- PopMenu.this.onShow(me);
- refreshUI();
- }
- @Override
- public void onDismiss() {
- isShow = false;
- getDialogLifecycleCallback().onDismiss(me);
- PopMenu.this.onDismiss(me);
- menuListAdapter = null;
- dialogImpl = null;
- baseView(null);
- dialogLifecycleCallback = null;
- setLifecycleState(Lifecycle.State.DESTROYED);
- System.gc();
- }
- });
- boxRoot.setOnBackPressedListener(new DialogXBaseRelativeLayout.PrivateBackPressedListener() {
- @Override
- public boolean onBackPressed() {
- if (onBackPressedListener != null) {
- if (onBackPressedListener.onBackPressed(me)) {
- dismiss();
- }
- } else {
- if (isCancelable()) {
- dismiss();
- }
- }
- return true;
- }
- });
- listMenu.setMaxHeight(getRootFrameLayout() == null ? dip2px(500) : getRootFrameLayout().getMeasuredHeight() - dip2px(150));
- boxBody.setVisibility(View.INVISIBLE);
- boxBody.post(new Runnable() {
- @Override
- public void run() {
- getDialogXAnimImpl().doShowAnim(me, boxBody);
- setLifecycleState(Lifecycle.State.RESUMED);
- Integer blurFrontColor = null;
- Float dialogXRadius = null;
- if (style.popMenuSettings() != null && style.popMenuSettings().blurBackgroundSettings() != null) {
- blurFrontColor = getColorNullable(getIntStyleAttr(style.popMenuSettings().blurBackgroundSettings().blurForwardColorRes(isLightTheme())));
- dialogXRadius = getFloatStyleAttr((float) style.popMenuSettings().blurBackgroundSettings().blurBackgroundRoundRadiusPx());
- }
- if (blurViews != null) {
- for (View blurView : blurViews) {
- ((BlurViewType) blurView).setOverlayColor(backgroundColor == null ? blurFrontColor : backgroundColor);
- ((BlurViewType) blurView).setRadiusPx(dialogXRadius);
- }
- }
- }
- });
- int dividerDrawableResId = 0;
- int dividerHeight = 0;
- if (style.popMenuSettings() != null) {
- dividerDrawableResId = style.popMenuSettings().overrideMenuDividerDrawableRes(isLightTheme());
- dividerHeight = style.popMenuSettings().overrideMenuDividerHeight(isLightTheme());
- }
- if (dividerDrawableResId == 0) {
- dividerDrawableResId = isLightTheme() ? R.drawable.rect_dialogx_material_menu_split_divider : R.drawable.rect_dialogx_material_menu_split_divider_night;
- }
- listMenu.setOverScrollMode(OVER_SCROLL_NEVER);
- listMenu.setVerticalScrollBarEnabled(false);
- listMenu.setDivider(getResources().getDrawable(dividerDrawableResId));
- listMenu.setDividerHeight(dividerHeight);
- listMenu.setOnItemClickListener(new AdapterView.OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- selectIndex = position;
- if (!closing) {
- if (!getOnMenuItemClickListener().onClick(me, menuList.get(position), position)) {
- dismiss();
- }
- }
- }
- });
- onDialogInit();
- }
- @Override
- public void refreshView() {
- if (boxRoot == null || getOwnActivity() == null) {
- return;
- }
- boxRoot.setRootPadding(screenPaddings[0], screenPaddings[1], screenPaddings[2], screenPaddings[3]);
- if (listMenu.getAdapter() == null) {
- listMenu.setAdapter(menuListAdapter);
- } else {
- if (menuListAdapter.getMenuList() != menuList) {
- menuListAdapter = new PopMenuArrayAdapter(me, getOwnActivity(), menuList);
- listMenu.setAdapter(menuListAdapter);
- } else {
- menuListAdapter.notifyDataSetChanged();
- }
- }
- if (bkgInterceptTouch) {
- if (isCancelable()) {
- boxRoot.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (onBackgroundMaskClickListener == null || !onBackgroundMaskClickListener.onClick(me, v)) {
- doDismiss(v);
- }
- }
- });
- } else {
- boxRoot.setOnClickListener(null);
- }
- } else {
- boxRoot.setClickable(false);
- }
- if (backgroundRadius > -1) {
- GradientDrawable gradientDrawable = (GradientDrawable) boxBody.getBackground();
- if (gradientDrawable != null) gradientDrawable.setCornerRadius(backgroundRadius);
- if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
- boxBody.setOutlineProvider(new ViewOutlineProvider() {
- @Override
- public void getOutline(View view, Outline outline) {
- outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), backgroundRadius);
- }
- });
- boxBody.setClipToOutline(true);
- }
- if (blurViews != null) {
- for (View blurView : blurViews) {
- ((BlurViewType) blurView).setRadiusPx(backgroundRadius);
- }
- }
- }
- if (onBindView != null && onBindView.getCustomView() != null) {
- onBindView.bindParent(boxCustom, me);
- boxCustom.setVisibility(View.VISIBLE);
- } else {
- boxCustom.setVisibility(View.GONE);
- }
- if (width != -1) {
- boxBody.setMaxWidth(width);
- boxBody.setMinimumWidth(width);
- }
- if (height != -1) {
- boxBody.setMaxHeight(height);
- boxBody.setMinimumHeight(height);
- }
- if (backgroundColor != null) {
- tintColor(boxBody, backgroundColor);
- if (blurViews != null) {
- for (View blurView : blurViews) {
- ((BlurViewType) blurView).setOverlayColor(backgroundColor);
- }
- }
- }
- onDialogRefreshUI();
- }
- @Override
- public void doDismiss(View v) {
- if (v != null) {
- v.setEnabled(false);
- }
- if (!dismissAnimFlag && boxRoot != null) {
- dismissAnimFlag = true;
- boxRoot.post(new Runnable() {
- @Override
- public void run() {
- getDialogXAnimImpl().doExitAnim(me, boxBody);
- runOnMainDelay(new Runnable() {
- @Override
- public void run() {
- if (baseViewDrawListener != null) {
- if (viewTreeObserver != null) {
- removeDrawListener(viewTreeObserver, baseViewDrawListener);
- } else {
- if (baseView() != null) {
- removeDrawListener(baseView().getViewTreeObserver(), baseViewDrawListener);
- }
- }
- baseViewDrawListener = null;
- viewTreeObserver = null;
- }
- dismiss(getDialogView());
- }
- }, getExitAnimationDuration(null));
- }
- });
- }
- }
- protected DialogXAnimInterface<PopMenu> getDialogXAnimImpl() {
- if (dialogXAnimImpl == null) {
- dialogXAnimImpl = new DialogXAnimInterface<PopMenu>() {
- int selectMenuIndex = -1;
- @Override
- public void doShowAnim(PopMenu dialog, ViewGroup dialogBodyView) {
- long enterAnimDurationTemp = getEnterAnimationDuration(null);
- if (baseView() != null) {
- //有绑定按钮的情况下
- int targetHeight = getBodyRealHeight();
- boxBody.getLayoutParams().height = 1;
- if (overlayBaseView && !listMenu.isCanScroll()) {
- if (baseView() instanceof TextView) {
- String baseText = ((TextView) baseView()).getText().toString();
- for (CharSequence c : menuList) {
- if (TextUtils.equals(c.toString(), baseText)) {
- selectMenuIndex = menuList.indexOf(c);
- break;
- }
- }
- }
- //找到已选中的项目
- if (selectMenuIndex != -1) {
- int[] viewLoc = new int[2];
- if (listMenu.getChildAt(selectMenuIndex) != null) {
- int itemHeight = listMenu.getChildAt(selectMenuIndex).getMeasuredHeight();
- listMenu.getChildAt(selectMenuIndex).getLocationInWindow(viewLoc);
- selectItemYDeviation = (int) ((baseView().getMeasuredHeight() / 2f) - (viewLoc[1] - boxBody.getY()) - (itemHeight / 2f));
- }
- }
- }
- refreshMenuLoc();
- selectItemYDeviation = (int) (getMenuLoc().getY() - baseViewLoc.getY());
- //展开动画
- ValueAnimator enterAnim = ValueAnimator.ofFloat(0f, 1f);
- enterAnim.setInterpolator(new DecelerateInterpolator());
- enterAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- if (!isShow || getDialogImpl() == null || getDialogImpl().boxBody == null)
- return;
- float animatedValue = (float) animation.getAnimatedValue();
- isEnterAnimRunning = !(animatedValue == 1f);
- DialogXViewLoc loc = getMenuLoc();
- int aimHeight = animatedValue == 1f ? ViewGroup.LayoutParams.WRAP_CONTENT : (int) (targetHeight * animatedValue);
- boxBody.getLayoutParams().height = aimHeight;
- boxBody.getLayoutParams().width = getWidth() == -1 ? baseView().getWidth() : getWidth();
- if ((boxBody.getY() + aimHeight) > boxRoot.getSafeHeight()) {
- boxBody.setY(boxRoot.getSafeHeight() - aimHeight);
- }
- float calX = loc.getX() != -1 ? loc.getX() : baseViewLoc.getX();
- float calY = baseViewLoc.getY() + selectItemYDeviation * animatedValue;
- if (!offScreen) {
- if (calX < 0) {
- calX = 0;
- }
- if (calY < 0) {
- calY = 0;
- }
- if ((calX + boxBody.getWidth()) > boxRoot.getUseAreaWidth()) {
- calX = boxRoot.getUseAreaWidth() - boxBody.getWidth();
- }
- if ((calY + boxBody.getHeight()) > boxRoot.getUseAreaHeight()) {
- calY = boxRoot.getUseAreaHeight() - boxBody.getHeight();
- }
- }
- boxBody.setX(calX);
- boxBody.setY(calY);
- boxBody.requestLayout();
- if (boxBody.getVisibility() != VISIBLE) {
- boxBody.setVisibility(View.VISIBLE);
- }
- if (isUseBlurBackground()) {
- boxRoot.setBkgAlpha((Float) animation.getAnimatedValue());
- }
- }
- });
- enterAnim.setInterpolator(new DecelerateInterpolator(2f));
- enterAnim.setDuration(enterAnimDurationTemp);
- enterAnim.start();
- } else {
- //无绑定按钮的情况下
- RelativeLayout.LayoutParams rLp = (RelativeLayout.LayoutParams) boxBody.getLayoutParams();
- rLp.addRule(RelativeLayout.CENTER_IN_PARENT);
- rLp.width = getWidth() == -1 ? RelativeLayout.LayoutParams.MATCH_PARENT : getWidth();
- rLp.leftMargin = dip2px(50);
- rLp.rightMargin = dip2px(50);
- boxBody.setLayoutParams(rLp);
- boxBody.setAlpha(0f);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && !isUseBlurBackground()) {
- boxBody.setElevation(dip2px(20));
- }
- boxBody.setVisibility(View.VISIBLE);
- boxBody.animate().alpha(1f).setDuration(enterAnimDurationTemp);
- ValueAnimator bkgAlpha = ValueAnimator.ofFloat(0f, 1f);
- bkgAlpha.setDuration(enterAnimDurationTemp);
- bkgAlpha.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- boxRoot.setBkgAlpha((Float) animation.getAnimatedValue());
- }
- });
- bkgAlpha.start();
- }
- }
- @Override
- public void doExitAnim(PopMenu dialog, ViewGroup dialogBodyView) {
- Animation exitAnim = AnimationUtils.loadAnimation(getOwnActivity() == null ? boxRoot.getContext() : getOwnActivity(), R.anim.anim_dialogx_default_exit);
- long exitAnimDuration = getExitAnimationDuration(exitAnim);
- exitAnim.setDuration(exitAnimDuration);
- boxBody.startAnimation(exitAnim);
- boxRoot.animate()
- .alpha(0f)
- .setInterpolator(new AccelerateInterpolator())
- .setDuration(exitAnimDuration);
- ValueAnimator bkgAlpha = ValueAnimator.ofFloat(1, 0f);
- bkgAlpha.setDuration(exitAnimDuration);
- bkgAlpha.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- if (boxRoot != null && baseView() == null) {
- boxRoot.setBkgAlpha((Float) animation.getAnimatedValue());
- }
- }
- });
- bkgAlpha.start();
- }
- };
- }
- return dialogXAnimImpl;
- }
- private boolean isUseBlurBackground() {
- return style.popMenuSettings() != null && style.popMenuSettings().blurBackgroundSettings() != null && style.popMenuSettings().blurBackgroundSettings().blurBackground();
- }
- public long getExitAnimationDuration(@Nullable Animation defaultExitAnim) {
- if (defaultExitAnim == null && boxBody.getAnimation() != null) {
- defaultExitAnim = boxBody.getAnimation();
- }
- long exitAnimDurationTemp = (defaultExitAnim == null || defaultExitAnim.getDuration() == 0) ? 150 : defaultExitAnim.getDuration();
- if (overrideExitDuration >= 0) {
- exitAnimDurationTemp = overrideExitDuration;
- }
- if (exitAnimDuration != -1) {
- exitAnimDurationTemp = exitAnimDuration;
- }
- return exitAnimDurationTemp;
- }
- public long getEnterAnimationDuration(@Nullable Animation defaultEnterAnim) {
- if (defaultEnterAnim == null && boxBody.getAnimation() != null) {
- defaultEnterAnim = boxBody.getAnimation();
- }
- long enterAnimDurationTemp = (defaultEnterAnim == null || defaultEnterAnim.getDuration() == 0) ? 150 : defaultEnterAnim.getDuration();
- if (overrideEnterDuration >= 0) {
- enterAnimDurationTemp = overrideEnterDuration;
- }
- if (enterAnimDuration >= 0) {
- enterAnimDurationTemp = enterAnimDuration;
- }
- return enterAnimDurationTemp;
- }
- }
- private void removeDrawListener(ViewTreeObserver viewTreeObserver, ViewTreeObserver.OnDrawListener listener) {
- if (viewTreeObserver == null || listener == null || !viewTreeObserver.isAlive()) {
- return;
- }
- try {
- viewTreeObserver.removeOnDrawListener(listener);
- } catch (Exception e) {
- }
- }
- private int getBodyRealHeight() {
- if (getDialogImpl() == null) {
- return 0;
- }
- int matchParentMeasureSpec = View.MeasureSpec.makeMeasureSpec(((View) getDialogImpl().boxBody.getParent()).getWidth(), View.MeasureSpec.EXACTLY);
- int wrapContentMeasureSpec = View.MeasureSpec.makeMeasureSpec(((View) getDialogImpl().boxBody.getParent()).getHeight(), View.MeasureSpec.AT_MOST);
- getDialogImpl().boxBody.measure(matchParentMeasureSpec, wrapContentMeasureSpec);
- return getDialogImpl().boxBody.getMeasuredHeight();
- }
- private boolean closing;
- public void dismiss() {
- closing = true;
- runOnMain(new Runnable() {
- @Override
- public void run() {
- if (dialogImpl == null) {
- return;
- }
- dialogImpl.doDismiss(null);
- }
- });
- }
- @Override
- public void restartDialog() {
- if (getDialogView() != null) {
- if (baseViewDrawListener != null) {
- if (viewTreeObserver != null) {
- removeDrawListener(viewTreeObserver, baseViewDrawListener);
- } else {
- if (baseView() != null) {
- removeDrawListener(baseView().getViewTreeObserver(), baseViewDrawListener);
- }
- }
- baseViewDrawListener = null;
- }
- dismiss(getDialogView());
- isShow = false;
- }
- if (getDialogImpl().boxCustom != null) {
- getDialogImpl().boxCustom.removeAllViews();
- }
- show();
- }
- @Override
- protected void shutdown() {
- }
- public List<CharSequence> getMenuList() {
- return menuList;
- }
- public PopMenu setMenuList(List<CharSequence> menuList) {
- this.menuList = new ArrayList<>();
- this.menuList.addAll(menuList);
- refreshUI();
- return this;
- }
- public PopMenu setMenuList(String[] menuList) {
- this.menuList = new ArrayList<>();
- this.menuList.addAll(Arrays.asList(menuList));
- refreshUI();
- return this;
- }
- public PopMenu setMenuList(CharSequence[] menuList) {
- this.menuList = new ArrayList<>();
- this.menuList.addAll(Arrays.asList(menuList));
- refreshUI();
- return this;
- }
- public void refreshUI() {
- if (getDialogImpl() == null) {
- return;
- }
- runOnMain(new Runnable() {
- @Override
- public void run() {
- if (dialogImpl != null) {
- dialogImpl.refreshView();
- }
- }
- });
- }
- @Override
- public boolean isCancelable() {
- return true;
- }
- public DialogImpl getDialogImpl() {
- return dialogImpl;
- }
- @Override
- public String dialogKey() {
- return getClass().getSimpleName() + "(" + Integer.toHexString(hashCode()) + ")";
- }
- public DialogLifecycleCallback<PopMenu> getDialogLifecycleCallback() {
- return dialogLifecycleCallback == null ? new DialogLifecycleCallback<PopMenu>() {
- } : dialogLifecycleCallback;
- }
- public PopMenu setDialogLifecycleCallback(DialogLifecycleCallback<PopMenu> dialogLifecycleCallback) {
- this.dialogLifecycleCallback = dialogLifecycleCallback;
- if (isShow) {
- dialogLifecycleCallback.onShow(me);
- }
- return this;
- }
- public boolean isOverlayBaseView() {
- return overlayBaseView;
- }
- public PopMenu setOverlayBaseView(boolean overlayBaseView) {
- this.overlayBaseView = overlayBaseView;
- refreshUI();
- return this;
- }
- public OnMenuItemClickListener<PopMenu> getOnMenuItemClickListener() {
- return onMenuItemClickListener == null ? new OnMenuItemClickListener<PopMenu>() {
- @Override
- public boolean onClick(PopMenu dialog, CharSequence text, int index) {
- return false;
- }
- } : onMenuItemClickListener;
- }
- public PopMenu setOnMenuItemClickListener(OnMenuItemClickListener<PopMenu> onMenuItemClickListener) {
- this.onMenuItemClickListener = onMenuItemClickListener;
- return this;
- }
- public OnIconChangeCallBack<PopMenu> getOnIconChangeCallBack() {
- return onIconChangeCallBack;
- }
- public PopMenu setOnIconChangeCallBack(OnIconChangeCallBack<PopMenu> onIconChangeCallBack) {
- this.onIconChangeCallBack = onIconChangeCallBack;
- return this;
- }
- public PopMenu setCustomView(OnBindView<PopMenu> onBindView) {
- this.onBindView = onBindView;
- refreshUI();
- return this;
- }
- public View getCustomView() {
- if (onBindView == null) {
- return null;
- }
- return onBindView.getCustomView();
- }
- public PopMenu removeCustomView() {
- this.onBindView.clean();
- refreshUI();
- return this;
- }
- public int getWidth() {
- return width;
- }
- /**
- * 设置菜单 UI 宽度(单位:像素)
- *
- * @param width 宽度(像素)
- * @return PopMenu实例
- */
- public PopMenu setWidth(int width) {
- this.width = width;
- refreshUI();
- return this;
- }
- public int getHeight() {
- return height;
- }
- /**
- * 设置菜单 UI 高度(单位:像素)
- *
- * @param height 高度(像素)
- * @return PopMenu实例
- */
- public PopMenu setHeight(int height) {
- this.height = height;
- refreshUI();
- return this;
- }
- public int getAlignGravity() {
- return alignGravity;
- }
- /**
- * 判断是否有设置对应的位置关系
- *
- * @param gravity 位置关系
- * @return 是否具备位置关系
- */
- public boolean isAlignGravity(int gravity) {
- return (alignGravity & gravity) == gravity;
- }
- public PopMenu setAlignGravity(int alignGravity) {
- this.alignGravity = alignGravity;
- refreshMenuLoc();
- return this;
- }
- public PopMenu setDialogImplMode(DialogX.IMPL_MODE dialogImplMode) {
- this.dialogImplMode = dialogImplMode;
- return this;
- }
- public TextInfo getMenuTextInfo() {
- if (menuTextInfo == null) {
- return DialogX.menuTextInfo;
- }
- return menuTextInfo;
- }
- public PopMenu setMenuTextInfo(TextInfo menuTextInfo) {
- this.menuTextInfo = menuTextInfo;
- return this;
- }
- public boolean isOffScreen() {
- return offScreen;
- }
- /**
- * 是否允许超出屏幕显示
- * PopMenu 默认位置显示在屏幕内,开启后将无视屏幕范围限制。
- *
- * @param offScreen 超出屏幕
- * @return PopMenu实例
- */
- public PopMenu setOffScreen(boolean offScreen) {
- this.offScreen = offScreen;
- return this;
- }
- public boolean isBkgInterceptTouch() {
- return bkgInterceptTouch;
- }
- public PopMenu setBkgInterceptTouch(boolean bkgInterceptTouch) {
- this.bkgInterceptTouch = bkgInterceptTouch;
- return this;
- }
- public OnBackgroundMaskClickListener<PopMenu> getOnBackgroundMaskClickListener() {
- return onBackgroundMaskClickListener;
- }
- public PopMenu setOnBackgroundMaskClickListener(OnBackgroundMaskClickListener<PopMenu> onBackgroundMaskClickListener) {
- this.onBackgroundMaskClickListener = onBackgroundMaskClickListener;
- refreshUI();
- return this;
- }
- public PopMenu setStyle(DialogXStyle style) {
- this.style = style;
- return this;
- }
- public PopMenu setTheme(DialogX.THEME theme) {
- this.theme = theme;
- return this;
- }
- public PopMenu setRadius(float radiusPx) {
- backgroundRadius = radiusPx;
- refreshUI();
- return this;
- }
- public float getRadius() {
- return backgroundRadius;
- }
- private boolean isHide;
- public void hide() {
- isHide = true;
- hideWithExitAnim = false;
- if (getDialogView() != null) {
- getDialogView().setVisibility(View.GONE);
- }
- }
- protected boolean hideWithExitAnim;
- public void hideWithExitAnim() {
- hideWithExitAnim = true;
- isHide = true;
- if (getDialogImpl() != null) {
- getDialogImpl().getDialogXAnimImpl().doExitAnim(me, getDialogImpl().boxBody);
- runOnMainDelay(new Runnable() {
- @Override
- public void run() {
- if (getDialogView() != null) {
- getDialogView().setVisibility(View.GONE);
- }
- }
- }, getDialogImpl().getExitAnimationDuration(null));
- }
- }
- public DialogXAnimInterface<PopMenu> getDialogXAnimImpl() {
- return dialogXAnimImpl;
- }
- public PopMenu setDialogXAnimImpl(DialogXAnimInterface<PopMenu> dialogXAnimImpl) {
- this.dialogXAnimImpl = dialogXAnimImpl;
- return this;
- }
- public OnBackPressedListener<PopMenu> getOnBackPressedListener() {
- return onBackPressedListener;
- }
- public PopMenu setOnBackPressedListener(OnBackPressedListener<PopMenu> onBackPressedListener) {
- this.onBackPressedListener = onBackPressedListener;
- return this;
- }
- public View getBaseView() {
- return baseView();
- }
- public PopMenu setBaseView(View baseView) {
- baseView(baseView);
- refreshUI();
- return this;
- }
- public PopMenu setRootPadding(int padding) {
- this.screenPaddings = new int[]{padding, padding, padding, padding};
- refreshUI();
- return this;
- }
- public PopMenu setRootPadding(int paddingLeft, int paddingTop, int paddingRight, int paddingBottom) {
- this.screenPaddings = new int[]{paddingLeft, paddingTop, paddingRight, paddingBottom};
- refreshUI();
- return this;
- }
- public int getPressedIndex() {
- return pressedIndex;
- }
- //设置已选择的菜单项(菜单背景会有选中状态的显示)
- public PopMenu setPressedIndex(int pressedIndex) {
- this.pressedIndex = pressedIndex;
- refreshUI();
- return this;
- }
- public int getSelectIndex() {
- return selectIndex;
- }
- public CharSequence getSelectMenuText() {
- if (menuList == null) return "";
- return menuList.get(selectIndex);
- }
- /**
- * 用于使用 new 构建实例时,override 的生命周期事件
- * 例如:
- * new PopMenu() {
- *
- * @param dialog self
- * @Override public void onShow(PopMenu dialog) {
- * //...
- * }
- * }
- */
- public void onShow(PopMenu dialog) {
- }
- /**
- * 用于使用 new 构建实例时,override 的生命周期事件
- * 例如:
- * new PopMenu() {
- *
- * @param dialog self
- * @Override public boolean onDismiss(PopMenu dialog) {
- * WaitDialog.show("Please Wait...");
- * if (dialog.getButtonSelectResult() == BUTTON_SELECT_RESULT.BUTTON_OK) {
- * //点击了OK的情况
- * //...
- * } else {
- * //其他按钮点击、对话框dismiss的情况
- * //...
- * }
- * return false;
- * }
- * }
- */
- //用于使用 new 构建实例时,override 的生命周期事件
- public void onDismiss(PopMenu dialog) {
- }
- public MenuItemLayoutRefreshCallback<PopMenu> getMenuMenuItemLayoutRefreshCallback() {
- return menuMenuItemLayoutRefreshCallback;
- }
- public PopMenu setMenuMenuItemLayoutRefreshCallback(MenuItemLayoutRefreshCallback<PopMenu> menuMenuItemLayoutRefreshCallback) {
- this.menuMenuItemLayoutRefreshCallback = menuMenuItemLayoutRefreshCallback;
- return this;
- }
- protected PopMenu baseView(View view) {
- if (view == null && baseViewWeakReference != null) {
- baseViewWeakReference.clear();
- baseViewWeakReference = null;
- } else {
- baseViewWeakReference = new WeakReference<>(view);
- }
- return this;
- }
- protected View baseView() {
- return baseViewWeakReference == null ? null : baseViewWeakReference.get();
- }
- }
|