/* * This file is part of FYReader. * FYReader is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * FYReader is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with FYReader. If not, see . * * Copyright (C) 2020 - 2022 fengyuecanzhu */ package com.kongzue.dialogx.dialogs; import android.animation.Animator; import android.animation.ObjectAnimator; import android.app.Activity; import android.content.res.Configuration; import android.graphics.Rect; import android.os.Handler; import android.os.Looper; import android.view.View; import android.view.ViewGroup; import android.view.animation.AccelerateInterpolator; import android.view.animation.DecelerateInterpolator; import android.widget.RelativeLayout; import androidx.annotation.ColorInt; import androidx.annotation.ColorRes; import com.kongzue.dialogx.DialogX; import com.kongzue.dialogx.R; import com.kongzue.dialogx.impl.AnimatorListenerEndCallBack; import com.kongzue.dialogx.interfaces.BaseDialog; import com.kongzue.dialogx.interfaces.DialogConvertViewInterface; import com.kongzue.dialogx.interfaces.DialogLifecycleCallback; import com.kongzue.dialogx.interfaces.DialogXStyle; import com.kongzue.dialogx.interfaces.OnBackPressedListener; import com.kongzue.dialogx.interfaces.OnBindView; import com.kongzue.dialogx.interfaces.OnSafeInsetsChangeListener; import com.kongzue.dialogx.util.FullScreenDialogTouchEventInterceptor; import com.kongzue.dialogx.util.views.ActivityScreenShotImageView; import com.kongzue.dialogx.util.views.DialogXBaseRelativeLayout; import com.kongzue.dialogx.util.views.MaxRelativeLayout; /** * @author: Kongzue * @github: https://github.com/kongzue/ * @homepage: http://kongzue.com/ * @mail: myzcxhh@live.cn * @createTime: 2020/10/6 15:17 */ public class FullScreenDialog extends BaseDialog { public static int overrideEnterDuration = -1; public static int overrideExitDuration = -1; public static BOOLEAN overrideCancelable; protected OnBindView onBindView; protected BOOLEAN privateCancelable; protected DialogLifecycleCallback dialogLifecycleCallback; protected FullScreenDialog me = this; protected FullScreenDialog() { super(); } private View dialogView; public static FullScreenDialog build() { return new FullScreenDialog(); } public FullScreenDialog(OnBindView onBindView) { this.onBindView = onBindView; } public static FullScreenDialog show(OnBindView onBindView) { FullScreenDialog fullScreenDialog = new FullScreenDialog(onBindView); fullScreenDialog.show(); return fullScreenDialog; } public void show() { super.beforeShow(); dialogView = createView(isLightTheme() ? R.layout.layout_dialogx_fullscreen : R.layout.layout_dialogx_fullscreen_dark); dialogImpl = new DialogImpl(dialogView); dialogView.setTag(me); show(dialogView); } public void show(Activity activity) { super.beforeShow(); dialogView = createView(isLightTheme() ? R.layout.layout_dialogx_fullscreen : R.layout.layout_dialogx_fullscreen_dark); dialogImpl = new DialogImpl(dialogView); dialogView.setTag(me); show(activity, dialogView); } protected DialogImpl dialogImpl; public class DialogImpl implements DialogConvertViewInterface { private FullScreenDialogTouchEventInterceptor fullScreenDialogTouchEventInterceptor; public ActivityScreenShotImageView imgZoomActivity; public DialogXBaseRelativeLayout boxRoot; public RelativeLayout boxBkg; public MaxRelativeLayout bkg; public RelativeLayout boxCustom; public DialogImpl(View convertView) { imgZoomActivity = convertView.findViewById(R.id.img_zoom_activity); boxRoot = convertView.findViewById(R.id.box_root); boxBkg = convertView.findViewById(R.id.box_bkg); bkg = convertView.findViewById(R.id.bkg); boxCustom = convertView.findViewById(R.id.box_custom); init(); dialogImpl = this; refreshView(); } public float bkgEnterAimY = -1; private long enterAnimDurationTemp = 300; @Override public void init() { boxRoot.setParentDialog(me); boxRoot.setOnLifecycleCallBack(new DialogXBaseRelativeLayout.OnLifecycleCallBack() { @Override public void onShow() { isShow = true; boxRoot.setAlpha(0f); getDialogLifecycleCallback().onShow(me); } @Override public void onDismiss() { isShow = false; getDialogLifecycleCallback().onDismiss(me); } }); boxRoot.setOnBackPressedListener(new OnBackPressedListener() { @Override public boolean onBackPressed() { if (onBackPressedListener != null && onBackPressedListener.onBackPressed()) { dismiss(); return false; } if (isCancelable()) { dismiss(); } return false; } }); fullScreenDialogTouchEventInterceptor = new FullScreenDialogTouchEventInterceptor(me, dialogImpl); enterAnimDurationTemp = 300; if (overrideEnterDuration >= 0) { enterAnimDurationTemp = overrideEnterDuration; } if (enterAnimDuration >= 0) { enterAnimDurationTemp = enterAnimDuration; } boxRoot.post(new Runnable() { @Override public void run() { bkgEnterAimY = boxRoot.getSafeHeight() - boxCustom.getHeight(); if (bkgEnterAimY < 0) bkgEnterAimY = 0; boxRoot.animate() .setDuration(enterAnimDurationTemp) .alpha(1f) .setInterpolator(new DecelerateInterpolator()) .setListener(null); ObjectAnimator exitAnim = ObjectAnimator.ofFloat(bkg, "y", boxRoot.getHeight(), bkgEnterAimY); exitAnim.setDuration(enterAnimDurationTemp); exitAnim.start(); } }); bkg.setOnYChanged(new MaxRelativeLayout.OnYChanged() { @Override public void y(float y) { float zoomScale = 1 - (boxRoot.getHeight() - y) * 0.00002f; if (zoomScale > 1) zoomScale = 1; imgZoomActivity.setScaleX(zoomScale); imgZoomActivity.setScaleY(zoomScale); imgZoomActivity.setRadius(dip2px(15) * ((boxRoot.getHeight() - y) / boxRoot.getHeight())); } }); boxRoot.setOnSafeInsetsChangeListener(new OnSafeInsetsChangeListener() { @Override public void onChange(Rect unsafeRect) { if (unsafeRect.bottom > dip2px(100)) { ObjectAnimator enterAnim = ObjectAnimator.ofFloat(bkg, "y", bkg.getY(), 0); enterAnim.setDuration(enterAnimDurationTemp); enterAnim.start(); } } }); } @Override public void refreshView() { if (backgroundColor != -1) { tintColor(bkg, backgroundColor); } if (isCancelable()) { boxRoot.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { doDismiss(v); } }); } else { boxRoot.setOnClickListener(null); } if (onBindView != null && onBindView.getCustomView() != null) { onBindView.bindParent(boxCustom, me); } fullScreenDialogTouchEventInterceptor.refresh(me, this); } @Override public void doDismiss(View v) { if (v != null) v.setEnabled(false); long exitAnimDurationTemp = 300; if (overrideExitDuration >= 0) { exitAnimDurationTemp = overrideExitDuration; } if (exitAnimDuration >= 0) { exitAnimDurationTemp = exitAnimDuration; } ObjectAnimator exitAnim = ObjectAnimator.ofFloat(bkg, "y", bkg.getY(), boxBkg.getHeight()); exitAnim.setDuration(exitAnimDurationTemp); exitAnim.start(); boxRoot.animate() .alpha(0f) .setInterpolator(new AccelerateInterpolator()) .setDuration(exitAnimDurationTemp); new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { @Override public void run() { dismiss(dialogView); } },exitAnimDurationTemp); } public void preDismiss() { if (isCancelable()) { doDismiss(boxRoot); } else { long exitAnimDurationTemp = 300; if (overrideExitDuration >= 0) { exitAnimDurationTemp = overrideExitDuration; } if (exitAnimDuration >= 0) { exitAnimDurationTemp = exitAnimDuration; } ObjectAnimator enterAnim = ObjectAnimator.ofFloat(bkg, "y", bkg.getY(), bkgEnterAimY); enterAnim.setDuration(exitAnimDurationTemp); enterAnim.start(); } } } @Override public String dialogKey() { return getClass().getSimpleName() + "(" + Integer.toHexString(hashCode()) + ")"; } public void refreshUI() { runOnMain(new Runnable() { @Override public void run() { if (dialogImpl != null) dialogImpl.refreshView(); } }); } public void dismiss() { if (dialogImpl == null) return; dialogImpl.doDismiss(null); } public DialogLifecycleCallback getDialogLifecycleCallback() { return dialogLifecycleCallback == null ? new DialogLifecycleCallback() { } : dialogLifecycleCallback; } public FullScreenDialog setDialogLifecycleCallback(DialogLifecycleCallback dialogLifecycleCallback) { this.dialogLifecycleCallback = dialogLifecycleCallback; if (isShow) dialogLifecycleCallback.onShow(me); return this; } public OnBackPressedListener getOnBackPressedListener() { return onBackPressedListener; } public FullScreenDialog setOnBackPressedListener(OnBackPressedListener onBackPressedListener) { this.onBackPressedListener = onBackPressedListener; refreshUI(); return this; } public FullScreenDialog setStyle(DialogXStyle style) { this.style = style; return this; } public FullScreenDialog setTheme(DialogX.THEME theme) { this.theme = theme; return this; } public boolean isCancelable() { if (privateCancelable != null) { return privateCancelable == BOOLEAN.TRUE; } if (overrideCancelable != null) { return overrideCancelable == BOOLEAN.TRUE; } return cancelable; } public FullScreenDialog setCancelable(boolean cancelable) { this.privateCancelable = cancelable ? BOOLEAN.TRUE : BOOLEAN.FALSE; refreshUI(); return this; } public DialogImpl getDialogImpl() { return dialogImpl; } public FullScreenDialog setCustomView(OnBindView onBindView) { this.onBindView = onBindView; refreshUI(); return this; } public View getCustomView() { if (onBindView == null) return null; return onBindView.getCustomView(); } public FullScreenDialog removeCustomView() { this.onBindView.clean(); refreshUI(); return this; } public int getBackgroundColor() { return backgroundColor; } public FullScreenDialog setBackgroundColor(@ColorInt int backgroundColor) { this.backgroundColor = backgroundColor; refreshUI(); return this; } public FullScreenDialog setBackgroundColorRes(@ColorRes int backgroundColorRes) { this.backgroundColor = getColor(backgroundColorRes); refreshUI(); return this; } public long getEnterAnimDuration() { return enterAnimDuration; } public FullScreenDialog setEnterAnimDuration(long enterAnimDuration) { this.enterAnimDuration = enterAnimDuration; return this; } public long getExitAnimDuration() { return exitAnimDuration; } public FullScreenDialog setExitAnimDuration(long exitAnimDuration) { this.exitAnimDuration = exitAnimDuration; return this; } @Override public void onUIModeChange(Configuration newConfig) { if (dialogView != null) { dismiss(dialogView); } if (getDialogImpl().boxCustom != null) { getDialogImpl().boxCustom.removeAllViews(); } enterAnimDuration = 0; dialogView = createView(isLightTheme() ? R.layout.layout_dialogx_fullscreen : R.layout.layout_dialogx_fullscreen_dark); dialogImpl = new DialogImpl(dialogView); dialogView.setTag(me); show(dialogView); } }