parent
1a32d43d1c
commit
5b11f21f85
@ -0,0 +1 @@ |
|||||||
|
/build |
@ -0,0 +1,90 @@ |
|||||||
|
apply plugin: 'com.android.library' |
||||||
|
apply plugin: 'android-maven' |
||||||
|
|
||||||
|
def siteUrl = 'https://github.com/kongzue/DialogX' //项目在github主页地址 |
||||||
|
def gitUrl = 'https://github.com/kongzue/DialogX.git' //Git仓库的地址 |
||||||
|
|
||||||
|
group = "com.kongzue.dialogx" |
||||||
|
|
||||||
|
android { |
||||||
|
compileSdkVersion 30 |
||||||
|
|
||||||
|
defaultConfig { |
||||||
|
minSdkVersion 21 |
||||||
|
targetSdkVersion 30 |
||||||
|
versionCode 10 |
||||||
|
versionName "1.0" |
||||||
|
|
||||||
|
consumerProguardFiles "consumer-rules.pro" |
||||||
|
|
||||||
|
renderscriptTargetApi 21 |
||||||
|
renderscriptSupportModeEnabled true // Enable RS support |
||||||
|
} |
||||||
|
|
||||||
|
buildTypes { |
||||||
|
release { |
||||||
|
minifyEnabled false |
||||||
|
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
//install { |
||||||
|
// repositories.mavenInstaller { |
||||||
|
// // This generates POM.xml with proper parameters |
||||||
|
// pom { |
||||||
|
// project { |
||||||
|
// packaging 'aar' |
||||||
|
// name 'dialogx' |
||||||
|
// url siteUrl |
||||||
|
// licenses { |
||||||
|
// license { |
||||||
|
// name 'The Apache Software License, Version 2.0' |
||||||
|
// url 'http://www.apache.org/licenses/LICENSE-2.0.txt' |
||||||
|
// } |
||||||
|
// } |
||||||
|
// developers { |
||||||
|
// developer { |
||||||
|
// id 'myzchh'//设置自己ID |
||||||
|
// name 'myzchh'//设置自己名字 |
||||||
|
// email 'myzcxhh@live.cn'//设置自己邮箱 |
||||||
|
// } |
||||||
|
// } |
||||||
|
// scm { |
||||||
|
// connection gitUrl |
||||||
|
// developerConnection gitUrl |
||||||
|
// url siteUrl |
||||||
|
// } |
||||||
|
// } |
||||||
|
// } |
||||||
|
// } |
||||||
|
//} |
||||||
|
task sourcesJar(type: Jar) { |
||||||
|
from android.sourceSets.main.java.srcDirs |
||||||
|
classifier = 'sources' |
||||||
|
} |
||||||
|
|
||||||
|
artifacts { |
||||||
|
archives sourcesJar |
||||||
|
} |
||||||
|
|
||||||
|
//Properties properties = new Properties() |
||||||
|
//properties.load(project.rootProject.file('local.properties').newDataInputStream()) |
||||||
|
//bintray { |
||||||
|
// user = properties.getProperty("bintray.user") |
||||||
|
// key = properties.getProperty("bintray.apikey") |
||||||
|
// configurations = ['archives'] |
||||||
|
// pkg { |
||||||
|
// repo = "maven" |
||||||
|
// name = "dialogX" //项目在JCenter的名字 |
||||||
|
// websiteUrl = siteUrl |
||||||
|
// vcsUrl = gitUrl |
||||||
|
// licenses = ["Apache-2.0"] |
||||||
|
// publish = true |
||||||
|
// } |
||||||
|
//} |
||||||
|
dependencies { |
||||||
|
implementation fileTree(dir: "libs", include: ["*.jar"]) |
||||||
|
implementation 'androidx.appcompat:appcompat:1.2.0+' |
||||||
|
api files('libs\\DialogXInterface.jar') |
||||||
|
} |
@ -0,0 +1,21 @@ |
|||||||
|
# Add project specific ProGuard rules here. |
||||||
|
# You can control the set of applied configuration files using the |
||||||
|
# proguardFiles setting in build.gradle. |
||||||
|
# |
||||||
|
# For more details, see |
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html |
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following |
||||||
|
# and specify the fully qualified class name to the JavaScript interface |
||||||
|
# class: |
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview { |
||||||
|
# public *; |
||||||
|
#} |
||||||
|
|
||||||
|
# Uncomment this to preserve the line number information for |
||||||
|
# debugging stack traces. |
||||||
|
#-keepattributes SourceFile,LineNumberTable |
||||||
|
|
||||||
|
# If you keep the line number information, uncomment this to |
||||||
|
# hide the original source file name. |
||||||
|
#-renamesourcefileattribute SourceFile |
@ -0,0 +1,4 @@ |
|||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
package="com.kongzue.dialogx"> |
||||||
|
|
||||||
|
</manifest> |
@ -0,0 +1,131 @@ |
|||||||
|
package com.kongzue.dialogx; |
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.util.Log; |
||||||
|
|
||||||
|
import com.kongzue.dialogx.interfaces.BaseDialog; |
||||||
|
import com.kongzue.dialogx.interfaces.DialogLifecycleCallback; |
||||||
|
import com.kongzue.dialogx.interfaces.DialogXStyle; |
||||||
|
import com.kongzue.dialogx.style.MaterialStyle; |
||||||
|
import com.kongzue.dialogx.util.InputInfo; |
||||||
|
import com.kongzue.dialogx.util.TextInfo; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author: Kongzue |
||||||
|
* @github: https://github.com/kongzue/
|
||||||
|
* @homepage: http://kongzue.com/
|
||||||
|
* @mail: myzcxhh@live.cn |
||||||
|
* @createTime: 2020/9/21 17:07 |
||||||
|
*/ |
||||||
|
public class DialogX { |
||||||
|
|
||||||
|
public static final String ERROR_INIT_TIPS = "DialogX.init: 初始化异常,context 为 null 或未初始化,详情请查看 https://github.com/kongzue/DialogX/wiki"; |
||||||
|
|
||||||
|
//开启日志
|
||||||
|
public static boolean DEBUGMODE = true; |
||||||
|
|
||||||
|
//全局主题风格
|
||||||
|
public static DialogXStyle globalStyle = MaterialStyle.style(); |
||||||
|
|
||||||
|
//全局对话框明暗风格
|
||||||
|
public static DialogX.THEME globalTheme = DialogX.THEME.LIGHT; |
||||||
|
|
||||||
|
//TipDialog 和 WaitDialog 明暗风格,不设置则默认根据 globalTheme 定义
|
||||||
|
public static DialogX.THEME tipTheme; |
||||||
|
|
||||||
|
//DialogX 实现模式(实验性功能)
|
||||||
|
public static IMPL_MODE implIMPLMode = IMPL_MODE.VIEW; |
||||||
|
|
||||||
|
//对话框最大宽度(像素)
|
||||||
|
public static int dialogMaxWidth; |
||||||
|
|
||||||
|
//是否允许 InputDialog 自动弹出键盘
|
||||||
|
public static boolean autoShowInputKeyboard = true; |
||||||
|
|
||||||
|
//同时只显示一个 PopTip
|
||||||
|
public static boolean onlyOnePopTip = false; |
||||||
|
|
||||||
|
//默认按钮文字样式
|
||||||
|
public static TextInfo buttonTextInfo; |
||||||
|
|
||||||
|
//默认确定按钮文字样式
|
||||||
|
public static TextInfo okButtonTextInfo; |
||||||
|
|
||||||
|
//默认标题文字样式
|
||||||
|
public static TextInfo titleTextInfo; |
||||||
|
|
||||||
|
//默认内容文字样式
|
||||||
|
public static TextInfo messageTextInfo; |
||||||
|
|
||||||
|
//默认 WaitDialog 和 TipDialog 文字样式
|
||||||
|
public static TextInfo tipTextInfo; |
||||||
|
|
||||||
|
//默认输入框文字样式
|
||||||
|
public static InputInfo inputInfo; |
||||||
|
|
||||||
|
//默认底部菜单、对话框的标题文字样式
|
||||||
|
public static TextInfo menuTitleInfo; |
||||||
|
|
||||||
|
//默认底部菜单文本样式
|
||||||
|
public static TextInfo menuTextInfo; |
||||||
|
|
||||||
|
//默认对话框背景颜色(值为 ColorInt,为-1不生效)
|
||||||
|
public static int backgroundColor = -1; |
||||||
|
|
||||||
|
//默认 TipDialog 和 WaitDialog 背景颜色(值为 ColorInt,为-1不生效)
|
||||||
|
public static int tipBackgroundColor = -1; |
||||||
|
|
||||||
|
/** |
||||||
|
* 重写 TipDialog 和 WaitDialog 进度动画颜色, |
||||||
|
* 注意此属性为覆盖性质,即设置此值将替换提示框原本的进度动画的颜色,包括亮暗色切换的颜色变化也将被替代 |
||||||
|
* (值为 ColorInt,为-1不生效) |
||||||
|
*/ |
||||||
|
public static int tipProgressColor = -1; |
||||||
|
|
||||||
|
//默认对话框默认是否可以点击外围遮罩区域或返回键关闭,此开关不影响提示框(TipDialog)以及等待框(TipDialog)
|
||||||
|
public static boolean cancelable = true; |
||||||
|
|
||||||
|
//默认提示框及等待框(WaitDialog、TipDialog)默认是否可以关闭
|
||||||
|
public static boolean cancelableTipDialog = false; |
||||||
|
|
||||||
|
//默认取消按钮文本文字,影响 BottomDialog
|
||||||
|
public static String cancelButtonText; |
||||||
|
|
||||||
|
//默认 PopTip 文本样式
|
||||||
|
public static TextInfo popTextInfo; |
||||||
|
|
||||||
|
//默认启动对话框动画时长
|
||||||
|
public static long enterAnimDuration = -1; |
||||||
|
|
||||||
|
//默认关闭对话框动画时长
|
||||||
|
public static long exitAnimDuration = -1; |
||||||
|
|
||||||
|
//全局 Dialog 生命周期监听器
|
||||||
|
public static DialogLifecycleCallback<BaseDialog> dialogLifeCycleListener; |
||||||
|
|
||||||
|
//是否自动在主线程执行
|
||||||
|
public static boolean autoRunOnUIThread = true; |
||||||
|
|
||||||
|
//使用振动反馈
|
||||||
|
public static boolean useHaptic = true; |
||||||
|
|
||||||
|
public enum THEME { |
||||||
|
LIGHT, DARK, AUTO |
||||||
|
} |
||||||
|
|
||||||
|
public enum IMPL_MODE { |
||||||
|
VIEW, WINDOW |
||||||
|
} |
||||||
|
|
||||||
|
public static void init(Context context) { |
||||||
|
if (context == null) { |
||||||
|
error(ERROR_INIT_TIPS); |
||||||
|
return; |
||||||
|
} |
||||||
|
BaseDialog.init(context); |
||||||
|
} |
||||||
|
|
||||||
|
public static void error(Object o) { |
||||||
|
if (DEBUGMODE) Log.e(">>>", o.toString()); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,952 @@ |
|||||||
|
package com.kongzue.dialogx.dialogs; |
||||||
|
|
||||||
|
import android.animation.Animator; |
||||||
|
import android.animation.ObjectAnimator; |
||||||
|
import android.app.Activity; |
||||||
|
import android.content.res.Configuration; |
||||||
|
import android.os.Handler; |
||||||
|
import android.os.Looper; |
||||||
|
import android.view.View; |
||||||
|
import android.view.ViewGroup; |
||||||
|
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.widget.ImageView; |
||||||
|
import android.widget.LinearLayout; |
||||||
|
import android.widget.RelativeLayout; |
||||||
|
import android.widget.ScrollView; |
||||||
|
import android.widget.TextView; |
||||||
|
|
||||||
|
import androidx.annotation.ColorInt; |
||||||
|
import androidx.annotation.ColorRes; |
||||||
|
import androidx.core.view.ViewCompat; |
||||||
|
|
||||||
|
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.OnDialogButtonClickListener; |
||||||
|
import com.kongzue.dialogx.util.BottomDialogTouchEventInterceptor; |
||||||
|
import com.kongzue.dialogx.util.TextInfo; |
||||||
|
import com.kongzue.dialogx.util.views.BlurView; |
||||||
|
import com.kongzue.dialogx.util.views.DialogXBaseRelativeLayout; |
||||||
|
import com.kongzue.dialogx.util.views.MaxRelativeLayout; |
||||||
|
|
||||||
|
import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_CLICK; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author: Kongzue |
||||||
|
* @github: https://github.com/kongzue/
|
||||||
|
* @homepage: http://kongzue.com/
|
||||||
|
* @mail: myzcxhh@live.cn |
||||||
|
* @createTime: 2020/10/6 15:17 |
||||||
|
*/ |
||||||
|
public class BottomDialog extends BaseDialog { |
||||||
|
|
||||||
|
public static int overrideEnterDuration = -1; |
||||||
|
public static int overrideExitDuration = -1; |
||||||
|
public static BOOLEAN overrideCancelable; |
||||||
|
protected OnBindView<BottomDialog> onBindView; |
||||||
|
protected CharSequence title; |
||||||
|
protected CharSequence message; |
||||||
|
protected CharSequence cancelText; |
||||||
|
protected CharSequence okText; |
||||||
|
protected CharSequence otherText; |
||||||
|
protected boolean allowInterceptTouch = true; |
||||||
|
protected int maskColor = -1; |
||||||
|
protected OnDialogButtonClickListener<BottomDialog> cancelButtonClickListener; |
||||||
|
protected OnDialogButtonClickListener<BottomDialog> okButtonClickListener; |
||||||
|
protected OnDialogButtonClickListener<BottomDialog> otherButtonClickListener; |
||||||
|
protected BOOLEAN privateCancelable; |
||||||
|
|
||||||
|
protected TextInfo titleTextInfo; |
||||||
|
protected TextInfo messageTextInfo; |
||||||
|
protected TextInfo cancelTextInfo = new TextInfo().setBold(true); |
||||||
|
protected TextInfo okTextInfo = new TextInfo().setBold(true); |
||||||
|
protected TextInfo otherTextInfo = new TextInfo().setBold(true); |
||||||
|
|
||||||
|
/** |
||||||
|
* 此值用于,当禁用滑动时(style.overrideBottomDialogRes.touchSlide = false时)的最大显示高度。 |
||||||
|
* 0:不限制,最大显示到屏幕可用高度。 |
||||||
|
*/ |
||||||
|
protected float bottomDialogMaxHeight = 0.6f; |
||||||
|
|
||||||
|
protected DialogLifecycleCallback<BottomDialog> dialogLifecycleCallback; |
||||||
|
|
||||||
|
protected BottomDialog me = this; |
||||||
|
|
||||||
|
protected BottomDialog() { |
||||||
|
super(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String dialogKey() { |
||||||
|
return getClass().getSimpleName() + "(" + Integer.toHexString(hashCode()) + ")"; |
||||||
|
} |
||||||
|
|
||||||
|
private View dialogView; |
||||||
|
|
||||||
|
public static BottomDialog build() { |
||||||
|
return new BottomDialog(); |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog(CharSequence title, CharSequence message) { |
||||||
|
this.title = title; |
||||||
|
this.message = message; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog(int titleResId, int messageResId) { |
||||||
|
this.title = getString(titleResId); |
||||||
|
this.message = getString(messageResId); |
||||||
|
} |
||||||
|
|
||||||
|
public static BottomDialog show(CharSequence title, CharSequence message) { |
||||||
|
BottomDialog bottomDialog = new BottomDialog(title, message); |
||||||
|
bottomDialog.show(); |
||||||
|
return bottomDialog; |
||||||
|
} |
||||||
|
|
||||||
|
public static BottomDialog show(int titleResId, int messageResId) { |
||||||
|
BottomDialog bottomDialog = new BottomDialog(titleResId, messageResId); |
||||||
|
bottomDialog.show(); |
||||||
|
return bottomDialog; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog(CharSequence title, CharSequence message, OnBindView<BottomDialog> onBindView) { |
||||||
|
this.title = title; |
||||||
|
this.message = message; |
||||||
|
this.onBindView = onBindView; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog(int titleResId, int messageResId, OnBindView<BottomDialog> onBindView) { |
||||||
|
this.title = getString(titleResId); |
||||||
|
this.message = getString(messageResId); |
||||||
|
this.onBindView = onBindView; |
||||||
|
} |
||||||
|
|
||||||
|
public static BottomDialog show(CharSequence title, CharSequence message, OnBindView<BottomDialog> onBindView) { |
||||||
|
BottomDialog bottomDialog = new BottomDialog(title, message, onBindView); |
||||||
|
bottomDialog.show(); |
||||||
|
return bottomDialog; |
||||||
|
} |
||||||
|
|
||||||
|
public static BottomDialog show(int titleResId, int messageResId, OnBindView<BottomDialog> onBindView) { |
||||||
|
BottomDialog bottomDialog = new BottomDialog(titleResId, messageResId, onBindView); |
||||||
|
bottomDialog.show(); |
||||||
|
return bottomDialog; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog(CharSequence title, OnBindView<BottomDialog> onBindView) { |
||||||
|
this.title = title; |
||||||
|
this.onBindView = onBindView; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog(int titleResId, OnBindView<BottomDialog> onBindView) { |
||||||
|
this.title = getString(titleResId); |
||||||
|
this.onBindView = onBindView; |
||||||
|
} |
||||||
|
|
||||||
|
public static BottomDialog show(CharSequence title, OnBindView<BottomDialog> onBindView) { |
||||||
|
BottomDialog bottomDialog = new BottomDialog(title, onBindView); |
||||||
|
bottomDialog.show(); |
||||||
|
return bottomDialog; |
||||||
|
} |
||||||
|
|
||||||
|
public static BottomDialog show(int titleResId, OnBindView<BottomDialog> onBindView) { |
||||||
|
BottomDialog bottomDialog = new BottomDialog(titleResId, onBindView); |
||||||
|
bottomDialog.show(); |
||||||
|
return bottomDialog; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog(OnBindView<BottomDialog> onBindView) { |
||||||
|
this.onBindView = onBindView; |
||||||
|
} |
||||||
|
|
||||||
|
public static BottomDialog show(OnBindView<BottomDialog> onBindView) { |
||||||
|
BottomDialog bottomDialog = new BottomDialog(onBindView); |
||||||
|
bottomDialog.show(); |
||||||
|
return bottomDialog; |
||||||
|
} |
||||||
|
|
||||||
|
public void show() { |
||||||
|
super.beforeShow(); |
||||||
|
int layoutId = isLightTheme() ? R.layout.layout_dialogx_bottom_material : R.layout.layout_dialogx_bottom_material_dark; |
||||||
|
if (style.overrideBottomDialogRes() != null) { |
||||||
|
layoutId = style.overrideBottomDialogRes().overrideDialogLayout(isLightTheme()); |
||||||
|
} |
||||||
|
|
||||||
|
dialogView = createView(layoutId); |
||||||
|
dialogImpl = new DialogImpl(dialogView); |
||||||
|
dialogView.setTag(me); |
||||||
|
show(dialogView); |
||||||
|
} |
||||||
|
|
||||||
|
public void show(Activity activity) { |
||||||
|
super.beforeShow(); |
||||||
|
int layoutId = isLightTheme() ? R.layout.layout_dialogx_bottom_material : R.layout.layout_dialogx_bottom_material_dark; |
||||||
|
if (style.overrideBottomDialogRes() != null) { |
||||||
|
layoutId = style.overrideBottomDialogRes().overrideDialogLayout(isLightTheme()); |
||||||
|
} |
||||||
|
|
||||||
|
dialogView = createView(layoutId); |
||||||
|
dialogImpl = new DialogImpl(dialogView); |
||||||
|
dialogView.setTag(me); |
||||||
|
show(activity, dialogView); |
||||||
|
} |
||||||
|
|
||||||
|
protected DialogImpl dialogImpl; |
||||||
|
|
||||||
|
public class DialogImpl implements DialogConvertViewInterface { |
||||||
|
|
||||||
|
private BottomDialogTouchEventInterceptor bottomDialogTouchEventInterceptor; |
||||||
|
|
||||||
|
public DialogXBaseRelativeLayout boxRoot; |
||||||
|
public RelativeLayout boxBkg; |
||||||
|
public MaxRelativeLayout bkg; |
||||||
|
public ViewGroup boxBody; |
||||||
|
public ImageView imgTab; |
||||||
|
public TextView txtDialogTitle; |
||||||
|
public ScrollView scrollView; |
||||||
|
public LinearLayout boxContent; |
||||||
|
public TextView txtDialogTip; |
||||||
|
public View imgSplit; |
||||||
|
public RelativeLayout boxList; |
||||||
|
public RelativeLayout boxCustom; |
||||||
|
public BlurView blurView; |
||||||
|
public ViewGroup boxCancel; |
||||||
|
public TextView btnCancel; |
||||||
|
public BlurView cancelBlurView; |
||||||
|
|
||||||
|
public TextView btnSelectOther; |
||||||
|
public TextView btnSelectPositive; |
||||||
|
|
||||||
|
public DialogImpl(View convertView) { |
||||||
|
boxRoot = convertView.findViewById(R.id.box_root); |
||||||
|
boxBkg = convertView.findViewById(R.id.box_bkg); |
||||||
|
bkg = convertView.findViewById(R.id.bkg); |
||||||
|
boxBody = convertView.findViewWithTag("body"); |
||||||
|
imgTab = convertView.findViewById(R.id.img_tab); |
||||||
|
txtDialogTitle = convertView.findViewById(R.id.txt_dialog_title); |
||||||
|
scrollView = convertView.findViewById(R.id.scrollView); |
||||||
|
boxContent = convertView.findViewById(R.id.box_content); |
||||||
|
txtDialogTip = convertView.findViewById(R.id.txt_dialog_tip); |
||||||
|
imgSplit = convertView.findViewWithTag("split"); |
||||||
|
boxList = convertView.findViewById(R.id.box_list); |
||||||
|
boxCustom = convertView.findViewById(R.id.box_custom); |
||||||
|
blurView = convertView.findViewById(R.id.blurView); |
||||||
|
boxCancel = convertView.findViewWithTag("cancelBox"); |
||||||
|
btnCancel = convertView.findViewWithTag("cancel"); |
||||||
|
|
||||||
|
btnSelectOther = convertView.findViewById(R.id.btn_selectOther); |
||||||
|
btnSelectPositive = convertView.findViewById(R.id.btn_selectPositive); |
||||||
|
|
||||||
|
init(); |
||||||
|
dialogImpl = this; |
||||||
|
refreshView(); |
||||||
|
} |
||||||
|
|
||||||
|
public void reBuild() { |
||||||
|
init(); |
||||||
|
dialogImpl = this; |
||||||
|
refreshView(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 此值记录了BottomDialog启动后的位置 |
||||||
|
* ·当内容高度大于屏幕安全区高度时,BottomDialog会以全屏方式启动,但一开始只会展开到 0.8×屏幕高度, |
||||||
|
* 此时可以再次上划查看全部内容。 |
||||||
|
* ·当内容高度小于屏幕安全区高度时,BottomDialog会以内容高度启动。 |
||||||
|
* <p> |
||||||
|
* 记录这个值的目的是,当用户向下滑动时,判断情况该回到这个位置还是关闭对话框, |
||||||
|
* 并阻止当内容高度已经完全显示时的继续向上滑动操作。 |
||||||
|
*/ |
||||||
|
public float bkgEnterAimY = -1; |
||||||
|
|
||||||
|
@Override |
||||||
|
public void init() { |
||||||
|
if (titleTextInfo == null) titleTextInfo = DialogX.menuTitleInfo; |
||||||
|
if (titleTextInfo == null) titleTextInfo = DialogX.titleTextInfo; |
||||||
|
if (messageTextInfo == null) messageTextInfo = DialogX.messageTextInfo; |
||||||
|
if (okTextInfo == null) okTextInfo = DialogX.okButtonTextInfo; |
||||||
|
if (okTextInfo == null) okTextInfo = DialogX.buttonTextInfo; |
||||||
|
if (cancelTextInfo == null) cancelTextInfo = DialogX.buttonTextInfo; |
||||||
|
if (otherTextInfo == null) otherTextInfo = DialogX.buttonTextInfo; |
||||||
|
if (backgroundColor == -1) backgroundColor = DialogX.backgroundColor; |
||||||
|
if (cancelText == null) cancelText = DialogX.cancelButtonText; |
||||||
|
|
||||||
|
txtDialogTitle.getPaint().setFakeBoldText(true); |
||||||
|
if (btnCancel != null) btnCancel.getPaint().setFakeBoldText(true); |
||||||
|
if (btnSelectPositive != null) btnSelectPositive.getPaint().setFakeBoldText(true); |
||||||
|
if (btnSelectOther != null) btnSelectOther.getPaint().setFakeBoldText(true); |
||||||
|
|
||||||
|
boxRoot.setParentDialog(me); |
||||||
|
boxRoot.setOnLifecycleCallBack(new DialogXBaseRelativeLayout.OnLifecycleCallBack() { |
||||||
|
@Override |
||||||
|
public void onShow() { |
||||||
|
bkg.setY(getRootFrameLayout().getMeasuredHeight()); |
||||||
|
|
||||||
|
isShow = true; |
||||||
|
boxRoot.setAlpha(0f); |
||||||
|
|
||||||
|
boxContent.getViewTreeObserver().addOnGlobalLayoutListener(onContentViewLayoutChangeListener); |
||||||
|
|
||||||
|
getDialogLifecycleCallback().onShow(me); |
||||||
|
|
||||||
|
onDialogInit(dialogImpl); |
||||||
|
|
||||||
|
boxRoot.post(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
if (style.messageDialogBlurSettings() != null && style.messageDialogBlurSettings().blurBackground() && boxBody != null && boxCancel != null) { |
||||||
|
int blurFrontColor = getResources().getColor(style.messageDialogBlurSettings().blurForwardColorRes(isLightTheme())); |
||||||
|
blurView = new BlurView(bkg.getContext(), null); |
||||||
|
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(bkg.getWidth(), bkg.getHeight()); |
||||||
|
blurView.setOverlayColor(backgroundColor == -1 ? blurFrontColor : backgroundColor); |
||||||
|
blurView.setTag("blurView"); |
||||||
|
blurView.setRadiusPx(style.messageDialogBlurSettings().blurBackgroundRoundRadiusPx()); |
||||||
|
boxBody.addView(blurView, 0, params); |
||||||
|
|
||||||
|
cancelBlurView = new BlurView(boxCancel.getContext(), null); |
||||||
|
RelativeLayout.LayoutParams cancelButtonLp = new RelativeLayout.LayoutParams(boxCancel.getWidth(), boxCancel.getHeight()); |
||||||
|
cancelBlurView.setOverlayColor(backgroundColor == -1 ? blurFrontColor : backgroundColor); |
||||||
|
cancelBlurView.setTag("blurView"); |
||||||
|
cancelBlurView.setRadiusPx(style.messageDialogBlurSettings().blurBackgroundRoundRadiusPx()); |
||||||
|
boxCancel.addView(cancelBlurView, 0, cancelButtonLp); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onDismiss() { |
||||||
|
isShow = false; |
||||||
|
getDialogLifecycleCallback().onDismiss(me); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
if (btnCancel != null) { |
||||||
|
btnCancel.setOnClickListener(new View.OnClickListener() { |
||||||
|
@Override |
||||||
|
public void onClick(View v) { |
||||||
|
if (cancelButtonClickListener != null) { |
||||||
|
if (!cancelButtonClickListener.onClick(me, v)) { |
||||||
|
dismiss(); |
||||||
|
} |
||||||
|
} else { |
||||||
|
dismiss(); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
if (btnSelectOther != null) { |
||||||
|
btnSelectOther.setOnClickListener(new View.OnClickListener() { |
||||||
|
@Override |
||||||
|
public void onClick(View v) { |
||||||
|
if (otherButtonClickListener != null) { |
||||||
|
if (!otherButtonClickListener.onClick(me, v)) { |
||||||
|
dismiss(); |
||||||
|
} |
||||||
|
} else { |
||||||
|
dismiss(); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
if (btnSelectPositive != null) { |
||||||
|
btnSelectPositive.setOnClickListener(new View.OnClickListener() { |
||||||
|
@Override |
||||||
|
public void onClick(View v) { |
||||||
|
if (okButtonClickListener != null) { |
||||||
|
if (!okButtonClickListener.onClick(me, v)) { |
||||||
|
dismiss(); |
||||||
|
} |
||||||
|
} else { |
||||||
|
dismiss(); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
if (imgSplit != null) { |
||||||
|
int dividerRes = style.overrideBottomDialogRes().overrideMenuDividerDrawableRes(isLightTheme()); |
||||||
|
int dividerHeight = style.overrideBottomDialogRes().overrideMenuDividerHeight(isLightTheme()); |
||||||
|
if (dividerRes != 0) imgSplit.setBackgroundResource(dividerRes); |
||||||
|
if (dividerHeight != 0) { |
||||||
|
ViewGroup.LayoutParams lp = imgSplit.getLayoutParams(); |
||||||
|
lp.height = dividerHeight; |
||||||
|
imgSplit.setLayoutParams(lp); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
boxRoot.setOnBackPressedListener(new OnBackPressedListener() { |
||||||
|
@Override |
||||||
|
public boolean onBackPressed() { |
||||||
|
if (onBackPressedListener != null && onBackPressedListener.onBackPressed()) { |
||||||
|
dismiss(); |
||||||
|
return false; |
||||||
|
} |
||||||
|
if (isCancelable()) { |
||||||
|
dismiss(); |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
bottomDialogTouchEventInterceptor = new BottomDialogTouchEventInterceptor(me, dialogImpl); |
||||||
|
|
||||||
|
boxRoot.post(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
long enterAnimDurationTemp = 300; |
||||||
|
/** |
||||||
|
* 对于非支持滑动展开的对话框,直接使用从下往上的资源动画实现 |
||||||
|
* 其他情况不适用,请参考 onContentViewLayoutChangeListener 的代码实现。 |
||||||
|
*/ |
||||||
|
if (style.overrideBottomDialogRes() == null || !style.overrideBottomDialogRes().touchSlide()) { |
||||||
|
//bkg.setY(getRootFrameLayout().getMeasuredHeight());
|
||||||
|
Animation enterAnim = AnimationUtils.loadAnimation(getContext(), R.anim.anim_dialogx_bottom_enter); |
||||||
|
enterAnimDurationTemp = enterAnim.getDuration(); |
||||||
|
if (overrideEnterDuration >= 0) { |
||||||
|
enterAnimDurationTemp = overrideEnterDuration; |
||||||
|
} |
||||||
|
if (enterAnimDuration >= 0) { |
||||||
|
enterAnimDurationTemp = enterAnimDuration; |
||||||
|
} |
||||||
|
enterAnim.setDuration(enterAnimDurationTemp); |
||||||
|
enterAnim.setInterpolator(new DecelerateInterpolator(2f)); |
||||||
|
|
||||||
|
bkg.setY(bkgEnterAimY); |
||||||
|
bkg.startAnimation(enterAnim); |
||||||
|
} |
||||||
|
|
||||||
|
boxRoot.animate() |
||||||
|
.setDuration(enterAnimDurationTemp) |
||||||
|
.alpha(1f) |
||||||
|
.setInterpolator(new DecelerateInterpolator()) |
||||||
|
.setListener(null); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
private boolean isEnterAnimFinished = false; |
||||||
|
|
||||||
|
private ViewTreeObserver.OnGlobalLayoutListener onContentViewLayoutChangeListener = new ViewTreeObserver.OnGlobalLayoutListener() { |
||||||
|
@Override |
||||||
|
public void onGlobalLayout() { |
||||||
|
if (boxContent != null) { |
||||||
|
if (style.overrideBottomDialogRes() != null &&style.overrideBottomDialogRes().touchSlide()) { |
||||||
|
//若内容布已经超出屏幕可用范围,且预设的对话框最大高度已知
|
||||||
|
if (bkg.isChildScrollViewCanScroll() && bottomDialogMaxHeight != 0) { |
||||||
|
//先将内容布局放置到屏幕底部以外区域,然后执行上移动画
|
||||||
|
if (!isEnterAnimFinished)bkg.setY(getRootFrameLayout().getMeasuredHeight()); |
||||||
|
//执行上移动画
|
||||||
|
if (bottomDialogMaxHeight <= 1) { |
||||||
|
//bottomDialogMaxHeight 值若为小于 1 的小数,视为比例
|
||||||
|
bkgEnterAimY = boxBkg.getHeight() - bkg.getHeight() * bottomDialogMaxHeight; |
||||||
|
} else { |
||||||
|
bkgEnterAimY = boxBkg.getHeight() - bottomDialogMaxHeight; |
||||||
|
} |
||||||
|
long enterAnimDurationTemp = 300; |
||||||
|
if (overrideEnterDuration >= 0) { |
||||||
|
enterAnimDurationTemp = overrideEnterDuration; |
||||||
|
} |
||||||
|
if (enterAnimDuration >= 0) { |
||||||
|
enterAnimDurationTemp = enterAnimDuration; |
||||||
|
} |
||||||
|
ObjectAnimator keepBottomAnim = ObjectAnimator.ofFloat(bkg, "y", bkg.getY(), bkgEnterAimY); |
||||||
|
keepBottomAnim.setDuration(enterAnimDurationTemp); |
||||||
|
keepBottomAnim.setInterpolator(new DecelerateInterpolator(2f)); |
||||||
|
keepBottomAnim.start(); |
||||||
|
} else { |
||||||
|
bkgEnterAimY = boxBkg.getHeight() - bkg.getHeight(); |
||||||
|
if (!isEnterAnimFinished)bkg.setY(boxRoot.getHeight()); |
||||||
|
bkg.post(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
ObjectAnimator enterAnim = ObjectAnimator.ofFloat(bkg, "y", bkg.getY(), bkgEnterAimY); |
||||||
|
long enterAnimDurationTemp = 300; |
||||||
|
if (overrideEnterDuration >= 0) { |
||||||
|
enterAnimDurationTemp = overrideEnterDuration; |
||||||
|
} |
||||||
|
if (enterAnimDuration >= 0) { |
||||||
|
enterAnimDurationTemp = enterAnimDuration; |
||||||
|
} |
||||||
|
enterAnim.setDuration(enterAnimDurationTemp); |
||||||
|
enterAnim.setInterpolator(new DecelerateInterpolator(2f)); |
||||||
|
enterAnim.start(); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
}else{ |
||||||
|
bkgEnterAimY = boxBkg.getHeight() - bkg.getHeight(); |
||||||
|
} |
||||||
|
} |
||||||
|
isEnterAnimFinished = true; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
@Override |
||||||
|
public void refreshView() { |
||||||
|
if (backgroundColor != -1) { |
||||||
|
tintColor(bkg, backgroundColor); |
||||||
|
if (blurView != null && cancelBlurView != null) { |
||||||
|
blurView.setOverlayColor(backgroundColor); |
||||||
|
cancelBlurView.setOverlayColor(backgroundColor); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
showText(txtDialogTitle, title); |
||||||
|
showText(txtDialogTip, message); |
||||||
|
|
||||||
|
useTextInfo(txtDialogTitle, titleTextInfo); |
||||||
|
useTextInfo(txtDialogTip, messageTextInfo); |
||||||
|
useTextInfo(btnCancel, cancelTextInfo); |
||||||
|
useTextInfo(btnSelectOther, otherTextInfo); |
||||||
|
useTextInfo(btnSelectPositive, okTextInfo); |
||||||
|
|
||||||
|
if (isCancelable()) { |
||||||
|
boxRoot.setOnClickListener(new View.OnClickListener() { |
||||||
|
@Override |
||||||
|
public void onClick(View v) { |
||||||
|
doDismiss(v); |
||||||
|
} |
||||||
|
}); |
||||||
|
} else { |
||||||
|
boxRoot.setOnClickListener(null); |
||||||
|
} |
||||||
|
boxBkg.setOnClickListener(new View.OnClickListener() { |
||||||
|
@Override |
||||||
|
public void onClick(View v) { |
||||||
|
boxRoot.callOnClick(); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
if (maskColor != -1) boxRoot.setBackgroundColor(maskColor); |
||||||
|
|
||||||
|
if (onBindView != null && onBindView.getCustomView() != null) { |
||||||
|
onBindView.bindParent(boxCustom, me); |
||||||
|
} |
||||||
|
|
||||||
|
if (isAllowInterceptTouch() && isCancelable()) { |
||||||
|
if (imgTab != null) imgTab.setVisibility(View.VISIBLE); |
||||||
|
} else { |
||||||
|
if (imgTab != null) imgTab.setVisibility(View.GONE); |
||||||
|
} |
||||||
|
|
||||||
|
bottomDialogTouchEventInterceptor.refresh(me, this); |
||||||
|
|
||||||
|
if (imgSplit != null) { |
||||||
|
if (txtDialogTitle.getVisibility() == View.VISIBLE || txtDialogTip.getVisibility() == View.VISIBLE) { |
||||||
|
imgSplit.setVisibility(View.VISIBLE); |
||||||
|
} else { |
||||||
|
imgSplit.setVisibility(View.GONE); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (boxCancel != null) { |
||||||
|
if (isNull(cancelText)) { |
||||||
|
boxCancel.setVisibility(View.GONE); |
||||||
|
} else { |
||||||
|
boxCancel.setVisibility(View.VISIBLE); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
showText(btnSelectPositive, okText); |
||||||
|
showText(btnCancel, cancelText); |
||||||
|
showText(btnSelectOther, otherText); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void doDismiss(View v) { |
||||||
|
if (v != null) v.setEnabled(false); |
||||||
|
|
||||||
|
if (boxContent != null) |
||||||
|
boxContent.getViewTreeObserver().removeOnGlobalLayoutListener(onContentViewLayoutChangeListener); |
||||||
|
|
||||||
|
ObjectAnimator exitAnim = ObjectAnimator.ofFloat(bkg, "y", bkg.getY(), boxBkg.getHeight()); |
||||||
|
long exitAnimDurationTemp = 300; |
||||||
|
if (overrideExitDuration >= 0) { |
||||||
|
exitAnimDurationTemp = overrideExitDuration; |
||||||
|
} |
||||||
|
if (exitAnimDuration >= 0) { |
||||||
|
exitAnimDurationTemp = exitAnimDuration; |
||||||
|
} |
||||||
|
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 exitAnim = ObjectAnimator.ofFloat(bkg, "y", bkg.getY(), bkgEnterAimY); |
||||||
|
exitAnim.setDuration(exitAnimDurationTemp); |
||||||
|
exitAnim.start(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected void onDialogInit(DialogImpl dialog) { |
||||||
|
} |
||||||
|
|
||||||
|
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<BottomDialog> getDialogLifecycleCallback() { |
||||||
|
return dialogLifecycleCallback == null ? new DialogLifecycleCallback<BottomDialog>() { |
||||||
|
} : dialogLifecycleCallback; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog setDialogLifecycleCallback(DialogLifecycleCallback<BottomDialog> dialogLifecycleCallback) { |
||||||
|
this.dialogLifecycleCallback = dialogLifecycleCallback; |
||||||
|
if (isShow) dialogLifecycleCallback.onShow(me); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public OnBackPressedListener getOnBackPressedListener() { |
||||||
|
return onBackPressedListener; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog setOnBackPressedListener(OnBackPressedListener onBackPressedListener) { |
||||||
|
this.onBackPressedListener = onBackPressedListener; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog setStyle(DialogXStyle style) { |
||||||
|
this.style = style; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog 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 BottomDialog setCancelable(boolean cancelable) { |
||||||
|
this.privateCancelable = cancelable ? BOOLEAN.TRUE : BOOLEAN.FALSE; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public DialogImpl getDialogImpl() { |
||||||
|
return dialogImpl; |
||||||
|
} |
||||||
|
|
||||||
|
public CharSequence getTitle() { |
||||||
|
return title; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog setTitle(CharSequence title) { |
||||||
|
this.title = title; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog setTitle(int titleResId) { |
||||||
|
this.title = getString(titleResId); |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public CharSequence getMessage() { |
||||||
|
return message; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog setMessage(CharSequence message) { |
||||||
|
this.message = message; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog setMessage(int messageResId) { |
||||||
|
this.message = getString(messageResId); |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public CharSequence getCancelButton() { |
||||||
|
return cancelText; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog setCancelButton(CharSequence cancelText) { |
||||||
|
this.cancelText = cancelText; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog setCancelButton(int cancelTextResId) { |
||||||
|
this.cancelText = getString(cancelTextResId); |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog setCancelButton(OnDialogButtonClickListener<BottomDialog> cancelButtonClickListener) { |
||||||
|
this.cancelButtonClickListener = cancelButtonClickListener; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog setCancelButton(CharSequence cancelText, OnDialogButtonClickListener<BottomDialog> cancelButtonClickListener) { |
||||||
|
this.cancelText = cancelText; |
||||||
|
this.cancelButtonClickListener = cancelButtonClickListener; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog setCancelButton(int cancelTextResId, OnDialogButtonClickListener<BottomDialog> cancelButtonClickListener) { |
||||||
|
this.cancelText = getString(cancelTextResId); |
||||||
|
this.cancelButtonClickListener = cancelButtonClickListener; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog setCustomView(OnBindView<BottomDialog> onBindView) { |
||||||
|
this.onBindView = onBindView; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public View getCustomView() { |
||||||
|
if (onBindView == null) return null; |
||||||
|
return onBindView.getCustomView(); |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog removeCustomView() { |
||||||
|
this.onBindView.clean(); |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isAllowInterceptTouch() { |
||||||
|
if (style.overrideBottomDialogRes() == null) { |
||||||
|
return false; |
||||||
|
} else { |
||||||
|
return allowInterceptTouch && style.overrideBottomDialogRes().touchSlide(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog setAllowInterceptTouch(boolean allowInterceptTouch) { |
||||||
|
this.allowInterceptTouch = allowInterceptTouch; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public OnDialogButtonClickListener<BottomDialog> getCancelButtonClickListener() { |
||||||
|
return cancelButtonClickListener; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog setCancelButtonClickListener(OnDialogButtonClickListener<BottomDialog> cancelButtonClickListener) { |
||||||
|
this.cancelButtonClickListener = cancelButtonClickListener; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public TextInfo getTitleTextInfo() { |
||||||
|
return titleTextInfo; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog setTitleTextInfo(TextInfo titleTextInfo) { |
||||||
|
this.titleTextInfo = titleTextInfo; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public TextInfo getMessageTextInfo() { |
||||||
|
return messageTextInfo; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog setMessageTextInfo(TextInfo messageTextInfo) { |
||||||
|
this.messageTextInfo = messageTextInfo; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public TextInfo getCancelTextInfo() { |
||||||
|
return cancelTextInfo; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog setCancelTextInfo(TextInfo cancelTextInfo) { |
||||||
|
this.cancelTextInfo = cancelTextInfo; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public int getBackgroundColor() { |
||||||
|
return backgroundColor; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog setBackgroundColor(@ColorInt int backgroundColor) { |
||||||
|
this.backgroundColor = backgroundColor; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog setBackgroundColorRes(@ColorRes int backgroundRes) { |
||||||
|
this.backgroundColor = getColor(backgroundRes); |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public CharSequence getOkButton() { |
||||||
|
return okText; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog setOkButton(CharSequence okText) { |
||||||
|
this.okText = okText; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog setOkButton(int OkTextResId) { |
||||||
|
this.okText = getString(OkTextResId); |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog setOkButton(OnDialogButtonClickListener<BottomDialog> OkButtonClickListener) { |
||||||
|
this.okButtonClickListener = OkButtonClickListener; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog setOkButton(CharSequence OkText, OnDialogButtonClickListener<BottomDialog> OkButtonClickListener) { |
||||||
|
this.okText = OkText; |
||||||
|
this.okButtonClickListener = OkButtonClickListener; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog setOkButton(int OkTextResId, OnDialogButtonClickListener<BottomDialog> OkButtonClickListener) { |
||||||
|
this.okText = getString(OkTextResId); |
||||||
|
this.okButtonClickListener = OkButtonClickListener; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public CharSequence getOtherButton() { |
||||||
|
return otherText; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog setOtherButton(CharSequence otherText) { |
||||||
|
this.otherText = otherText; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog setOtherButton(int OtherTextResId) { |
||||||
|
this.otherText = getString(OtherTextResId); |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog setOtherButton(OnDialogButtonClickListener<BottomDialog> OtherButtonClickListener) { |
||||||
|
this.otherButtonClickListener = OtherButtonClickListener; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog setOtherButton(CharSequence OtherText, OnDialogButtonClickListener<BottomDialog> OtherButtonClickListener) { |
||||||
|
this.otherText = OtherText; |
||||||
|
this.otherButtonClickListener = OtherButtonClickListener; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog setOtherButton(int OtherTextResId, OnDialogButtonClickListener<BottomDialog> OtherButtonClickListener) { |
||||||
|
this.otherText = getString(OtherTextResId); |
||||||
|
this.otherButtonClickListener = OtherButtonClickListener; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog setMaskColor(@ColorInt int maskColor) { |
||||||
|
this.maskColor = maskColor; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public long getEnterAnimDuration() { |
||||||
|
return enterAnimDuration; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog setEnterAnimDuration(long enterAnimDuration) { |
||||||
|
this.enterAnimDuration = enterAnimDuration; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public long getExitAnimDuration() { |
||||||
|
return exitAnimDuration; |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialog 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(); |
||||||
|
} |
||||||
|
if (getDialogImpl().boxList != null) { |
||||||
|
getDialogImpl().boxList.removeAllViews(); |
||||||
|
} |
||||||
|
int layoutId = isLightTheme() ? R.layout.layout_dialogx_bottom_material : R.layout.layout_dialogx_bottom_material_dark; |
||||||
|
if (style.overrideBottomDialogRes() != null) { |
||||||
|
layoutId = style.overrideBottomDialogRes().overrideDialogLayout(isLightTheme()); |
||||||
|
} |
||||||
|
|
||||||
|
enterAnimDuration = 0; |
||||||
|
dialogView = createView(layoutId); |
||||||
|
dialogImpl = new DialogImpl(dialogView); |
||||||
|
dialogView.setTag(me); |
||||||
|
show(dialogView); |
||||||
|
} |
||||||
|
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,477 @@ |
|||||||
|
package com.kongzue.dialogx.dialogs; |
||||||
|
|
||||||
|
import android.app.Activity; |
||||||
|
import android.content.Context; |
||||||
|
import android.content.res.Configuration; |
||||||
|
import android.graphics.Color; |
||||||
|
import android.view.View; |
||||||
|
import android.view.ViewGroup; |
||||||
|
import android.view.animation.Animation; |
||||||
|
import android.view.animation.AnimationUtils; |
||||||
|
import android.view.animation.DecelerateInterpolator; |
||||||
|
import android.widget.RelativeLayout; |
||||||
|
|
||||||
|
import androidx.annotation.ColorInt; |
||||||
|
|
||||||
|
import com.kongzue.dialogx.DialogX; |
||||||
|
import com.kongzue.dialogx.R; |
||||||
|
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.util.views.DialogXBaseRelativeLayout; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author: Kongzue |
||||||
|
* @github: https://github.com/kongzue/
|
||||||
|
* @homepage: http://kongzue.com/
|
||||||
|
* @mail: myzcxhh@live.cn |
||||||
|
* @createTime: 2020/10/20 11:59 |
||||||
|
*/ |
||||||
|
public class CustomDialog extends BaseDialog { |
||||||
|
|
||||||
|
public static int overrideEnterDuration = -1; |
||||||
|
public static int overrideExitDuration = -1; |
||||||
|
public static int overrideEnterAnimRes = 0; |
||||||
|
public static int overrideExitAnimRes = 0; |
||||||
|
public static int overrideMaskEnterAnimRes = R.anim.anim_dialogx_default_alpha_enter; |
||||||
|
public static int overrideMaskExitAnimRes = R.anim.anim_dialogx_default_exit; |
||||||
|
public static BOOLEAN overrideCancelable; |
||||||
|
protected OnBindView<CustomDialog> onBindView; |
||||||
|
protected DialogLifecycleCallback<CustomDialog> dialogLifecycleCallback; |
||||||
|
protected CustomDialog me = this; |
||||||
|
protected DialogImpl dialogImpl; |
||||||
|
protected int enterAnimResId = R.anim.anim_dialogx_default_enter; |
||||||
|
protected int exitAnimResId = R.anim.anim_dialogx_default_exit; |
||||||
|
protected ALIGN align = ALIGN.CENTER; |
||||||
|
protected boolean autoUnsafePlacePadding = true; |
||||||
|
private View dialogView; |
||||||
|
protected int maskColor = Color.TRANSPARENT; |
||||||
|
protected BOOLEAN privateCancelable; |
||||||
|
|
||||||
|
public enum ALIGN { |
||||||
|
CENTER, |
||||||
|
TOP, |
||||||
|
BOTTOM, |
||||||
|
LEFT, |
||||||
|
RIGHT |
||||||
|
} |
||||||
|
|
||||||
|
protected CustomDialog() { |
||||||
|
super(); |
||||||
|
} |
||||||
|
|
||||||
|
public static CustomDialog build() { |
||||||
|
return new CustomDialog(); |
||||||
|
} |
||||||
|
|
||||||
|
public CustomDialog(OnBindView<CustomDialog> onBindView) { |
||||||
|
this.onBindView = onBindView; |
||||||
|
} |
||||||
|
|
||||||
|
public static CustomDialog show(OnBindView<CustomDialog> onBindView) { |
||||||
|
CustomDialog customDialog = new CustomDialog(onBindView); |
||||||
|
customDialog.show(); |
||||||
|
return customDialog; |
||||||
|
} |
||||||
|
|
||||||
|
public static CustomDialog show(OnBindView<CustomDialog> onBindView, ALIGN align) { |
||||||
|
CustomDialog customDialog = new CustomDialog(onBindView); |
||||||
|
customDialog.align = align; |
||||||
|
customDialog.show(); |
||||||
|
return customDialog; |
||||||
|
} |
||||||
|
|
||||||
|
public void show() { |
||||||
|
super.beforeShow(); |
||||||
|
dialogView = createView(R.layout.layout_dialogx_custom); |
||||||
|
dialogImpl = new DialogImpl(dialogView); |
||||||
|
dialogView.setTag(me); |
||||||
|
show(dialogView); |
||||||
|
} |
||||||
|
|
||||||
|
public void show(Activity activity) { |
||||||
|
super.beforeShow(); |
||||||
|
dialogView = createView(R.layout.layout_dialogx_custom); |
||||||
|
dialogImpl = new DialogImpl(dialogView); |
||||||
|
dialogView.setTag(me); |
||||||
|
show(activity, dialogView); |
||||||
|
} |
||||||
|
|
||||||
|
public class DialogImpl implements DialogConvertViewInterface { |
||||||
|
|
||||||
|
public DialogXBaseRelativeLayout boxRoot; |
||||||
|
public RelativeLayout boxCustom; |
||||||
|
|
||||||
|
public DialogImpl(View convertView) { |
||||||
|
boxRoot = convertView.findViewById(R.id.box_root); |
||||||
|
boxCustom = convertView.findViewById(R.id.box_custom); |
||||||
|
|
||||||
|
init(); |
||||||
|
dialogImpl = this; |
||||||
|
refreshView(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void init() { |
||||||
|
boxRoot.setParentDialog(me); |
||||||
|
boxRoot.setOnLifecycleCallBack(new DialogXBaseRelativeLayout.OnLifecycleCallBack() { |
||||||
|
@Override |
||||||
|
public void onShow() { |
||||||
|
isShow = true; |
||||||
|
getDialogLifecycleCallback().onShow(me); |
||||||
|
boxCustom.setVisibility(View.GONE); |
||||||
|
} |
||||||
|
|
||||||
|
@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; |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
boxRoot.post(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
Animation enterAnim; |
||||||
|
if (enterAnimResId == R.anim.anim_dialogx_default_enter && exitAnimResId == R.anim.anim_dialogx_default_exit) { |
||||||
|
switch (align) { |
||||||
|
case TOP: |
||||||
|
enterAnimResId = R.anim.anim_dialogx_top_enter; |
||||||
|
exitAnimResId = R.anim.anim_dialogx_top_exit; |
||||||
|
break; |
||||||
|
case BOTTOM: |
||||||
|
enterAnimResId = R.anim.anim_dialogx_bottom_enter; |
||||||
|
exitAnimResId = R.anim.anim_dialogx_bottom_exit; |
||||||
|
break; |
||||||
|
case LEFT: |
||||||
|
enterAnimResId = R.anim.anim_dialogx_left_enter; |
||||||
|
exitAnimResId = R.anim.anim_dialogx_left_exit; |
||||||
|
break; |
||||||
|
case RIGHT: |
||||||
|
enterAnimResId = R.anim.anim_dialogx_right_enter; |
||||||
|
exitAnimResId = R.anim.anim_dialogx_right_exit; |
||||||
|
break; |
||||||
|
} |
||||||
|
enterAnim = AnimationUtils.loadAnimation(getContext(), enterAnimResId); |
||||||
|
enterAnim.setInterpolator(new DecelerateInterpolator(2f)); |
||||||
|
} else { |
||||||
|
int enterAnimResIdTemp = R.anim.anim_dialogx_default_enter; |
||||||
|
if (overrideEnterAnimRes != 0) { |
||||||
|
enterAnimResIdTemp = overrideEnterAnimRes; |
||||||
|
} |
||||||
|
if (enterAnimResId != 0) { |
||||||
|
enterAnimResIdTemp = enterAnimResId; |
||||||
|
} |
||||||
|
enterAnim = AnimationUtils.loadAnimation(getContext(), enterAnimResIdTemp); |
||||||
|
} |
||||||
|
long enterAnimDurationTemp = enterAnim.getDuration(); |
||||||
|
if (overrideEnterDuration >= 0) { |
||||||
|
enterAnimDurationTemp = overrideEnterDuration; |
||||||
|
} |
||||||
|
if (enterAnimDuration >= 0) { |
||||||
|
enterAnimDurationTemp = enterAnimDuration; |
||||||
|
} |
||||||
|
enterAnim.setDuration(enterAnimDurationTemp); |
||||||
|
boxCustom.setVisibility(View.VISIBLE); |
||||||
|
boxCustom.startAnimation(enterAnim); |
||||||
|
|
||||||
|
boxRoot.setBackgroundColor(maskColor); |
||||||
|
if (overrideMaskEnterAnimRes != 0) { |
||||||
|
Animation maskEnterAnim = AnimationUtils.loadAnimation(getContext(), overrideMaskEnterAnimRes); |
||||||
|
maskEnterAnim.setInterpolator(new DecelerateInterpolator(2f)); |
||||||
|
maskEnterAnim.setDuration(enterAnimDurationTemp); |
||||||
|
boxRoot.startAnimation(maskEnterAnim); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void refreshView() { |
||||||
|
RelativeLayout.LayoutParams rlp; |
||||||
|
rlp = ((RelativeLayout.LayoutParams) boxCustom.getLayoutParams()); |
||||||
|
switch (align) { |
||||||
|
case TOP: |
||||||
|
rlp.removeRule(RelativeLayout.CENTER_IN_PARENT); |
||||||
|
rlp.addRule(RelativeLayout.ALIGN_PARENT_TOP); |
||||||
|
break; |
||||||
|
case BOTTOM: |
||||||
|
rlp.removeRule(RelativeLayout.CENTER_IN_PARENT); |
||||||
|
rlp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); |
||||||
|
break; |
||||||
|
case CENTER: |
||||||
|
rlp.removeRule(RelativeLayout.ALIGN_PARENT_TOP); |
||||||
|
rlp.removeRule(RelativeLayout.ALIGN_PARENT_BOTTOM); |
||||||
|
rlp.addRule(RelativeLayout.CENTER_IN_PARENT); |
||||||
|
break; |
||||||
|
case LEFT: |
||||||
|
rlp.removeRule(RelativeLayout.CENTER_IN_PARENT); |
||||||
|
rlp.addRule(RelativeLayout.ALIGN_PARENT_TOP); |
||||||
|
rlp.addRule(RelativeLayout.ALIGN_PARENT_LEFT); |
||||||
|
break; |
||||||
|
case RIGHT: |
||||||
|
rlp.removeRule(RelativeLayout.CENTER_IN_PARENT); |
||||||
|
rlp.addRule(RelativeLayout.ALIGN_PARENT_TOP); |
||||||
|
rlp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); |
||||||
|
break; |
||||||
|
} |
||||||
|
boxCustom.setLayoutParams(rlp); |
||||||
|
|
||||||
|
boxRoot.setAutoUnsafePlacePadding(autoUnsafePlacePadding); |
||||||
|
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); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void doDismiss(View v) { |
||||||
|
if (v != null) v.setEnabled(false); |
||||||
|
|
||||||
|
int exitAnimResIdTemp = R.anim.anim_dialogx_default_exit; |
||||||
|
if (overrideExitAnimRes != 0) { |
||||||
|
exitAnimResIdTemp = overrideExitAnimRes; |
||||||
|
} |
||||||
|
if (exitAnimResId != 0) { |
||||||
|
exitAnimResIdTemp = exitAnimResId; |
||||||
|
} |
||||||
|
Animation exitAnim = AnimationUtils.loadAnimation(getContext(), exitAnimResIdTemp); |
||||||
|
|
||||||
|
long exitAnimDurationTemp = exitAnim.getDuration(); |
||||||
|
if (overrideExitDuration >= 0) { |
||||||
|
exitAnimDurationTemp = overrideExitDuration; |
||||||
|
} |
||||||
|
if (exitAnimDuration >= 0) { |
||||||
|
exitAnimDurationTemp = exitAnimDuration; |
||||||
|
} |
||||||
|
exitAnim.setDuration(exitAnimDurationTemp); |
||||||
|
exitAnim.setAnimationListener(new Animation.AnimationListener() { |
||||||
|
@Override |
||||||
|
public void onAnimationStart(Animation animation) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onAnimationEnd(Animation animation) { |
||||||
|
dismiss(dialogView); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onAnimationRepeat(Animation animation) { |
||||||
|
|
||||||
|
} |
||||||
|
}); |
||||||
|
boxCustom.startAnimation(exitAnim); |
||||||
|
|
||||||
|
if (overrideMaskExitAnimRes != 0) { |
||||||
|
Animation maskExitAnim = AnimationUtils.loadAnimation(getContext(), overrideMaskExitAnimRes); |
||||||
|
maskExitAnim.setDuration(exitAnimDurationTemp); |
||||||
|
maskExitAnim.setInterpolator(new DecelerateInterpolator(2f)); |
||||||
|
boxRoot.startAnimation(maskExitAnim); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@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<CustomDialog> getDialogLifecycleCallback() { |
||||||
|
return dialogLifecycleCallback == null ? new DialogLifecycleCallback<CustomDialog>() { |
||||||
|
} : dialogLifecycleCallback; |
||||||
|
} |
||||||
|
|
||||||
|
public CustomDialog setDialogLifecycleCallback(DialogLifecycleCallback<CustomDialog> dialogLifecycleCallback) { |
||||||
|
this.dialogLifecycleCallback = dialogLifecycleCallback; |
||||||
|
if (isShow) dialogLifecycleCallback.onShow(me); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public OnBackPressedListener getOnBackPressedListener() { |
||||||
|
return onBackPressedListener; |
||||||
|
} |
||||||
|
|
||||||
|
public CustomDialog setOnBackPressedListener(OnBackPressedListener onBackPressedListener) { |
||||||
|
this.onBackPressedListener = onBackPressedListener; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public CustomDialog setStyle(DialogXStyle style) { |
||||||
|
this.style = style; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public CustomDialog 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 CustomDialog setCancelable(boolean cancelable) { |
||||||
|
this.privateCancelable = cancelable ? BOOLEAN.TRUE : BOOLEAN.FALSE; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public CustomDialog.DialogImpl getDialogImpl() { |
||||||
|
return dialogImpl; |
||||||
|
} |
||||||
|
|
||||||
|
public CustomDialog setCustomView(OnBindView<CustomDialog> onBindView) { |
||||||
|
this.onBindView = onBindView; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public View getCustomView() { |
||||||
|
if (onBindView == null) return null; |
||||||
|
return onBindView.getCustomView(); |
||||||
|
} |
||||||
|
|
||||||
|
public CustomDialog removeCustomView() { |
||||||
|
this.onBindView.clean(); |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public int getEnterAnimResId() { |
||||||
|
return enterAnimResId; |
||||||
|
} |
||||||
|
|
||||||
|
public CustomDialog setEnterAnimResId(int enterAnimResId) { |
||||||
|
this.enterAnimResId = enterAnimResId; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public int getExitAnimResId() { |
||||||
|
return exitAnimResId; |
||||||
|
} |
||||||
|
|
||||||
|
public CustomDialog setExitAnimResId(int exitAnimResId) { |
||||||
|
this.exitAnimResId = exitAnimResId; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public CustomDialog setAnimResId(int enterAnimResId, int exitAnimResId) { |
||||||
|
this.enterAnimResId = enterAnimResId; |
||||||
|
this.exitAnimResId = exitAnimResId; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public ALIGN getAlign() { |
||||||
|
return align; |
||||||
|
} |
||||||
|
|
||||||
|
public CustomDialog setAlign(ALIGN align) { |
||||||
|
this.align = align; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isAutoUnsafePlacePadding() { |
||||||
|
return autoUnsafePlacePadding; |
||||||
|
} |
||||||
|
|
||||||
|
public CustomDialog setAutoUnsafePlacePadding(boolean autoUnsafePlacePadding) { |
||||||
|
this.autoUnsafePlacePadding = autoUnsafePlacePadding; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public CustomDialog setFullScreen(boolean fullscreen) { |
||||||
|
this.autoUnsafePlacePadding = !autoUnsafePlacePadding; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public CustomDialog setMaskColor(@ColorInt int maskColor) { |
||||||
|
this.maskColor = maskColor; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public long getEnterAnimDuration() { |
||||||
|
return enterAnimDuration; |
||||||
|
} |
||||||
|
|
||||||
|
public CustomDialog setEnterAnimDuration(long enterAnimDuration) { |
||||||
|
this.enterAnimDuration = enterAnimDuration; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public long getExitAnimDuration() { |
||||||
|
return exitAnimDuration; |
||||||
|
} |
||||||
|
|
||||||
|
public CustomDialog 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(R.layout.layout_dialogx_custom); |
||||||
|
dialogImpl = new DialogImpl(dialogView); |
||||||
|
dialogView.setTag(me); |
||||||
|
show(dialogView); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,407 @@ |
|||||||
|
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<FullScreenDialog> onBindView; |
||||||
|
protected BOOLEAN privateCancelable; |
||||||
|
|
||||||
|
protected DialogLifecycleCallback<FullScreenDialog> dialogLifecycleCallback; |
||||||
|
|
||||||
|
protected FullScreenDialog me = this; |
||||||
|
|
||||||
|
protected FullScreenDialog() { |
||||||
|
super(); |
||||||
|
} |
||||||
|
|
||||||
|
private View dialogView; |
||||||
|
|
||||||
|
public static FullScreenDialog build() { |
||||||
|
return new FullScreenDialog(); |
||||||
|
} |
||||||
|
|
||||||
|
public FullScreenDialog(OnBindView<FullScreenDialog> onBindView) { |
||||||
|
this.onBindView = onBindView; |
||||||
|
} |
||||||
|
|
||||||
|
public static FullScreenDialog show(OnBindView<FullScreenDialog> 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<FullScreenDialog> getDialogLifecycleCallback() { |
||||||
|
return dialogLifecycleCallback == null ? new DialogLifecycleCallback<FullScreenDialog>() { |
||||||
|
} : dialogLifecycleCallback; |
||||||
|
} |
||||||
|
|
||||||
|
public FullScreenDialog setDialogLifecycleCallback(DialogLifecycleCallback<FullScreenDialog> 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<FullScreenDialog> 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); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,550 @@ |
|||||||
|
package com.kongzue.dialogx.dialogs; |
||||||
|
|
||||||
|
import android.content.res.Configuration; |
||||||
|
import android.view.View; |
||||||
|
|
||||||
|
import androidx.annotation.ColorInt; |
||||||
|
import androidx.annotation.ColorRes; |
||||||
|
|
||||||
|
import com.kongzue.dialogx.DialogX; |
||||||
|
import com.kongzue.dialogx.R; |
||||||
|
import com.kongzue.dialogx.interfaces.OnBackPressedListener; |
||||||
|
import com.kongzue.dialogx.interfaces.OnBindView; |
||||||
|
import com.kongzue.dialogx.interfaces.OnInputDialogButtonClickListener; |
||||||
|
import com.kongzue.dialogx.interfaces.OnInputDialogButtonClickListener; |
||||||
|
import com.kongzue.dialogx.util.InputInfo; |
||||||
|
import com.kongzue.dialogx.util.TextInfo; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author: Kongzue |
||||||
|
* @github: https://github.com/kongzue/
|
||||||
|
* @homepage: http://kongzue.com/
|
||||||
|
* @mail: myzcxhh@live.cn |
||||||
|
* @createTime: 2020/9/24 13:53 |
||||||
|
*/ |
||||||
|
public class InputDialog extends MessageDialog { |
||||||
|
|
||||||
|
protected InputDialog() { |
||||||
|
super(); |
||||||
|
} |
||||||
|
|
||||||
|
public static InputDialog build() { |
||||||
|
return new InputDialog(); |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog(CharSequence title, CharSequence message, CharSequence okText) { |
||||||
|
cancelable = DialogX.cancelable; |
||||||
|
this.title = title; |
||||||
|
this.message = message; |
||||||
|
this.okText = okText; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog(int titleResId, int messageResId, int okTextResId) { |
||||||
|
cancelable = DialogX.cancelable; |
||||||
|
this.title = getString(titleResId); |
||||||
|
this.message = getString(messageResId); |
||||||
|
this.okText = getString(okTextResId); |
||||||
|
} |
||||||
|
|
||||||
|
public static InputDialog show(CharSequence title, CharSequence message, CharSequence okText) { |
||||||
|
InputDialog inputDialog = new InputDialog(title, message, okText); |
||||||
|
inputDialog.show(); |
||||||
|
return inputDialog; |
||||||
|
} |
||||||
|
|
||||||
|
public static InputDialog show(int titleResId, int messageResId, int okTextResId) { |
||||||
|
InputDialog inputDialog = new InputDialog(titleResId, messageResId, okTextResId); |
||||||
|
inputDialog.show(); |
||||||
|
return inputDialog; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog(CharSequence title, CharSequence message, CharSequence okText, CharSequence cancelText) { |
||||||
|
cancelable = DialogX.cancelable; |
||||||
|
this.title = title; |
||||||
|
this.message = message; |
||||||
|
this.okText = okText; |
||||||
|
this.cancelText = cancelText; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog(int titleResId, int messageResId, int okTextResId, int cancelTextResId) { |
||||||
|
cancelable = DialogX.cancelable; |
||||||
|
this.title = getString(titleResId); |
||||||
|
this.message = getString(messageResId); |
||||||
|
this.okText = getString(okTextResId); |
||||||
|
this.cancelText = getString(cancelTextResId); |
||||||
|
} |
||||||
|
|
||||||
|
public static InputDialog show(CharSequence title, CharSequence message, CharSequence okText, CharSequence cancelText) { |
||||||
|
InputDialog inputDialog = new InputDialog(title, message, okText, cancelText); |
||||||
|
inputDialog.show(); |
||||||
|
return inputDialog; |
||||||
|
} |
||||||
|
|
||||||
|
public static InputDialog show(int titleResId, int messageResId, int okTextResId, int cancelTextResId) { |
||||||
|
InputDialog inputDialog = new InputDialog(titleResId, messageResId, okTextResId, cancelTextResId); |
||||||
|
inputDialog.show(); |
||||||
|
return inputDialog; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog(CharSequence title, CharSequence message, CharSequence okText, CharSequence cancelText, String inputText) { |
||||||
|
cancelable = DialogX.cancelable; |
||||||
|
this.title = title; |
||||||
|
this.message = message; |
||||||
|
this.okText = okText; |
||||||
|
this.cancelText = cancelText; |
||||||
|
this.inputText = inputText; |
||||||
|
} |
||||||
|
|
||||||
|
public static InputDialog show(CharSequence title, CharSequence message, CharSequence okText, CharSequence cancelText, String inputText) { |
||||||
|
InputDialog inputDialog = new InputDialog(title, message, okText, cancelText, inputText); |
||||||
|
inputDialog.show(); |
||||||
|
return inputDialog; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog(CharSequence title, CharSequence message, CharSequence okText, CharSequence cancelText, CharSequence otherText) { |
||||||
|
cancelable = DialogX.cancelable; |
||||||
|
this.title = title; |
||||||
|
this.message = message; |
||||||
|
this.okText = okText; |
||||||
|
this.cancelText = cancelText; |
||||||
|
this.otherText = otherText; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog(int titleResId, int messageResId, int okTextResId, int cancelTextResId, int otherTextResId) { |
||||||
|
cancelable = DialogX.cancelable; |
||||||
|
this.title = getString(titleResId); |
||||||
|
this.message = getString(messageResId); |
||||||
|
this.okText = getString(okTextResId); |
||||||
|
this.cancelText = getString(cancelTextResId); |
||||||
|
this.otherText = getString(otherTextResId); |
||||||
|
} |
||||||
|
|
||||||
|
public static InputDialog show(CharSequence title, CharSequence message, CharSequence okText, CharSequence cancelText, CharSequence otherText) { |
||||||
|
InputDialog inputDialog = new InputDialog(title, message, okText, cancelText, otherText); |
||||||
|
inputDialog.show(); |
||||||
|
return inputDialog; |
||||||
|
} |
||||||
|
|
||||||
|
public static InputDialog show(int titleResId, int messageResId, int okTextResId, int cancelTextResId, int otherTextResId) { |
||||||
|
InputDialog inputDialog = new InputDialog(titleResId, messageResId, okTextResId, cancelTextResId, otherTextResId); |
||||||
|
inputDialog.show(); |
||||||
|
return inputDialog; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog(CharSequence title, CharSequence message, CharSequence okText, CharSequence cancelText, CharSequence otherText, String inputText) { |
||||||
|
cancelable = DialogX.cancelable; |
||||||
|
this.title = title; |
||||||
|
this.message = message; |
||||||
|
this.okText = okText; |
||||||
|
this.cancelText = cancelText; |
||||||
|
this.otherText = otherText; |
||||||
|
this.inputText = inputText; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog(int titleResId, int messageResId, int okTextResId, int cancelTextResId, int otherTextResId, int inputTextResId) { |
||||||
|
cancelable = DialogX.cancelable; |
||||||
|
this.title = getString(titleResId); |
||||||
|
this.message = getString(messageResId); |
||||||
|
this.okText = getString(okTextResId); |
||||||
|
this.cancelText = getString(cancelTextResId); |
||||||
|
this.otherText = getString(otherTextResId); |
||||||
|
this.inputText = getString(inputTextResId); |
||||||
|
} |
||||||
|
|
||||||
|
public static InputDialog show(CharSequence title, CharSequence message, CharSequence okText, CharSequence cancelText, CharSequence otherText, String inputText) { |
||||||
|
InputDialog inputDialog = new InputDialog(title, message, okText, cancelText, otherText, inputText); |
||||||
|
inputDialog.show(); |
||||||
|
return inputDialog; |
||||||
|
} |
||||||
|
|
||||||
|
public static InputDialog show(int titleResId, int messageResId, int okTextResId, int cancelTextResId, int otherTextResId, int inputTextResId) { |
||||||
|
InputDialog inputDialog = new InputDialog(titleResId, messageResId, okTextResId, cancelTextResId, otherTextResId, inputTextResId); |
||||||
|
inputDialog.show(); |
||||||
|
return inputDialog; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String dialogKey() { |
||||||
|
return getClass().getSimpleName() + "(" + Integer.toHexString(hashCode()) + ")"; |
||||||
|
} |
||||||
|
|
||||||
|
public CharSequence getOkButton() { |
||||||
|
return okText; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setOkButton(CharSequence okText) { |
||||||
|
this.okText = okText; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setOkButton(int okTextResId) { |
||||||
|
this.okText = getString(okTextResId); |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setOkButton(OnInputDialogButtonClickListener<InputDialog> okButtonClickListener) { |
||||||
|
this.okButtonClickListener = okButtonClickListener; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setOkButton(CharSequence okText, OnInputDialogButtonClickListener<InputDialog> okButtonClickListener) { |
||||||
|
this.okText = okText; |
||||||
|
this.okButtonClickListener = okButtonClickListener; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setOkButton(int okTextResId, OnInputDialogButtonClickListener<InputDialog> okButtonClickListener) { |
||||||
|
this.okText = getString(okTextResId); |
||||||
|
this.okButtonClickListener = okButtonClickListener; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public CharSequence getCancelButton() { |
||||||
|
return cancelText; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setCancelButton(CharSequence cancelText) { |
||||||
|
this.cancelText = cancelText; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setCancelButton(int cancelTextResId) { |
||||||
|
this.cancelText = getString(cancelTextResId); |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setCancelButton(OnInputDialogButtonClickListener<InputDialog> cancelButtonClickListener) { |
||||||
|
this.cancelButtonClickListener = cancelButtonClickListener; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setCancelButton(CharSequence cancelText, OnInputDialogButtonClickListener<InputDialog> cancelButtonClickListener) { |
||||||
|
this.cancelText = cancelText; |
||||||
|
this.cancelButtonClickListener = cancelButtonClickListener; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setCancelButton(int cancelTextResId, OnInputDialogButtonClickListener<InputDialog> cancelButtonClickListener) { |
||||||
|
this.cancelText = getString(cancelTextResId); |
||||||
|
this.cancelButtonClickListener = cancelButtonClickListener; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public CharSequence getOtherButton() { |
||||||
|
return otherText; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setOtherButton(CharSequence otherText) { |
||||||
|
this.otherText = otherText; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setOtherButton(int otherTextResId) { |
||||||
|
this.otherText = getString(otherTextResId); |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setOtherButton(OnInputDialogButtonClickListener<InputDialog> otherButtonClickListener) { |
||||||
|
this.otherButtonClickListener = otherButtonClickListener; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setOtherButton(CharSequence otherText, OnInputDialogButtonClickListener<InputDialog> otherButtonClickListener) { |
||||||
|
this.otherText = otherText; |
||||||
|
this.otherButtonClickListener = otherButtonClickListener; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setOtherButton(int otherTextResId, OnInputDialogButtonClickListener<InputDialog> otherButtonClickListener) { |
||||||
|
this.otherText = getString(otherTextResId); |
||||||
|
this.otherButtonClickListener = otherButtonClickListener; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public OnInputDialogButtonClickListener<InputDialog> getInputOkButtonClickListener() { |
||||||
|
return (OnInputDialogButtonClickListener<InputDialog>) okButtonClickListener; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setOkButtonClickListener(OnInputDialogButtonClickListener<InputDialog> okButtonClickListener) { |
||||||
|
this.okButtonClickListener = okButtonClickListener; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public OnInputDialogButtonClickListener getInputCancelButtonClickListener() { |
||||||
|
return (OnInputDialogButtonClickListener<InputDialog>) cancelButtonClickListener; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setCancelButtonClickListener(OnInputDialogButtonClickListener<InputDialog> cancelButtonClickListener) { |
||||||
|
this.cancelButtonClickListener = cancelButtonClickListener; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public OnInputDialogButtonClickListener getInputOtherButtonClickListener() { |
||||||
|
return (OnInputDialogButtonClickListener<InputDialog>) otherButtonClickListener; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setOtherButtonClickListener(OnInputDialogButtonClickListener<InputDialog> otherButtonClickListener) { |
||||||
|
this.otherButtonClickListener = otherButtonClickListener; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public CharSequence getTitle() { |
||||||
|
return title; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setTitle(CharSequence title) { |
||||||
|
this.title = title; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setTitle(int titleResId) { |
||||||
|
this.title = getString(titleResId); |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public CharSequence getMessage() { |
||||||
|
return message; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setMessage(CharSequence message) { |
||||||
|
this.message = message; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setMessage(int messageResId) { |
||||||
|
this.message = getString(messageResId); |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public String getInputText() { |
||||||
|
if (getDialogImpl() != null && getDialogImpl().txtInput != null) { |
||||||
|
return getDialogImpl().txtInput.getText().toString(); |
||||||
|
} |
||||||
|
return inputText; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setInputText(String inputText) { |
||||||
|
this.inputText = inputText; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setInputText(int inputTextResId) { |
||||||
|
this.inputText = getString(inputTextResId); |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public String getInputHintText() { |
||||||
|
return inputHintText; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setInputHintText(String inputHintText) { |
||||||
|
this.inputHintText = inputHintText; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setInputHintText(int inputHintTextResId) { |
||||||
|
this.inputHintText = getString(inputHintTextResId); |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public TextInfo getTitleTextInfo() { |
||||||
|
return titleTextInfo; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setTitleTextInfo(TextInfo titleTextInfo) { |
||||||
|
this.titleTextInfo = titleTextInfo; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public TextInfo getMessageTextInfo() { |
||||||
|
return messageTextInfo; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setMessageTextInfo(TextInfo messageTextInfo) { |
||||||
|
this.messageTextInfo = messageTextInfo; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public TextInfo getOkTextInfo() { |
||||||
|
return okTextInfo; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setOkTextInfo(TextInfo okTextInfo) { |
||||||
|
this.okTextInfo = okTextInfo; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public TextInfo getCancelTextInfo() { |
||||||
|
return cancelTextInfo; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setCancelTextInfo(TextInfo cancelTextInfo) { |
||||||
|
this.cancelTextInfo = cancelTextInfo; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public TextInfo getOtherTextInfo() { |
||||||
|
return otherTextInfo; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setOtherTextInfo(TextInfo otherTextInfo) { |
||||||
|
this.otherTextInfo = otherTextInfo; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public InputInfo getInputInfo() { |
||||||
|
return inputInfo; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setInputInfo(InputInfo inputInfo) { |
||||||
|
this.inputInfo = inputInfo; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public int getButtonOrientation() { |
||||||
|
return buttonOrientation; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setButtonOrientation(int buttonOrientation) { |
||||||
|
this.buttonOrientation = buttonOrientation; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isCancelable() { |
||||||
|
if (privateCancelable != null) { |
||||||
|
return privateCancelable == BOOLEAN.TRUE; |
||||||
|
} |
||||||
|
if (overrideCancelable != null) { |
||||||
|
return overrideCancelable == BOOLEAN.TRUE; |
||||||
|
} |
||||||
|
return cancelable; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setCancelable(boolean cancelable) { |
||||||
|
this.privateCancelable = cancelable ? BOOLEAN.TRUE : BOOLEAN.FALSE; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public OnBackPressedListener getOnBackPressedListener() { |
||||||
|
return onBackPressedListener; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setOnBackPressedListener(OnBackPressedListener onBackPressedListener) { |
||||||
|
this.onBackPressedListener = onBackPressedListener; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isAutoShowInputKeyboard() { |
||||||
|
return autoShowInputKeyboard; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setAutoShowInputKeyboard(boolean autoShowInputKeyboard) { |
||||||
|
this.autoShowInputKeyboard = autoShowInputKeyboard; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setCustomView(OnBindView<MessageDialog> onBindView) { |
||||||
|
this.onBindView = onBindView; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public View getCustomView() { |
||||||
|
if (onBindView == null) return null; |
||||||
|
return onBindView.getCustomView(); |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog removeCustomView() { |
||||||
|
this.onBindView.clean(); |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public int getBackgroundColor() { |
||||||
|
return backgroundColor; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setBackgroundColor(@ColorInt int backgroundColor) { |
||||||
|
this.backgroundColor = backgroundColor; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setBackgroundColorRes(@ColorRes int backgroundColorResId) { |
||||||
|
this.backgroundColor = getColor(backgroundColorResId); |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setMaskColor(@ColorInt int maskColor) { |
||||||
|
this.maskColor = maskColor; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public long getEnterAnimDuration() { |
||||||
|
return enterAnimDuration; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog setEnterAnimDuration(long enterAnimDuration) { |
||||||
|
this.enterAnimDuration = enterAnimDuration; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public long getExitAnimDuration() { |
||||||
|
return exitAnimDuration; |
||||||
|
} |
||||||
|
|
||||||
|
public InputDialog 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(); |
||||||
|
} |
||||||
|
int layoutId = style.layout(isLightTheme()); |
||||||
|
layoutId = layoutId == 0 ? (isLightTheme() ? R.layout.layout_dialogx_material : R.layout.layout_dialogx_material_dark) : layoutId; |
||||||
|
|
||||||
|
String inputText = getInputText(); |
||||||
|
enterAnimDuration = 0; |
||||||
|
dialogView = createView(layoutId); |
||||||
|
dialogImpl = new DialogImpl(dialogView); |
||||||
|
dialogView.setTag(me); |
||||||
|
show(dialogView); |
||||||
|
setInputText(inputText); |
||||||
|
} |
||||||
|
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,851 @@ |
|||||||
|
package com.kongzue.dialogx.dialogs; |
||||||
|
|
||||||
|
import android.animation.Animator; |
||||||
|
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.Animation; |
||||||
|
import android.view.animation.AnimationUtils; |
||||||
|
import android.view.animation.DecelerateInterpolator; |
||||||
|
import android.widget.ImageView; |
||||||
|
import android.widget.LinearLayout; |
||||||
|
import android.widget.RelativeLayout; |
||||||
|
import android.widget.TextView; |
||||||
|
|
||||||
|
import androidx.annotation.ColorInt; |
||||||
|
import androidx.annotation.ColorRes; |
||||||
|
import androidx.annotation.IdRes; |
||||||
|
|
||||||
|
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.OnDialogButtonClickListener; |
||||||
|
import com.kongzue.dialogx.interfaces.OnSafeInsetsChangeListener; |
||||||
|
import com.kongzue.dialogx.style.MaterialStyle; |
||||||
|
import com.kongzue.dialogx.util.TextInfo; |
||||||
|
import com.kongzue.dialogx.util.views.DialogXBaseRelativeLayout; |
||||||
|
|
||||||
|
import java.lang.ref.WeakReference; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Timer; |
||||||
|
import java.util.TimerTask; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author: Kongzue |
||||||
|
* @github: https://github.com/kongzue/
|
||||||
|
* @homepage: http://kongzue.com/
|
||||||
|
* @mail: myzcxhh@live.cn |
||||||
|
* @createTime: 2020/10/20 11:59 |
||||||
|
*/ |
||||||
|
public class PopTip extends BaseDialog { |
||||||
|
|
||||||
|
public static final int TIME_NO_AUTO_DISMISS_DELAY = -1; |
||||||
|
protected static List<PopTip> popTipList; |
||||||
|
|
||||||
|
protected OnBindView<PopTip> onBindView; |
||||||
|
protected DialogLifecycleCallback<PopTip> dialogLifecycleCallback; |
||||||
|
protected PopTip me = this; |
||||||
|
protected DialogImpl dialogImpl; |
||||||
|
protected int enterAnimResId = R.anim.anim_dialogx_default_enter; |
||||||
|
protected int exitAnimResId = R.anim.anim_dialogx_default_exit; |
||||||
|
private View dialogView; |
||||||
|
protected DialogXStyle.PopTipSettings.ALIGN align; |
||||||
|
protected OnDialogButtonClickListener<PopTip> onButtonClickListener; |
||||||
|
protected OnDialogButtonClickListener<PopTip> onPopTipClickListener; |
||||||
|
protected boolean autoTintIconInLightOrDarkMode = true; |
||||||
|
|
||||||
|
protected int iconResId; |
||||||
|
protected CharSequence message; |
||||||
|
protected CharSequence buttonText; |
||||||
|
|
||||||
|
protected TextInfo messageTextInfo; |
||||||
|
protected TextInfo buttonTextInfo = new TextInfo().setBold(true); |
||||||
|
|
||||||
|
protected PopTip() { |
||||||
|
super(); |
||||||
|
} |
||||||
|
|
||||||
|
public static PopTip build() { |
||||||
|
return new PopTip(); |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip(OnBindView<PopTip> onBindView) { |
||||||
|
this.onBindView = onBindView; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip(CharSequence message) { |
||||||
|
this.message = message; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip(int messageResId) { |
||||||
|
this.message = getString(messageResId); |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip(int iconResId, CharSequence message) { |
||||||
|
this.iconResId = iconResId; |
||||||
|
this.message = message; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip(int iconResId, CharSequence message, CharSequence buttonText) { |
||||||
|
this.iconResId = iconResId; |
||||||
|
this.message = message; |
||||||
|
this.buttonText = buttonText; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip(int iconResId, int messageResId, int buttonTextResId) { |
||||||
|
this.iconResId = iconResId; |
||||||
|
this.message = getString(messageResId); |
||||||
|
this.buttonText = getString(buttonTextResId); |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip(CharSequence message, CharSequence buttonText) { |
||||||
|
this.message = message; |
||||||
|
this.buttonText = buttonText; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip(int messageResId, int buttonTextResId) { |
||||||
|
this.message = getString(messageResId); |
||||||
|
this.buttonText = getString(buttonTextResId); |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip(CharSequence message, OnBindView<PopTip> onBindView) { |
||||||
|
this.message = message; |
||||||
|
this.onBindView = onBindView; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip(int messageResId, OnBindView<PopTip> onBindView) { |
||||||
|
this.message = getString(messageResId); |
||||||
|
this.onBindView = onBindView; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip(int iconResId, CharSequence message, OnBindView<PopTip> onBindView) { |
||||||
|
this.iconResId = iconResId; |
||||||
|
this.message = message; |
||||||
|
this.onBindView = onBindView; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip(int iconResId, CharSequence message, CharSequence buttonText, OnBindView<PopTip> onBindView) { |
||||||
|
this.iconResId = iconResId; |
||||||
|
this.message = message; |
||||||
|
this.buttonText = buttonText; |
||||||
|
this.onBindView = onBindView; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip(int iconResId, int messageResId, int buttonTextResId, OnBindView<PopTip> onBindView) { |
||||||
|
this.iconResId = iconResId; |
||||||
|
this.message = getString(messageResId); |
||||||
|
this.buttonText = getString(buttonTextResId); |
||||||
|
this.onBindView = onBindView; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip(CharSequence message, CharSequence buttonText, OnBindView<PopTip> onBindView) { |
||||||
|
this.message = message; |
||||||
|
this.buttonText = buttonText; |
||||||
|
this.onBindView = onBindView; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip(int messageResId, int buttonTextResId, OnBindView<PopTip> onBindView) { |
||||||
|
this.message = getString(messageResId); |
||||||
|
this.buttonText = getString(buttonTextResId); |
||||||
|
this.onBindView = onBindView; |
||||||
|
} |
||||||
|
|
||||||
|
public static PopTip show(OnBindView<PopTip> onBindView) { |
||||||
|
PopTip popTip = new PopTip(onBindView); |
||||||
|
popTip.show(); |
||||||
|
return popTip; |
||||||
|
} |
||||||
|
|
||||||
|
public static PopTip show(CharSequence message) { |
||||||
|
PopTip popTip = new PopTip(message); |
||||||
|
popTip.show(); |
||||||
|
return popTip; |
||||||
|
} |
||||||
|
|
||||||
|
public static PopTip show(int messageResId) { |
||||||
|
PopTip popTip = new PopTip(messageResId); |
||||||
|
popTip.show(); |
||||||
|
return popTip; |
||||||
|
} |
||||||
|
|
||||||
|
public static PopTip show(CharSequence message, OnBindView<PopTip> onBindView) { |
||||||
|
PopTip popTip = new PopTip(message, onBindView); |
||||||
|
popTip.show(); |
||||||
|
return popTip; |
||||||
|
} |
||||||
|
|
||||||
|
public static PopTip show(int messageResId, OnBindView<PopTip> onBindView) { |
||||||
|
PopTip popTip = new PopTip(messageResId, onBindView); |
||||||
|
popTip.show(); |
||||||
|
return popTip; |
||||||
|
} |
||||||
|
|
||||||
|
public static PopTip show(CharSequence message, CharSequence buttonText) { |
||||||
|
PopTip popTip = new PopTip(message, buttonText); |
||||||
|
popTip.show(); |
||||||
|
return popTip; |
||||||
|
} |
||||||
|
|
||||||
|
public static PopTip show(int messageResId, int buttonTextResId) { |
||||||
|
PopTip popTip = new PopTip(messageResId, buttonTextResId); |
||||||
|
popTip.show(); |
||||||
|
return popTip; |
||||||
|
} |
||||||
|
|
||||||
|
public static PopTip show(int iconResId, CharSequence message, OnBindView<PopTip> onBindView) { |
||||||
|
PopTip popTip = new PopTip(iconResId, message, onBindView); |
||||||
|
popTip.show(); |
||||||
|
return popTip; |
||||||
|
} |
||||||
|
|
||||||
|
public static PopTip show(int iconResId, CharSequence message) { |
||||||
|
PopTip popTip = new PopTip(iconResId, message); |
||||||
|
popTip.show(); |
||||||
|
return popTip; |
||||||
|
} |
||||||
|
|
||||||
|
public static PopTip show(int iconResId, CharSequence message, CharSequence buttonText) { |
||||||
|
PopTip popTip = new PopTip(iconResId, message, buttonText); |
||||||
|
popTip.show(); |
||||||
|
return popTip; |
||||||
|
} |
||||||
|
|
||||||
|
public static PopTip show(int iconResId, CharSequence message, CharSequence buttonText, OnBindView<PopTip> onBindView) { |
||||||
|
PopTip popTip = new PopTip(iconResId, message, buttonText, onBindView); |
||||||
|
popTip.show(); |
||||||
|
return popTip; |
||||||
|
} |
||||||
|
|
||||||
|
public static PopTip show(int iconResId, int messageResId, int buttonTextResId, OnBindView<PopTip> onBindView) { |
||||||
|
PopTip popTip = new PopTip(iconResId, messageResId, buttonTextResId, onBindView); |
||||||
|
popTip.show(); |
||||||
|
return popTip; |
||||||
|
} |
||||||
|
|
||||||
|
public static PopTip show(CharSequence message, CharSequence buttonText, OnBindView<PopTip> onBindView) { |
||||||
|
PopTip popTip = new PopTip(message, buttonText, onBindView); |
||||||
|
popTip.show(); |
||||||
|
return popTip; |
||||||
|
} |
||||||
|
|
||||||
|
public static PopTip show(int messageResId, int buttonTextResId, OnBindView<PopTip> onBindView) { |
||||||
|
PopTip popTip = new PopTip(messageResId, buttonTextResId, onBindView); |
||||||
|
popTip.show(); |
||||||
|
return popTip; |
||||||
|
} |
||||||
|
|
||||||
|
public void show() { |
||||||
|
super.beforeShow(); |
||||||
|
if (DialogX.onlyOnePopTip) { |
||||||
|
PopTip oldInstance = null; |
||||||
|
if (popTipList != null && !popTipList.isEmpty()) { |
||||||
|
oldInstance = popTipList.get(popTipList.size() - 1); |
||||||
|
} |
||||||
|
if (oldInstance != null) { |
||||||
|
oldInstance.dismiss(); |
||||||
|
} |
||||||
|
} else { |
||||||
|
if (popTipList != null) { |
||||||
|
for (int i = 0; i < popTipList.size(); i++) { |
||||||
|
PopTip popInstance = popTipList.get(i); |
||||||
|
popInstance.moveUp(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
if (popTipList == null) popTipList = new ArrayList<>(); |
||||||
|
popTipList.add(PopTip.this); |
||||||
|
int layoutResId = isLightTheme() ? R.layout.layout_dialogx_poptip_material : R.layout.layout_dialogx_poptip_material_dark; |
||||||
|
if (style.popTipSettings() != null) { |
||||||
|
if (style.popTipSettings().layout(isLightTheme()) != 0) { |
||||||
|
layoutResId = style.popTipSettings().layout(isLightTheme()); |
||||||
|
} |
||||||
|
align = style.popTipSettings().align(); |
||||||
|
if (align == null) align = DialogXStyle.PopTipSettings.ALIGN.BOTTOM; |
||||||
|
enterAnimResId = style.popTipSettings().enterAnimResId(isLightTheme()) != 0 ? style.popTipSettings().enterAnimResId(isLightTheme()) : R.anim.anim_dialogx_default_enter; |
||||||
|
exitAnimResId = style.popTipSettings().exitAnimResId(isLightTheme()) != 0 ? style.popTipSettings().exitAnimResId(isLightTheme()) : R.anim.anim_dialogx_default_exit; |
||||||
|
} |
||||||
|
dialogView = createView(layoutResId); |
||||||
|
dialogImpl = new DialogImpl(dialogView); |
||||||
|
dialogView.setTag(me); |
||||||
|
show(dialogView); |
||||||
|
} |
||||||
|
|
||||||
|
public void show(Activity activity) { |
||||||
|
super.beforeShow(); |
||||||
|
if (DialogX.onlyOnePopTip) { |
||||||
|
PopTip oldInstance = null; |
||||||
|
if (popTipList != null && !popTipList.isEmpty()) { |
||||||
|
oldInstance = popTipList.get(popTipList.size() - 1); |
||||||
|
} |
||||||
|
if (oldInstance != null) { |
||||||
|
oldInstance.dismiss(); |
||||||
|
} |
||||||
|
} else { |
||||||
|
if (popTipList != null) { |
||||||
|
for (int i = 0; i < popTipList.size(); i++) { |
||||||
|
PopTip popInstance = popTipList.get(i); |
||||||
|
popInstance.moveUp(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
if (popTipList == null) popTipList = new ArrayList<>(); |
||||||
|
popTipList.add(PopTip.this); |
||||||
|
int layoutResId = isLightTheme() ? R.layout.layout_dialogx_poptip_material : R.layout.layout_dialogx_poptip_material_dark; |
||||||
|
if (style.popTipSettings() != null) { |
||||||
|
if (style.popTipSettings().layout(isLightTheme()) != 0) { |
||||||
|
layoutResId = style.popTipSettings().layout(isLightTheme()); |
||||||
|
} |
||||||
|
align = style.popTipSettings().align(); |
||||||
|
if (align == null) align = DialogXStyle.PopTipSettings.ALIGN.BOTTOM; |
||||||
|
enterAnimResId = style.popTipSettings().enterAnimResId(isLightTheme()) != 0 ? style.popTipSettings().enterAnimResId(isLightTheme()) : R.anim.anim_dialogx_default_enter; |
||||||
|
exitAnimResId = style.popTipSettings().exitAnimResId(isLightTheme()) != 0 ? style.popTipSettings().exitAnimResId(isLightTheme()) : R.anim.anim_dialogx_default_exit; |
||||||
|
} |
||||||
|
dialogView = createView(layoutResId); |
||||||
|
dialogImpl = new DialogImpl(dialogView); |
||||||
|
dialogView.setTag(me); |
||||||
|
show(activity, dialogView); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String dialogKey() { |
||||||
|
return getClass().getSimpleName() + "(" + Integer.toHexString(hashCode()) + ")"; |
||||||
|
} |
||||||
|
|
||||||
|
protected Timer autoDismissTimer; |
||||||
|
|
||||||
|
public PopTip autoDismiss(long delay) { |
||||||
|
if (autoDismissTimer != null) { |
||||||
|
autoDismissTimer.cancel(); |
||||||
|
} |
||||||
|
if (delay < 0) return this; |
||||||
|
autoDismissTimer = new Timer(); |
||||||
|
autoDismissTimer.schedule(new TimerTask() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
dismiss(); |
||||||
|
} |
||||||
|
}, delay); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip showShort() { |
||||||
|
autoDismiss(2000); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip showLong() { |
||||||
|
autoDismiss(3500); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip showAlways() { |
||||||
|
return noAutoDismiss(); |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip noAutoDismiss() { |
||||||
|
autoDismiss(TIME_NO_AUTO_DISMISS_DELAY); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public class DialogImpl implements DialogConvertViewInterface { |
||||||
|
|
||||||
|
public DialogXBaseRelativeLayout boxRoot; |
||||||
|
public LinearLayout boxBody; |
||||||
|
public ImageView imgDialogxPopIcon; |
||||||
|
public TextView txtDialogxPopText; |
||||||
|
public RelativeLayout boxCustom; |
||||||
|
public TextView txtDialogxButton; |
||||||
|
|
||||||
|
public DialogImpl(View convertView) { |
||||||
|
boxRoot = convertView.findViewById(R.id.box_root); |
||||||
|
boxBody = convertView.findViewById(R.id.box_body); |
||||||
|
imgDialogxPopIcon = convertView.findViewById(R.id.img_dialogx_pop_icon); |
||||||
|
txtDialogxPopText = convertView.findViewById(R.id.txt_dialogx_pop_text); |
||||||
|
boxCustom = convertView.findViewById(R.id.box_custom); |
||||||
|
txtDialogxButton = convertView.findViewById(R.id.txt_dialogx_button); |
||||||
|
|
||||||
|
init(); |
||||||
|
dialogImpl = this; |
||||||
|
refreshView(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void init() { |
||||||
|
if (messageTextInfo == null) messageTextInfo = DialogX.popTextInfo; |
||||||
|
if (buttonTextInfo == null) buttonTextInfo = DialogX.buttonTextInfo; |
||||||
|
if (backgroundColor == -1) backgroundColor = DialogX.backgroundColor; |
||||||
|
|
||||||
|
if (autoDismissTimer == null) { |
||||||
|
showShort(); |
||||||
|
} |
||||||
|
|
||||||
|
boxRoot.setParentDialog(me); |
||||||
|
boxRoot.setAutoUnsafePlacePadding(false); |
||||||
|
boxRoot.setOnLifecycleCallBack(new DialogXBaseRelativeLayout.OnLifecycleCallBack() { |
||||||
|
@Override |
||||||
|
public void onShow() { |
||||||
|
isShow = true; |
||||||
|
boxRoot.setAlpha(0f); |
||||||
|
|
||||||
|
getDialogLifecycleCallback().onShow(me); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onDismiss() { |
||||||
|
if (popTipList != null) popTipList.remove(PopTip.this); |
||||||
|
isShow = false; |
||||||
|
getDialogLifecycleCallback().onDismiss(me); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
RelativeLayout.LayoutParams rlp; |
||||||
|
rlp = ((RelativeLayout.LayoutParams) boxBody.getLayoutParams()); |
||||||
|
if (align == null) align = DialogXStyle.PopTipSettings.ALIGN.BOTTOM; |
||||||
|
switch (align) { |
||||||
|
case TOP: |
||||||
|
rlp.removeRule(RelativeLayout.CENTER_IN_PARENT); |
||||||
|
rlp.addRule(RelativeLayout.ALIGN_PARENT_TOP); |
||||||
|
break; |
||||||
|
case BOTTOM: |
||||||
|
rlp.removeRule(RelativeLayout.CENTER_IN_PARENT); |
||||||
|
rlp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); |
||||||
|
boxRoot.setAutoUnsafePlacePadding(true); |
||||||
|
break; |
||||||
|
case CENTER: |
||||||
|
rlp.removeRule(RelativeLayout.ALIGN_PARENT_TOP); |
||||||
|
rlp.removeRule(RelativeLayout.ALIGN_PARENT_BOTTOM); |
||||||
|
rlp.addRule(RelativeLayout.CENTER_IN_PARENT); |
||||||
|
break; |
||||||
|
} |
||||||
|
boxBody.setLayoutParams(rlp); |
||||||
|
|
||||||
|
boxRoot.setOnSafeInsetsChangeListener(new OnSafeInsetsChangeListener() { |
||||||
|
@Override |
||||||
|
public void onChange(Rect unsafeRect) { |
||||||
|
if (align == DialogXStyle.PopTipSettings.ALIGN.TOP) { |
||||||
|
boxBody.setY(unsafeRect.top); |
||||||
|
} else if (align == DialogXStyle.PopTipSettings.ALIGN.TOP_INSIDE) { |
||||||
|
boxBody.setPadding(0, unsafeRect.top, 0, 0); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
boxRoot.setOnBackPressedListener(new OnBackPressedListener() { |
||||||
|
@Override |
||||||
|
public boolean onBackPressed() { |
||||||
|
return false; |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
boxRoot.post(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
|
||||||
|
Animation enterAnim = AnimationUtils.loadAnimation(getContext(), enterAnimResId); |
||||||
|
enterAnim.setInterpolator(new DecelerateInterpolator(2f)); |
||||||
|
if (enterAnimDuration != -1) { |
||||||
|
enterAnim.setDuration(enterAnimDuration); |
||||||
|
} |
||||||
|
boxBody.startAnimation(enterAnim); |
||||||
|
|
||||||
|
boxRoot.animate() |
||||||
|
.setDuration(enterAnimDuration == -1 ? enterAnim.getDuration() : enterAnimDuration) |
||||||
|
.alpha(1f) |
||||||
|
.setInterpolator(new DecelerateInterpolator()) |
||||||
|
.setListener(null); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
txtDialogxButton.setOnClickListener(new View.OnClickListener() { |
||||||
|
@Override |
||||||
|
public void onClick(View v) { |
||||||
|
if (onButtonClickListener != null) { |
||||||
|
if (!onButtonClickListener.onClick(me, v)) { |
||||||
|
doDismiss(v); |
||||||
|
} |
||||||
|
} else { |
||||||
|
doDismiss(v); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void refreshView() { |
||||||
|
if (backgroundColor != -1) { |
||||||
|
tintColor(boxBody, backgroundColor); |
||||||
|
} |
||||||
|
|
||||||
|
if (onBindView != null && onBindView.getCustomView() != null) { |
||||||
|
onBindView.bindParent(boxCustom, me); |
||||||
|
boxCustom.setVisibility(View.VISIBLE); |
||||||
|
} else { |
||||||
|
boxCustom.setVisibility(View.GONE); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
showText(txtDialogxPopText, message); |
||||||
|
showText(txtDialogxButton, buttonText); |
||||||
|
|
||||||
|
useTextInfo(txtDialogxPopText, messageTextInfo); |
||||||
|
useTextInfo(txtDialogxButton, buttonTextInfo); |
||||||
|
|
||||||
|
if (iconResId != 0) { |
||||||
|
imgDialogxPopIcon.setVisibility(View.VISIBLE); |
||||||
|
imgDialogxPopIcon.setImageResource(iconResId); |
||||||
|
if (autoTintIconInLightOrDarkMode) { |
||||||
|
imgDialogxPopIcon.setImageTintList(txtDialogxPopText.getTextColors()); |
||||||
|
} else { |
||||||
|
imgDialogxPopIcon.setImageTintList(null); |
||||||
|
} |
||||||
|
} else { |
||||||
|
imgDialogxPopIcon.setVisibility(View.GONE); |
||||||
|
} |
||||||
|
|
||||||
|
if (onPopTipClickListener != null) { |
||||||
|
boxBody.setOnClickListener(new View.OnClickListener() { |
||||||
|
@Override |
||||||
|
public void onClick(View v) { |
||||||
|
if (!onPopTipClickListener.onClick(me, v)) { |
||||||
|
dismiss(); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} else { |
||||||
|
boxBody.setOnClickListener(null); |
||||||
|
boxBody.setClickable(false); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void doDismiss(final View v) { |
||||||
|
boxRoot.post(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
if (v != null) v.setEnabled(false); |
||||||
|
|
||||||
|
Animation exitAnim = AnimationUtils.loadAnimation(getContext(), exitAnimResId); |
||||||
|
if (exitAnimDuration != -1) { |
||||||
|
exitAnim.setDuration(exitAnimResId); |
||||||
|
} |
||||||
|
boxBody.startAnimation(exitAnim); |
||||||
|
|
||||||
|
boxRoot.animate() |
||||||
|
.alpha(0f) |
||||||
|
.setInterpolator(new AccelerateInterpolator()) |
||||||
|
.setDuration(exitAnimDuration == -1 ? exitAnim.getDuration() : exitAnimDuration); |
||||||
|
|
||||||
|
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
dismiss(dialogView); |
||||||
|
} |
||||||
|
},exitAnimDuration == -1 ? exitAnim.getDuration() : exitAnimDuration); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void moveUp() { |
||||||
|
if (getDialogImpl() != null && getDialogImpl().boxBody != null) { |
||||||
|
getDialogImpl().boxBody.post(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
if (style.popTipSettings() != null) align = style.popTipSettings().align(); |
||||||
|
if (align == null) align = DialogXStyle.PopTipSettings.ALIGN.BOTTOM; |
||||||
|
switch (align) { |
||||||
|
case TOP: |
||||||
|
getDialogImpl().boxBody.animate() |
||||||
|
.y(getDialogImpl().boxBody.getY() + getDialogImpl().boxBody.getHeight() * 1.3f) |
||||||
|
.setDuration(enterAnimDuration == -1 ? 300 : enterAnimDuration) |
||||||
|
.setInterpolator(new DecelerateInterpolator(2f)) |
||||||
|
; |
||||||
|
break; |
||||||
|
case TOP_INSIDE: |
||||||
|
getDialogImpl().boxBody.animate() |
||||||
|
.y(getDialogImpl().boxBody.getY() + getDialogImpl().boxBody.getHeight() - getDialogImpl().boxBody.getPaddingTop()) |
||||||
|
.setDuration(enterAnimDuration == -1 ? 300 : enterAnimDuration) |
||||||
|
.setInterpolator(new DecelerateInterpolator(2f)) |
||||||
|
; |
||||||
|
break; |
||||||
|
case CENTER: |
||||||
|
case BOTTOM: |
||||||
|
case BOTTOM_INSIDE: |
||||||
|
getDialogImpl().boxBody.animate() |
||||||
|
.y(getDialogImpl().boxBody.getY() - getDialogImpl().boxBody.getHeight() * 1.3f) |
||||||
|
.setDuration(enterAnimDuration == -1 ? 300 : enterAnimDuration) |
||||||
|
.setInterpolator(new DecelerateInterpolator(2f)) |
||||||
|
; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
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<PopTip> getDialogLifecycleCallback() { |
||||||
|
return dialogLifecycleCallback == null ? new DialogLifecycleCallback<PopTip>() { |
||||||
|
} : dialogLifecycleCallback; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip setDialogLifecycleCallback(DialogLifecycleCallback<PopTip> dialogLifecycleCallback) { |
||||||
|
this.dialogLifecycleCallback = dialogLifecycleCallback; |
||||||
|
if (isShow) dialogLifecycleCallback.onShow(me); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip setStyle(DialogXStyle style) { |
||||||
|
this.style = style; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip setTheme(DialogX.THEME theme) { |
||||||
|
this.theme = theme; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip.DialogImpl getDialogImpl() { |
||||||
|
return dialogImpl; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip setCustomView(OnBindView<PopTip> onBindView) { |
||||||
|
this.onBindView = onBindView; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public View getCustomView() { |
||||||
|
if (onBindView == null) return null; |
||||||
|
return onBindView.getCustomView(); |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip removeCustomView() { |
||||||
|
this.onBindView.clean(); |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public DialogXStyle.PopTipSettings.ALIGN getAlign() { |
||||||
|
return align; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip setAlign(DialogXStyle.PopTipSettings.ALIGN align) { |
||||||
|
this.align = align; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public int getIconResId() { |
||||||
|
return iconResId; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip setIconResId(int iconResId) { |
||||||
|
this.iconResId = iconResId; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public CharSequence getMessage() { |
||||||
|
return message; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip setMessage(CharSequence message) { |
||||||
|
this.message = message; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip setMessage(int messageResId) { |
||||||
|
this.message = getString(messageResId); |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public CharSequence getButtonText() { |
||||||
|
return buttonText; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip setButton(CharSequence buttonText) { |
||||||
|
this.buttonText = buttonText; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip setButton(int buttonTextResId) { |
||||||
|
this.buttonText = getString(buttonTextResId); |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip setButton(CharSequence buttonText, OnDialogButtonClickListener<PopTip> onButtonClickListener) { |
||||||
|
this.buttonText = buttonText; |
||||||
|
this.onButtonClickListener = onButtonClickListener; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip setButton(int buttonTextResId, OnDialogButtonClickListener<PopTip> onButtonClickListener) { |
||||||
|
this.buttonText = getString(buttonTextResId); |
||||||
|
this.onButtonClickListener = onButtonClickListener; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip setButton(OnDialogButtonClickListener<PopTip> onButtonClickListener) { |
||||||
|
this.onButtonClickListener = onButtonClickListener; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public TextInfo getMessageTextInfo() { |
||||||
|
return messageTextInfo; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip setMessageTextInfo(TextInfo messageTextInfo) { |
||||||
|
this.messageTextInfo = messageTextInfo; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public TextInfo getButtonTextInfo() { |
||||||
|
return buttonTextInfo; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip setButtonTextInfo(TextInfo buttonTextInfo) { |
||||||
|
this.buttonTextInfo = buttonTextInfo; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public OnDialogButtonClickListener<PopTip> getOnButtonClickListener() { |
||||||
|
return onButtonClickListener; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip setOnButtonClickListener(OnDialogButtonClickListener<PopTip> onButtonClickListener) { |
||||||
|
this.onButtonClickListener = onButtonClickListener; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isAutoTintIconInLightOrDarkMode() { |
||||||
|
return autoTintIconInLightOrDarkMode; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip setAutoTintIconInLightOrDarkMode(boolean autoTintIconInLightOrDarkMode) { |
||||||
|
this.autoTintIconInLightOrDarkMode = autoTintIconInLightOrDarkMode; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public OnDialogButtonClickListener<PopTip> getOnPopTipClickListener() { |
||||||
|
return onPopTipClickListener; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip setOnPopTipClickListener(OnDialogButtonClickListener<PopTip> onPopTipClickListener) { |
||||||
|
this.onPopTipClickListener = onPopTipClickListener; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public int getBackgroundColor() { |
||||||
|
return backgroundColor; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip setBackgroundColor(@ColorInt int backgroundColor) { |
||||||
|
this.backgroundColor = backgroundColor; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip setBackgroundColorRes(@ColorRes int backgroundColorResId) { |
||||||
|
this.backgroundColor = getColor(backgroundColorResId); |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public long getEnterAnimDuration() { |
||||||
|
return enterAnimDuration; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip setEnterAnimDuration(long enterAnimDuration) { |
||||||
|
this.enterAnimDuration = enterAnimDuration; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public long getExitAnimDuration() { |
||||||
|
return exitAnimDuration; |
||||||
|
} |
||||||
|
|
||||||
|
public PopTip 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(); |
||||||
|
} |
||||||
|
|
||||||
|
if (DialogX.onlyOnePopTip) { |
||||||
|
PopTip oldInstance = null; |
||||||
|
if (popTipList != null && !popTipList.isEmpty()) { |
||||||
|
oldInstance = popTipList.get(popTipList.size() - 1); |
||||||
|
} |
||||||
|
if (oldInstance != null) { |
||||||
|
oldInstance.dismiss(); |
||||||
|
} |
||||||
|
} else { |
||||||
|
if (popTipList != null) { |
||||||
|
for (int i = 0; i < popTipList.size(); i++) { |
||||||
|
PopTip popInstance = popTipList.get(i); |
||||||
|
popInstance.moveUp(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
if (popTipList == null) popTipList = new ArrayList<>(); |
||||||
|
popTipList.add(PopTip.this); |
||||||
|
|
||||||
|
int layoutResId = isLightTheme() ? R.layout.layout_dialogx_poptip_material : R.layout.layout_dialogx_poptip_material_dark; |
||||||
|
if (style.popTipSettings() != null) { |
||||||
|
if (style.popTipSettings().layout(isLightTheme()) != 0) { |
||||||
|
layoutResId = style.popTipSettings().layout(isLightTheme()); |
||||||
|
} |
||||||
|
align = style.popTipSettings().align(); |
||||||
|
if (align == null) align = DialogXStyle.PopTipSettings.ALIGN.BOTTOM; |
||||||
|
enterAnimResId = style.popTipSettings().enterAnimResId(isLightTheme()) != 0 ? style.popTipSettings().enterAnimResId(isLightTheme()) : R.anim.anim_dialogx_default_enter; |
||||||
|
exitAnimResId = style.popTipSettings().exitAnimResId(isLightTheme()) != 0 ? style.popTipSettings().exitAnimResId(isLightTheme()) : R.anim.anim_dialogx_default_exit; |
||||||
|
} |
||||||
|
enterAnimDuration = 0; |
||||||
|
dialogView = createView(layoutResId); |
||||||
|
dialogImpl = new DialogImpl(dialogView); |
||||||
|
dialogView.setTag(me); |
||||||
|
show(dialogView); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,162 @@ |
|||||||
|
package com.kongzue.dialogx.dialogs; |
||||||
|
|
||||||
|
import android.app.Activity; |
||||||
|
|
||||||
|
import com.kongzue.dialogx.interfaces.DialogLifecycleCallback; |
||||||
|
|
||||||
|
import java.lang.ref.WeakReference; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author: Kongzue |
||||||
|
* @github: https://github.com/kongzue/
|
||||||
|
* @homepage: http://kongzue.com/
|
||||||
|
* @mail: myzcxhh@live.cn |
||||||
|
* @createTime: 2020/9/28 23:53 |
||||||
|
*/ |
||||||
|
public class TipDialog extends WaitDialog { |
||||||
|
|
||||||
|
protected TipDialog() { |
||||||
|
super(); |
||||||
|
} |
||||||
|
|
||||||
|
public static WaitDialog show(int messageResId) { |
||||||
|
DialogImpl dialogImpl = me().dialogImpl; |
||||||
|
me().preMessage(messageResId); |
||||||
|
if (dialogImpl != null) { |
||||||
|
dialogImpl.showTip(TYPE.WARNING); |
||||||
|
} else { |
||||||
|
me().showTip(messageResId, TYPE.WARNING); |
||||||
|
} |
||||||
|
return me(); |
||||||
|
} |
||||||
|
|
||||||
|
public static WaitDialog show(Activity activity, int messageResId) { |
||||||
|
DialogImpl dialogImpl = me().dialogImpl; |
||||||
|
me().preMessage(messageResId); |
||||||
|
if (dialogImpl != null && dialogImpl.bkg.getContext() == activity) { |
||||||
|
dialogImpl.showTip(TYPE.WARNING); |
||||||
|
} else { |
||||||
|
me().showTip(activity, messageResId, TYPE.WARNING); |
||||||
|
} |
||||||
|
return me(); |
||||||
|
} |
||||||
|
|
||||||
|
public static WaitDialog show(CharSequence message) { |
||||||
|
DialogImpl dialogImpl = me().dialogImpl; |
||||||
|
me().preMessage(message); |
||||||
|
if (dialogImpl != null) { |
||||||
|
dialogImpl.showTip(TYPE.WARNING); |
||||||
|
} else { |
||||||
|
me().showTip(message, TYPE.WARNING); |
||||||
|
} |
||||||
|
return me(); |
||||||
|
} |
||||||
|
|
||||||
|
public static WaitDialog show(Activity activity, CharSequence message) { |
||||||
|
DialogImpl dialogImpl = me().dialogImpl; |
||||||
|
me().preMessage(message); |
||||||
|
if (dialogImpl != null && dialogImpl.bkg.getContext() == activity) { |
||||||
|
dialogImpl.showTip(TYPE.WARNING); |
||||||
|
} else { |
||||||
|
me().showTip(activity, message, TYPE.WARNING); |
||||||
|
} |
||||||
|
return me(); |
||||||
|
} |
||||||
|
|
||||||
|
public static WaitDialog show(int messageResId, TYPE tip) { |
||||||
|
DialogImpl dialogImpl = me().dialogImpl; |
||||||
|
me().preMessage(messageResId); |
||||||
|
if (dialogImpl != null) { |
||||||
|
dialogImpl.showTip(tip); |
||||||
|
} else { |
||||||
|
me().showTip(messageResId, tip); |
||||||
|
} |
||||||
|
return me(); |
||||||
|
} |
||||||
|
|
||||||
|
public static WaitDialog show(Activity activity, int messageResId, TYPE tip) { |
||||||
|
DialogImpl dialogImpl = me().dialogImpl; |
||||||
|
me().preMessage(messageResId); |
||||||
|
if (dialogImpl != null && dialogImpl.bkg.getContext() == activity) { |
||||||
|
dialogImpl.showTip(tip); |
||||||
|
} else { |
||||||
|
me().showTip(activity, messageResId, tip); |
||||||
|
} |
||||||
|
return me(); |
||||||
|
} |
||||||
|
|
||||||
|
public static WaitDialog show(CharSequence message, TYPE tip) { |
||||||
|
DialogImpl dialogImpl = me().dialogImpl; |
||||||
|
me().preMessage(message); |
||||||
|
if (dialogImpl != null) { |
||||||
|
dialogImpl.showTip(tip); |
||||||
|
} else { |
||||||
|
me().showTip(message, tip); |
||||||
|
} |
||||||
|
return me(); |
||||||
|
} |
||||||
|
|
||||||
|
public static WaitDialog show(Activity activity, CharSequence message, TYPE tip) { |
||||||
|
DialogImpl dialogImpl = me().dialogImpl; |
||||||
|
me().preMessage(message); |
||||||
|
if (dialogImpl != null && dialogImpl.bkg.getContext() == activity) { |
||||||
|
dialogImpl.showTip(tip); |
||||||
|
} else { |
||||||
|
me().showTip(activity, message, tip); |
||||||
|
} |
||||||
|
return me(); |
||||||
|
} |
||||||
|
|
||||||
|
public static WaitDialog show(int messageResId, TYPE tip, long duration) { |
||||||
|
DialogImpl dialogImpl = me().dialogImpl; |
||||||
|
me().preMessage(messageResId); |
||||||
|
me().tipShowDuration = duration; |
||||||
|
if (dialogImpl != null) { |
||||||
|
dialogImpl.showTip(tip); |
||||||
|
} else { |
||||||
|
me().showTip(messageResId, tip); |
||||||
|
} |
||||||
|
return me(); |
||||||
|
} |
||||||
|
|
||||||
|
public static WaitDialog show(Activity activity, int messageResId, TYPE tip, long duration) { |
||||||
|
DialogImpl dialogImpl = me().dialogImpl; |
||||||
|
me().preMessage(messageResId); |
||||||
|
me().tipShowDuration = duration; |
||||||
|
if (dialogImpl != null && dialogImpl.bkg.getContext() == activity) { |
||||||
|
dialogImpl.showTip(tip); |
||||||
|
} else { |
||||||
|
me().showTip(activity, messageResId, tip); |
||||||
|
} |
||||||
|
return me(); |
||||||
|
} |
||||||
|
|
||||||
|
public static WaitDialog show(CharSequence message, TYPE tip, long duration) { |
||||||
|
DialogImpl dialogImpl = me().dialogImpl; |
||||||
|
me().preMessage(message); |
||||||
|
me().tipShowDuration = duration; |
||||||
|
if (dialogImpl != null) { |
||||||
|
dialogImpl.showTip(tip); |
||||||
|
} else { |
||||||
|
me().showTip(message, tip); |
||||||
|
} |
||||||
|
return me(); |
||||||
|
} |
||||||
|
|
||||||
|
public static WaitDialog show(Activity activity, CharSequence message, TYPE tip, long duration) { |
||||||
|
DialogImpl dialogImpl = me().dialogImpl; |
||||||
|
me().preMessage(message); |
||||||
|
me().tipShowDuration = duration; |
||||||
|
if (dialogImpl != null && dialogImpl.bkg.getContext() == activity) { |
||||||
|
dialogImpl.showTip(tip); |
||||||
|
} else { |
||||||
|
me().showTip(activity, message, tip); |
||||||
|
} |
||||||
|
return me(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String dialogKey() { |
||||||
|
return getClass().getSimpleName() + "(" + Integer.toHexString(hashCode()) + ")"; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,750 @@ |
|||||||
|
package com.kongzue.dialogx.dialogs; |
||||||
|
|
||||||
|
import android.animation.Animator; |
||||||
|
import android.app.Activity; |
||||||
|
import android.content.res.Configuration; |
||||||
|
import android.graphics.Color; |
||||||
|
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.Animation; |
||||||
|
import android.view.animation.AnimationUtils; |
||||||
|
import android.view.animation.DecelerateInterpolator; |
||||||
|
import android.widget.RelativeLayout; |
||||||
|
import android.widget.TextView; |
||||||
|
|
||||||
|
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.OnBackPressedListener; |
||||||
|
import com.kongzue.dialogx.interfaces.OnBindView; |
||||||
|
import com.kongzue.dialogx.interfaces.ProgressViewInterface; |
||||||
|
import com.kongzue.dialogx.util.TextInfo; |
||||||
|
import com.kongzue.dialogx.util.views.BlurView; |
||||||
|
import com.kongzue.dialogx.util.views.DialogXBaseRelativeLayout; |
||||||
|
import com.kongzue.dialogx.util.views.MaxRelativeLayout; |
||||||
|
import com.kongzue.dialogx.util.views.ProgressView; |
||||||
|
|
||||||
|
import java.lang.ref.WeakReference; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author: Kongzue |
||||||
|
* @github: https://github.com/kongzue/
|
||||||
|
* @homepage: http://kongzue.com/
|
||||||
|
* @mail: myzcxhh@live.cn |
||||||
|
* @createTime: 2020/9/27 14:50 |
||||||
|
*/ |
||||||
|
public class WaitDialog extends BaseDialog { |
||||||
|
|
||||||
|
public static int overrideEnterDuration = -1; |
||||||
|
public static int overrideExitDuration = -1; |
||||||
|
public static int overrideEnterAnimRes = 0; |
||||||
|
public static int overrideExitAnimRes = 0; |
||||||
|
public static BOOLEAN overrideCancelable; |
||||||
|
protected OnBindView<WaitDialog> onBindView; |
||||||
|
|
||||||
|
public enum TYPE { |
||||||
|
NONE, |
||||||
|
SUCCESS, |
||||||
|
WARNING, |
||||||
|
ERROR |
||||||
|
} |
||||||
|
|
||||||
|
protected static WeakReference<WaitDialog> me; |
||||||
|
protected CharSequence message; |
||||||
|
protected long tipShowDuration = 1500; |
||||||
|
protected float waitProgress = -1; |
||||||
|
protected int showType = -1; //-1:Waitdialog 状态标示符,其余为 TipDialog 状态标示
|
||||||
|
protected TextInfo messageTextInfo; |
||||||
|
protected int maskColor = -1; |
||||||
|
protected BOOLEAN privateCancelable; |
||||||
|
|
||||||
|
private DialogLifecycleCallback<WaitDialog> dialogLifecycleCallback; |
||||||
|
|
||||||
|
protected WaitDialog() { |
||||||
|
super(); |
||||||
|
me = new WeakReference<>(this); |
||||||
|
cancelable = DialogX.cancelableTipDialog; |
||||||
|
} |
||||||
|
|
||||||
|
public static WaitDialog show(CharSequence message) { |
||||||
|
DialogImpl dialogImpl = me().dialogImpl; |
||||||
|
me().message = message; |
||||||
|
me().showType = -1; |
||||||
|
if (dialogImpl != null) { |
||||||
|
dialogImpl.progressView.loading(); |
||||||
|
setMessage(message); |
||||||
|
return me(); |
||||||
|
} else { |
||||||
|
WaitDialog waitDialog = new WaitDialog(); |
||||||
|
waitDialog.message = message; |
||||||
|
waitDialog.show(); |
||||||
|
return waitDialog; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static WaitDialog show(Activity activity, CharSequence message) { |
||||||
|
DialogImpl dialogImpl = me().dialogImpl; |
||||||
|
me().message = message; |
||||||
|
me().showType = -1; |
||||||
|
if (dialogImpl != null && dialogImpl.bkg.getContext() == activity) { |
||||||
|
dialogImpl.progressView.loading(); |
||||||
|
setMessage(message); |
||||||
|
return me(); |
||||||
|
} else { |
||||||
|
WaitDialog waitDialog = new WaitDialog(); |
||||||
|
waitDialog.message = message; |
||||||
|
waitDialog.show(activity); |
||||||
|
return waitDialog; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static WaitDialog show(int messageResId) { |
||||||
|
DialogImpl dialogImpl = me().dialogImpl; |
||||||
|
me().preMessage(messageResId); |
||||||
|
me().showType = -1; |
||||||
|
if (dialogImpl != null) { |
||||||
|
dialogImpl.progressView.loading(); |
||||||
|
setMessage(messageResId); |
||||||
|
return me(); |
||||||
|
} else { |
||||||
|
WaitDialog waitDialog = new WaitDialog(); |
||||||
|
waitDialog.preMessage(messageResId); |
||||||
|
waitDialog.show(); |
||||||
|
return waitDialog; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static WaitDialog show(Activity activity, int messageResId) { |
||||||
|
DialogImpl dialogImpl = me().dialogImpl; |
||||||
|
me().preMessage(messageResId); |
||||||
|
me().showType = -1; |
||||||
|
if (dialogImpl != null && dialogImpl.bkg.getContext() == activity) { |
||||||
|
dialogImpl.progressView.loading(); |
||||||
|
setMessage(messageResId); |
||||||
|
return me(); |
||||||
|
} else { |
||||||
|
WaitDialog waitDialog = new WaitDialog(); |
||||||
|
waitDialog.preMessage(messageResId); |
||||||
|
waitDialog.show(activity); |
||||||
|
return waitDialog; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static WaitDialog show(CharSequence message, float progress) { |
||||||
|
DialogImpl dialogImpl = me().dialogImpl; |
||||||
|
me().showType = -1; |
||||||
|
me().preMessage(message); |
||||||
|
if (dialogImpl != null) { |
||||||
|
setMessage(message); |
||||||
|
me().setProgress(progress); |
||||||
|
return me(); |
||||||
|
} else { |
||||||
|
WaitDialog waitDialog = new WaitDialog(); |
||||||
|
waitDialog.preMessage(message); |
||||||
|
waitDialog.show(); |
||||||
|
waitDialog.setProgress(progress); |
||||||
|
return waitDialog; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static WaitDialog show(Activity activity, CharSequence message, float progress) { |
||||||
|
DialogImpl dialogImpl = me().dialogImpl; |
||||||
|
me().showType = -1; |
||||||
|
me().preMessage(message); |
||||||
|
if (dialogImpl != null && dialogImpl.bkg.getContext() == activity) { |
||||||
|
setMessage(message); |
||||||
|
me().setProgress(progress); |
||||||
|
return me(); |
||||||
|
} else { |
||||||
|
WaitDialog waitDialog = new WaitDialog(); |
||||||
|
waitDialog.preMessage(message); |
||||||
|
waitDialog.show(activity); |
||||||
|
waitDialog.setProgress(progress); |
||||||
|
return waitDialog; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static WaitDialog show(int messageResId, float progress) { |
||||||
|
DialogImpl dialogImpl = me().dialogImpl; |
||||||
|
me().showType = -1; |
||||||
|
me().preMessage(messageResId); |
||||||
|
if (dialogImpl != null) { |
||||||
|
setMessage(messageResId); |
||||||
|
me().setProgress(progress); |
||||||
|
return me(); |
||||||
|
} else { |
||||||
|
WaitDialog waitDialog = new WaitDialog(); |
||||||
|
waitDialog.preMessage(messageResId); |
||||||
|
waitDialog.show(); |
||||||
|
waitDialog.setProgress(progress); |
||||||
|
return waitDialog; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static WaitDialog show(Activity activity, int messageResId, float progress) { |
||||||
|
DialogImpl dialogImpl = me().dialogImpl; |
||||||
|
me().showType = -1; |
||||||
|
me().preMessage(messageResId); |
||||||
|
if (dialogImpl != null && dialogImpl.bkg.getContext() == activity) { |
||||||
|
setMessage(messageResId); |
||||||
|
me().setProgress(progress); |
||||||
|
return me(); |
||||||
|
} else { |
||||||
|
WaitDialog waitDialog = new WaitDialog(); |
||||||
|
waitDialog.preMessage(messageResId); |
||||||
|
waitDialog.show(activity); |
||||||
|
waitDialog.setProgress(progress); |
||||||
|
return waitDialog; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static WaitDialog show(Activity activity, float progress) { |
||||||
|
DialogImpl dialogImpl = me().dialogImpl; |
||||||
|
me().showType = -1; |
||||||
|
if (dialogImpl != null && dialogImpl.bkg.getContext() == activity) { |
||||||
|
me().setProgress(progress); |
||||||
|
return me(); |
||||||
|
} else { |
||||||
|
WaitDialog waitDialog = new WaitDialog(); |
||||||
|
waitDialog.show(activity); |
||||||
|
waitDialog.setProgress(progress); |
||||||
|
return waitDialog; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static WaitDialog show(float progress) { |
||||||
|
DialogImpl dialogImpl = me().dialogImpl; |
||||||
|
me().showType = -1; |
||||||
|
if (dialogImpl != null) { |
||||||
|
me().setProgress(progress); |
||||||
|
return me(); |
||||||
|
} else { |
||||||
|
WaitDialog waitDialog = new WaitDialog(); |
||||||
|
waitDialog.show(); |
||||||
|
waitDialog.setProgress(progress); |
||||||
|
return waitDialog; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public float getProgress() { |
||||||
|
return waitProgress; |
||||||
|
} |
||||||
|
|
||||||
|
public WaitDialog setProgress(float waitProgress) { |
||||||
|
this.waitProgress = waitProgress; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
private View dialogView; |
||||||
|
|
||||||
|
public WaitDialog show() { |
||||||
|
super.beforeShow(); |
||||||
|
int layoutResId = R.layout.layout_dialogx_wait; |
||||||
|
if (style.overrideWaitTipRes() != null && style.overrideWaitTipRes().overrideWaitLayout(isLightTheme()) != 0) { |
||||||
|
layoutResId = style.overrideWaitTipRes().overrideWaitLayout(isLightTheme()); |
||||||
|
} |
||||||
|
dialogImpl = new DialogImpl(layoutResId); |
||||||
|
runOnMain(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
dialogImpl.lazyCreate(); |
||||||
|
dialogView.setTag(me.get()); |
||||||
|
show(dialogView); |
||||||
|
} |
||||||
|
}); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public WaitDialog show(final Activity activity) { |
||||||
|
super.beforeShow(); |
||||||
|
int layoutResId = R.layout.layout_dialogx_wait; |
||||||
|
if (style.overrideWaitTipRes() != null && style.overrideWaitTipRes().overrideWaitLayout(isLightTheme()) != 0) { |
||||||
|
layoutResId = style.overrideWaitTipRes().overrideWaitLayout(isLightTheme()); |
||||||
|
} |
||||||
|
dialogImpl = new DialogImpl(layoutResId); |
||||||
|
runOnMain(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
dialogImpl.lazyCreate(); |
||||||
|
dialogView.setTag(me.get()); |
||||||
|
show(activity, dialogView); |
||||||
|
} |
||||||
|
}); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
protected DialogImpl dialogImpl; |
||||||
|
|
||||||
|
public class DialogImpl implements DialogConvertViewInterface { |
||||||
|
public DialogXBaseRelativeLayout boxRoot; |
||||||
|
public MaxRelativeLayout bkg; |
||||||
|
public BlurView blurView; |
||||||
|
public RelativeLayout boxProgress; |
||||||
|
public ProgressViewInterface progressView; |
||||||
|
public RelativeLayout boxCustomView; |
||||||
|
public TextView txtInfo; |
||||||
|
|
||||||
|
private int layoutResId; |
||||||
|
|
||||||
|
public DialogImpl(int layoutResId) { |
||||||
|
this.layoutResId = layoutResId; |
||||||
|
} |
||||||
|
|
||||||
|
public void lazyCreate(){ |
||||||
|
dialogView = createView(layoutResId); |
||||||
|
boxRoot = dialogView.findViewById(R.id.box_root); |
||||||
|
bkg = dialogView.findViewById(R.id.bkg); |
||||||
|
blurView = dialogView.findViewById(R.id.blurView); |
||||||
|
boxProgress = dialogView.findViewById(R.id.box_progress); |
||||||
|
View progressViewCache = (View) style.overrideWaitTipRes().overrideWaitView(getContext(), isLightTheme()); |
||||||
|
if (progressViewCache == null) { |
||||||
|
progressViewCache = new ProgressView(getContext()); |
||||||
|
} |
||||||
|
progressView = (ProgressViewInterface) progressViewCache; |
||||||
|
boxProgress.addView(progressViewCache, new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); |
||||||
|
boxCustomView = dialogView.findViewById(R.id.box_customView); |
||||||
|
txtInfo = dialogView.findViewById(R.id.txt_info); |
||||||
|
init(); |
||||||
|
dialogImpl = this; |
||||||
|
refreshView(); |
||||||
|
} |
||||||
|
|
||||||
|
public DialogImpl(View convertView) { |
||||||
|
boxRoot = convertView.findViewById(R.id.box_root); |
||||||
|
bkg = convertView.findViewById(R.id.bkg); |
||||||
|
blurView = convertView.findViewById(R.id.blurView); |
||||||
|
boxProgress = convertView.findViewById(R.id.box_progress); |
||||||
|
View progressViewCache = (View) style.overrideWaitTipRes().overrideWaitView(getContext(), isLightTheme()); |
||||||
|
if (progressViewCache == null) { |
||||||
|
progressViewCache = new ProgressView(getContext()); |
||||||
|
} |
||||||
|
progressView = (ProgressViewInterface) progressViewCache; |
||||||
|
boxProgress.addView(progressViewCache, new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); |
||||||
|
boxCustomView = convertView.findViewById(R.id.box_customView); |
||||||
|
txtInfo = convertView.findViewById(R.id.txt_info); |
||||||
|
init(); |
||||||
|
dialogImpl = this; |
||||||
|
refreshView(); |
||||||
|
} |
||||||
|
|
||||||
|
public void init() { |
||||||
|
if (messageTextInfo == null) messageTextInfo = DialogX.tipTextInfo; |
||||||
|
if (backgroundColor == -1) backgroundColor = DialogX.tipBackgroundColor; |
||||||
|
|
||||||
|
if (style.overrideWaitTipRes() == null) { |
||||||
|
blurView.setRadiusPx(dip2px(15)); |
||||||
|
} else { |
||||||
|
blurView.setRadiusPx(style.overrideWaitTipRes().overrideRadiusPx() < 0 ? dip2px(15) : style.overrideWaitTipRes().overrideRadiusPx()); |
||||||
|
} |
||||||
|
boxRoot.setClickable(true); |
||||||
|
|
||||||
|
boxRoot.setParentDialog(me.get()); |
||||||
|
boxRoot.setOnLifecycleCallBack(new DialogXBaseRelativeLayout.OnLifecycleCallBack() { |
||||||
|
@Override |
||||||
|
public void onShow() { |
||||||
|
isShow = true; |
||||||
|
boxRoot.setAlpha(0f); |
||||||
|
bkg.post(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
int enterAnimResId = R.anim.anim_dialogx_default_enter; |
||||||
|
if (overrideEnterAnimRes != 0) { |
||||||
|
enterAnimResId = overrideEnterAnimRes; |
||||||
|
} |
||||||
|
Animation enterAnim = AnimationUtils.loadAnimation(getContext(), enterAnimResId); |
||||||
|
long enterAnimDurationTemp = enterAnim.getDuration(); |
||||||
|
enterAnim.setInterpolator(new DecelerateInterpolator()); |
||||||
|
if (overrideEnterDuration >= 0) { |
||||||
|
enterAnimDurationTemp = overrideEnterDuration; |
||||||
|
} |
||||||
|
if (enterAnimDuration >= 0) { |
||||||
|
enterAnimDurationTemp = enterAnimDuration; |
||||||
|
} |
||||||
|
enterAnim.setDuration(enterAnimDurationTemp); |
||||||
|
bkg.startAnimation(enterAnim); |
||||||
|
|
||||||
|
boxRoot.animate() |
||||||
|
.setDuration(enterAnimDurationTemp) |
||||||
|
.alpha(1f) |
||||||
|
.setInterpolator(new DecelerateInterpolator()) |
||||||
|
.setListener(null); |
||||||
|
|
||||||
|
getDialogLifecycleCallback().onShow(me()); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onDismiss() { |
||||||
|
isShow = false; |
||||||
|
dialogImpl = null; |
||||||
|
getDialogLifecycleCallback().onDismiss(me()); |
||||||
|
me.clear(); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
if (readyTipType != null) { |
||||||
|
progressView.noLoading(); |
||||||
|
((View) progressView).postDelayed(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
showTip(readyTipType); |
||||||
|
} |
||||||
|
}, 100); |
||||||
|
} |
||||||
|
|
||||||
|
boxRoot.setOnBackPressedListener(new OnBackPressedListener() { |
||||||
|
@Override |
||||||
|
public boolean onBackPressed() { |
||||||
|
if (onBackPressedListener != null && onBackPressedListener.onBackPressed()) { |
||||||
|
dismiss(); |
||||||
|
return false; |
||||||
|
} |
||||||
|
if (isCancelable()) { |
||||||
|
dismiss(); |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
private float oldProgress; |
||||||
|
|
||||||
|
public void refreshView() { |
||||||
|
if (style.overrideWaitTipRes() != null) { |
||||||
|
int overrideBackgroundColorRes = style.overrideWaitTipRes().overrideBackgroundColorRes(isLightTheme()); |
||||||
|
if (overrideBackgroundColorRes == 0) { |
||||||
|
overrideBackgroundColorRes = isLightTheme() ? R.color.dialogxWaitBkgDark : R.color.dialogxWaitBkgLight; |
||||||
|
} |
||||||
|
blurView.setOverlayColor(backgroundColor == -1 ? getResources().getColor(overrideBackgroundColorRes) : backgroundColor); |
||||||
|
int overrideTextColorRes = style.overrideWaitTipRes().overrideTextColorRes(isLightTheme()); |
||||||
|
if (overrideTextColorRes == 0) { |
||||||
|
overrideTextColorRes = isLightTheme() ? R.color.white : R.color.black; |
||||||
|
} |
||||||
|
txtInfo.setTextColor(getResources().getColor(overrideTextColorRes)); |
||||||
|
progressView.setColor(getResources().getColor(overrideTextColorRes)); |
||||||
|
blurView.setUseBlur(style.overrideWaitTipRes().blurBackground()); |
||||||
|
} else { |
||||||
|
if (isLightTheme()) { |
||||||
|
blurView.setOverlayColor(backgroundColor == -1 ? getResources().getColor(R.color.dialogxWaitBkgDark) : backgroundColor); |
||||||
|
progressView.setColor(Color.WHITE); |
||||||
|
txtInfo.setTextColor(Color.WHITE); |
||||||
|
} else { |
||||||
|
blurView.setOverlayColor(backgroundColor == -1 ? getResources().getColor(R.color.dialogxWaitBkgLight) : backgroundColor); |
||||||
|
progressView.setColor(Color.BLACK); |
||||||
|
txtInfo.setTextColor(Color.BLACK); |
||||||
|
} |
||||||
|
} |
||||||
|
if (DialogX.tipProgressColor != -1) progressView.setColor(DialogX.tipProgressColor); |
||||||
|
|
||||||
|
if (waitProgress >= 0 && waitProgress <= 1 && oldProgress != waitProgress) { |
||||||
|
progressView.progress(waitProgress); |
||||||
|
oldProgress = waitProgress; |
||||||
|
} |
||||||
|
|
||||||
|
showText(txtInfo, message); |
||||||
|
useTextInfo(txtInfo, messageTextInfo); |
||||||
|
|
||||||
|
if (maskColor != -1) boxRoot.setBackgroundColor(maskColor); |
||||||
|
|
||||||
|
if (onBindView != null && onBindView.getCustomView() != null) { |
||||||
|
onBindView.bindParent(boxCustomView, me.get()); |
||||||
|
boxCustomView.setVisibility(View.VISIBLE); |
||||||
|
boxProgress.setVisibility(View.GONE); |
||||||
|
} else { |
||||||
|
boxCustomView.setVisibility(View.GONE); |
||||||
|
boxProgress.setVisibility(View.VISIBLE); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void doDismiss(final View v) { |
||||||
|
boxRoot.post(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
if (v != null) v.setEnabled(false); |
||||||
|
|
||||||
|
int exitAnimResId = R.anim.anim_dialogx_default_exit; |
||||||
|
if (overrideExitAnimRes != 0) { |
||||||
|
exitAnimResId = overrideExitAnimRes; |
||||||
|
} |
||||||
|
Animation exitAnim = AnimationUtils.loadAnimation(getContext(), exitAnimResId); |
||||||
|
long exitAnimDurationTemp = exitAnim.getDuration(); |
||||||
|
if (overrideExitDuration >= 0) { |
||||||
|
exitAnimDurationTemp = overrideExitDuration; |
||||||
|
} |
||||||
|
if (exitAnimDuration != -1) { |
||||||
|
exitAnimDurationTemp = exitAnimDuration; |
||||||
|
} |
||||||
|
exitAnim.setDuration(exitAnimDurationTemp); |
||||||
|
exitAnim.setInterpolator(new AccelerateInterpolator()); |
||||||
|
bkg.startAnimation(exitAnim); |
||||||
|
|
||||||
|
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 showTip(final TYPE tip) { |
||||||
|
runOnMain(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
showType = tip.ordinal(); |
||||||
|
if (progressView == null) return; |
||||||
|
switch (tip) { |
||||||
|
case NONE: |
||||||
|
progressView.loading(); |
||||||
|
return; |
||||||
|
case SUCCESS: |
||||||
|
progressView.success(); |
||||||
|
break; |
||||||
|
case WARNING: |
||||||
|
progressView.warning(); |
||||||
|
break; |
||||||
|
case ERROR: |
||||||
|
progressView.error(); |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
//此事件是在完成衔接动画绘制后执行的逻辑
|
||||||
|
progressView.whenShowTick(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
getDialogLifecycleCallback().onShow(WaitDialog.this); |
||||||
|
refreshView(); |
||||||
|
((View) progressView).postDelayed(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
if (showType > -1) { |
||||||
|
doDismiss(null); |
||||||
|
} |
||||||
|
} |
||||||
|
}, tipShowDuration); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String dialogKey() { |
||||||
|
return getClass().getSimpleName() + "(" + Integer.toHexString(hashCode()) + ")"; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isLightTheme() { |
||||||
|
if (DialogX.tipTheme == null) { |
||||||
|
return super.isLightTheme(); |
||||||
|
} else { |
||||||
|
return DialogX.tipTheme == DialogX.THEME.LIGHT; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void refreshUI() { |
||||||
|
runOnMain(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
if (dialogImpl != null) dialogImpl.refreshView(); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
public void doDismiss() { |
||||||
|
if (dialogImpl == null) return; |
||||||
|
dialogImpl.doDismiss(null); |
||||||
|
} |
||||||
|
|
||||||
|
public static void dismiss() { |
||||||
|
me().doDismiss(); |
||||||
|
} |
||||||
|
|
||||||
|
protected static WaitDialog me() { |
||||||
|
if (me == null || me.get() == null) me = new WeakReference<>(new WaitDialog()); |
||||||
|
return me.get(); |
||||||
|
} |
||||||
|
|
||||||
|
protected TYPE readyTipType; |
||||||
|
|
||||||
|
protected void showTip(CharSequence message, TYPE type) { |
||||||
|
showType = type.ordinal(); |
||||||
|
this.message = message; |
||||||
|
readyTipType = type; |
||||||
|
show(); |
||||||
|
} |
||||||
|
|
||||||
|
protected void showTip(Activity activity, CharSequence message, TYPE type) { |
||||||
|
showType = type.ordinal(); |
||||||
|
this.message = message; |
||||||
|
readyTipType = type; |
||||||
|
show(activity); |
||||||
|
} |
||||||
|
|
||||||
|
protected void showTip(int messageResId, TYPE type) { |
||||||
|
showType = type.ordinal(); |
||||||
|
this.message = getString(messageResId); |
||||||
|
readyTipType = type; |
||||||
|
show(); |
||||||
|
} |
||||||
|
|
||||||
|
protected void showTip(Activity activity, int messageResId, TYPE type) { |
||||||
|
showType = type.ordinal(); |
||||||
|
this.message = getString(messageResId); |
||||||
|
readyTipType = type; |
||||||
|
show(activity); |
||||||
|
} |
||||||
|
|
||||||
|
public static CharSequence getMessage() { |
||||||
|
return me().message; |
||||||
|
} |
||||||
|
|
||||||
|
public static WaitDialog setMessage(CharSequence message) { |
||||||
|
me().preMessage(message); |
||||||
|
me().refreshUI(); |
||||||
|
return me(); |
||||||
|
} |
||||||
|
|
||||||
|
public static WaitDialog setMessage(int messageResId) { |
||||||
|
me().preMessage(messageResId); |
||||||
|
me().refreshUI(); |
||||||
|
return me(); |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isCancelable() { |
||||||
|
if (privateCancelable != null) { |
||||||
|
return privateCancelable == BOOLEAN.TRUE; |
||||||
|
} |
||||||
|
if (overrideCancelable != null) { |
||||||
|
return overrideCancelable == BOOLEAN.TRUE; |
||||||
|
} |
||||||
|
return cancelable; |
||||||
|
} |
||||||
|
|
||||||
|
public WaitDialog setCancelable(boolean cancelable) { |
||||||
|
privateCancelable = cancelable ? BOOLEAN.TRUE : BOOLEAN.FALSE; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 用于从 WaitDialog 到 TipDialog 的消息设置 |
||||||
|
* 此方法不会立即执行,而是等到动画衔接完成后由事件设置 |
||||||
|
* |
||||||
|
* @param message 消息 |
||||||
|
* @return me |
||||||
|
*/ |
||||||
|
protected WaitDialog preMessage(CharSequence message) { |
||||||
|
me().message = message; |
||||||
|
return me(); |
||||||
|
} |
||||||
|
|
||||||
|
protected WaitDialog preMessage(int messageResId) { |
||||||
|
me().message = getString(messageResId); |
||||||
|
return me(); |
||||||
|
} |
||||||
|
|
||||||
|
public DialogLifecycleCallback<WaitDialog> getDialogLifecycleCallback() { |
||||||
|
return dialogLifecycleCallback == null ? new DialogLifecycleCallback<WaitDialog>() { |
||||||
|
} : dialogLifecycleCallback; |
||||||
|
} |
||||||
|
|
||||||
|
public WaitDialog setDialogLifecycleCallback(DialogLifecycleCallback<WaitDialog> dialogLifecycleCallback) { |
||||||
|
this.dialogLifecycleCallback = dialogLifecycleCallback; |
||||||
|
if (isShow) dialogLifecycleCallback.onShow(me.get()); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public DialogImpl getDialogImpl() { |
||||||
|
return dialogImpl; |
||||||
|
} |
||||||
|
|
||||||
|
public WaitDialog setCustomView(OnBindView<WaitDialog> onBindView) { |
||||||
|
this.onBindView = onBindView; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public View getCustomView() { |
||||||
|
if (onBindView == null) return null; |
||||||
|
return onBindView.getCustomView(); |
||||||
|
} |
||||||
|
|
||||||
|
public WaitDialog removeCustomView() { |
||||||
|
this.onBindView.clean(); |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public OnBackPressedListener getOnBackPressedListener() { |
||||||
|
return onBackPressedListener; |
||||||
|
} |
||||||
|
|
||||||
|
public WaitDialog setOnBackPressedListener(OnBackPressedListener onBackPressedListener) { |
||||||
|
this.onBackPressedListener = onBackPressedListener; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public int getBackgroundColor() { |
||||||
|
return backgroundColor; |
||||||
|
} |
||||||
|
|
||||||
|
public WaitDialog setBackgroundColor(@ColorInt int backgroundColor) { |
||||||
|
this.backgroundColor = backgroundColor; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public WaitDialog setBackgroundColorRes(@ColorRes int backgroundColorResId) { |
||||||
|
this.backgroundColor = getColor(backgroundColorResId); |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public WaitDialog setMaskColor(@ColorInt int maskColor) { |
||||||
|
this.maskColor = maskColor; |
||||||
|
refreshUI(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public WaitDialog setEnterAnimDuration(long enterAnimDuration) { |
||||||
|
this.enterAnimDuration = enterAnimDuration; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public long getExitAnimDuration() { |
||||||
|
return exitAnimDuration; |
||||||
|
} |
||||||
|
|
||||||
|
public WaitDialog setExitAnimDuration(long exitAnimDuration) { |
||||||
|
this.exitAnimDuration = exitAnimDuration; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onUIModeChange(Configuration newConfig) { |
||||||
|
refreshUI(); |
||||||
|
} |
||||||
|
|
||||||
|
public static WaitDialog getInstance() { |
||||||
|
return me(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,87 @@ |
|||||||
|
package com.kongzue.dialogx.impl; |
||||||
|
|
||||||
|
import android.app.Activity; |
||||||
|
import android.app.Application; |
||||||
|
import android.content.Context; |
||||||
|
import android.os.Bundle; |
||||||
|
import android.os.Looper; |
||||||
|
import android.util.Log; |
||||||
|
|
||||||
|
import androidx.annotation.NonNull; |
||||||
|
import androidx.annotation.Nullable; |
||||||
|
import androidx.appcompat.app.AppCompatActivity; |
||||||
|
|
||||||
|
import com.kongzue.dialogx.interfaces.BaseDialog; |
||||||
|
|
||||||
|
import java.lang.ref.WeakReference; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author: Kongzue |
||||||
|
* @github: https://github.com/kongzue/
|
||||||
|
* @homepage: http://kongzue.com/
|
||||||
|
* @mail: myzcxhh@live.cn |
||||||
|
* @createTime: 2020/9/22 11:31 |
||||||
|
*/ |
||||||
|
public class ActivityLifecycleImpl implements Application.ActivityLifecycleCallbacks { |
||||||
|
|
||||||
|
private onActivityResumeCallBack onActivityResumeCallBack; |
||||||
|
|
||||||
|
public ActivityLifecycleImpl(ActivityLifecycleImpl.onActivityResumeCallBack onActivityResumeCallBack) { |
||||||
|
this.onActivityResumeCallBack = onActivityResumeCallBack; |
||||||
|
} |
||||||
|
|
||||||
|
public static void init(Context context, ActivityLifecycleImpl.onActivityResumeCallBack onActivityResumeCallBack) { |
||||||
|
((Application) context.getApplicationContext()).registerActivityLifecycleCallbacks(new ActivityLifecycleImpl(onActivityResumeCallBack)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) { |
||||||
|
if (onActivityResumeCallBack != null) { |
||||||
|
onActivityResumeCallBack.getActivity(activity); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onActivityStarted(@NonNull Activity activity) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onActivityResumed(@NonNull Activity activity) { |
||||||
|
if (activity.isDestroyed() || activity.isFinishing()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
if (onActivityResumeCallBack != null) { |
||||||
|
onActivityResumeCallBack.getActivity(activity); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onActivityPaused(@NonNull Activity activity) { |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onActivityStopped(@NonNull Activity activity) { |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onActivityDestroyed(@NonNull Activity activity) { |
||||||
|
if (BaseDialog.getContext()==activity){ |
||||||
|
BaseDialog.cleanContext(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onActivityPreDestroyed(@NonNull final Activity activity) { |
||||||
|
BaseDialog.recycleDialog(activity); |
||||||
|
} |
||||||
|
|
||||||
|
public interface onActivityResumeCallBack { |
||||||
|
void getActivity(Activity activity); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,30 @@ |
|||||||
|
package com.kongzue.dialogx.impl; |
||||||
|
|
||||||
|
import android.animation.Animator; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author: Kongzue |
||||||
|
* @github: https://github.com/kongzue/
|
||||||
|
* @homepage: http://kongzue.com/
|
||||||
|
* @mail: myzcxhh@live.cn |
||||||
|
* @createTime: 2020/9/22 14:37 |
||||||
|
*/ |
||||||
|
public abstract class AnimatorListenerEndCallBack implements Animator.AnimatorListener { |
||||||
|
@Override |
||||||
|
public void onAnimationStart(Animator animation) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public abstract void onAnimationEnd(Animator animation); |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onAnimationCancel(Animator animation) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onAnimationRepeat(Animator animation) { |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,365 @@ |
|||||||
|
package com.kongzue.dialogx.interfaces; |
||||||
|
|
||||||
|
import android.app.Activity; |
||||||
|
import android.content.Context; |
||||||
|
import android.content.res.ColorStateList; |
||||||
|
import android.content.res.Configuration; |
||||||
|
import android.content.res.Resources; |
||||||
|
import android.graphics.Color; |
||||||
|
import android.graphics.Typeface; |
||||||
|
import android.os.Handler; |
||||||
|
import android.os.Looper; |
||||||
|
import android.util.Log; |
||||||
|
import android.util.TypedValue; |
||||||
|
import android.view.LayoutInflater; |
||||||
|
import android.view.View; |
||||||
|
import android.view.ViewGroup; |
||||||
|
import android.view.WindowManager; |
||||||
|
import android.widget.FrameLayout; |
||||||
|
import android.widget.LinearLayout; |
||||||
|
import android.widget.TextView; |
||||||
|
|
||||||
|
import androidx.annotation.ColorRes; |
||||||
|
import androidx.appcompat.app.AppCompatDelegate; |
||||||
|
|
||||||
|
import com.kongzue.dialogx.DialogX; |
||||||
|
import com.kongzue.dialogx.dialogs.PopTip; |
||||||
|
import com.kongzue.dialogx.impl.ActivityLifecycleImpl; |
||||||
|
import com.kongzue.dialogx.util.TextInfo; |
||||||
|
import com.kongzue.dialogx.util.WindowUtil; |
||||||
|
|
||||||
|
import java.lang.ref.WeakReference; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
import java.util.concurrent.CopyOnWriteArrayList; |
||||||
|
|
||||||
|
import static com.kongzue.dialogx.DialogX.DEBUGMODE; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author: Kongzue |
||||||
|
* @github: https://github.com/kongzue/
|
||||||
|
* @homepage: http://kongzue.com/
|
||||||
|
* @mail: myzcxhh@live.cn |
||||||
|
* @createTime: 2020/9/22 14:10 |
||||||
|
*/ |
||||||
|
public abstract class BaseDialog { |
||||||
|
|
||||||
|
private static WeakReference<FrameLayout> rootFrameLayout; |
||||||
|
private static WeakReference<Activity> contextWeakReference; |
||||||
|
protected WeakReference<Activity> ownActivity; |
||||||
|
private static List<BaseDialog> runningDialogList; |
||||||
|
private WeakReference<View> dialogView; |
||||||
|
|
||||||
|
public static void init(Context context) { |
||||||
|
if (context instanceof Activity) { |
||||||
|
initActivityContext((Activity) context); |
||||||
|
} |
||||||
|
ActivityLifecycleImpl.init(context, new ActivityLifecycleImpl.onActivityResumeCallBack() { |
||||||
|
@Override |
||||||
|
public void getActivity(Activity activity) { |
||||||
|
initActivityContext(activity); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
private static void initActivityContext(Activity activity) { |
||||||
|
try { |
||||||
|
contextWeakReference = new WeakReference<>(activity); |
||||||
|
rootFrameLayout = new WeakReference<>((FrameLayout) activity.getWindow().getDecorView()); |
||||||
|
} catch (Exception e) { |
||||||
|
error("DialogX.init: 初始化异常,找不到Activity的根布局"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected static void log(Object o) { |
||||||
|
if (DEBUGMODE) Log.i(">>>", o.toString()); |
||||||
|
} |
||||||
|
|
||||||
|
protected static void error(Object o) { |
||||||
|
if (DEBUGMODE) Log.e(">>>", o.toString()); |
||||||
|
} |
||||||
|
|
||||||
|
public abstract void onUIModeChange(Configuration newConfig); |
||||||
|
|
||||||
|
protected static void show(final View view) { |
||||||
|
if (view == null) return; |
||||||
|
final BaseDialog baseDialog = (BaseDialog) view.getTag(); |
||||||
|
baseDialog.ownActivity = new WeakReference<>(contextWeakReference.get()); |
||||||
|
baseDialog.dialogView = new WeakReference<>(view); |
||||||
|
|
||||||
|
log(baseDialog.dialogKey() + ".show"); |
||||||
|
addDialogToRunningList(baseDialog); |
||||||
|
if (DialogX.implIMPLMode == DialogX.IMPL_MODE.VIEW) { |
||||||
|
if (rootFrameLayout == null || rootFrameLayout.get() == null) return; |
||||||
|
runOnMain(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
rootFrameLayout.get().addView(view); |
||||||
|
} |
||||||
|
}); |
||||||
|
} else { |
||||||
|
runOnMain(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
WindowUtil.show(contextWeakReference.get(), view, !(baseDialog instanceof PopTip)); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected static void show(final Activity activity, final View view) { |
||||||
|
if (activity == null || view == null) return; |
||||||
|
if (activity.isDestroyed()) { |
||||||
|
error(((BaseDialog) view.getTag()).dialogKey() + ".show ERROR: activity is Destroyed."); |
||||||
|
return; |
||||||
|
} |
||||||
|
final BaseDialog baseDialog = (BaseDialog) view.getTag(); |
||||||
|
baseDialog.ownActivity = new WeakReference<>(activity); |
||||||
|
baseDialog.dialogView = new WeakReference<>(view); |
||||||
|
|
||||||
|
log(baseDialog + ".show"); |
||||||
|
addDialogToRunningList(baseDialog); |
||||||
|
if (DialogX.implIMPLMode == DialogX.IMPL_MODE.VIEW) { |
||||||
|
final FrameLayout activityRootView = (FrameLayout) activity.getWindow().getDecorView(); |
||||||
|
if (activityRootView == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
runOnMain(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
activityRootView.addView(view); |
||||||
|
} |
||||||
|
}); |
||||||
|
} else { |
||||||
|
runOnMain(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
WindowUtil.show(activity, view, !(baseDialog instanceof PopTip)); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected static void dismiss(final View dialogView) { |
||||||
|
if (dialogView == null) return; |
||||||
|
final BaseDialog baseDialog = (BaseDialog) dialogView.getTag(); |
||||||
|
log(baseDialog.dialogKey() + ".dismiss"); |
||||||
|
removeDialogToRunningList(baseDialog); |
||||||
|
if (baseDialog.dialogView != null) baseDialog.dialogView.clear(); |
||||||
|
if (DialogX.implIMPLMode == DialogX.IMPL_MODE.VIEW) { |
||||||
|
runOnMain(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
if (dialogView.getParent() == null || !(dialogView.getParent() instanceof ViewGroup)) { |
||||||
|
if (rootFrameLayout == null) return; |
||||||
|
rootFrameLayout.get().removeView(dialogView); |
||||||
|
} else { |
||||||
|
((ViewGroup) dialogView.getParent()).removeView(dialogView); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} else { |
||||||
|
runOnMain(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
WindowUtil.dismiss(dialogView); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static void addDialogToRunningList(BaseDialog baseDialog) { |
||||||
|
if (runningDialogList == null) runningDialogList = new ArrayList<>(); |
||||||
|
runningDialogList.add(baseDialog); |
||||||
|
} |
||||||
|
|
||||||
|
private static void removeDialogToRunningList(BaseDialog baseDialog) { |
||||||
|
if (runningDialogList != null) runningDialogList.remove(baseDialog); |
||||||
|
} |
||||||
|
|
||||||
|
public static Context getContext() { |
||||||
|
if (contextWeakReference == null) return null; |
||||||
|
return contextWeakReference.get(); |
||||||
|
} |
||||||
|
|
||||||
|
public static void cleanContext() { |
||||||
|
contextWeakReference.clear(); |
||||||
|
contextWeakReference = null; |
||||||
|
System.gc(); |
||||||
|
} |
||||||
|
|
||||||
|
protected boolean cancelable = true; |
||||||
|
protected OnBackPressedListener onBackPressedListener; |
||||||
|
protected boolean isShow; |
||||||
|
protected DialogXStyle style; |
||||||
|
protected DialogX.THEME theme; |
||||||
|
protected boolean autoShowInputKeyboard; |
||||||
|
protected int backgroundColor = -1; |
||||||
|
protected long enterAnimDuration = -1; |
||||||
|
protected long exitAnimDuration = -1; |
||||||
|
|
||||||
|
public BaseDialog() { |
||||||
|
cancelable = DialogX.cancelable; |
||||||
|
style = DialogX.globalStyle; |
||||||
|
theme = DialogX.globalTheme; |
||||||
|
enterAnimDuration = DialogX.enterAnimDuration; |
||||||
|
exitAnimDuration = DialogX.exitAnimDuration; |
||||||
|
autoShowInputKeyboard = DialogX.autoShowInputKeyboard; |
||||||
|
} |
||||||
|
|
||||||
|
public View createView(int layoutId) { |
||||||
|
return LayoutInflater.from(getContext()).inflate(layoutId, null); |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isShow() { |
||||||
|
return isShow; |
||||||
|
} |
||||||
|
|
||||||
|
public DialogXStyle getStyle() { |
||||||
|
return style; |
||||||
|
} |
||||||
|
|
||||||
|
public DialogX.THEME getTheme() { |
||||||
|
return theme; |
||||||
|
} |
||||||
|
|
||||||
|
protected void useTextInfo(TextView textView, TextInfo textInfo) { |
||||||
|
if (textInfo == null) return; |
||||||
|
if (textView == null) return; |
||||||
|
if (textInfo.getFontSize() > 0) { |
||||||
|
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, textInfo.getFontSize()); |
||||||
|
} |
||||||
|
if (textInfo.getFontColor() != 1) { |
||||||
|
textView.setTextColor(textInfo.getFontColor()); |
||||||
|
} |
||||||
|
if (textInfo.getGravity() != -1) { |
||||||
|
textView.setGravity(textInfo.getGravity()); |
||||||
|
} |
||||||
|
textView.getPaint().setFakeBoldText(textInfo.isBold()); |
||||||
|
} |
||||||
|
|
||||||
|
protected void showText(TextView textView, CharSequence text) { |
||||||
|
if (textView == null) return; |
||||||
|
if (isNull(text)) { |
||||||
|
textView.setVisibility(View.GONE); |
||||||
|
textView.setText(""); |
||||||
|
} else { |
||||||
|
textView.setVisibility(View.VISIBLE); |
||||||
|
textView.setText(text); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected View createHorizontalSplitView(int color) { |
||||||
|
View splitView = new View(getContext()); |
||||||
|
splitView.setBackgroundColor(color); |
||||||
|
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 1); |
||||||
|
splitView.setLayoutParams(lp); |
||||||
|
return splitView; |
||||||
|
} |
||||||
|
|
||||||
|
protected View createVerticalSplitView(int color, int height) { |
||||||
|
View splitView = new View(getContext()); |
||||||
|
splitView.setBackgroundColor(color); |
||||||
|
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(1, dip2px(height)); |
||||||
|
splitView.setLayoutParams(lp); |
||||||
|
return splitView; |
||||||
|
} |
||||||
|
|
||||||
|
public static boolean isNull(String s) { |
||||||
|
if (s == null || s.trim().isEmpty() || "null".equals(s) || "(null)".equals(s)) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
public static boolean isNull(CharSequence c) { |
||||||
|
String s = String.valueOf(c); |
||||||
|
if (c == null || s.trim().isEmpty() || "null".equals(s) || "(null)".equals(s)) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
public Resources getResources() { |
||||||
|
if (getContext() == null) return Resources.getSystem(); |
||||||
|
return getContext().getResources(); |
||||||
|
} |
||||||
|
|
||||||
|
public int dip2px(float dpValue) { |
||||||
|
final float scale = getContext().getResources().getDisplayMetrics().density; |
||||||
|
return (int) (dpValue * scale + 0.5f); |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isLightTheme() { |
||||||
|
if (theme == DialogX.THEME.AUTO) { |
||||||
|
return (getContext().getApplicationContext().getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_NO; |
||||||
|
} |
||||||
|
return theme == DialogX.THEME.LIGHT; |
||||||
|
} |
||||||
|
|
||||||
|
public static FrameLayout getRootFrameLayout() { |
||||||
|
if (rootFrameLayout == null) return null; |
||||||
|
return rootFrameLayout.get(); |
||||||
|
} |
||||||
|
|
||||||
|
public void tintColor(View view, int color) { |
||||||
|
view.setBackgroundTintList(ColorStateList.valueOf(color)); |
||||||
|
} |
||||||
|
|
||||||
|
protected void beforeShow() { |
||||||
|
if (getContext() == null) { |
||||||
|
error("DialogX 未初始化。\n请检查是否在启动对话框前进行初始化操作,使用以下代码进行初始化:\nDialogX.init(context);\n\n另外建议您前往查看 DialogX 的文档进行使用:https://github.com/kongzue/DialogX"); |
||||||
|
} |
||||||
|
if (style.styleVer != DialogXStyle.styleVer) { |
||||||
|
error("DialogX 所引用的 Style 不符合当前适用版本:" + DialogXStyle.styleVer + " 引入的 Style(" + style.getClass().getSimpleName() + ") 版本" + style.styleVer); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected String getString(int titleResId) { |
||||||
|
if (getContext() == null) { |
||||||
|
error("DialogX 未初始化。\n请检查是否在启动对话框前进行初始化操作,使用以下代码进行初始化:\nDialogX.init(context);\n\n另外建议您前往查看 DialogX 的文档进行使用:https://github.com/kongzue/DialogX"); |
||||||
|
return null; |
||||||
|
} |
||||||
|
return getContext().getString(titleResId); |
||||||
|
} |
||||||
|
|
||||||
|
protected int getColor(int backgroundRes) { |
||||||
|
if (getContext() == null) { |
||||||
|
error("DialogX 未初始化。\n请检查是否在启动对话框前进行初始化操作,使用以下代码进行初始化:\nDialogX.init(context);\n\n另外建议您前往查看 DialogX 的文档进行使用:https://github.com/kongzue/DialogX"); |
||||||
|
return Color.BLACK; |
||||||
|
} |
||||||
|
return getResources().getColor(backgroundRes); |
||||||
|
} |
||||||
|
|
||||||
|
public enum BOOLEAN { |
||||||
|
TRUE, FALSE |
||||||
|
} |
||||||
|
|
||||||
|
public abstract String dialogKey(); |
||||||
|
|
||||||
|
protected static void runOnMain(Runnable runnable) { |
||||||
|
if (!DialogX.autoRunOnUIThread) runnable.run(); |
||||||
|
new Handler(Looper.getMainLooper()).post(runnable); |
||||||
|
} |
||||||
|
|
||||||
|
public Activity getActivity() { |
||||||
|
return ownActivity == null ? null : ownActivity.get(); |
||||||
|
} |
||||||
|
|
||||||
|
protected void cleanActivityContext() { |
||||||
|
if (ownActivity != null) ownActivity.clear(); |
||||||
|
} |
||||||
|
|
||||||
|
public static void recycleDialog(Activity activity) { |
||||||
|
if (DialogX.implIMPLMode == DialogX.IMPL_MODE.WINDOW) { |
||||||
|
if (runningDialogList != null) { |
||||||
|
CopyOnWriteArrayList<BaseDialog> copyOnWriteList = new CopyOnWriteArrayList<>(runningDialogList); |
||||||
|
for (BaseDialog baseDialog : copyOnWriteList) { |
||||||
|
if (baseDialog.getActivity() == activity && baseDialog.dialogView != null) { |
||||||
|
WindowUtil.dismiss(baseDialog.dialogView.get()); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,11 @@ |
|||||||
|
package com.kongzue.dialogx.interfaces; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author: Kongzue |
||||||
|
* @github: https://github.com/kongzue/
|
||||||
|
* @homepage: http://kongzue.com/
|
||||||
|
* @mail: myzcxhh@live.cn |
||||||
|
* @createTime: 2020/10/22 15:07 |
||||||
|
*/ |
||||||
|
public interface BaseOnDialogClickCallback { |
||||||
|
} |
@ -0,0 +1,17 @@ |
|||||||
|
package com.kongzue.dialogx.interfaces; |
||||||
|
|
||||||
|
import android.view.MotionEvent; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author: Kongzue |
||||||
|
* @github: https://github.com/kongzue/
|
||||||
|
* @homepage: http://kongzue.com/
|
||||||
|
* @mail: myzcxhh@live.cn |
||||||
|
* @createTime: 2020/11/18 15:01 |
||||||
|
*/ |
||||||
|
public abstract class BottomMenuListViewTouchEvent { |
||||||
|
|
||||||
|
public void down(MotionEvent event){}; |
||||||
|
public void move(MotionEvent event){}; |
||||||
|
public void up(MotionEvent event){}; |
||||||
|
} |
@ -0,0 +1,19 @@ |
|||||||
|
package com.kongzue.dialogx.interfaces; |
||||||
|
|
||||||
|
import android.view.View; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author: Kongzue |
||||||
|
* @github: https://github.com/kongzue/
|
||||||
|
* @homepage: http://kongzue.com/
|
||||||
|
* @mail: myzcxhh@live.cn |
||||||
|
* @createTime: 2020/10/6 15:52 |
||||||
|
*/ |
||||||
|
public interface DialogConvertViewInterface { |
||||||
|
|
||||||
|
void init(); |
||||||
|
|
||||||
|
void refreshView(); |
||||||
|
|
||||||
|
void doDismiss(View v); |
||||||
|
} |
@ -0,0 +1,19 @@ |
|||||||
|
package com.kongzue.dialogx.interfaces; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author: Kongzue |
||||||
|
* @github: https://github.com/kongzue/
|
||||||
|
* @homepage: http://kongzue.com/
|
||||||
|
* @mail: myzcxhh@live.cn |
||||||
|
* @createTime: 2020/9/22 14:09 |
||||||
|
*/ |
||||||
|
public abstract class DialogLifecycleCallback<T extends BaseDialog> { |
||||||
|
|
||||||
|
public void onShow(T dialog){ |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public void onDismiss(T dialog){ |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,12 @@ |
|||||||
|
package com.kongzue.dialogx.interfaces; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author: Kongzue |
||||||
|
* @github: https://github.com/kongzue/
|
||||||
|
* @homepage: http://kongzue.com/
|
||||||
|
* @mail: myzcxhh@live.cn |
||||||
|
* @createTime: 2020/9/25 15:48 |
||||||
|
*/ |
||||||
|
public interface OnBackPressedListener { |
||||||
|
boolean onBackPressed(); |
||||||
|
} |
@ -0,0 +1,93 @@ |
|||||||
|
package com.kongzue.dialogx.interfaces; |
||||||
|
|
||||||
|
import android.view.LayoutInflater; |
||||||
|
import android.view.View; |
||||||
|
import android.view.ViewGroup; |
||||||
|
import android.widget.RelativeLayout; |
||||||
|
|
||||||
|
import com.kongzue.dialogx.DialogX; |
||||||
|
|
||||||
|
import static com.kongzue.dialogx.DialogX.ERROR_INIT_TIPS; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author: Kongzue |
||||||
|
* @github: https://github.com/kongzue/
|
||||||
|
* @homepage: http://kongzue.com/
|
||||||
|
* @mail: myzcxhh@live.cn |
||||||
|
* @createTime: 2020/10/8 17:00 |
||||||
|
*/ |
||||||
|
public abstract class OnBindView<D> { |
||||||
|
int layoutResId; |
||||||
|
View customView; |
||||||
|
|
||||||
|
public OnBindView(int layoutResId) { |
||||||
|
if (BaseDialog.getContext() == null) { |
||||||
|
DialogX.error(ERROR_INIT_TIPS); |
||||||
|
return; |
||||||
|
} |
||||||
|
this.layoutResId = layoutResId; |
||||||
|
customView = LayoutInflater.from(BaseDialog.getContext()).inflate(layoutResId, new RelativeLayout(BaseDialog.getContext()), false); |
||||||
|
} |
||||||
|
|
||||||
|
public OnBindView(View customView) { |
||||||
|
this.customView = customView; |
||||||
|
} |
||||||
|
|
||||||
|
public abstract void onBind(D dialog, View v); |
||||||
|
|
||||||
|
public int getLayoutResId() { |
||||||
|
return layoutResId; |
||||||
|
} |
||||||
|
|
||||||
|
public OnBindView<D> setLayoutResId(int layoutResId) { |
||||||
|
this.layoutResId = layoutResId; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public View getCustomView() { |
||||||
|
return customView; |
||||||
|
} |
||||||
|
|
||||||
|
public OnBindView<D> setCustomView(View customView) { |
||||||
|
this.customView = customView; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public void clean() { |
||||||
|
layoutResId = 0; |
||||||
|
customView = null; |
||||||
|
} |
||||||
|
|
||||||
|
public OnBindView<D> bindParent(ViewGroup parentView) { |
||||||
|
if (customView == null) return this; |
||||||
|
if (customView.getParent() != null) { |
||||||
|
if (customView.getParent()==parentView){ |
||||||
|
return this; |
||||||
|
} |
||||||
|
((ViewGroup) customView.getParent()).removeView(customView); |
||||||
|
} |
||||||
|
ViewGroup.LayoutParams lp = parentView.getLayoutParams(); |
||||||
|
if (lp == null) { |
||||||
|
lp = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); |
||||||
|
} |
||||||
|
parentView.addView(customView, lp); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public OnBindView<D> bindParent(ViewGroup parentView, BaseDialog dialog) { |
||||||
|
if (customView == null) return this; |
||||||
|
if (customView.getParent() != null) { |
||||||
|
if (customView.getParent()==parentView){ |
||||||
|
return this; |
||||||
|
} |
||||||
|
((ViewGroup) customView.getParent()).removeView(customView); |
||||||
|
} |
||||||
|
ViewGroup.LayoutParams lp = customView.getLayoutParams(); |
||||||
|
if (lp == null) { |
||||||
|
lp = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); |
||||||
|
} |
||||||
|
parentView.addView(customView, lp); |
||||||
|
onBind((D) dialog, customView); |
||||||
|
return this; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,16 @@ |
|||||||
|
package com.kongzue.dialogx.interfaces; |
||||||
|
|
||||||
|
import android.view.View; |
||||||
|
|
||||||
|
/** |
||||||
|
* Author: @Kongzue |
||||||
|
* Github: https://github.com/kongzue/
|
||||||
|
* Homepage: http://kongzue.com/
|
||||||
|
* Mail: myzcxhh@live.cn |
||||||
|
* CreateTime: 2019/3/29 18:44 |
||||||
|
*/ |
||||||
|
public interface OnDialogButtonClickListener<D extends BaseDialog> extends BaseOnDialogClickCallback{ |
||||||
|
|
||||||
|
boolean onClick(D baseDialog, View v); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,28 @@ |
|||||||
|
package com.kongzue.dialogx.interfaces; |
||||||
|
|
||||||
|
import com.kongzue.dialogx.dialogs.BottomMenu; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author: Kongzue |
||||||
|
* @github: https://github.com/kongzue/
|
||||||
|
* @homepage: http://kongzue.com/
|
||||||
|
* @mail: myzcxhh@live.cn |
||||||
|
* @createTime: 2020/10/9 14:54 |
||||||
|
*/ |
||||||
|
public abstract class OnIconChangeCallBack { |
||||||
|
|
||||||
|
private boolean autoTintIconInLightOrDarkMode; |
||||||
|
|
||||||
|
public OnIconChangeCallBack() { |
||||||
|
} |
||||||
|
|
||||||
|
public OnIconChangeCallBack(boolean autoTintIconInLightOrDarkMode) { |
||||||
|
this.autoTintIconInLightOrDarkMode = autoTintIconInLightOrDarkMode; |
||||||
|
} |
||||||
|
|
||||||
|
public abstract int getIcon(BottomMenu bottomMenu, int index, String menuText); |
||||||
|
|
||||||
|
public boolean isAutoTintIconInLightOrDarkMode() { |
||||||
|
return autoTintIconInLightOrDarkMode; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,17 @@ |
|||||||
|
package com.kongzue.dialogx.interfaces; |
||||||
|
|
||||||
|
import android.view.View; |
||||||
|
|
||||||
|
import com.kongzue.dialogx.dialogs.MessageDialog; |
||||||
|
|
||||||
|
/** |
||||||
|
* Author: @Kongzue |
||||||
|
* Github: https://github.com/kongzue/
|
||||||
|
* Homepage: http://kongzue.com/
|
||||||
|
* Mail: myzcxhh@live.cn |
||||||
|
* CreateTime: 2019/4/8 21:09 |
||||||
|
*/ |
||||||
|
public interface OnInputDialogButtonClickListener<D extends BaseDialog> extends BaseOnDialogClickCallback{ |
||||||
|
|
||||||
|
boolean onClick(D baseDialog, View v, String inputStr); |
||||||
|
} |
@ -0,0 +1,12 @@ |
|||||||
|
package com.kongzue.dialogx.interfaces; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author: Kongzue |
||||||
|
* @github: https://github.com/kongzue/
|
||||||
|
* @homepage: http://kongzue.com/
|
||||||
|
* @mail: myzcxhh@live.cn |
||||||
|
* @createTime: 2020/10/10 6:26 |
||||||
|
*/ |
||||||
|
public interface OnMenuItemClickListener<D> { |
||||||
|
boolean onClick(D dialog, CharSequence text, int which); |
||||||
|
} |
@ -0,0 +1,37 @@ |
|||||||
|
package com.kongzue.dialogx.interfaces; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author: Kongzue |
||||||
|
* @github: https://github.com/kongzue/
|
||||||
|
* @homepage: http://kongzue.com/
|
||||||
|
* @mail: myzcxhh@live.cn |
||||||
|
* @createTime: 2021/4/11 19:18 |
||||||
|
*/ |
||||||
|
public abstract class OnMenuItemSelectListener<D> implements OnMenuItemClickListener<D> { |
||||||
|
|
||||||
|
/** |
||||||
|
* 警告:不建议重写此方法! |
||||||
|
* 如果选择使用 OnMenuItemSelectListener 作为 BottomMenu 的回调,那么点击 Item 后,菜单默认不应该关闭, |
||||||
|
* 若选择自行处理菜单点击 onClick,那么请务必 return true 作为返回值, |
||||||
|
* 否则不会处理 onOneItemSelect 或 onMultiItemSelect 事件。 |
||||||
|
* |
||||||
|
* @param dialog BottomMenu实例 |
||||||
|
* @param text 菜单文本 |
||||||
|
* @param index 菜单索引值 |
||||||
|
* @return return true:拦截自动关闭对话框;return false:点击后关闭对话框 |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
@Override |
||||||
|
public boolean onClick(D dialog, CharSequence text, int index) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
public void onOneItemSelect(D dialog, CharSequence text, int which) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public void onMultiItemSelect(D dialog, CharSequence[] text, int[] indexArray) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,15 @@ |
|||||||
|
package com.kongzue.dialogx.interfaces; |
||||||
|
|
||||||
|
import android.graphics.Rect; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author: Kongzue |
||||||
|
* @github: https://github.com/kongzue/
|
||||||
|
* @homepage: http://kongzue.com/
|
||||||
|
* @mail: myzcxhh@live.cn |
||||||
|
* @createTime: 2020/10/19 16:06 |
||||||
|
*/ |
||||||
|
public interface OnSafeInsetsChangeListener { |
||||||
|
|
||||||
|
void onChange(Rect unsafeRect); |
||||||
|
} |
@ -0,0 +1,225 @@ |
|||||||
|
package com.kongzue.dialogx.style; |
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
|
||||||
|
import com.kongzue.dialogx.R; |
||||||
|
import com.kongzue.dialogx.interfaces.DialogXStyle; |
||||||
|
import com.kongzue.dialogx.interfaces.ProgressViewInterface; |
||||||
|
import com.kongzue.dialogx.util.views.ProgressView; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author: Kongzue |
||||||
|
* @github: https://github.com/kongzue/
|
||||||
|
* @homepage: http://kongzue.com/
|
||||||
|
* @mail: myzcxhh@live.cn |
||||||
|
* @createTime: 2020/9/26 13:09 |
||||||
|
*/ |
||||||
|
public class MaterialStyle implements DialogXStyle { |
||||||
|
|
||||||
|
public static MaterialStyle style() { |
||||||
|
return new MaterialStyle(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int layout(boolean light) { |
||||||
|
return light ? R.layout.layout_dialogx_material : R.layout.layout_dialogx_material_dark; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int enterAnimResId() { |
||||||
|
return R.anim.anim_dialogx_default_enter; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int exitAnimResId() { |
||||||
|
return R.anim.anim_dialogx_default_exit; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int[] verticalButtonOrder() { |
||||||
|
return new int[]{BUTTON_OK, BUTTON_OTHER, BUTTON_CANCEL}; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int[] horizontalButtonOrder() { |
||||||
|
return new int[]{BUTTON_OTHER, SPACE, BUTTON_CANCEL, BUTTON_OK}; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int splitWidthPx() { |
||||||
|
return 1; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int splitColorRes(boolean light) { |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public BlurBackgroundSetting messageDialogBlurSettings() { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public HorizontalButtonRes overrideHorizontalButtonRes() { |
||||||
|
return new HorizontalButtonRes() { |
||||||
|
@Override |
||||||
|
public int overrideHorizontalOkButtonBackgroundRes(int visibleButtonCount, boolean light) { |
||||||
|
return light ? R.drawable.button_dialogx_material_light : R.drawable.button_dialogx_material_night; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int overrideHorizontalCancelButtonBackgroundRes(int visibleButtonCount, boolean light) { |
||||||
|
return light ? R.drawable.button_dialogx_material_light : R.drawable.button_dialogx_material_night; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int overrideHorizontalOtherButtonBackgroundRes(int visibleButtonCount, boolean light) { |
||||||
|
return light ? R.drawable.button_dialogx_material_light : R.drawable.button_dialogx_material_night; |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public VerticalButtonRes overrideVerticalButtonRes() { |
||||||
|
return new VerticalButtonRes() { |
||||||
|
@Override |
||||||
|
public int overrideVerticalOkButtonBackgroundRes(int visibleButtonCount, boolean light) { |
||||||
|
return light ? R.drawable.button_dialogx_material_light : R.drawable.button_dialogx_material_night; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int overrideVerticalCancelButtonBackgroundRes(int visibleButtonCount, boolean light) { |
||||||
|
return light ? R.drawable.button_dialogx_material_light : R.drawable.button_dialogx_material_night; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int overrideVerticalOtherButtonBackgroundRes(int visibleButtonCount, boolean light) { |
||||||
|
return light ? R.drawable.button_dialogx_material_light : R.drawable.button_dialogx_material_night; |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public WaitTipRes overrideWaitTipRes() { |
||||||
|
return new WaitTipRes() { |
||||||
|
@Override |
||||||
|
public int overrideWaitLayout(boolean light) { |
||||||
|
return R.layout.layout_dialogx_wait; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int overrideRadiusPx() { |
||||||
|
return -1; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean blurBackground() { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int overrideBackgroundColorRes(boolean light) { |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int overrideTextColorRes(boolean light) { |
||||||
|
return light ? R.color.white : R.color.black; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ProgressViewInterface overrideWaitView(Context context, boolean light) { |
||||||
|
return new ProgressView(context); |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public BottomDialogRes overrideBottomDialogRes() { |
||||||
|
return new BottomDialogRes() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean touchSlide() { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int overrideDialogLayout(boolean light) { |
||||||
|
return light ? R.layout.layout_dialogx_bottom_material : R.layout.layout_dialogx_bottom_material_dark; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int overrideMenuDividerDrawableRes(boolean light) { |
||||||
|
return light ? R.drawable.rect_dialogx_material_menu_split_divider : R.drawable.rect_dialogx_material_menu_split_divider_night; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int overrideMenuDividerHeight(boolean light) { |
||||||
|
return 1; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int overrideMenuTextColor(boolean light) { |
||||||
|
return light ? R.color.black90 : R.color.white90; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public float overrideBottomDialogMaxHeight() { |
||||||
|
return 0.6f; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int overrideMenuItemLayout(boolean light, int index, int count, boolean isContentVisibility) { |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int overrideSelectionMenuBackgroundColor(boolean light) { |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean selectionImageTint(boolean light) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int overrideSelectionImage(boolean light, boolean isSelected) { |
||||||
|
return isSelected ? R.mipmap.img_dialogx_bottom_menu_material_item_selection : R.mipmap.img_dialogx_bottom_menu_material_item_non_select; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int overrideMultiSelectionImage(boolean light, boolean isSelected) { |
||||||
|
return isSelected ? R.mipmap.img_dialogx_bottom_menu_material_item_multi_selection : R.mipmap.img_dialogx_bottom_menu_material_item_non_multi_select; |
||||||
|
} |
||||||
|
|
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public PopTipSettings popTipSettings() { |
||||||
|
return new PopTipSettings() { |
||||||
|
@Override |
||||||
|
public int layout(boolean light) { |
||||||
|
return light ? R.layout.layout_dialogx_poptip_material : R.layout.layout_dialogx_poptip_material_dark; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ALIGN align() { |
||||||
|
return ALIGN.BOTTOM; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int enterAnimResId(boolean light) { |
||||||
|
return R.anim.anim_dialogx_default_enter; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int exitAnimResId(boolean light) { |
||||||
|
return R.anim.anim_dialogx_default_exit; |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,145 @@ |
|||||||
|
package com.kongzue.dialogx.util; |
||||||
|
|
||||||
|
import android.animation.ObjectAnimator; |
||||||
|
import android.content.res.Resources; |
||||||
|
import android.util.Log; |
||||||
|
import android.view.MotionEvent; |
||||||
|
import android.view.View; |
||||||
|
import android.view.animation.DecelerateInterpolator; |
||||||
|
|
||||||
|
import com.kongzue.dialogx.dialogs.BottomDialog; |
||||||
|
import com.kongzue.dialogx.interfaces.DialogConvertViewInterface; |
||||||
|
import com.kongzue.dialogx.util.views.BottomDialogScrollView; |
||||||
|
import com.kongzue.dialogx.util.views.DialogXBaseRelativeLayout; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author: Kongzue |
||||||
|
* @github: https://github.com/kongzue/
|
||||||
|
* @homepage: http://kongzue.com/
|
||||||
|
* @mail: myzcxhh@live.cn |
||||||
|
* @createTime: 2020/10/7 4:01 |
||||||
|
*/ |
||||||
|
public class BottomDialogTouchEventInterceptor { |
||||||
|
|
||||||
|
/** |
||||||
|
* 下边三个值用于判断触控过程, |
||||||
|
* isBkgTouched:标记是否已按下 |
||||||
|
* bkgTouchDownY:记录起始触控位置 |
||||||
|
* scrolledY:记录 ScrollView 已滚动过的距离,下次触控事件将接着上次的位置继续滑动 |
||||||
|
* bkgOldY:记录按下时 bkg 的位置,用于区分松开手指时,bkg 移动的方向。 |
||||||
|
*/ |
||||||
|
private boolean isBkgTouched = false; |
||||||
|
private float bkgTouchDownY; |
||||||
|
private float scrolledY; |
||||||
|
private float bkgOldY; |
||||||
|
/** |
||||||
|
* 0:bkg接收触控事件,-1:scrollView进行滚动 |
||||||
|
* 此标记的意义在于,当从 [scrollView滚动] 与 [bkg接收触控事件] 状态切换时, |
||||||
|
* 需要对bkgTouchDownY、scrolledY的值进行刷新,否则触控连续过程会出现闪跳。 |
||||||
|
*/ |
||||||
|
private int oldMode; |
||||||
|
|
||||||
|
public BottomDialogTouchEventInterceptor(BottomDialog me, BottomDialog.DialogImpl impl) { |
||||||
|
refresh(me, impl); |
||||||
|
} |
||||||
|
|
||||||
|
public void refresh(final BottomDialog me, final BottomDialog.DialogImpl impl) { |
||||||
|
if (me == null || impl == null || impl.bkg == null || impl.scrollView == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
/** |
||||||
|
* BottomDialog 触控事件说明: |
||||||
|
* bkg 将拦截并接管所有触控操作。 |
||||||
|
* BottomDialog 的启动方式依据是内容布局高度是否大于可显示安全区域的高度。 |
||||||
|
* bkg 会在合适的时机,直接接管控制 ScrollView 的滚动。 |
||||||
|
* 因此,请确保内容布局的高度计算方式一定是按照内容高度计算, |
||||||
|
* 即,请重写 onMeasure 方法: |
||||||
|
* @Override |
||||||
|
* protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { |
||||||
|
* int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); |
||||||
|
* super.onMeasure(widthMeasureSpec, expandSpec); |
||||||
|
* } |
||||||
|
*/ |
||||||
|
if (me.isAllowInterceptTouch()) { |
||||||
|
impl.bkg.setOnTouchListener(new View.OnTouchListener() { |
||||||
|
@Override |
||||||
|
public boolean onTouch(View v, MotionEvent event) { |
||||||
|
//这里 return 什么实际上无关紧要,重点在于 MaxRelativeLayout.java(dispatchTouchEvent:184) 的事件分发会独立触发此处的额外滑动事件
|
||||||
|
switch (event.getAction()) { |
||||||
|
case MotionEvent.ACTION_DOWN: |
||||||
|
bkgTouchDownY = event.getY(); |
||||||
|
isBkgTouched = true; |
||||||
|
bkgOldY = impl.bkg.getY(); |
||||||
|
break; |
||||||
|
case MotionEvent.ACTION_MOVE: |
||||||
|
if (isBkgTouched) { |
||||||
|
float aimY = impl.bkg.getY() + event.getY() - bkgTouchDownY; |
||||||
|
if (impl.bkg.isChildScrollViewCanScroll()) { |
||||||
|
if (aimY > 0) { |
||||||
|
if (impl.scrollView.getScrollY() == 0) { |
||||||
|
if (impl.scrollView instanceof BottomDialogScrollView) { |
||||||
|
((BottomDialogScrollView) impl.scrollView).lockScroll(true); |
||||||
|
} |
||||||
|
impl.bkg.setY(aimY); |
||||||
|
} else { |
||||||
|
bkgTouchDownY = event.getY(); |
||||||
|
} |
||||||
|
} else { |
||||||
|
if (impl.scrollView instanceof BottomDialogScrollView) { |
||||||
|
((BottomDialogScrollView) impl.scrollView).lockScroll(false); |
||||||
|
} |
||||||
|
impl.bkg.setY(0); |
||||||
|
} |
||||||
|
} else { |
||||||
|
if (aimY > impl.bkgEnterAimY) { |
||||||
|
impl.bkg.setY(aimY); |
||||||
|
} else { |
||||||
|
impl.bkg.setY(impl.bkgEnterAimY); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
break; |
||||||
|
case MotionEvent.ACTION_UP: |
||||||
|
case MotionEvent.ACTION_CANCEL: |
||||||
|
scrolledY = impl.scrollView.getScrollY(); |
||||||
|
isBkgTouched = false; |
||||||
|
if (bkgOldY == 0) { |
||||||
|
if (impl.bkg.getY() < dip2px(35)) { |
||||||
|
ObjectAnimator enterAnim = ObjectAnimator.ofFloat(impl.bkg, "y", impl.bkg.getY(), 0); |
||||||
|
enterAnim.setDuration(300); |
||||||
|
enterAnim.start(); |
||||||
|
} else if (impl.bkg.getY() > impl.bkgEnterAimY + dip2px(35)) { |
||||||
|
impl.preDismiss(); |
||||||
|
} else { |
||||||
|
ObjectAnimator enterAnim = ObjectAnimator.ofFloat(impl.bkg, "y", impl.bkg.getY(), impl.bkgEnterAimY); |
||||||
|
enterAnim.setDuration(300); |
||||||
|
enterAnim.start(); |
||||||
|
} |
||||||
|
} else { |
||||||
|
if (impl.bkg.getY() < bkgOldY - dip2px(35)) { |
||||||
|
ObjectAnimator enterAnim = ObjectAnimator.ofFloat(impl.bkg, "y", impl.bkg.getY(), 0); |
||||||
|
enterAnim.setDuration(300); |
||||||
|
enterAnim.start(); |
||||||
|
} else if (impl.bkg.getY() > bkgOldY + dip2px(35)) { |
||||||
|
impl.preDismiss(); |
||||||
|
} else { |
||||||
|
ObjectAnimator enterAnim = ObjectAnimator.ofFloat(impl.bkg, "y", impl.bkg.getY(), impl.bkgEnterAimY); |
||||||
|
enterAnim.setDuration(300); |
||||||
|
enterAnim.start(); |
||||||
|
} |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
}); |
||||||
|
} else { |
||||||
|
impl.bkg.setOnTouchListener(null); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private int dip2px(float dpValue) { |
||||||
|
final float scale = Resources.getSystem().getDisplayMetrics().density; |
||||||
|
return (int) (dpValue * scale + 0.5f); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,96 @@ |
|||||||
|
package com.kongzue.dialogx.util; |
||||||
|
|
||||||
|
import android.animation.ObjectAnimator; |
||||||
|
import android.content.res.Resources; |
||||||
|
import android.view.MotionEvent; |
||||||
|
import android.view.View; |
||||||
|
|
||||||
|
import com.kongzue.dialogx.dialogs.FullScreenDialog; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author: Kongzue |
||||||
|
* @github: https://github.com/kongzue/
|
||||||
|
* @homepage: http://kongzue.com/
|
||||||
|
* @mail: myzcxhh@live.cn |
||||||
|
* @createTime: 2020/10/19 13:54 |
||||||
|
*/ |
||||||
|
public class FullScreenDialogTouchEventInterceptor { |
||||||
|
|
||||||
|
/** |
||||||
|
* 下边三个值用于判断触控过程, |
||||||
|
* isBkgTouched:标记是否已按下 |
||||||
|
* bkgTouchDownY:记录起始触控位置 |
||||||
|
* scrolledY:记录 ScrollView 已滚动过的距离,下次触控事件将接着上次的位置继续滑动 |
||||||
|
* bkgOldY:记录按下时 bkg 的位置,用于区分松开手指时,bkg 移动的方向。 |
||||||
|
*/ |
||||||
|
private boolean isBkgTouched = false; |
||||||
|
private float bkgTouchDownY; |
||||||
|
private float bkgOldY; |
||||||
|
|
||||||
|
public FullScreenDialogTouchEventInterceptor(FullScreenDialog me, FullScreenDialog.DialogImpl impl) { |
||||||
|
refresh(me, impl); |
||||||
|
} |
||||||
|
|
||||||
|
public void refresh(final FullScreenDialog me, final FullScreenDialog.DialogImpl impl) { |
||||||
|
if (me == null || impl == null || impl.bkg == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
impl.boxCustom.setOnTouchListener(new View.OnTouchListener() { |
||||||
|
@Override |
||||||
|
public boolean onTouch(View v, MotionEvent event) { |
||||||
|
switch (event.getAction()) { |
||||||
|
case MotionEvent.ACTION_DOWN: |
||||||
|
bkgTouchDownY = event.getY(); |
||||||
|
isBkgTouched = true; |
||||||
|
bkgOldY = impl.bkg.getY(); |
||||||
|
break; |
||||||
|
case MotionEvent.ACTION_MOVE: |
||||||
|
if (isBkgTouched) { |
||||||
|
float aimY = impl.bkg.getY() + event.getY() - bkgTouchDownY; |
||||||
|
if (aimY < 0) { |
||||||
|
aimY = 0; |
||||||
|
} |
||||||
|
impl.bkg.setY(aimY); |
||||||
|
} |
||||||
|
break; |
||||||
|
case MotionEvent.ACTION_UP: |
||||||
|
case MotionEvent.ACTION_CANCEL: |
||||||
|
isBkgTouched = false; |
||||||
|
if (bkgOldY == 0) { |
||||||
|
if (impl.bkg.getY() < dip2px(35)) { |
||||||
|
ObjectAnimator enterAnim = ObjectAnimator.ofFloat(impl.bkg, "y", impl.bkg.getY(), 0); |
||||||
|
enterAnim.setDuration(300); |
||||||
|
enterAnim.start(); |
||||||
|
} else if (impl.bkg.getY() > impl.bkgEnterAimY + dip2px(35)) { |
||||||
|
impl.preDismiss(); |
||||||
|
} else { |
||||||
|
ObjectAnimator enterAnim = ObjectAnimator.ofFloat(impl.bkg, "y", impl.bkg.getY(), impl.bkgEnterAimY); |
||||||
|
enterAnim.setDuration(300); |
||||||
|
enterAnim.start(); |
||||||
|
} |
||||||
|
} else { |
||||||
|
if (impl.bkg.getY() < bkgOldY - dip2px(35)) { |
||||||
|
ObjectAnimator enterAnim = ObjectAnimator.ofFloat(impl.bkg, "y", impl.bkg.getY(), 0); |
||||||
|
enterAnim.setDuration(300); |
||||||
|
enterAnim.start(); |
||||||
|
} else if (impl.bkg.getY() > bkgOldY + dip2px(35)) { |
||||||
|
impl.preDismiss(); |
||||||
|
} else { |
||||||
|
ObjectAnimator enterAnim = ObjectAnimator.ofFloat(impl.bkg, "y", impl.bkg.getY(), impl.bkgEnterAimY); |
||||||
|
enterAnim.setDuration(300); |
||||||
|
enterAnim.start(); |
||||||
|
} |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
private int dip2px(float dpValue) { |
||||||
|
final float scale = Resources.getSystem().getDisplayMetrics().density; |
||||||
|
return (int) (dpValue * scale + 0.5f); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,19 @@ |
|||||||
|
package com.kongzue.dialogx.util; |
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.widget.ArrayAdapter; |
||||||
|
|
||||||
|
import androidx.annotation.NonNull; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author: Kongzue |
||||||
|
* @github: https://github.com/kongzue/
|
||||||
|
* @homepage: http://kongzue.com/
|
||||||
|
* @mail: myzcxhh@live.cn |
||||||
|
* @createTime: 2020/10/10 19:56 |
||||||
|
*/ |
||||||
|
public class IOSMenuArrayAdapter extends ArrayAdapter<CharSequence> { |
||||||
|
public IOSMenuArrayAdapter(@NonNull Context context, int resource) { |
||||||
|
super(context, resource); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,62 @@ |
|||||||
|
package com.kongzue.dialogx.util; |
||||||
|
|
||||||
|
/** |
||||||
|
* Author: @Kongzue |
||||||
|
* Github: https://github.com/kongzue/
|
||||||
|
* Homepage: http://kongzue.com/
|
||||||
|
* Mail: myzcxhh@live.cn |
||||||
|
* CreateTime: 2018/11/8 21:41 |
||||||
|
*/ |
||||||
|
public class InputInfo { |
||||||
|
|
||||||
|
private int MAX_LENGTH = -1; //最大长度,-1不生效
|
||||||
|
private int inputType; //类型详见 android.text.InputType
|
||||||
|
private TextInfo textInfo; //默认字体样式
|
||||||
|
private boolean multipleLines; //支持多行
|
||||||
|
private boolean selectAllText; //默认选中所有文字(便于修改)
|
||||||
|
|
||||||
|
public int getMAX_LENGTH() { |
||||||
|
return MAX_LENGTH; |
||||||
|
} |
||||||
|
|
||||||
|
public InputInfo setMAX_LENGTH(int MAX_LENGTH) { |
||||||
|
this.MAX_LENGTH = MAX_LENGTH; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public int getInputType() { |
||||||
|
return inputType; |
||||||
|
} |
||||||
|
|
||||||
|
public InputInfo setInputType(int inputType) { |
||||||
|
this.inputType = inputType; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public TextInfo getTextInfo() { |
||||||
|
return textInfo; |
||||||
|
} |
||||||
|
|
||||||
|
public InputInfo setTextInfo(TextInfo textInfo) { |
||||||
|
this.textInfo = textInfo; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isMultipleLines() { |
||||||
|
return multipleLines; |
||||||
|
} |
||||||
|
|
||||||
|
public InputInfo setMultipleLines(boolean multipleLines) { |
||||||
|
this.multipleLines = multipleLines; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isSelectAllText() { |
||||||
|
return selectAllText; |
||||||
|
} |
||||||
|
|
||||||
|
public InputInfo setSelectAllText(boolean selectAllText) { |
||||||
|
this.selectAllText = selectAllText; |
||||||
|
return this; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,213 @@ |
|||||||
|
package com.kongzue.dialogx.util; |
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.content.res.ColorStateList; |
||||||
|
import android.graphics.Typeface; |
||||||
|
import android.graphics.drawable.StateListDrawable; |
||||||
|
import android.util.Log; |
||||||
|
import android.util.TypedValue; |
||||||
|
import android.view.LayoutInflater; |
||||||
|
import android.view.View; |
||||||
|
import android.view.ViewGroup; |
||||||
|
import android.widget.ArrayAdapter; |
||||||
|
import android.widget.BaseAdapter; |
||||||
|
import android.widget.ImageView; |
||||||
|
import android.widget.SimpleAdapter; |
||||||
|
import android.widget.TextView; |
||||||
|
|
||||||
|
import com.kongzue.dialogx.DialogX; |
||||||
|
import com.kongzue.dialogx.R; |
||||||
|
import com.kongzue.dialogx.dialogs.BottomMenu; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author: Kongzue |
||||||
|
* @github: https://github.com/kongzue/
|
||||||
|
* @homepage: http://kongzue.com/
|
||||||
|
* @mail: myzcxhh@live.cn |
||||||
|
* @createTime: 2020/10/7 0:00 |
||||||
|
*/ |
||||||
|
public class NormalMenuArrayAdapter extends BaseAdapter { |
||||||
|
|
||||||
|
private BottomMenu bottomMenu; |
||||||
|
public List<CharSequence> objects; |
||||||
|
public Context context; |
||||||
|
|
||||||
|
public NormalMenuArrayAdapter(BottomMenu bottomMenu, Context context, List<CharSequence> objects) { |
||||||
|
this.objects = objects; |
||||||
|
this.context = context; |
||||||
|
this.bottomMenu = bottomMenu; |
||||||
|
} |
||||||
|
|
||||||
|
class ViewHolder { |
||||||
|
ImageView imgDialogxMenuIcon; |
||||||
|
TextView txtDialogxMenuText; |
||||||
|
ImageView imgDialogxMenuSelection; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getCount() { |
||||||
|
return objects.size(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public CharSequence getItem(int position) { |
||||||
|
return objects.get(position); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public long getItemId(int position) { |
||||||
|
return position; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public View getView(int position, View convertView, ViewGroup parent) { |
||||||
|
ViewHolder viewHolder = null; |
||||||
|
if (convertView == null) { |
||||||
|
viewHolder = new ViewHolder(); |
||||||
|
LayoutInflater mInflater = LayoutInflater.from(context); |
||||||
|
|
||||||
|
int resourceId = R.layout.item_dialogx_material_bottom_menu_normal_text; |
||||||
|
if (bottomMenu.getStyle().overrideBottomDialogRes() != null) { |
||||||
|
resourceId = bottomMenu.getStyle().overrideBottomDialogRes().overrideMenuItemLayout(bottomMenu.isLightTheme(), position, getCount(), false); |
||||||
|
if (resourceId == 0) { |
||||||
|
resourceId = R.layout.item_dialogx_material_bottom_menu_normal_text; |
||||||
|
} else { |
||||||
|
if (bottomMenu.getDialogImpl().txtDialogTitle.getVisibility() == View.VISIBLE || |
||||||
|
bottomMenu.getDialogImpl().txtDialogTip.getVisibility() == View.VISIBLE || |
||||||
|
bottomMenu.getCustomView() != null) { |
||||||
|
if (position == 0) { |
||||||
|
resourceId = bottomMenu.getStyle().overrideBottomDialogRes().overrideMenuItemLayout(bottomMenu.isLightTheme(), position, getCount(), true); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
convertView = mInflater.inflate(resourceId, null); |
||||||
|
|
||||||
|
viewHolder.imgDialogxMenuIcon = convertView.findViewById(R.id.img_dialogx_menu_icon); |
||||||
|
viewHolder.txtDialogxMenuText = convertView.findViewById(R.id.txt_dialogx_menu_text); |
||||||
|
viewHolder.imgDialogxMenuSelection = convertView.findViewById(R.id.img_dialogx_menu_selection); |
||||||
|
|
||||||
|
convertView.setTag(viewHolder); |
||||||
|
} else { |
||||||
|
viewHolder = (ViewHolder) convertView.getTag(); |
||||||
|
} |
||||||
|
if (bottomMenu.getSelectMode() == BottomMenu.SELECT_MODE.SINGLE) { |
||||||
|
if (viewHolder.imgDialogxMenuSelection != null) { |
||||||
|
if (bottomMenu.getSelection() == position) { |
||||||
|
viewHolder.imgDialogxMenuSelection.setVisibility(View.VISIBLE); |
||||||
|
int overrideSelectionImageResId = bottomMenu.getStyle().overrideBottomDialogRes().overrideSelectionImage(bottomMenu.isLightTheme(), true); |
||||||
|
if (overrideSelectionImageResId != 0) { |
||||||
|
viewHolder.imgDialogxMenuSelection.setImageResource(overrideSelectionImageResId); |
||||||
|
} |
||||||
|
} else { |
||||||
|
int overrideSelectionImageResId = bottomMenu.getStyle().overrideBottomDialogRes().overrideSelectionImage(bottomMenu.isLightTheme(), false); |
||||||
|
if (overrideSelectionImageResId != 0) { |
||||||
|
viewHolder.imgDialogxMenuSelection.setVisibility(View.VISIBLE); |
||||||
|
viewHolder.imgDialogxMenuSelection.setImageResource(overrideSelectionImageResId); |
||||||
|
} else { |
||||||
|
viewHolder.imgDialogxMenuSelection.setVisibility(View.INVISIBLE); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} else if (bottomMenu.getSelectMode() == BottomMenu.SELECT_MODE.MULTIPLE) { |
||||||
|
if (viewHolder.imgDialogxMenuSelection != null) { |
||||||
|
if (bottomMenu.getSelectionList().contains(position)) { |
||||||
|
viewHolder.imgDialogxMenuSelection.setVisibility(View.VISIBLE); |
||||||
|
int overrideSelectionImageResId = bottomMenu.getStyle().overrideBottomDialogRes().overrideMultiSelectionImage(bottomMenu.isLightTheme(), true); |
||||||
|
if (overrideSelectionImageResId != 0) { |
||||||
|
viewHolder.imgDialogxMenuSelection.setImageResource(overrideSelectionImageResId); |
||||||
|
} |
||||||
|
} else { |
||||||
|
int overrideSelectionImageResId = bottomMenu.getStyle().overrideBottomDialogRes().overrideMultiSelectionImage(bottomMenu.isLightTheme(), false); |
||||||
|
if (overrideSelectionImageResId != 0) { |
||||||
|
viewHolder.imgDialogxMenuSelection.setVisibility(View.VISIBLE); |
||||||
|
viewHolder.imgDialogxMenuSelection.setImageResource(overrideSelectionImageResId); |
||||||
|
} else { |
||||||
|
viewHolder.imgDialogxMenuSelection.setVisibility(View.INVISIBLE); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} else { |
||||||
|
viewHolder.imgDialogxMenuSelection.setVisibility(View.GONE); |
||||||
|
} |
||||||
|
int overrideSelectionBackgroundColorRes = 0; |
||||||
|
if (bottomMenu.getStyle().overrideBottomDialogRes() != null) { |
||||||
|
overrideSelectionBackgroundColorRes = bottomMenu.getStyle().overrideBottomDialogRes().overrideSelectionMenuBackgroundColor(bottomMenu.isLightTheme()); |
||||||
|
} |
||||||
|
if (bottomMenu.getSelection() == position) { |
||||||
|
if (overrideSelectionBackgroundColorRes != 0) { |
||||||
|
convertView.setBackgroundTintList(ColorStateList.valueOf(context.getResources().getColor(overrideSelectionBackgroundColorRes))); |
||||||
|
final View finalRootView = convertView; |
||||||
|
convertView.post(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
finalRootView.setPressed(true); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
} else { |
||||||
|
convertView.setBackgroundTintList(null); |
||||||
|
} |
||||||
|
CharSequence text = objects.get(position); |
||||||
|
|
||||||
|
int textColor = bottomMenu.isLightTheme() ? R.color.black90 : R.color.white90; |
||||||
|
if (bottomMenu.getStyle().overrideBottomDialogRes() != null) { |
||||||
|
if (bottomMenu.getStyle().overrideBottomDialogRes().overrideMenuTextColor(bottomMenu.isLightTheme()) != 0) { |
||||||
|
textColor = bottomMenu.getStyle().overrideBottomDialogRes().overrideMenuTextColor(bottomMenu.isLightTheme()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (null != text) { |
||||||
|
viewHolder.txtDialogxMenuText.setText(text); |
||||||
|
viewHolder.txtDialogxMenuText.setTextColor(context.getResources().getColor(textColor)); |
||||||
|
if (DialogX.menuTextInfo != null) { |
||||||
|
useTextInfo(viewHolder.txtDialogxMenuText, DialogX.menuTextInfo); |
||||||
|
} |
||||||
|
if (viewHolder.imgDialogxMenuSelection != null) { |
||||||
|
if (bottomMenu.getStyle().overrideBottomDialogRes() != null && bottomMenu.getStyle().overrideBottomDialogRes().selectionImageTint(bottomMenu.isLightTheme())) { |
||||||
|
viewHolder.imgDialogxMenuSelection.setImageTintList(ColorStateList.valueOf(context.getResources().getColor(textColor))); |
||||||
|
} else { |
||||||
|
viewHolder.imgDialogxMenuSelection.setImageTintList(null); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (bottomMenu.getOnIconChangeCallBack() != null) { |
||||||
|
int resId = bottomMenu.getOnIconChangeCallBack().getIcon(bottomMenu, position, text.toString()); |
||||||
|
boolean autoTintIconInLightOrDarkMode = bottomMenu.getOnIconChangeCallBack().isAutoTintIconInLightOrDarkMode(); |
||||||
|
|
||||||
|
if (resId != 0) { |
||||||
|
viewHolder.imgDialogxMenuIcon.setVisibility(View.VISIBLE); |
||||||
|
viewHolder.imgDialogxMenuIcon.setImageResource(resId); |
||||||
|
|
||||||
|
if (autoTintIconInLightOrDarkMode) { |
||||||
|
viewHolder.imgDialogxMenuIcon.setImageTintList(ColorStateList.valueOf(context.getResources().getColor(textColor))); |
||||||
|
} |
||||||
|
} else { |
||||||
|
viewHolder.imgDialogxMenuIcon.setVisibility(View.GONE); |
||||||
|
} |
||||||
|
} else { |
||||||
|
viewHolder.imgDialogxMenuIcon.setVisibility(View.GONE); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return convertView; |
||||||
|
} |
||||||
|
|
||||||
|
protected void useTextInfo(TextView textView, TextInfo textInfo) { |
||||||
|
if (textInfo == null) return; |
||||||
|
if (textView == null) return; |
||||||
|
if (textInfo.getFontSize() > 0) { |
||||||
|
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, textInfo.getFontSize()); |
||||||
|
} |
||||||
|
if (textInfo.getFontColor() != 1) { |
||||||
|
textView.setTextColor(textInfo.getFontColor()); |
||||||
|
} |
||||||
|
if (textInfo.getGravity() != -1) { |
||||||
|
textView.setGravity(textInfo.getGravity()); |
||||||
|
} |
||||||
|
Typeface font = Typeface.create(Typeface.SANS_SERIF, textInfo.isBold() ? Typeface.BOLD : Typeface.NORMAL); |
||||||
|
textView.setTypeface(font); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,62 @@ |
|||||||
|
package com.kongzue.dialogx.util; |
||||||
|
|
||||||
|
/** |
||||||
|
* Author: @Kongzue |
||||||
|
* Github: https://github.com/kongzue/
|
||||||
|
* Homepage: http://kongzue.com/
|
||||||
|
* Mail: myzcxhh@live.cn |
||||||
|
* CreateTime: 2018/11/10 22:01 |
||||||
|
*/ |
||||||
|
public class TextInfo { |
||||||
|
|
||||||
|
private int fontSize = -1; //字号大小,值为-1时使用默认样式,单位:dp
|
||||||
|
private int gravity = -1; //对齐方式,值为-1时使用默认样式,取值可使用Gravity.CENTER等对齐方式
|
||||||
|
private int fontColor = 1; //文字颜色,值为1时使用默认样式,取值可以用Color.rgb(r,g,b)等方式获取
|
||||||
|
private boolean bold = false; //是否粗体
|
||||||
|
|
||||||
|
public int getFontSize() { |
||||||
|
return fontSize; |
||||||
|
} |
||||||
|
|
||||||
|
public TextInfo setFontSize(int fontSize) { |
||||||
|
this.fontSize = fontSize; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public int getGravity() { |
||||||
|
return gravity; |
||||||
|
} |
||||||
|
|
||||||
|
public TextInfo setGravity(int gravity) { |
||||||
|
this.gravity = gravity; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public int getFontColor() { |
||||||
|
return fontColor; |
||||||
|
} |
||||||
|
|
||||||
|
public TextInfo setFontColor(int fontColor) { |
||||||
|
this.fontColor = fontColor; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isBold() { |
||||||
|
return bold; |
||||||
|
} |
||||||
|
|
||||||
|
public TextInfo setBold(boolean bold) { |
||||||
|
this.bold = bold; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "TextInfo{" + |
||||||
|
"fontSize=" + fontSize + |
||||||
|
", gravity=" + gravity + |
||||||
|
", fontColor=" + fontColor + |
||||||
|
", bold=" + bold + |
||||||
|
'}'; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,57 @@ |
|||||||
|
package com.kongzue.dialogx.util; |
||||||
|
|
||||||
|
import android.app.Activity; |
||||||
|
import android.content.Context; |
||||||
|
import android.graphics.PixelFormat; |
||||||
|
import android.os.Build; |
||||||
|
import android.util.Log; |
||||||
|
import android.view.Gravity; |
||||||
|
import android.view.View; |
||||||
|
import android.view.ViewGroup; |
||||||
|
import android.view.WindowManager; |
||||||
|
import android.widget.Toast; |
||||||
|
|
||||||
|
import com.kongzue.dialogx.R; |
||||||
|
import com.kongzue.dialogx.interfaces.BaseDialog; |
||||||
|
|
||||||
|
import static android.view.WindowManager.LayoutParams.*; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author: Kongzue |
||||||
|
* @github: https://github.com/kongzue/
|
||||||
|
* @homepage: http://kongzue.com/
|
||||||
|
* @mail: myzcxhh@live.cn |
||||||
|
* @createTime: 2021/4/29 16:02 |
||||||
|
*/ |
||||||
|
public class WindowUtil { |
||||||
|
|
||||||
|
public static void show(Activity activity, View dialogView, boolean touchEnable) { |
||||||
|
WindowManager manager = (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE); |
||||||
|
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(); |
||||||
|
|
||||||
|
layoutParams.gravity = Gravity.CENTER_VERTICAL; |
||||||
|
layoutParams.format = PixelFormat.TRANSPARENT; |
||||||
|
layoutParams.type = TYPE_APPLICATION_ATTACHED_DIALOG; |
||||||
|
layoutParams.flags = FLAG_FULLSCREEN | |
||||||
|
FLAG_TRANSLUCENT_STATUS | |
||||||
|
FLAG_TRANSLUCENT_NAVIGATION | |
||||||
|
FLAG_LAYOUT_IN_SCREEN |
||||||
|
; |
||||||
|
if (!touchEnable) { |
||||||
|
layoutParams.flags = layoutParams.flags | FLAG_NOT_FOCUSABLE; |
||||||
|
} |
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { |
||||||
|
layoutParams.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; |
||||||
|
} |
||||||
|
|
||||||
|
manager.addView(dialogView, layoutParams); |
||||||
|
} |
||||||
|
|
||||||
|
public static void dismiss(View dialogView) { |
||||||
|
BaseDialog baseDialog = (BaseDialog) dialogView.getTag(); |
||||||
|
if (baseDialog != null && baseDialog.getActivity() != null) { |
||||||
|
WindowManager manager = (WindowManager) baseDialog.getActivity().getSystemService(Context.WINDOW_SERVICE); |
||||||
|
manager.removeViewImmediate(dialogView); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,124 @@ |
|||||||
|
package com.kongzue.dialogx.util.views; |
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.graphics.Bitmap; |
||||||
|
import android.graphics.Canvas; |
||||||
|
import android.graphics.Path; |
||||||
|
import android.os.Build; |
||||||
|
import android.util.AttributeSet; |
||||||
|
import android.util.Log; |
||||||
|
import android.view.Gravity; |
||||||
|
import android.view.View; |
||||||
|
import android.view.Window; |
||||||
|
import android.view.WindowManager; |
||||||
|
|
||||||
|
import androidx.appcompat.widget.AppCompatImageView; |
||||||
|
|
||||||
|
import com.kongzue.dialogx.interfaces.BaseDialog; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author: Kongzue |
||||||
|
* @github: https://github.com/kongzue/
|
||||||
|
* @homepage: http://kongzue.com/
|
||||||
|
* @mail: myzcxhh@live.cn |
||||||
|
* @createTime: 2019/11/17 23:53 |
||||||
|
*/ |
||||||
|
public class ActivityScreenShotImageView extends AppCompatImageView { |
||||||
|
|
||||||
|
float width, height, mRadius; |
||||||
|
|
||||||
|
public ActivityScreenShotImageView(Context context) { |
||||||
|
super(context); |
||||||
|
init(null); |
||||||
|
} |
||||||
|
|
||||||
|
public ActivityScreenShotImageView(Context context, AttributeSet attrs) { |
||||||
|
super(context, attrs); |
||||||
|
init(attrs); |
||||||
|
} |
||||||
|
|
||||||
|
public ActivityScreenShotImageView(Context context, AttributeSet attrs, int defStyleAttr) { |
||||||
|
super(context, attrs, defStyleAttr); |
||||||
|
init(attrs); |
||||||
|
} |
||||||
|
|
||||||
|
private void init(AttributeSet attrs) { |
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { |
||||||
|
setLayerType(LAYER_TYPE_HARDWARE, null); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void setRadius(float mRadius) { |
||||||
|
this.mRadius = mRadius; |
||||||
|
invalidate(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onLayout(boolean changed, int left, int top, int right, int bottom) { |
||||||
|
super.onLayout(changed, left, top, right, bottom); |
||||||
|
width = getWidth(); |
||||||
|
height = getHeight(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onDraw(Canvas canvas) { |
||||||
|
if (width >= mRadius && height > mRadius) { |
||||||
|
Path path = new Path(); |
||||||
|
path.moveTo(mRadius, 0); |
||||||
|
path.lineTo(width - mRadius, 0); |
||||||
|
path.quadTo(width, 0, width, mRadius); |
||||||
|
path.lineTo(width, height - mRadius); |
||||||
|
path.quadTo(width, height, width - mRadius, height); |
||||||
|
path.lineTo(mRadius, height); |
||||||
|
path.quadTo(0, height, 0, height - mRadius); |
||||||
|
path.lineTo(0, mRadius); |
||||||
|
path.quadTo(0, 0, mRadius, 0); |
||||||
|
|
||||||
|
canvas.clipPath(path); |
||||||
|
} |
||||||
|
try { |
||||||
|
super.onDraw(canvas); |
||||||
|
} catch (Exception e) { |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { |
||||||
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec); |
||||||
|
|
||||||
|
refreshImage(); |
||||||
|
} |
||||||
|
|
||||||
|
private int screenWidth, screenHeight; |
||||||
|
|
||||||
|
private void refreshImage() { |
||||||
|
if (screenWidth != getMeasuredWidth() || screenHeight != getMeasuredHeight()) { |
||||||
|
screenWidth = getMeasuredWidth(); |
||||||
|
screenHeight = getMeasuredHeight(); |
||||||
|
doScreenshotActivityAndZoom(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void doScreenshotActivityAndZoom() { |
||||||
|
if (BaseDialog.getRootFrameLayout() == null) return; |
||||||
|
final View view = BaseDialog.getRootFrameLayout().getChildAt(0); |
||||||
|
//先执行一次绘制,防止出现闪屏问题
|
||||||
|
drawViewImage(view); |
||||||
|
view.post(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
//当view渲染完成后再次通知刷新一下界面(当旋转屏幕执行时,很可能出现渲染延迟的问题)
|
||||||
|
drawViewImage(view); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
private void drawViewImage(View view) { |
||||||
|
view.destroyDrawingCache(); |
||||||
|
view.setDrawingCacheEnabled(true); |
||||||
|
view.buildDrawingCache(); |
||||||
|
Bitmap bmp = view.getDrawingCache(); |
||||||
|
setImageBitmap(bmp); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,455 @@ |
|||||||
|
package com.kongzue.dialogx.util.views; |
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.content.res.TypedArray; |
||||||
|
import android.graphics.Bitmap; |
||||||
|
import android.graphics.Canvas; |
||||||
|
import android.graphics.Color; |
||||||
|
import android.graphics.Paint; |
||||||
|
import android.graphics.Path; |
||||||
|
import android.graphics.Rect; |
||||||
|
import android.graphics.RectF; |
||||||
|
import android.util.AttributeSet; |
||||||
|
import android.util.Log; |
||||||
|
import android.util.TypedValue; |
||||||
|
import android.view.View; |
||||||
|
import android.view.ViewTreeObserver; |
||||||
|
|
||||||
|
import androidx.annotation.ColorInt; |
||||||
|
import androidx.annotation.Nullable; |
||||||
|
import androidx.renderscript.Allocation; |
||||||
|
import androidx.renderscript.Element; |
||||||
|
import androidx.renderscript.RenderScript; |
||||||
|
import androidx.renderscript.ScriptIntrinsicBlur; |
||||||
|
|
||||||
|
import com.kongzue.dialogx.DialogX; |
||||||
|
import com.kongzue.dialogx.R; |
||||||
|
import com.kongzue.dialogx.interfaces.BaseDialog; |
||||||
|
|
||||||
|
public class BlurView extends View { |
||||||
|
private float mDownsampleFactor = 4; |
||||||
|
private int mOverlayColor = Color.WHITE; |
||||||
|
private float mBlurRadius = 35; |
||||||
|
|
||||||
|
private float mRadius = 0; |
||||||
|
private Path mBoundPath = null; |
||||||
|
|
||||||
|
private boolean mDirty; |
||||||
|
private Bitmap mBitmapToBlur, mBlurredBitmap; |
||||||
|
private Canvas mBlurringCanvas; |
||||||
|
private RenderScript mRenderScript; |
||||||
|
private ScriptIntrinsicBlur mBlurScript; |
||||||
|
private Allocation mBlurInput, mBlurOutput; |
||||||
|
private boolean mIsRendering; |
||||||
|
private final Rect mRectSrc = new Rect(), mRectDst = new Rect(); |
||||||
|
// mDecorView should be the root view of the activity (even if you are on a different window like a dialog)
|
||||||
|
private View mDecorView; |
||||||
|
// If the view is on different root view (usually means we are on a PopupWindow),
|
||||||
|
// we need to manually call invalidate() in onPreDraw(), otherwise we will not be able to see the changes
|
||||||
|
private boolean mDifferentRoot; |
||||||
|
private static int RENDERING_COUNT; |
||||||
|
|
||||||
|
private Paint mPaint; |
||||||
|
private RectF mRectF; |
||||||
|
|
||||||
|
private Bitmap mRoundBitmap; |
||||||
|
private Canvas mTmpCanvas; |
||||||
|
|
||||||
|
public BlurView(Context context, AttributeSet attrs) { |
||||||
|
super(context, attrs); |
||||||
|
|
||||||
|
init(context, attrs); |
||||||
|
} |
||||||
|
|
||||||
|
public BlurView(Context context) { |
||||||
|
super(context); |
||||||
|
|
||||||
|
init(context, null); |
||||||
|
} |
||||||
|
|
||||||
|
public BlurView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { |
||||||
|
super(context, attrs, defStyleAttr); |
||||||
|
|
||||||
|
init(context, attrs); |
||||||
|
} |
||||||
|
|
||||||
|
public BlurView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { |
||||||
|
super(context, attrs, defStyleAttr, defStyleRes); |
||||||
|
|
||||||
|
init(context, attrs); |
||||||
|
} |
||||||
|
|
||||||
|
private boolean isInit = false; |
||||||
|
|
||||||
|
private void init(Context context, AttributeSet attrs) { |
||||||
|
if (!isInit) { |
||||||
|
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RealtimeBlurView); |
||||||
|
mBlurRadius = a.getDimension( |
||||||
|
R.styleable.RealtimeBlurView_realtimeBlurRadius, |
||||||
|
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 35, context.getResources().getDisplayMetrics()) |
||||||
|
); |
||||||
|
mDownsampleFactor = a.getFloat(R.styleable.RealtimeBlurView_realtimeDownsampleFactor, 4); |
||||||
|
mOverlayColor = a.getColor(R.styleable.RealtimeBlurView_realtimeOverlayColor, 0x00ffffff); |
||||||
|
|
||||||
|
//ready rounded corner
|
||||||
|
mPaint = new Paint(); |
||||||
|
mPaint.setAntiAlias(true); |
||||||
|
mRectF = new RectF(); |
||||||
|
|
||||||
|
mRadius = a.getDimension(R.styleable.RealtimeBlurView_radius, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 15, context.getResources().getDisplayMetrics())); |
||||||
|
a.recycle(); |
||||||
|
|
||||||
|
isInit = true; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void setBlurRadius(float radius) { |
||||||
|
if (mBlurRadius != radius) { |
||||||
|
mBlurRadius = radius; |
||||||
|
mDirty = true; |
||||||
|
invalidate(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void setRadiusPx(float r) { |
||||||
|
if (mRadius != r) { |
||||||
|
mRadius = r; |
||||||
|
mDirty = true; |
||||||
|
invalidate(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void setDownsampleFactor(float factor) { |
||||||
|
if (factor <= 0) { |
||||||
|
throw new IllegalArgumentException("Downsample factor must be greater than 0."); |
||||||
|
} |
||||||
|
|
||||||
|
if (mDownsampleFactor != factor) { |
||||||
|
mDownsampleFactor = factor; |
||||||
|
mDirty = true; // may also change blur radius
|
||||||
|
releaseBitmap(); |
||||||
|
invalidate(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void setOverlayColor(int color) { |
||||||
|
if (mOverlayColor != color) { |
||||||
|
mOverlayColor = color; |
||||||
|
invalidate(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void releaseBitmap() { |
||||||
|
if (mBlurInput != null) { |
||||||
|
mBlurInput.destroy(); |
||||||
|
mBlurInput = null; |
||||||
|
} |
||||||
|
if (mBlurOutput != null) { |
||||||
|
mBlurOutput.destroy(); |
||||||
|
mBlurOutput = null; |
||||||
|
} |
||||||
|
if (mBitmapToBlur != null) { |
||||||
|
mBitmapToBlur.recycle(); |
||||||
|
mBitmapToBlur = null; |
||||||
|
} |
||||||
|
if (mBlurredBitmap != null) { |
||||||
|
mBlurredBitmap.recycle(); |
||||||
|
mBlurredBitmap = null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void releaseScript() { |
||||||
|
if (mRenderScript != null) { |
||||||
|
mRenderScript.destroy(); |
||||||
|
mRenderScript = null; |
||||||
|
} |
||||||
|
if (mBlurScript != null) { |
||||||
|
mBlurScript.destroy(); |
||||||
|
mBlurScript = null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected void release() { |
||||||
|
log("release"); |
||||||
|
releaseBitmap(); |
||||||
|
releaseScript(); |
||||||
|
} |
||||||
|
|
||||||
|
protected boolean prepare() { |
||||||
|
if (mBlurRadius == 0) { |
||||||
|
release(); |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
float downsampleFactor = mDownsampleFactor; |
||||||
|
|
||||||
|
if (mDirty || mRenderScript == null) { |
||||||
|
if (supportRenderScript && useBlur) { |
||||||
|
if (mRenderScript == null) { |
||||||
|
try { |
||||||
|
mRenderScript = RenderScript.create(getContext()); |
||||||
|
mBlurScript = ScriptIntrinsicBlur.create(mRenderScript, Element.U8_4(mRenderScript)); |
||||||
|
|
||||||
|
} catch (Exception e) { |
||||||
|
if (isDebug()) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
mDirty = false; |
||||||
|
float radius = mBlurRadius / downsampleFactor; |
||||||
|
if (radius > 25) { |
||||||
|
downsampleFactor = downsampleFactor * radius / 25; |
||||||
|
radius = 25; |
||||||
|
} |
||||||
|
if (mBlurScript != null) mBlurScript.setRadius(radius); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
final int width = getWidth(); |
||||||
|
final int height = getHeight(); |
||||||
|
|
||||||
|
int scaledWidth = Math.max(1, (int) (width / downsampleFactor)); |
||||||
|
int scaledHeight = Math.max(1, (int) (height / downsampleFactor)); |
||||||
|
|
||||||
|
if (mBlurringCanvas == null || mBlurredBitmap == null || mBlurredBitmap.getWidth() != scaledWidth || mBlurredBitmap.getHeight() != scaledHeight) { |
||||||
|
releaseBitmap(); |
||||||
|
|
||||||
|
boolean r = false; |
||||||
|
try { |
||||||
|
mBitmapToBlur = Bitmap.createBitmap(scaledWidth, scaledHeight, Bitmap.Config.ARGB_8888); |
||||||
|
if (mBitmapToBlur == null) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
mBlurringCanvas = new Canvas(mBitmapToBlur); |
||||||
|
|
||||||
|
if (!supportRenderScript || !useBlur) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
mBlurInput = Allocation.createFromBitmap(mRenderScript, mBitmapToBlur, |
||||||
|
Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT |
||||||
|
); |
||||||
|
mBlurOutput = Allocation.createTyped(mRenderScript, mBlurInput.getType()); |
||||||
|
|
||||||
|
mBlurredBitmap = Bitmap.createBitmap(scaledWidth, scaledHeight, Bitmap.Config.ARGB_8888); |
||||||
|
if (mBlurredBitmap == null) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
r = true; |
||||||
|
} catch (Exception e) { |
||||||
|
if (isDebug()) e.printStackTrace(); |
||||||
|
} finally { |
||||||
|
if (!r) { |
||||||
|
releaseBitmap(); |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
protected void blur(Bitmap bitmapToBlur, Bitmap blurredBitmap) { |
||||||
|
mBlurInput.copyFrom(bitmapToBlur); |
||||||
|
mBlurScript.setInput(mBlurInput); |
||||||
|
mBlurScript.forEach(mBlurOutput); |
||||||
|
mBlurOutput.copyTo(blurredBitmap); |
||||||
|
} |
||||||
|
|
||||||
|
private final ViewTreeObserver.OnPreDrawListener preDrawListener = new ViewTreeObserver.OnPreDrawListener() { |
||||||
|
@Override |
||||||
|
public boolean onPreDraw() { |
||||||
|
final int[] locations = new int[2]; |
||||||
|
Bitmap oldBmp = mBlurredBitmap; |
||||||
|
View decor = mDecorView; |
||||||
|
if (decor != null && isShown() && prepare()) { |
||||||
|
boolean redrawBitmap = mBlurredBitmap != oldBmp; |
||||||
|
oldBmp = null; |
||||||
|
decor.getLocationOnScreen(locations); |
||||||
|
int x = -locations[0]; |
||||||
|
int y = -locations[1]; |
||||||
|
|
||||||
|
getLocationOnScreen(locations); |
||||||
|
x += locations[0]; |
||||||
|
y += locations[1]; |
||||||
|
|
||||||
|
// just erase transparent
|
||||||
|
mBitmapToBlur.eraseColor(mOverlayColor & 0xffffff); |
||||||
|
|
||||||
|
int rc = mBlurringCanvas.save(); |
||||||
|
mIsRendering = true; |
||||||
|
RENDERING_COUNT++; |
||||||
|
try { |
||||||
|
mBlurringCanvas.scale(1.f * mBitmapToBlur.getWidth() / getWidth(), 1.f * mBitmapToBlur.getHeight() / getHeight()); |
||||||
|
mBlurringCanvas.translate(-x, -y); |
||||||
|
if (decor.getBackground() != null) { |
||||||
|
decor.getBackground().draw(mBlurringCanvas); |
||||||
|
} |
||||||
|
decor.draw(mBlurringCanvas); |
||||||
|
} catch (Exception e) { |
||||||
|
if (isDebug()) e.printStackTrace(); |
||||||
|
} finally { |
||||||
|
mIsRendering = false; |
||||||
|
RENDERING_COUNT--; |
||||||
|
mBlurringCanvas.restoreToCount(rc); |
||||||
|
} |
||||||
|
|
||||||
|
blur(mBitmapToBlur, mBlurredBitmap); |
||||||
|
|
||||||
|
if (redrawBitmap || mDifferentRoot) { |
||||||
|
invalidate(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onAttachedToWindow() { |
||||||
|
super.onAttachedToWindow(); |
||||||
|
if (BaseDialog.getRootFrameLayout() != null && BaseDialog.getRootFrameLayout().getChildCount() >= 1) { |
||||||
|
mDecorView = BaseDialog.getRootFrameLayout().getChildAt(0); |
||||||
|
} |
||||||
|
if (mDecorView != null) { |
||||||
|
log("mDecorView is ok."); |
||||||
|
mDecorView.getViewTreeObserver().addOnPreDrawListener(preDrawListener); |
||||||
|
mDifferentRoot = mDecorView.getRootView() != getRootView(); |
||||||
|
if (mDifferentRoot) { |
||||||
|
mDecorView.postInvalidate(); |
||||||
|
} |
||||||
|
} else { |
||||||
|
log("mDecorView is NULL."); |
||||||
|
mDifferentRoot = false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onDetachedFromWindow() { |
||||||
|
if (mDecorView != null) { |
||||||
|
mDecorView.getViewTreeObserver().removeOnPreDrawListener(preDrawListener); |
||||||
|
} |
||||||
|
release(); |
||||||
|
super.onDetachedFromWindow(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void draw(Canvas canvas) { |
||||||
|
if (!useBlur) { |
||||||
|
Paint cutPaint = new Paint(); |
||||||
|
cutPaint.setAntiAlias(true); |
||||||
|
cutPaint.setColor(mOverlayColor); |
||||||
|
mRectF.right = getWidth(); |
||||||
|
mRectF.bottom = getHeight(); |
||||||
|
canvas.drawRoundRect(mRectF, mRadius, mRadius, cutPaint); |
||||||
|
} else { |
||||||
|
if (mIsRendering) { |
||||||
|
// Quit here, don't draw views above me
|
||||||
|
//throw STOP_EXCEPTION;
|
||||||
|
} else if (RENDERING_COUNT > 0) { |
||||||
|
// Doesn't support blurview overlap on another blurview
|
||||||
|
} else { |
||||||
|
if (mRadius != 0) { |
||||||
|
Rect rect = new Rect(); |
||||||
|
getLocalVisibleRect(rect); |
||||||
|
rect.right = rect.left + getWidth(); |
||||||
|
rect.bottom = rect.top + getHeight(); |
||||||
|
mBoundPath = caculateRoundRectPath(rect); |
||||||
|
canvas.clipPath(mBoundPath); |
||||||
|
} |
||||||
|
super.draw(canvas); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private Path caculateRoundRectPath(Rect r) { |
||||||
|
Path path = new Path(); |
||||||
|
float radius = mRadius; |
||||||
|
float elevation = 0; |
||||||
|
path.addRoundRect(new RectF(r.left + elevation, r.top + elevation, r.right - elevation, r.bottom - elevation), radius, radius, Path.Direction.CW); |
||||||
|
return path; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onDraw(Canvas canvas) { |
||||||
|
super.onDraw(canvas); |
||||||
|
drawBlurredBitmap(canvas, mBlurredBitmap, mOverlayColor); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Custom draw the blurred bitmap and color to define your own shape |
||||||
|
* |
||||||
|
* @param canvas |
||||||
|
* @param blurredBitmap |
||||||
|
* @param overlayColor |
||||||
|
*/ |
||||||
|
protected void drawBlurredBitmap(Canvas canvas, Bitmap blurredBitmap, int overlayColor) { |
||||||
|
if (blurredBitmap != null) { |
||||||
|
mRectSrc.right = blurredBitmap.getWidth(); |
||||||
|
mRectSrc.bottom = blurredBitmap.getHeight(); |
||||||
|
mRectDst.right = getWidth(); |
||||||
|
mRectDst.bottom = getHeight(); |
||||||
|
canvas.drawBitmap(blurredBitmap, mRectSrc, mRectDst, null); |
||||||
|
} |
||||||
|
canvas.drawColor((supportRenderScript && useBlur) ? overlayColor : removeAlphaColor(overlayColor)); |
||||||
|
} |
||||||
|
|
||||||
|
private static boolean supportRenderScript = false; |
||||||
|
private boolean useBlur = true; |
||||||
|
|
||||||
|
public boolean isUseBlur() { |
||||||
|
return useBlur; |
||||||
|
} |
||||||
|
|
||||||
|
public BlurView setUseBlur(boolean useBlur) { |
||||||
|
this.useBlur = useBlur; |
||||||
|
invalidate(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
private static int removeAlphaColor(@ColorInt int color) { |
||||||
|
int alpha = 255; |
||||||
|
int red = Color.red(color); |
||||||
|
int green = Color.green(color); |
||||||
|
int blue = Color.blue(color); |
||||||
|
return Color.argb(alpha, red, green, blue); |
||||||
|
} |
||||||
|
|
||||||
|
static { |
||||||
|
/** |
||||||
|
* 之所以需要启动一个新线程检测RenderScript是否可用的原因是不清楚Android什么时候对loadClass做了变更, |
||||||
|
* 会直接抛出NoClassDefFoundError无法拦截,在主线程检测会导致程序直接闪退,因此改为异步检测。 |
||||||
|
* 检测后会给定(boolean)supportRenderScript用于判断时光支持 |
||||||
|
*/ |
||||||
|
new Thread() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
try { |
||||||
|
BlurView.class.getClassLoader().loadClass(RenderScript.class.getCanonicalName()); |
||||||
|
supportRenderScript = true; |
||||||
|
} catch (Throwable e) { |
||||||
|
if (isDebug()) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
supportRenderScript = false; |
||||||
|
} |
||||||
|
} |
||||||
|
}.start(); |
||||||
|
} |
||||||
|
|
||||||
|
public static boolean DEBUGMODE = false; |
||||||
|
|
||||||
|
static boolean isDebug() { |
||||||
|
return DEBUGMODE && DialogX.DEBUGMODE; |
||||||
|
} |
||||||
|
|
||||||
|
public static void log(Object o) { |
||||||
|
if (isDebug()) Log.i(">>>", o.toString()); |
||||||
|
} |
||||||
|
|
||||||
|
public static void error(Object o) { |
||||||
|
if (isDebug()) Log.e(">>>", o.toString()); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,115 @@ |
|||||||
|
package com.kongzue.dialogx.util.views; |
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.content.res.Resources; |
||||||
|
import android.os.Build; |
||||||
|
import android.util.AttributeSet; |
||||||
|
import android.util.Log; |
||||||
|
import android.view.MotionEvent; |
||||||
|
import android.view.View; |
||||||
|
import android.view.ViewGroup; |
||||||
|
import android.view.ViewParent; |
||||||
|
import android.widget.ListAdapter; |
||||||
|
import android.widget.ListView; |
||||||
|
import android.widget.ScrollView; |
||||||
|
|
||||||
|
import androidx.annotation.RequiresApi; |
||||||
|
|
||||||
|
import com.kongzue.dialogx.dialogs.BottomDialog; |
||||||
|
import com.kongzue.dialogx.interfaces.BottomMenuListViewTouchEvent; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author: Kongzue |
||||||
|
* @github: https://github.com/kongzue/
|
||||||
|
* @homepage: http://kongzue.com/
|
||||||
|
* @mail: myzcxhh@live.cn |
||||||
|
* @createTime: 2020/10/6 23:42 |
||||||
|
*/ |
||||||
|
public class BottomDialogListView extends ListView { |
||||||
|
|
||||||
|
private BottomMenuListViewTouchEvent bottomMenuListViewTouchEvent; |
||||||
|
|
||||||
|
public BottomDialogListView(Context context) { |
||||||
|
super(context); |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialogListView(Context context, AttributeSet attrs) { |
||||||
|
super(context, attrs); |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialogListView(Context context, AttributeSet attrs, int defStyleAttr) { |
||||||
|
super(context, attrs, defStyleAttr); |
||||||
|
} |
||||||
|
|
||||||
|
private BottomDialog.DialogImpl dialogImpl; |
||||||
|
|
||||||
|
public BottomDialogListView(BottomDialog.DialogImpl dialog, Context context) { |
||||||
|
super(context); |
||||||
|
dialogImpl = dialog; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { |
||||||
|
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); |
||||||
|
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(dip2px(55)*size+size, MeasureSpec.EXACTLY)); |
||||||
|
|
||||||
|
//super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(expandSpec, MeasureSpec.AT_MOST));
|
||||||
|
} |
||||||
|
|
||||||
|
private int dip2px(float dpValue) { |
||||||
|
final float scale = Resources.getSystem().getDisplayMetrics().density; |
||||||
|
return (int) (dpValue * scale + 0.5f); |
||||||
|
} |
||||||
|
|
||||||
|
private int mPosition; |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean dispatchTouchEvent(MotionEvent ev) { |
||||||
|
final int actionMasked = ev.getActionMasked() & MotionEvent.ACTION_MASK; |
||||||
|
|
||||||
|
if (actionMasked == MotionEvent.ACTION_DOWN) { |
||||||
|
if (bottomMenuListViewTouchEvent != null) { |
||||||
|
bottomMenuListViewTouchEvent.down(ev); |
||||||
|
} |
||||||
|
mPosition = pointToPosition((int) ev.getX(), (int) ev.getY()); |
||||||
|
return super.dispatchTouchEvent(ev); |
||||||
|
} |
||||||
|
|
||||||
|
if (actionMasked == MotionEvent.ACTION_MOVE) { |
||||||
|
if (bottomMenuListViewTouchEvent != null) { |
||||||
|
bottomMenuListViewTouchEvent.move(ev); |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
if (actionMasked == MotionEvent.ACTION_UP || actionMasked == MotionEvent.ACTION_CANCEL) { |
||||||
|
if (bottomMenuListViewTouchEvent != null) { |
||||||
|
bottomMenuListViewTouchEvent.up(ev); |
||||||
|
} |
||||||
|
if (pointToPosition((int) ev.getX(), (int) ev.getY()) == mPosition) { |
||||||
|
super.dispatchTouchEvent(ev); |
||||||
|
} else { |
||||||
|
setPressed(false); |
||||||
|
invalidate(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return super.dispatchTouchEvent(ev); |
||||||
|
} |
||||||
|
|
||||||
|
public BottomMenuListViewTouchEvent getBottomMenuListViewTouchEvent() { |
||||||
|
return bottomMenuListViewTouchEvent; |
||||||
|
} |
||||||
|
|
||||||
|
private int size =1; |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setAdapter(ListAdapter adapter) { |
||||||
|
size = adapter.getCount(); |
||||||
|
super.setAdapter(adapter); |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialogListView setBottomMenuListViewTouchEvent(BottomMenuListViewTouchEvent bottomMenuListViewTouchEvent) { |
||||||
|
this.bottomMenuListViewTouchEvent = bottomMenuListViewTouchEvent; |
||||||
|
return this; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,55 @@ |
|||||||
|
package com.kongzue.dialogx.util.views; |
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.util.AttributeSet; |
||||||
|
import android.util.Log; |
||||||
|
import android.view.MotionEvent; |
||||||
|
import android.widget.ScrollView; |
||||||
|
|
||||||
|
import com.kongzue.dialogx.dialogs.BottomDialog; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author: Kongzue |
||||||
|
* @github: https://github.com/kongzue/
|
||||||
|
* @homepage: http://kongzue.com/
|
||||||
|
* @mail: myzcxhh@live.cn |
||||||
|
* @createTime: 2020/11/17 15:29 |
||||||
|
*/ |
||||||
|
public class BottomDialogScrollView extends ScrollView { |
||||||
|
|
||||||
|
public BottomDialogScrollView(Context context) { |
||||||
|
super(context); |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialogScrollView(Context context, AttributeSet attrs) { |
||||||
|
super(context, attrs); |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialogScrollView(Context context, AttributeSet attrs, int defStyleAttr) { |
||||||
|
super(context, attrs, defStyleAttr); |
||||||
|
} |
||||||
|
|
||||||
|
public BottomDialogScrollView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { |
||||||
|
super(context, attrs, defStyleAttr, defStyleRes); |
||||||
|
} |
||||||
|
|
||||||
|
boolean lockScroll; |
||||||
|
|
||||||
|
public void lockScroll(boolean lockScroll) { |
||||||
|
this.lockScroll = lockScroll; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean onTouchEvent(MotionEvent ev) { |
||||||
|
if (lockScroll) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
return super.onTouchEvent(ev); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean dispatchTouchEvent(MotionEvent ev) { |
||||||
|
return super.dispatchTouchEvent(ev); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,244 @@ |
|||||||
|
package com.kongzue.dialogx.util.views; |
||||||
|
|
||||||
|
import android.app.Activity; |
||||||
|
import android.content.Context; |
||||||
|
import android.content.res.Configuration; |
||||||
|
import android.content.res.TypedArray; |
||||||
|
import android.graphics.Rect; |
||||||
|
import android.os.Build; |
||||||
|
import android.util.AttributeSet; |
||||||
|
import android.util.DisplayMetrics; |
||||||
|
import android.util.Log; |
||||||
|
import android.view.KeyEvent; |
||||||
|
import android.view.MotionEvent; |
||||||
|
import android.view.View; |
||||||
|
import android.view.ViewParent; |
||||||
|
import android.view.ViewTreeObserver; |
||||||
|
import android.view.WindowInsets; |
||||||
|
import android.view.inputmethod.InputMethodManager; |
||||||
|
import android.widget.RelativeLayout; |
||||||
|
|
||||||
|
import androidx.core.view.ViewCompat; |
||||||
|
|
||||||
|
import com.kongzue.dialogx.R; |
||||||
|
import com.kongzue.dialogx.interfaces.BaseDialog; |
||||||
|
import com.kongzue.dialogx.interfaces.OnBackPressedListener; |
||||||
|
import com.kongzue.dialogx.interfaces.OnSafeInsetsChangeListener; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author: Kongzue |
||||||
|
* @github: https://github.com/kongzue/
|
||||||
|
* @homepage: http://kongzue.com/
|
||||||
|
* @mail: myzcxhh@live.cn |
||||||
|
* @createTime: 2020/9/22 13:53 |
||||||
|
*/ |
||||||
|
public class DialogXBaseRelativeLayout extends RelativeLayout { |
||||||
|
|
||||||
|
private OnSafeInsetsChangeListener onSafeInsetsChangeListener; |
||||||
|
private BaseDialog parentDialog; |
||||||
|
private boolean autoUnsafePlacePadding = true; |
||||||
|
private boolean focusable = true; |
||||||
|
|
||||||
|
private OnLifecycleCallBack onLifecycleCallBack; |
||||||
|
private OnBackPressedListener onBackPressedListener; |
||||||
|
|
||||||
|
public DialogXBaseRelativeLayout(Context context) { |
||||||
|
super(context); |
||||||
|
init(null); |
||||||
|
} |
||||||
|
|
||||||
|
public DialogXBaseRelativeLayout(Context context, AttributeSet attrs) { |
||||||
|
super(context, attrs); |
||||||
|
init(attrs); |
||||||
|
} |
||||||
|
|
||||||
|
public DialogXBaseRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) { |
||||||
|
super(context, attrs, defStyleAttr); |
||||||
|
init(attrs); |
||||||
|
} |
||||||
|
|
||||||
|
public DialogXBaseRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { |
||||||
|
super(context, attrs, defStyleAttr, defStyleRes); |
||||||
|
init(attrs); |
||||||
|
} |
||||||
|
|
||||||
|
private boolean isInited = false; |
||||||
|
|
||||||
|
private void init(AttributeSet attrs) { |
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { |
||||||
|
setForceDarkAllowed(false); |
||||||
|
} |
||||||
|
if (!isInited ) { |
||||||
|
if (attrs != null) { |
||||||
|
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.DialogXBaseRelativeLayout); |
||||||
|
focusable = a.getBoolean(R.styleable.DialogXBaseRelativeLayout_baseFocusable, true); |
||||||
|
a.recycle(); |
||||||
|
} |
||||||
|
if (focusable) { |
||||||
|
setFocusable(true); |
||||||
|
setFocusableInTouchMode(true); |
||||||
|
requestFocus(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected boolean fitSystemWindows(Rect insets) { |
||||||
|
paddingView(insets.left, insets.top, insets.right, insets.bottom); |
||||||
|
return super.fitSystemWindows(insets); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) { |
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { |
||||||
|
paddingView(insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(), insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom()); |
||||||
|
} |
||||||
|
return super.dispatchApplyWindowInsets(insets); |
||||||
|
} |
||||||
|
|
||||||
|
public void paddingView(WindowInsets insets) { |
||||||
|
if (insets == null) return; |
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { |
||||||
|
paddingView(insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(), insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean dispatchKeyEvent(KeyEvent event) { |
||||||
|
if (isAttachedToWindow() && event.getAction() == KeyEvent.ACTION_UP && event.getKeyCode() == KeyEvent.KEYCODE_BACK) { |
||||||
|
if (onBackPressedListener != null) { |
||||||
|
onBackPressedListener.onBackPressed(); |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
return super.dispatchKeyEvent(event); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean onTouchEvent(MotionEvent event) { |
||||||
|
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); |
||||||
|
imm.hideSoftInputFromWindow(getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); |
||||||
|
return super.onTouchEvent(event); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onAttachedToWindow() { |
||||||
|
super.onAttachedToWindow(); |
||||||
|
final ViewParent parent = getParent(); |
||||||
|
|
||||||
|
if (parent instanceof View)ViewCompat.setFitsSystemWindows(this, ViewCompat.getFitsSystemWindows((View) parent)); |
||||||
|
ViewCompat.requestApplyInsets(this); |
||||||
|
|
||||||
|
if (BaseDialog.getContext() == null) return; |
||||||
|
if (!isInEditMode()) { |
||||||
|
((Activity) BaseDialog.getContext()).getWindow().getDecorView().getViewTreeObserver().addOnGlobalLayoutListener(decorViewLayoutListener); |
||||||
|
} |
||||||
|
|
||||||
|
if (onLifecycleCallBack != null) { |
||||||
|
onLifecycleCallBack.onShow(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private ViewTreeObserver.OnGlobalLayoutListener decorViewLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() { |
||||||
|
@Override |
||||||
|
public void onGlobalLayout() { |
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { |
||||||
|
paddingView(getRootWindowInsets()); |
||||||
|
} else { |
||||||
|
if (BaseDialog.getContext() == null) return; |
||||||
|
DisplayMetrics displayMetrics = new DisplayMetrics(); |
||||||
|
((Activity) BaseDialog.getContext()).getWindowManager().getDefaultDisplay().getRealMetrics(displayMetrics); |
||||||
|
Rect rect = new Rect(); |
||||||
|
((Activity) BaseDialog.getContext()).getWindow().getDecorView().getWindowVisibleDisplayFrame(rect); |
||||||
|
paddingView(rect.left, rect.top, displayMetrics.widthPixels - rect.right, displayMetrics.heightPixels - rect.bottom); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onDetachedFromWindow() { |
||||||
|
if (decorViewLayoutListener != null && ((Activity) BaseDialog.getContext()) != null) { |
||||||
|
((Activity) BaseDialog.getContext()).getWindow().getDecorView().getViewTreeObserver().removeOnGlobalLayoutListener(decorViewLayoutListener); |
||||||
|
} |
||||||
|
if (onLifecycleCallBack != null) { |
||||||
|
onLifecycleCallBack.onDismiss(); |
||||||
|
} |
||||||
|
super.onDetachedFromWindow(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean performClick() { |
||||||
|
return super.performClick(); |
||||||
|
} |
||||||
|
|
||||||
|
public DialogXBaseRelativeLayout setOnLifecycleCallBack(OnLifecycleCallBack onLifecycleCallBack) { |
||||||
|
this.onLifecycleCallBack = onLifecycleCallBack; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public float getSafeHeight() { |
||||||
|
return getMeasuredHeight() - unsafePlace.bottom - unsafePlace.top; |
||||||
|
} |
||||||
|
|
||||||
|
public abstract static class OnLifecycleCallBack { |
||||||
|
public void onShow() { |
||||||
|
} |
||||||
|
|
||||||
|
public abstract void onDismiss(); |
||||||
|
} |
||||||
|
|
||||||
|
protected Rect unsafePlace = new Rect(); |
||||||
|
|
||||||
|
private void paddingView(int left, int top, int right, int bottom) { |
||||||
|
unsafePlace = new Rect(left, top, right, bottom); |
||||||
|
if (onSafeInsetsChangeListener != null) onSafeInsetsChangeListener.onChange(unsafePlace); |
||||||
|
MaxRelativeLayout bkgView = findViewById(R.id.bkg); |
||||||
|
if (bkgView != null && bkgView.getLayoutParams() instanceof LayoutParams) { |
||||||
|
LayoutParams bkgLp = (LayoutParams) bkgView.getLayoutParams(); |
||||||
|
if (bkgLp.getRules()[ALIGN_PARENT_BOTTOM] == RelativeLayout.TRUE && isAutoUnsafePlacePadding()) { |
||||||
|
bkgView.setPadding(0, 0, 0, bottom); |
||||||
|
setPadding(left, top, right, 0); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
if (isAutoUnsafePlacePadding()) setPadding(left, top, right, bottom); |
||||||
|
} |
||||||
|
|
||||||
|
public DialogXBaseRelativeLayout setOnBackPressedListener(OnBackPressedListener onBackPressedListener) { |
||||||
|
this.onBackPressedListener = onBackPressedListener; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public OnSafeInsetsChangeListener getOnSafeInsetsChangeListener() { |
||||||
|
return onSafeInsetsChangeListener; |
||||||
|
} |
||||||
|
|
||||||
|
public DialogXBaseRelativeLayout setOnSafeInsetsChangeListener(OnSafeInsetsChangeListener onSafeInsetsChangeListener) { |
||||||
|
this.onSafeInsetsChangeListener = onSafeInsetsChangeListener; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isAutoUnsafePlacePadding() { |
||||||
|
return autoUnsafePlacePadding; |
||||||
|
} |
||||||
|
|
||||||
|
public DialogXBaseRelativeLayout setAutoUnsafePlacePadding(boolean autoUnsafePlacePadding) { |
||||||
|
this.autoUnsafePlacePadding = autoUnsafePlacePadding; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public BaseDialog getParentDialog() { |
||||||
|
return parentDialog; |
||||||
|
} |
||||||
|
|
||||||
|
public DialogXBaseRelativeLayout setParentDialog(BaseDialog parentDialog) { |
||||||
|
this.parentDialog = parentDialog; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onConfigurationChanged(Configuration newConfig) { |
||||||
|
super.onConfigurationChanged(newConfig); |
||||||
|
getParentDialog().onUIModeChange(newConfig); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,224 @@ |
|||||||
|
package com.kongzue.dialogx.util.views; |
||||||
|
|
||||||
|
import android.animation.ValueAnimator; |
||||||
|
import android.content.Context; |
||||||
|
import android.content.res.TypedArray; |
||||||
|
import android.os.Build; |
||||||
|
import android.util.AttributeSet; |
||||||
|
import android.util.Log; |
||||||
|
import android.view.MotionEvent; |
||||||
|
import android.view.View; |
||||||
|
import android.view.ViewParent; |
||||||
|
import android.widget.RelativeLayout; |
||||||
|
import android.widget.ScrollView; |
||||||
|
|
||||||
|
import com.kongzue.dialogx.R; |
||||||
|
|
||||||
|
import static android.view.View.MeasureSpec.EXACTLY; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author: Kongzue |
||||||
|
* @github: https://github.com/kongzue/
|
||||||
|
* @homepage: http://kongzue.com/
|
||||||
|
* @mail: myzcxhh@live.cn |
||||||
|
* @createTime: 2019/9/24 17:34 |
||||||
|
*/ |
||||||
|
public class MaxRelativeLayout extends RelativeLayout { |
||||||
|
|
||||||
|
private int maxWidth; |
||||||
|
private int maxHeight; |
||||||
|
private int minWidth; |
||||||
|
private int minHeight; |
||||||
|
private boolean lockWidth; |
||||||
|
private boolean interceptTouch = true; |
||||||
|
|
||||||
|
public MaxRelativeLayout(Context context) { |
||||||
|
super(context); |
||||||
|
init(context, null); |
||||||
|
} |
||||||
|
|
||||||
|
public MaxRelativeLayout(Context context, AttributeSet attrs) { |
||||||
|
super(context, attrs); |
||||||
|
init(context, attrs); |
||||||
|
} |
||||||
|
|
||||||
|
public MaxRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) { |
||||||
|
super(context, attrs, defStyleAttr); |
||||||
|
init(context, attrs); |
||||||
|
} |
||||||
|
|
||||||
|
private float startAnimValue = 0, endAnimValue = 0; |
||||||
|
|
||||||
|
private void init(Context context, AttributeSet attrs) { |
||||||
|
if (attrs != null) { |
||||||
|
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MaxRelativeLayout); |
||||||
|
maxWidth = a.getDimensionPixelSize(R.styleable.MaxRelativeLayout_maxLayoutWidth, 0); |
||||||
|
maxHeight = a.getDimensionPixelSize(R.styleable.MaxRelativeLayout_maxLayoutHeight, 0); |
||||||
|
lockWidth = a.getBoolean(R.styleable.MaxRelativeLayout_lockWidth, false); |
||||||
|
interceptTouch = a.getBoolean(R.styleable.MaxRelativeLayout_interceptTouch, true); |
||||||
|
|
||||||
|
a.recycle(); |
||||||
|
} |
||||||
|
minWidth = getMinimumWidth(); |
||||||
|
minHeight = getMinimumHeight(); |
||||||
|
|
||||||
|
if (!isInEditMode()) { |
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { |
||||||
|
animate().setUpdateListener(new ValueAnimator.AnimatorUpdateListener() { |
||||||
|
@Override |
||||||
|
public void onAnimationUpdate(ValueAnimator animation) { |
||||||
|
float progress = (float) animation.getAnimatedValue(); |
||||||
|
long value = (long) (startAnimValue + (endAnimValue - startAnimValue) * progress); |
||||||
|
if (onYChangedListener != null) onYChangedListener.y(value); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private ScrollView childScrollView; |
||||||
|
|
||||||
|
public MaxRelativeLayout setMaxHeight(int maxHeight) { |
||||||
|
this.maxHeight = maxHeight; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public MaxRelativeLayout setMaxWidth(int maxWidth) { |
||||||
|
if (maxWidth > 0 && this.maxWidth != 0) this.maxWidth = maxWidth; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
private int preWidth = -1; |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { |
||||||
|
int heightMode = MeasureSpec.getMode(heightMeasureSpec); |
||||||
|
int widthMode = MeasureSpec.getMode(widthMeasureSpec); |
||||||
|
|
||||||
|
int heightSize = MeasureSpec.getSize(heightMeasureSpec); |
||||||
|
int widthSize = MeasureSpec.getSize(widthMeasureSpec); |
||||||
|
|
||||||
|
if (preWidth == -1 && widthSize != 0) { |
||||||
|
preWidth = widthSize; |
||||||
|
} |
||||||
|
if (lockWidth) { |
||||||
|
maxWidth = Math.min(widthSize, preWidth); |
||||||
|
} |
||||||
|
if (maxHeight > 0) { |
||||||
|
heightSize = Math.min(heightSize, maxHeight); |
||||||
|
} |
||||||
|
if (maxWidth > 0) { |
||||||
|
widthSize = Math.min(widthSize, maxWidth); |
||||||
|
} |
||||||
|
View blurView = findViewWithTag("blurView"); |
||||||
|
View contentView = findViewWithoutTag("blurView"); |
||||||
|
if (contentView != null) { |
||||||
|
int widthTemp = contentView.getMeasuredWidth() == 0 ? getMeasuredWidth() : contentView.getMeasuredWidth(); |
||||||
|
int heightTemp = contentView.getMeasuredHeight() == 0 ? getMeasuredHeight() : contentView.getMeasuredHeight(); |
||||||
|
if (widthTemp < minWidth) widthTemp = minWidth; |
||||||
|
if (heightTemp < minHeight) heightTemp = minHeight; |
||||||
|
if (blurView != null) { |
||||||
|
if (heightMode == EXACTLY){ |
||||||
|
heightTemp = heightSize; |
||||||
|
} |
||||||
|
if (widthMode == EXACTLY){ |
||||||
|
widthTemp = widthSize; |
||||||
|
} |
||||||
|
LayoutParams lp = (LayoutParams) blurView.getLayoutParams(); |
||||||
|
lp.width = widthTemp; |
||||||
|
lp.height = heightTemp; |
||||||
|
blurView.setLayoutParams(lp); |
||||||
|
} |
||||||
|
} else { |
||||||
|
if (blurView != null) { |
||||||
|
LayoutParams lp = (LayoutParams) blurView.getLayoutParams(); |
||||||
|
lp.width = getMeasuredWidth(); |
||||||
|
lp.height = getMeasuredHeight(); |
||||||
|
blurView.setLayoutParams(lp); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
int maxHeightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, heightMode); |
||||||
|
int maxWidthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize, widthMode); |
||||||
|
super.onMeasure(maxWidthMeasureSpec, maxHeightMeasureSpec); |
||||||
|
|
||||||
|
childScrollView = findViewById(R.id.scrollView); |
||||||
|
} |
||||||
|
|
||||||
|
private View findViewWithoutTag(String tag) { |
||||||
|
for (int i = 0; i < getChildCount(); i++) { |
||||||
|
if (!tag.equals(getChildAt(i).getTag())) { |
||||||
|
return getChildAt(i); |
||||||
|
} |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isChildScrollViewCanScroll() { |
||||||
|
if (childScrollView == null) return false; |
||||||
|
if (!childScrollView.isEnabled()) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
View child = childScrollView.getChildAt(0); |
||||||
|
if (child != null) { |
||||||
|
int childHeight = child.getHeight(); |
||||||
|
return childScrollView.getHeight() < childHeight; |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
public int dip2px(float dpValue) { |
||||||
|
final float scale = getResources().getDisplayMetrics().density; |
||||||
|
return (int) (dpValue * scale + 0.5f); |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isLockWidth() { |
||||||
|
return lockWidth; |
||||||
|
} |
||||||
|
|
||||||
|
public MaxRelativeLayout setLockWidth(boolean lockWidth) { |
||||||
|
this.lockWidth = lockWidth; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
private OnYChanged onYChangedListener; |
||||||
|
|
||||||
|
public interface OnYChanged { |
||||||
|
void y(float y); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setY(float y) { |
||||||
|
super.setY(y); |
||||||
|
} |
||||||
|
|
||||||
|
public OnYChanged getOnYChanged() { |
||||||
|
return onYChangedListener; |
||||||
|
} |
||||||
|
|
||||||
|
public MaxRelativeLayout setOnYChanged(OnYChanged onYChanged) { |
||||||
|
this.onYChangedListener = onYChanged; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setTranslationY(float translationY) { |
||||||
|
super.setTranslationY(translationY); |
||||||
|
if (onYChangedListener != null) onYChangedListener.y(translationY); |
||||||
|
} |
||||||
|
|
||||||
|
private OnTouchListener onTouchListener; |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setOnTouchListener(OnTouchListener l) { |
||||||
|
onTouchListener = l; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean dispatchTouchEvent(MotionEvent ev) { |
||||||
|
if (onTouchListener != null) { |
||||||
|
onTouchListener.onTouch(this, ev); |
||||||
|
} |
||||||
|
return super.dispatchTouchEvent(ev); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,452 @@ |
|||||||
|
package com.kongzue.dialogx.util.views; |
||||||
|
|
||||||
|
import android.animation.TimeInterpolator; |
||||||
|
import android.animation.ValueAnimator; |
||||||
|
import android.content.Context; |
||||||
|
import android.content.res.Resources; |
||||||
|
import android.content.res.TypedArray; |
||||||
|
import android.graphics.Canvas; |
||||||
|
import android.graphics.Color; |
||||||
|
import android.graphics.Paint; |
||||||
|
import android.graphics.RectF; |
||||||
|
import android.util.AttributeSet; |
||||||
|
import android.util.Log; |
||||||
|
import android.view.HapticFeedbackConstants; |
||||||
|
import android.view.View; |
||||||
|
import android.view.animation.AccelerateDecelerateInterpolator; |
||||||
|
import android.view.animation.DecelerateInterpolator; |
||||||
|
import android.view.animation.LinearInterpolator; |
||||||
|
|
||||||
|
import androidx.annotation.Nullable; |
||||||
|
|
||||||
|
import com.kongzue.dialogx.R; |
||||||
|
import com.kongzue.dialogx.interfaces.ProgressViewInterface; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author: Kongzue |
||||||
|
* @github: https://github.com/kongzue/
|
||||||
|
* @homepage: http://kongzue.com/
|
||||||
|
* @mail: myzcxhh@live.cn |
||||||
|
* @createTime: 2021/3/14 20:58 |
||||||
|
*/ |
||||||
|
public class NoArticulatedProgressView extends View implements ProgressViewInterface { |
||||||
|
public static final int STATUS_LOADING = 0; |
||||||
|
public static final int STATUS_SUCCESS = 1; |
||||||
|
public static final int STATUS_WARNING = 2; |
||||||
|
public static final int STATUS_ERROR = 3; |
||||||
|
public static final int STATUS_PROGRESSING = 4; |
||||||
|
|
||||||
|
private int status = STATUS_LOADING; |
||||||
|
|
||||||
|
private int width = dip2px(2); |
||||||
|
private int color = Color.WHITE; |
||||||
|
|
||||||
|
public NoArticulatedProgressView(Context context) { |
||||||
|
super(context); |
||||||
|
init(null); |
||||||
|
} |
||||||
|
|
||||||
|
public NoArticulatedProgressView(Context context, @Nullable AttributeSet attrs) { |
||||||
|
super(context, attrs); |
||||||
|
init(attrs); |
||||||
|
} |
||||||
|
|
||||||
|
public NoArticulatedProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { |
||||||
|
super(context, attrs, defStyleAttr); |
||||||
|
init(attrs); |
||||||
|
} |
||||||
|
|
||||||
|
public NoArticulatedProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { |
||||||
|
super(context, attrs, defStyleAttr, defStyleRes); |
||||||
|
init(attrs); |
||||||
|
} |
||||||
|
|
||||||
|
private ValueAnimator rotateAnimator; |
||||||
|
private ValueAnimator followAnimator; |
||||||
|
|
||||||
|
private float currentRotateDegrees; |
||||||
|
private float followRotateDegrees; |
||||||
|
|
||||||
|
//跟随点度数做正弦值变化,halfSweepAMinValue为最低相较目标点度数差值,halfSweepAMaxValue为最大相较目标点度数差值
|
||||||
|
private float halfSweepAMaxValue = 180; |
||||||
|
private float halfSweepAMinValue = 80; |
||||||
|
//正弦函数的半径
|
||||||
|
private float halfSweepA; |
||||||
|
|
||||||
|
Paint mPaint = new Paint(); |
||||||
|
|
||||||
|
private boolean isInited = false; |
||||||
|
|
||||||
|
private void init(AttributeSet attrs) { |
||||||
|
synchronized (NoArticulatedProgressView.class) { |
||||||
|
if (isInited) { |
||||||
|
return; |
||||||
|
} |
||||||
|
isInited = true; |
||||||
|
if (attrs != null) { |
||||||
|
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.ProgressView); |
||||||
|
width = a.getDimensionPixelSize(R.styleable.ProgressView_progressStrokeWidth, dip2px(2)); |
||||||
|
color = a.getDimensionPixelSize(R.styleable.ProgressView_progressStrokeColor, color); |
||||||
|
|
||||||
|
a.recycle(); |
||||||
|
} |
||||||
|
|
||||||
|
mPaint.setAntiAlias(true); |
||||||
|
mPaint.setStyle(Paint.Style.STROKE); |
||||||
|
mPaint.setStrokeWidth(width); |
||||||
|
mPaint.setStrokeCap(Paint.Cap.ROUND); |
||||||
|
mPaint.setColor(color); |
||||||
|
|
||||||
|
if (!isInEditMode()) { |
||||||
|
halfSweepA = (halfSweepAMaxValue - halfSweepAMinValue) / 2; |
||||||
|
|
||||||
|
rotateAnimator = ValueAnimator.ofFloat(0, 365); |
||||||
|
rotateAnimator.setDuration(1000); |
||||||
|
rotateAnimator.setInterpolator(new LinearInterpolator()); |
||||||
|
rotateAnimator.setRepeatCount(-1); |
||||||
|
rotateAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { |
||||||
|
@Override |
||||||
|
public void onAnimationUpdate(ValueAnimator animation) { |
||||||
|
currentRotateDegrees = (float) animation.getAnimatedValue(); |
||||||
|
invalidate(); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
followAnimator = ValueAnimator.ofFloat(0, 365); |
||||||
|
followAnimator.setDuration(1500); |
||||||
|
followAnimator.setInterpolator(new LinearInterpolator()); |
||||||
|
followAnimator.setRepeatCount(-1); |
||||||
|
followAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { |
||||||
|
@Override |
||||||
|
public void onAnimationUpdate(ValueAnimator animation) { |
||||||
|
followRotateDegrees = (float) animation.getAnimatedValue(); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
followAnimator.start(); |
||||||
|
rotateAnimator.start(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
//旋转圆的中心坐标
|
||||||
|
private float mCenterX; |
||||||
|
private float mCenterY; |
||||||
|
//半径
|
||||||
|
private float mRadius = 100; |
||||||
|
private RectF oval; |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onSizeChanged(int w, int h, int oldw, int oldh) { |
||||||
|
super.onSizeChanged(w, h, oldw, oldh); |
||||||
|
mCenterX = w * 1f / 2; |
||||||
|
mCenterY = h * 1f / 2; |
||||||
|
mRadius = Math.min(getWidth(), getHeight()) / 2 - width / 2; |
||||||
|
oval = new RectF(mCenterX - mRadius, mCenterY - mRadius, mCenterX + mRadius, mCenterY + mRadius); |
||||||
|
} |
||||||
|
|
||||||
|
protected float oldAnimAngle; |
||||||
|
private int successStep = 0; |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onDraw(Canvas canvas) { |
||||||
|
if (isInEditMode()) { |
||||||
|
canvas.drawArc(oval, 0, 365, false, mPaint); |
||||||
|
return; |
||||||
|
} |
||||||
|
if (noShowLoading) { |
||||||
|
canvas.drawArc(oval, 0, 365, false, mPaint); |
||||||
|
successStep = 2; |
||||||
|
drawDoneMark(status, canvas); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
float sweepAngle = (float) (halfSweepA * Math.sin(Math.toRadians(followRotateDegrees))) + halfSweepA + halfSweepAMinValue / 2; |
||||||
|
switch (status) { |
||||||
|
case STATUS_LOADING: |
||||||
|
canvas.drawArc(oval, currentRotateDegrees, -sweepAngle, false, mPaint); |
||||||
|
break; |
||||||
|
case STATUS_SUCCESS: |
||||||
|
case STATUS_WARNING: |
||||||
|
case STATUS_ERROR: |
||||||
|
canvas.drawArc(oval, 0, 360, false, mPaint); |
||||||
|
drawDoneMark(status, canvas); |
||||||
|
break; |
||||||
|
case STATUS_PROGRESSING: |
||||||
|
canvas.drawArc(oval, -90, currentRotateDegrees, false, mPaint); |
||||||
|
if (waitProgressingRunnable != null) { |
||||||
|
waitProgressingRunnable.run(); |
||||||
|
waitProgressingRunnable = null; |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void drawDoneMark(int status, Canvas canvas) { |
||||||
|
if (rotateAnimator.getInterpolator() != interpolator) { |
||||||
|
rotateAnimator.setInterpolator(interpolator); |
||||||
|
} |
||||||
|
if (tickShowRunnable != null) { |
||||||
|
tickShowRunnable.run(); |
||||||
|
performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); |
||||||
|
tickShowRunnable = null; |
||||||
|
} |
||||||
|
switch (status) { |
||||||
|
case STATUS_SUCCESS: |
||||||
|
showSuccessTick(canvas); |
||||||
|
break; |
||||||
|
case STATUS_WARNING: |
||||||
|
showWarningTick(canvas); |
||||||
|
break; |
||||||
|
case STATUS_ERROR: |
||||||
|
showErrorTick(canvas); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private int line1X = 0; |
||||||
|
private int line1Y = 0; |
||||||
|
private int line2X = 0; |
||||||
|
private int line2Y = 0; |
||||||
|
|
||||||
|
private int tickStep = 0; |
||||||
|
|
||||||
|
//绘制对号
|
||||||
|
private void showSuccessTick(Canvas canvas) { |
||||||
|
int tickLeftPoint = (int) (mCenterX - mRadius * 1 / 2); |
||||||
|
int tickTurnLeftPoint = (int) (mCenterX - mRadius / 10); |
||||||
|
int tickRightPoint = (int) (mRadius * 0.99f); |
||||||
|
int speed = 2; |
||||||
|
switch (tickStep) { |
||||||
|
case 0: |
||||||
|
if (tickLeftPoint + line1X < tickTurnLeftPoint) { |
||||||
|
line1X = line1X + speed; |
||||||
|
line1Y = line1Y + speed; |
||||||
|
} else { |
||||||
|
line2X = line1X; |
||||||
|
line2Y = line1Y; |
||||||
|
tickStep = 1; |
||||||
|
} |
||||||
|
break; |
||||||
|
case 1: |
||||||
|
if (line2X < tickRightPoint) { |
||||||
|
line2X = line2X + 4; |
||||||
|
line2Y = line2Y - 5; |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
canvas.drawLine(tickLeftPoint, mCenterY, tickLeftPoint + line1X, mCenterY + line1Y, mPaint); |
||||||
|
canvas.drawLine(tickLeftPoint + line1X, mCenterY + line1Y, tickLeftPoint + line2X, mCenterY + line2Y, mPaint); |
||||||
|
|
||||||
|
postInvalidateDelayed(1); |
||||||
|
} |
||||||
|
|
||||||
|
//绘制感叹号
|
||||||
|
private void showWarningTick(Canvas canvas) { |
||||||
|
int tickLeftPoint = (int) mCenterX; |
||||||
|
int line1StartY = (int) (mCenterY - mRadius * 1 / 2); |
||||||
|
int line1EndY = (int) (mCenterY + mRadius * 1 / 8); |
||||||
|
int line2StartY = (int) (mCenterY + mRadius * 3 / 7); |
||||||
|
int speed = 4; |
||||||
|
switch (tickStep) { |
||||||
|
case 0: |
||||||
|
if (line1Y < line1EndY - line1StartY) { |
||||||
|
line1Y = line1Y + speed; |
||||||
|
} else { |
||||||
|
line1Y = line1EndY - line1StartY; |
||||||
|
tickStep = 1; |
||||||
|
} |
||||||
|
break; |
||||||
|
case 1: |
||||||
|
if (line2Y != line2StartY) { |
||||||
|
canvas.drawLine(tickLeftPoint, line2StartY, tickLeftPoint, line2StartY + 1, mPaint); |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
canvas.drawLine(tickLeftPoint, line1StartY, tickLeftPoint, line1StartY + line1Y, mPaint); |
||||||
|
postInvalidateDelayed(tickStep == 1 ? 100 : 1); |
||||||
|
} |
||||||
|
|
||||||
|
//绘制错误符号
|
||||||
|
private void showErrorTick(Canvas canvas) { |
||||||
|
int tickLeftPoint = (int) (mCenterX - mRadius * 4 / 10); |
||||||
|
int tickRightPoint = (int) (mCenterX + mRadius * 4 / 10); |
||||||
|
int tickTopPoint = (int) (mCenterY - mRadius * 4 / 10); |
||||||
|
int speed = 4; |
||||||
|
|
||||||
|
switch (tickStep) { |
||||||
|
case 0: |
||||||
|
if (tickRightPoint - line1X > tickLeftPoint) { |
||||||
|
line1X = line1X + speed; |
||||||
|
line1Y = line1Y + speed; |
||||||
|
} else { |
||||||
|
tickStep = 1; |
||||||
|
canvas.drawLine(tickRightPoint, tickTopPoint, tickRightPoint - line1X, tickTopPoint + line1Y, mPaint); |
||||||
|
postInvalidateDelayed(150); |
||||||
|
return; |
||||||
|
} |
||||||
|
break; |
||||||
|
case 1: |
||||||
|
if (tickLeftPoint + line2X < tickRightPoint) { |
||||||
|
line2X = line2X + speed; |
||||||
|
line2Y = line2Y + speed; |
||||||
|
} |
||||||
|
canvas.drawLine(tickLeftPoint, tickTopPoint, tickLeftPoint + line2X, tickTopPoint + line2Y, mPaint); |
||||||
|
break; |
||||||
|
} |
||||||
|
canvas.drawLine(tickRightPoint, tickTopPoint, tickRightPoint - line1X, tickTopPoint + line1Y, mPaint); |
||||||
|
postInvalidateDelayed(1); |
||||||
|
} |
||||||
|
|
||||||
|
private TimeInterpolator interpolator; |
||||||
|
private Runnable waitProgressingRunnable; |
||||||
|
|
||||||
|
public void success() { |
||||||
|
if (status == STATUS_PROGRESSING) { |
||||||
|
progress(1f); |
||||||
|
waitProgressingRunnable = new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
tickStep = 0; |
||||||
|
successStep = 2; |
||||||
|
interpolator = new AccelerateDecelerateInterpolator(); |
||||||
|
status = STATUS_SUCCESS; |
||||||
|
} |
||||||
|
}; |
||||||
|
return; |
||||||
|
} |
||||||
|
tickStep = 0; |
||||||
|
interpolator = new AccelerateDecelerateInterpolator(); |
||||||
|
status = STATUS_SUCCESS; |
||||||
|
invalidate(); |
||||||
|
} |
||||||
|
|
||||||
|
public void warning() { |
||||||
|
if (status == STATUS_PROGRESSING) { |
||||||
|
progress(1f); |
||||||
|
waitProgressingRunnable = new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
tickStep = 0; |
||||||
|
successStep = 2; |
||||||
|
interpolator = new DecelerateInterpolator(2); |
||||||
|
status = STATUS_WARNING; |
||||||
|
} |
||||||
|
}; |
||||||
|
return; |
||||||
|
} |
||||||
|
tickStep = 0; |
||||||
|
interpolator = new DecelerateInterpolator(2); |
||||||
|
status = STATUS_WARNING; |
||||||
|
invalidate(); |
||||||
|
} |
||||||
|
|
||||||
|
public void error() { |
||||||
|
if (status == STATUS_PROGRESSING) { |
||||||
|
progress(1f); |
||||||
|
waitProgressingRunnable = new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
tickStep = 0; |
||||||
|
successStep = 2; |
||||||
|
interpolator = new DecelerateInterpolator(2); |
||||||
|
status = STATUS_ERROR; |
||||||
|
} |
||||||
|
}; |
||||||
|
return; |
||||||
|
} |
||||||
|
tickStep = 0; |
||||||
|
interpolator = new DecelerateInterpolator(2); |
||||||
|
status = STATUS_ERROR; |
||||||
|
invalidate(); |
||||||
|
} |
||||||
|
|
||||||
|
public void progress(float progress) { |
||||||
|
if (rotateAnimator != null) rotateAnimator.cancel(); |
||||||
|
if (followAnimator != null) followAnimator.cancel(); |
||||||
|
if (status != STATUS_PROGRESSING) { |
||||||
|
currentRotateDegrees = 0; |
||||||
|
} |
||||||
|
rotateAnimator = ValueAnimator.ofFloat(currentRotateDegrees, 365 * progress); |
||||||
|
rotateAnimator.setDuration(1000); |
||||||
|
rotateAnimator.setInterpolator(new DecelerateInterpolator(2)); |
||||||
|
rotateAnimator.setRepeatCount(0); |
||||||
|
rotateAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { |
||||||
|
@Override |
||||||
|
public void onAnimationUpdate(ValueAnimator animation) { |
||||||
|
currentRotateDegrees = (float) animation.getAnimatedValue(); |
||||||
|
invalidate(); |
||||||
|
} |
||||||
|
}); |
||||||
|
rotateAnimator.start(); |
||||||
|
status = STATUS_PROGRESSING; |
||||||
|
} |
||||||
|
|
||||||
|
private Runnable tickShowRunnable; |
||||||
|
|
||||||
|
public NoArticulatedProgressView whenShowTick(Runnable runnable) { |
||||||
|
tickShowRunnable = runnable; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public void loading() { |
||||||
|
noShowLoading = false; |
||||||
|
oldAnimAngle = 0; |
||||||
|
successStep = 0; |
||||||
|
line1X = 0; |
||||||
|
line1Y = 0; |
||||||
|
line2X = 0; |
||||||
|
line2Y = 0; |
||||||
|
status = STATUS_LOADING; |
||||||
|
if (rotateAnimator != null) rotateAnimator.cancel(); |
||||||
|
if (followAnimator != null) followAnimator.cancel(); |
||||||
|
isInited = false; |
||||||
|
init(null); |
||||||
|
} |
||||||
|
|
||||||
|
public int getStatus() { |
||||||
|
return status; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onDetachedFromWindow() { |
||||||
|
if (rotateAnimator != null) { |
||||||
|
rotateAnimator.cancel(); |
||||||
|
} |
||||||
|
if (followAnimator != null) { |
||||||
|
followAnimator.cancel(); |
||||||
|
} |
||||||
|
super.onDetachedFromWindow(); |
||||||
|
} |
||||||
|
|
||||||
|
public int getStrokeWidth() { |
||||||
|
return width; |
||||||
|
} |
||||||
|
|
||||||
|
public NoArticulatedProgressView setStrokeWidth(int width) { |
||||||
|
this.width = width; |
||||||
|
if (mPaint != null) mPaint.setStrokeWidth(width); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public int getColor() { |
||||||
|
return color; |
||||||
|
} |
||||||
|
|
||||||
|
public NoArticulatedProgressView setColor(int color) { |
||||||
|
this.color = color; |
||||||
|
if (mPaint != null) mPaint.setColor(color); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
private boolean noShowLoading; |
||||||
|
|
||||||
|
public void noLoading() { |
||||||
|
noShowLoading = true; |
||||||
|
} |
||||||
|
|
||||||
|
private int dip2px(float dpValue) { |
||||||
|
final float scale = Resources.getSystem().getDisplayMetrics().density; |
||||||
|
return (int) (dpValue * scale + 0.5f); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,475 @@ |
|||||||
|
package com.kongzue.dialogx.util.views; |
||||||
|
|
||||||
|
import android.animation.TimeInterpolator; |
||||||
|
import android.animation.ValueAnimator; |
||||||
|
import android.content.Context; |
||||||
|
import android.content.res.Resources; |
||||||
|
import android.content.res.TypedArray; |
||||||
|
import android.graphics.Canvas; |
||||||
|
import android.graphics.Color; |
||||||
|
import android.graphics.Paint; |
||||||
|
import android.graphics.RectF; |
||||||
|
import android.util.AttributeSet; |
||||||
|
import android.util.Log; |
||||||
|
import android.view.HapticFeedbackConstants; |
||||||
|
import android.view.View; |
||||||
|
import android.view.animation.AccelerateDecelerateInterpolator; |
||||||
|
import android.view.animation.DecelerateInterpolator; |
||||||
|
import android.view.animation.LinearInterpolator; |
||||||
|
|
||||||
|
import androidx.annotation.Nullable; |
||||||
|
|
||||||
|
import com.kongzue.dialogx.DialogX; |
||||||
|
import com.kongzue.dialogx.R; |
||||||
|
import com.kongzue.dialogx.interfaces.ProgressViewInterface; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author: Kongzue |
||||||
|
* @github: https://github.com/kongzue/
|
||||||
|
* @homepage: http://kongzue.com/
|
||||||
|
* @mail: myzcxhh@live.cn |
||||||
|
* @createTime: 2020/9/27 16:16 |
||||||
|
* @license: Apache License 2.0 |
||||||
|
*/ |
||||||
|
public class ProgressView extends View implements ProgressViewInterface { |
||||||
|
|
||||||
|
public static final int STATUS_LOADING = 0; |
||||||
|
public static final int STATUS_SUCCESS = 1; |
||||||
|
public static final int STATUS_WARNING = 2; |
||||||
|
public static final int STATUS_ERROR = 3; |
||||||
|
public static final int STATUS_PROGRESSING = 4; |
||||||
|
|
||||||
|
private int status = STATUS_LOADING; |
||||||
|
|
||||||
|
private int width = dip2px(2); |
||||||
|
private int color = Color.WHITE; |
||||||
|
|
||||||
|
public ProgressView(Context context) { |
||||||
|
super(context); |
||||||
|
init(null); |
||||||
|
} |
||||||
|
|
||||||
|
public ProgressView(Context context, @Nullable AttributeSet attrs) { |
||||||
|
super(context, attrs); |
||||||
|
init(attrs); |
||||||
|
} |
||||||
|
|
||||||
|
public ProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { |
||||||
|
super(context, attrs, defStyleAttr); |
||||||
|
init(attrs); |
||||||
|
} |
||||||
|
|
||||||
|
public ProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { |
||||||
|
super(context, attrs, defStyleAttr, defStyleRes); |
||||||
|
init(attrs); |
||||||
|
} |
||||||
|
|
||||||
|
private ValueAnimator rotateAnimator; |
||||||
|
private ValueAnimator followAnimator; |
||||||
|
|
||||||
|
private float currentRotateDegrees; |
||||||
|
private float followRotateDegrees; |
||||||
|
|
||||||
|
//跟随点度数做正弦值变化,halfSweepAMinValue为最低相较目标点度数差值,halfSweepAMaxValue为最大相较目标点度数差值
|
||||||
|
private float halfSweepAMaxValue = 180; |
||||||
|
private float halfSweepAMinValue = 80; |
||||||
|
//正弦函数的半径
|
||||||
|
private float halfSweepA; |
||||||
|
|
||||||
|
Paint mPaint = new Paint(); |
||||||
|
|
||||||
|
private boolean isInited = false; |
||||||
|
|
||||||
|
private void init(AttributeSet attrs) { |
||||||
|
synchronized (ProgressView.class) { |
||||||
|
if (isInited) { |
||||||
|
return; |
||||||
|
} |
||||||
|
isInited = true; |
||||||
|
if (attrs != null) { |
||||||
|
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.ProgressView); |
||||||
|
width = a.getDimensionPixelSize(R.styleable.ProgressView_progressStrokeWidth, dip2px(2)); |
||||||
|
color = a.getDimensionPixelSize(R.styleable.ProgressView_progressStrokeColor, color); |
||||||
|
|
||||||
|
a.recycle(); |
||||||
|
} |
||||||
|
|
||||||
|
mPaint.setAntiAlias(true); |
||||||
|
mPaint.setStyle(Paint.Style.STROKE); |
||||||
|
mPaint.setStrokeWidth(width); |
||||||
|
mPaint.setStrokeCap(Paint.Cap.ROUND); |
||||||
|
mPaint.setColor(color); |
||||||
|
|
||||||
|
if (!isInEditMode()) { |
||||||
|
halfSweepA = (halfSweepAMaxValue - halfSweepAMinValue) / 2; |
||||||
|
|
||||||
|
rotateAnimator = ValueAnimator.ofFloat(0, 365); |
||||||
|
rotateAnimator.setDuration(1000); |
||||||
|
rotateAnimator.setInterpolator(new LinearInterpolator()); |
||||||
|
rotateAnimator.setRepeatCount(-1); |
||||||
|
rotateAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { |
||||||
|
@Override |
||||||
|
public void onAnimationUpdate(ValueAnimator animation) { |
||||||
|
currentRotateDegrees = (float) animation.getAnimatedValue(); |
||||||
|
invalidate(); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
followAnimator = ValueAnimator.ofFloat(0, 365); |
||||||
|
followAnimator.setDuration(1500); |
||||||
|
followAnimator.setInterpolator(new LinearInterpolator()); |
||||||
|
followAnimator.setRepeatCount(-1); |
||||||
|
followAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { |
||||||
|
@Override |
||||||
|
public void onAnimationUpdate(ValueAnimator animation) { |
||||||
|
followRotateDegrees = (float) animation.getAnimatedValue(); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
followAnimator.start(); |
||||||
|
rotateAnimator.start(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
//旋转圆的中心坐标
|
||||||
|
private float mCenterX; |
||||||
|
private float mCenterY; |
||||||
|
//半径
|
||||||
|
private float mRadius = 100; |
||||||
|
private RectF oval; |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onSizeChanged(int w, int h, int oldw, int oldh) { |
||||||
|
super.onSizeChanged(w, h, oldw, oldh); |
||||||
|
mCenterX = w * 1f / 2; |
||||||
|
mCenterY = h * 1f / 2; |
||||||
|
mRadius = Math.min(getWidth(), getHeight()) / 2 - width / 2; |
||||||
|
oval = new RectF(mCenterX - mRadius, mCenterY - mRadius, mCenterX + mRadius, mCenterY + mRadius); |
||||||
|
} |
||||||
|
|
||||||
|
protected float oldAnimAngle; |
||||||
|
private int successStep = 0; |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onDraw(Canvas canvas) { |
||||||
|
if (isInEditMode()) { |
||||||
|
canvas.drawArc(oval, 0, 365, false, mPaint); |
||||||
|
return; |
||||||
|
} |
||||||
|
if (noShowLoading) { |
||||||
|
canvas.drawArc(oval, 0, 365, false, mPaint); |
||||||
|
successStep = 2; |
||||||
|
drawDoneMark(status, canvas); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
float sweepAngle = (float) (halfSweepA * Math.sin(Math.toRadians(followRotateDegrees))) + halfSweepA + halfSweepAMinValue / 2; |
||||||
|
switch (status) { |
||||||
|
case STATUS_LOADING: |
||||||
|
canvas.drawArc(oval, currentRotateDegrees, -sweepAngle, false, mPaint); |
||||||
|
break; |
||||||
|
case STATUS_SUCCESS: |
||||||
|
case STATUS_WARNING: |
||||||
|
case STATUS_ERROR: |
||||||
|
switch (successStep) { |
||||||
|
case 0: |
||||||
|
canvas.drawArc(oval, currentRotateDegrees, -sweepAngle, false, mPaint); |
||||||
|
if ((currentRotateDegrees - sweepAngle) > 270) { |
||||||
|
successStep = 1; |
||||||
|
} |
||||||
|
break; |
||||||
|
case 1: |
||||||
|
float aimAngle = currentRotateDegrees > 270 ? currentRotateDegrees - 270 : 90 + currentRotateDegrees; |
||||||
|
canvas.drawArc(oval, 270, aimAngle, false, mPaint); |
||||||
|
if (oldAnimAngle > aimAngle && oldAnimAngle > 300) { |
||||||
|
successStep = 2; |
||||||
|
canvas.drawArc(oval, 0, 360, false, mPaint); |
||||||
|
break; |
||||||
|
} |
||||||
|
oldAnimAngle = aimAngle; |
||||||
|
break; |
||||||
|
case 2: |
||||||
|
canvas.drawArc(oval, 0, 360, false, mPaint); |
||||||
|
drawDoneMark(status, canvas); |
||||||
|
break; |
||||||
|
} |
||||||
|
break; |
||||||
|
case STATUS_PROGRESSING: |
||||||
|
canvas.drawArc(oval, -90, currentRotateDegrees, false, mPaint); |
||||||
|
if (currentRotateDegrees == 365 && waitProgressingRunnable != null) { |
||||||
|
waitProgressingRunnable.run(); |
||||||
|
waitProgressingRunnable = null; |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void drawDoneMark(int status, Canvas canvas) { |
||||||
|
if (rotateAnimator.getInterpolator() != interpolator) { |
||||||
|
rotateAnimator.setInterpolator(interpolator); |
||||||
|
} |
||||||
|
if (tickShowRunnable != null) { |
||||||
|
tickShowRunnable.run(); |
||||||
|
if (DialogX.useHaptic) performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); |
||||||
|
tickShowRunnable = null; |
||||||
|
} |
||||||
|
switch (status) { |
||||||
|
case STATUS_SUCCESS: |
||||||
|
showSuccessTick(canvas); |
||||||
|
break; |
||||||
|
case STATUS_WARNING: |
||||||
|
showWarningTick(canvas); |
||||||
|
break; |
||||||
|
case STATUS_ERROR: |
||||||
|
showErrorTick(canvas); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private int line1X = 0; |
||||||
|
private int line1Y = 0; |
||||||
|
private int line2X = 0; |
||||||
|
private int line2Y = 0; |
||||||
|
|
||||||
|
private int tickStep = 0; |
||||||
|
|
||||||
|
//绘制对号
|
||||||
|
private void showSuccessTick(Canvas canvas) { |
||||||
|
int tickLeftPoint = (int) (mCenterX - mRadius * 1 / 2); |
||||||
|
int tickTurnLeftPoint = (int) (mCenterX - mRadius / 10); |
||||||
|
int tickRightPoint = (int) (mRadius * 0.99f); |
||||||
|
int speed = 2; |
||||||
|
switch (tickStep) { |
||||||
|
case 0: |
||||||
|
if (tickLeftPoint + line1X < tickTurnLeftPoint) { |
||||||
|
line1X = line1X + speed; |
||||||
|
line1Y = line1Y + speed; |
||||||
|
} else { |
||||||
|
line2X = line1X; |
||||||
|
line2Y = line1Y; |
||||||
|
tickStep = 1; |
||||||
|
} |
||||||
|
break; |
||||||
|
case 1: |
||||||
|
if (line2X < tickRightPoint) { |
||||||
|
line2X = line2X + 4; |
||||||
|
line2Y = line2Y - 5; |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
canvas.drawLine(tickLeftPoint, mCenterY, tickLeftPoint + line1X, mCenterY + line1Y, mPaint); |
||||||
|
canvas.drawLine(tickLeftPoint + line1X, mCenterY + line1Y, tickLeftPoint + line2X, mCenterY + line2Y, mPaint); |
||||||
|
|
||||||
|
postInvalidateDelayed(1); |
||||||
|
} |
||||||
|
|
||||||
|
//绘制感叹号
|
||||||
|
private void showWarningTick(Canvas canvas) { |
||||||
|
int tickLeftPoint = (int) mCenterX; |
||||||
|
int line1StartY = (int) (mCenterY - mRadius * 1 / 2); |
||||||
|
int line1EndY = (int) (mCenterY + mRadius * 1 / 8); |
||||||
|
int line2StartY = (int) (mCenterY + mRadius * 3 / 7); |
||||||
|
int speed = 4; |
||||||
|
switch (tickStep) { |
||||||
|
case 0: |
||||||
|
if (line1Y < line1EndY - line1StartY) { |
||||||
|
line1Y = line1Y + speed; |
||||||
|
} else { |
||||||
|
line1Y = line1EndY - line1StartY; |
||||||
|
tickStep = 1; |
||||||
|
} |
||||||
|
break; |
||||||
|
case 1: |
||||||
|
if (line2Y != line2StartY) { |
||||||
|
canvas.drawLine(tickLeftPoint, line2StartY, tickLeftPoint, line2StartY + 1, mPaint); |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
canvas.drawLine(tickLeftPoint, line1StartY, tickLeftPoint, line1StartY + line1Y, mPaint); |
||||||
|
postInvalidateDelayed(tickStep == 1 ? 100 : 1); |
||||||
|
} |
||||||
|
|
||||||
|
//绘制错误符号
|
||||||
|
private void showErrorTick(Canvas canvas) { |
||||||
|
int tickLeftPoint = (int) (mCenterX - mRadius * 4 / 10); |
||||||
|
int tickRightPoint = (int) (mCenterX + mRadius * 4 / 10); |
||||||
|
int tickTopPoint = (int) (mCenterY - mRadius * 4 / 10); |
||||||
|
int speed = 4; |
||||||
|
|
||||||
|
switch (tickStep) { |
||||||
|
case 0: |
||||||
|
if (tickRightPoint - line1X > tickLeftPoint) { |
||||||
|
line1X = line1X + speed; |
||||||
|
line1Y = line1Y + speed; |
||||||
|
} else { |
||||||
|
tickStep = 1; |
||||||
|
canvas.drawLine(tickRightPoint, tickTopPoint, tickRightPoint - line1X, tickTopPoint + line1Y, mPaint); |
||||||
|
postInvalidateDelayed(150); |
||||||
|
return; |
||||||
|
} |
||||||
|
break; |
||||||
|
case 1: |
||||||
|
if (tickLeftPoint + line2X < tickRightPoint) { |
||||||
|
line2X = line2X + speed; |
||||||
|
line2Y = line2Y + speed; |
||||||
|
} |
||||||
|
canvas.drawLine(tickLeftPoint, tickTopPoint, tickLeftPoint + line2X, tickTopPoint + line2Y, mPaint); |
||||||
|
break; |
||||||
|
} |
||||||
|
canvas.drawLine(tickRightPoint, tickTopPoint, tickRightPoint - line1X, tickTopPoint + line1Y, mPaint); |
||||||
|
postInvalidateDelayed(1); |
||||||
|
} |
||||||
|
|
||||||
|
private TimeInterpolator interpolator; |
||||||
|
private Runnable waitProgressingRunnable; |
||||||
|
|
||||||
|
public void success() { |
||||||
|
if (status == STATUS_PROGRESSING) { |
||||||
|
progress(1f); |
||||||
|
waitProgressingRunnable = new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
tickStep = 0; |
||||||
|
successStep = 2; |
||||||
|
interpolator = new AccelerateDecelerateInterpolator(); |
||||||
|
status = STATUS_SUCCESS; |
||||||
|
} |
||||||
|
}; |
||||||
|
return; |
||||||
|
} |
||||||
|
tickStep = 0; |
||||||
|
interpolator = new AccelerateDecelerateInterpolator(); |
||||||
|
status = STATUS_SUCCESS; |
||||||
|
invalidate(); |
||||||
|
} |
||||||
|
|
||||||
|
public void warning() { |
||||||
|
if (status == STATUS_PROGRESSING) { |
||||||
|
progress(1f); |
||||||
|
waitProgressingRunnable = new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
tickStep = 0; |
||||||
|
successStep = 2; |
||||||
|
interpolator = new DecelerateInterpolator(2); |
||||||
|
status = STATUS_WARNING; |
||||||
|
} |
||||||
|
}; |
||||||
|
return; |
||||||
|
} |
||||||
|
tickStep = 0; |
||||||
|
interpolator = new DecelerateInterpolator(2); |
||||||
|
status = STATUS_WARNING; |
||||||
|
invalidate(); |
||||||
|
} |
||||||
|
|
||||||
|
public void error() { |
||||||
|
if (status == STATUS_PROGRESSING) { |
||||||
|
progress(1f); |
||||||
|
waitProgressingRunnable = new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
tickStep = 0; |
||||||
|
successStep = 2; |
||||||
|
interpolator = new DecelerateInterpolator(2); |
||||||
|
status = STATUS_ERROR; |
||||||
|
} |
||||||
|
}; |
||||||
|
return; |
||||||
|
} |
||||||
|
tickStep = 0; |
||||||
|
interpolator = new DecelerateInterpolator(2); |
||||||
|
status = STATUS_ERROR; |
||||||
|
invalidate(); |
||||||
|
} |
||||||
|
|
||||||
|
public void progress(float progress) { |
||||||
|
if (rotateAnimator != null) rotateAnimator.cancel(); |
||||||
|
if (followAnimator != null) followAnimator.cancel(); |
||||||
|
if (status != STATUS_PROGRESSING) { |
||||||
|
currentRotateDegrees = 0; |
||||||
|
} |
||||||
|
rotateAnimator = ValueAnimator.ofFloat(currentRotateDegrees, 365 * progress); |
||||||
|
rotateAnimator.setDuration(1000); |
||||||
|
rotateAnimator.setInterpolator(new DecelerateInterpolator(2)); |
||||||
|
rotateAnimator.setRepeatCount(0); |
||||||
|
rotateAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { |
||||||
|
@Override |
||||||
|
public void onAnimationUpdate(ValueAnimator animation) { |
||||||
|
currentRotateDegrees = (float) animation.getAnimatedValue(); |
||||||
|
invalidate(); |
||||||
|
} |
||||||
|
}); |
||||||
|
rotateAnimator.start(); |
||||||
|
status = STATUS_PROGRESSING; |
||||||
|
} |
||||||
|
|
||||||
|
private Runnable tickShowRunnable; |
||||||
|
|
||||||
|
public ProgressView whenShowTick(Runnable runnable) { |
||||||
|
tickShowRunnable = runnable; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public void loading() { |
||||||
|
noShowLoading = false; |
||||||
|
oldAnimAngle = 0; |
||||||
|
successStep = 0; |
||||||
|
line1X = 0; |
||||||
|
line1Y = 0; |
||||||
|
line2X = 0; |
||||||
|
line2Y = 0; |
||||||
|
status = STATUS_LOADING; |
||||||
|
if (rotateAnimator != null) rotateAnimator.cancel(); |
||||||
|
if (followAnimator != null) followAnimator.cancel(); |
||||||
|
isInited = false; |
||||||
|
init(null); |
||||||
|
} |
||||||
|
|
||||||
|
public int getStatus() { |
||||||
|
return status; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onDetachedFromWindow() { |
||||||
|
if (rotateAnimator != null) { |
||||||
|
rotateAnimator.cancel(); |
||||||
|
} |
||||||
|
if (followAnimator != null) { |
||||||
|
followAnimator.cancel(); |
||||||
|
} |
||||||
|
super.onDetachedFromWindow(); |
||||||
|
} |
||||||
|
|
||||||
|
public int getStrokeWidth() { |
||||||
|
return width; |
||||||
|
} |
||||||
|
|
||||||
|
public ProgressView setStrokeWidth(int width) { |
||||||
|
this.width = width; |
||||||
|
if (mPaint != null) mPaint.setStrokeWidth(width); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public int getColor() { |
||||||
|
return color; |
||||||
|
} |
||||||
|
|
||||||
|
public ProgressView setColor(int color) { |
||||||
|
this.color = color; |
||||||
|
if (mPaint != null) mPaint.setColor(color); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
private boolean noShowLoading; |
||||||
|
|
||||||
|
public void noLoading() { |
||||||
|
noShowLoading = true; |
||||||
|
} |
||||||
|
|
||||||
|
private int dip2px(float dpValue) { |
||||||
|
final float scale = Resources.getSystem().getDisplayMetrics().density; |
||||||
|
return (int) (dpValue * scale + 0.5f); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,56 @@ |
|||||||
|
package com.kongzue.dialogx.util.views; |
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.graphics.Canvas; |
||||||
|
import android.graphics.Path; |
||||||
|
import android.graphics.Rect; |
||||||
|
import android.graphics.RectF; |
||||||
|
import android.util.AttributeSet; |
||||||
|
import android.widget.RelativeLayout; |
||||||
|
|
||||||
|
public class RoundView extends RelativeLayout { |
||||||
|
|
||||||
|
private float mRadius = 0; |
||||||
|
private Path mBoundPath = null; |
||||||
|
|
||||||
|
public RoundView(Context context) { |
||||||
|
this(context, null); |
||||||
|
} |
||||||
|
|
||||||
|
public RoundView(Context context, AttributeSet attrs) { |
||||||
|
this(context, attrs, 0); |
||||||
|
} |
||||||
|
|
||||||
|
public RoundView(Context context, AttributeSet attrs, int defStyleAttr) { |
||||||
|
super(context, attrs, defStyleAttr); |
||||||
|
setWillNotDraw(false); |
||||||
|
mRadius = 50; |
||||||
|
} |
||||||
|
|
||||||
|
public void setRadius(float radius) { |
||||||
|
if (mRadius == radius) |
||||||
|
return; |
||||||
|
this.mRadius = radius; |
||||||
|
postInvalidate(); |
||||||
|
} |
||||||
|
|
||||||
|
public float getRadius() { |
||||||
|
return mRadius; |
||||||
|
} |
||||||
|
|
||||||
|
public void draw(Canvas canvas) { |
||||||
|
Rect rect = new Rect(); |
||||||
|
getLocalVisibleRect(rect); |
||||||
|
mBoundPath = caculateRoundRectPath(rect); |
||||||
|
canvas.clipPath(mBoundPath); |
||||||
|
super.draw(canvas); |
||||||
|
} |
||||||
|
|
||||||
|
private Path caculateRoundRectPath(Rect r) { |
||||||
|
Path path = new Path(); |
||||||
|
float radius = getRadius(); |
||||||
|
float elevation = 0; |
||||||
|
path.addRoundRect(new RectF(r.left + elevation, r.top + elevation, r.right - elevation, r.bottom - elevation), radius, radius, Path.Direction.CW); |
||||||
|
return path; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,11 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android"> |
||||||
|
<translate |
||||||
|
android:duration="300" |
||||||
|
android:fromYDelta="100%p" |
||||||
|
android:toYDelta="0" /> |
||||||
|
<alpha |
||||||
|
android:duration="300" |
||||||
|
android:fromAlpha="0.0" |
||||||
|
android:toAlpha="1.0" /> |
||||||
|
</set> |
@ -0,0 +1,11 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android"> |
||||||
|
<translate |
||||||
|
android:duration="300" |
||||||
|
android:fromYDelta="0" |
||||||
|
android:toYDelta="100%p"/> |
||||||
|
<alpha |
||||||
|
android:duration="300" |
||||||
|
android:fromAlpha="1.0" |
||||||
|
android:toAlpha="0.0"/> |
||||||
|
</set> |
@ -0,0 +1,8 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android"> |
||||||
|
|
||||||
|
<alpha |
||||||
|
android:duration="300" |
||||||
|
android:fromAlpha="0.0" |
||||||
|
android:toAlpha="1.0" /> |
||||||
|
</set> |
@ -0,0 +1,17 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android"> |
||||||
|
|
||||||
|
<scale |
||||||
|
android:duration="300" |
||||||
|
android:fromXScale="0.9" |
||||||
|
android:fromYScale="0.9" |
||||||
|
android:pivotX="50%" |
||||||
|
android:pivotY="60%" |
||||||
|
android:toXScale="1.0" |
||||||
|
android:toYScale="1.0" /> |
||||||
|
|
||||||
|
<alpha |
||||||
|
android:duration="300" |
||||||
|
android:fromAlpha="0.0" |
||||||
|
android:toAlpha="1.0" /> |
||||||
|
</set> |
@ -0,0 +1,9 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android"> |
||||||
|
|
||||||
|
<alpha |
||||||
|
android:duration="300" |
||||||
|
android:fromAlpha="1.0" |
||||||
|
android:toAlpha="0.0" /> |
||||||
|
|
||||||
|
</set> |
@ -0,0 +1,11 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android"> |
||||||
|
<translate |
||||||
|
android:duration="300" |
||||||
|
android:fromXDelta="-100%p" |
||||||
|
android:toXDelta="0" /> |
||||||
|
<alpha |
||||||
|
android:duration="300" |
||||||
|
android:fromAlpha="0.0" |
||||||
|
android:toAlpha="1.0" /> |
||||||
|
</set> |
@ -0,0 +1,11 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android"> |
||||||
|
<translate |
||||||
|
android:duration="300" |
||||||
|
android:fromXDelta="0" |
||||||
|
android:toXDelta="-100%p"/> |
||||||
|
<alpha |
||||||
|
android:duration="300" |
||||||
|
android:fromAlpha="1.0" |
||||||
|
android:toAlpha="0.0"/> |
||||||
|
</set> |
@ -0,0 +1,11 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android"> |
||||||
|
<translate |
||||||
|
android:duration="300" |
||||||
|
android:fromXDelta="100%p" |
||||||
|
android:toXDelta="0" /> |
||||||
|
<alpha |
||||||
|
android:duration="300" |
||||||
|
android:fromAlpha="0.0" |
||||||
|
android:toAlpha="1.0" /> |
||||||
|
</set> |
@ -0,0 +1,11 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android"> |
||||||
|
<translate |
||||||
|
android:duration="300" |
||||||
|
android:fromXDelta="0" |
||||||
|
android:toXDelta="100%p"/> |
||||||
|
<alpha |
||||||
|
android:duration="300" |
||||||
|
android:fromAlpha="1.0" |
||||||
|
android:toAlpha="0.0"/> |
||||||
|
</set> |
@ -0,0 +1,11 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android"> |
||||||
|
<translate |
||||||
|
android:duration="300" |
||||||
|
android:fromYDelta="-100%p" |
||||||
|
android:toYDelta="0" /> |
||||||
|
<alpha |
||||||
|
android:duration="300" |
||||||
|
android:fromAlpha="0.0" |
||||||
|
android:toAlpha="1.0" /> |
||||||
|
</set> |
@ -0,0 +1,11 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android"> |
||||||
|
<translate |
||||||
|
android:duration="300" |
||||||
|
android:fromYDelta="0" |
||||||
|
android:toYDelta="-100%p"/> |
||||||
|
<alpha |
||||||
|
android:duration="300" |
||||||
|
android:fromAlpha="1.0" |
||||||
|
android:toAlpha="0.0"/> |
||||||
|
</set> |
@ -0,0 +1,7 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<ripple xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
xmlns:tools="http://schemas.android.com/tools" |
||||||
|
android:color="@color/black10"> |
||||||
|
|
||||||
|
<item android:drawable="@drawable/rect_dialogx_material_button_light_forword"/> |
||||||
|
</ripple> |
@ -0,0 +1,7 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<ripple xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
xmlns:tools="http://schemas.android.com/tools" |
||||||
|
android:color="@color/white10"> |
||||||
|
|
||||||
|
<item android:drawable="@drawable/rect_dialogx_material_button_night_forword"/> |
||||||
|
</ripple> |
@ -0,0 +1,6 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
android:shape="rectangle"> |
||||||
|
<solid android:color="@color/white"/> |
||||||
|
<corners android:radius="10dp" /> |
||||||
|
</shape> |
@ -0,0 +1,6 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
android:shape="rectangle"> |
||||||
|
<solid android:color="@color/dialogxMaterialDarkDialogBkgColor"/> |
||||||
|
<corners android:radius="10dp" /> |
||||||
|
</shape> |
@ -0,0 +1,11 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
android:shape="rectangle"> |
||||||
|
<!--left to right--> |
||||||
|
<solid |
||||||
|
android:color="@color/white"/> |
||||||
|
|
||||||
|
<corners |
||||||
|
android:topRightRadius="10dp" |
||||||
|
android:topLeftRadius="10dp"/> |
||||||
|
</shape> |
@ -0,0 +1,11 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
android:shape="rectangle"> |
||||||
|
<!--left to right--> |
||||||
|
<solid |
||||||
|
android:color="@color/dialogxMaterialDarkDialogBkgColor"/> |
||||||
|
|
||||||
|
<corners |
||||||
|
android:topRightRadius="10dp" |
||||||
|
android:topLeftRadius="10dp"/> |
||||||
|
</shape> |
@ -0,0 +1,6 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
android:shape="rectangle"> |
||||||
|
<solid android:color="@color/white"/> |
||||||
|
<corners android:radius="3dp" /> |
||||||
|
</shape> |
@ -0,0 +1,6 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
android:shape="rectangle"> |
||||||
|
<solid android:color="@color/dialogxMaterialDarkDialogBkgColor"/> |
||||||
|
<corners android:radius="3dp" /> |
||||||
|
</shape> |
@ -0,0 +1,6 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
android:shape="rectangle"> |
||||||
|
<solid android:color="@color/black10"/> |
||||||
|
<corners android:radius="99dp" /> |
||||||
|
</shape> |
@ -0,0 +1,6 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
android:shape="rectangle"> |
||||||
|
<solid android:color="@color/white10"/> |
||||||
|
<corners android:radius="99dp" /> |
||||||
|
</shape> |
@ -0,0 +1,12 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" > |
||||||
|
|
||||||
|
<item |
||||||
|
android:left="15dp" |
||||||
|
android:right="15dp"> |
||||||
|
<shape android:shape="rectangle" > |
||||||
|
<solid android:color="@color/black10" /> |
||||||
|
</shape> |
||||||
|
</item> |
||||||
|
|
||||||
|
</layer-list> |
@ -0,0 +1,12 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" > |
||||||
|
|
||||||
|
<item |
||||||
|
android:left="25dp" |
||||||
|
android:right="25dp"> |
||||||
|
<shape android:shape="rectangle" > |
||||||
|
<solid android:color="@color/white10" /> |
||||||
|
</shape> |
||||||
|
</item> |
||||||
|
|
||||||
|
</layer-list> |
@ -0,0 +1,10 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
android:shape="rectangle"> |
||||||
|
<!--left to right--> |
||||||
|
<solid |
||||||
|
android:color="@color/white"/> |
||||||
|
|
||||||
|
<corners |
||||||
|
android:radius="5dp"/> |
||||||
|
</shape> |
@ -0,0 +1,10 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
android:shape="rectangle"> |
||||||
|
<!--left to right--> |
||||||
|
<solid |
||||||
|
android:color="@color/dialogxMaterialDarkDialogBkgColor"/> |
||||||
|
|
||||||
|
<corners |
||||||
|
android:radius="5dp"/> |
||||||
|
</shape> |
@ -0,0 +1,43 @@ |
|||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content"> |
||||||
|
|
||||||
|
<LinearLayout |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="55dp" |
||||||
|
android:gravity="center_vertical" |
||||||
|
android:paddingLeft="20dp" |
||||||
|
android:paddingRight="20dp"> |
||||||
|
|
||||||
|
<ImageView |
||||||
|
android:id="@+id/img_dialogx_menu_icon" |
||||||
|
android:layout_width="35dp" |
||||||
|
android:layout_height="35dp" |
||||||
|
android:layout_marginLeft="-5dp" |
||||||
|
android:layout_marginRight="10dp" |
||||||
|
android:padding="5dp" /> |
||||||
|
|
||||||
|
<ImageView |
||||||
|
android:id="@+id/img_dialogx_menu_selection" |
||||||
|
android:layout_width="35dp" |
||||||
|
android:layout_height="35dp" |
||||||
|
android:layout_centerVertical="true" |
||||||
|
android:layout_marginLeft="-5dp" |
||||||
|
android:layout_marginRight="10dp" |
||||||
|
android:padding="5dp" |
||||||
|
android:src="@mipmap/img_dialogx_bottom_menu_material_item_selection" /> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/txt_dialogx_menu_text" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_weight="1" |
||||||
|
android:gravity="left|center_vertical" |
||||||
|
android:maxLines="1" |
||||||
|
android:text="" |
||||||
|
android:textColor="@color/black90" |
||||||
|
android:textSize="16dp" /> |
||||||
|
|
||||||
|
</LinearLayout> |
||||||
|
|
||||||
|
</RelativeLayout> |
@ -0,0 +1,161 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<com.kongzue.dialogx.util.views.DialogXBaseRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto" |
||||||
|
android:id="@+id/box_root" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="match_parent" |
||||||
|
android:background="@color/black20" |
||||||
|
android:orientation="vertical"> |
||||||
|
|
||||||
|
<RelativeLayout |
||||||
|
android:id="@+id/box_bkg" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="match_parent"> |
||||||
|
|
||||||
|
<com.kongzue.dialogx.util.views.MaxRelativeLayout |
||||||
|
android:id="@+id/bkg" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_alignParentBottom="true" |
||||||
|
android:background="@drawable/rect_dialogx_material_bottom_bkg_light" |
||||||
|
android:clickable="true" |
||||||
|
android:focusableInTouchMode="true"> |
||||||
|
|
||||||
|
<ImageView |
||||||
|
android:id="@+id/img_tab" |
||||||
|
android:layout_width="30dp" |
||||||
|
android:layout_height="4dp" |
||||||
|
android:layout_centerHorizontal="true" |
||||||
|
android:layout_marginTop="10dp" |
||||||
|
android:src="@drawable/rect_dialogx_material_dialogtap" /> |
||||||
|
|
||||||
|
<LinearLayout |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:orientation="vertical" |
||||||
|
android:paddingTop="15dp"> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/txt_dialog_title" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_gravity="center_horizontal" |
||||||
|
android:gravity="center_vertical" |
||||||
|
android:paddingLeft="20dp" |
||||||
|
android:paddingRight="20dp" |
||||||
|
android:paddingBottom="10dp" |
||||||
|
android:text="Title" |
||||||
|
android:textColor="@color/black" |
||||||
|
android:textSize="21dp" /> |
||||||
|
|
||||||
|
<com.kongzue.dialogx.util.views.BottomDialogScrollView |
||||||
|
android:id="@+id/scrollView" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_weight="1" |
||||||
|
android:overScrollMode="never" |
||||||
|
android:scrollbarSize="7dp" |
||||||
|
android:scrollbars="vertical"> |
||||||
|
|
||||||
|
<LinearLayout |
||||||
|
android:id="@+id/box_content" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:orientation="vertical"> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/txt_dialog_tip" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_marginLeft="20dp" |
||||||
|
android:layout_marginRight="20dp" |
||||||
|
android:layout_marginBottom="5dp" |
||||||
|
android:paddingBottom="5dp" |
||||||
|
android:text="This is content text." |
||||||
|
android:textColor="@color/black70" |
||||||
|
android:textSize="16dp" /> |
||||||
|
|
||||||
|
<RelativeLayout |
||||||
|
android:id="@+id/box_custom" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" /> |
||||||
|
|
||||||
|
<RelativeLayout |
||||||
|
android:id="@+id/box_list" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" /> |
||||||
|
|
||||||
|
</LinearLayout> |
||||||
|
|
||||||
|
</com.kongzue.dialogx.util.views.BottomDialogScrollView> |
||||||
|
|
||||||
|
<LinearLayout |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_gravity="center_horizontal" |
||||||
|
android:gravity="right|center_vertical" |
||||||
|
android:orientation="horizontal" |
||||||
|
android:paddingLeft="10dp" |
||||||
|
android:paddingRight="10dp"> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/btn_selectOther" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="36dp" |
||||||
|
android:layout_marginTop="10dp" |
||||||
|
android:layout_marginBottom="10dp" |
||||||
|
android:background="@drawable/button_dialogx_material_light" |
||||||
|
android:clickable="true" |
||||||
|
android:gravity="center" |
||||||
|
android:paddingLeft="15dp" |
||||||
|
android:paddingRight="15dp" |
||||||
|
android:text="Other" |
||||||
|
android:textColor="@color/colorAccent" |
||||||
|
android:textSize="15dp" |
||||||
|
android:visibility="gone" /> |
||||||
|
|
||||||
|
<Space |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_weight="1" /> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/btn_selectNegative" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="36dp" |
||||||
|
android:layout_marginTop="10dp" |
||||||
|
android:layout_marginBottom="10dp" |
||||||
|
android:background="@drawable/button_dialogx_material_light" |
||||||
|
android:clickable="true" |
||||||
|
android:gravity="center" |
||||||
|
android:paddingLeft="15dp" |
||||||
|
android:paddingRight="15dp" |
||||||
|
android:tag="cancel" |
||||||
|
android:text="Cancel" |
||||||
|
android:textColor="@color/colorAccent" |
||||||
|
android:textSize="15dp" /> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/btn_selectPositive" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="36dp" |
||||||
|
android:layout_marginTop="10dp" |
||||||
|
android:layout_marginBottom="10dp" |
||||||
|
android:background="@drawable/button_dialogx_material_light" |
||||||
|
android:clickable="true" |
||||||
|
android:gravity="center" |
||||||
|
android:paddingLeft="15dp" |
||||||
|
android:paddingRight="15dp" |
||||||
|
android:text="OK" |
||||||
|
android:textColor="@color/colorAccent" |
||||||
|
android:textSize="15dp" /> |
||||||
|
|
||||||
|
</LinearLayout> |
||||||
|
|
||||||
|
</LinearLayout> |
||||||
|
|
||||||
|
</com.kongzue.dialogx.util.views.MaxRelativeLayout> |
||||||
|
|
||||||
|
</RelativeLayout> |
||||||
|
|
||||||
|
</com.kongzue.dialogx.util.views.DialogXBaseRelativeLayout> |
@ -0,0 +1,161 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<com.kongzue.dialogx.util.views.DialogXBaseRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
android:id="@+id/box_root" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="match_parent" |
||||||
|
android:background="@color/black40" |
||||||
|
android:orientation="vertical"> |
||||||
|
|
||||||
|
<RelativeLayout |
||||||
|
android:id="@+id/box_bkg" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="match_parent"> |
||||||
|
|
||||||
|
<com.kongzue.dialogx.util.views.MaxRelativeLayout |
||||||
|
android:id="@+id/bkg" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_alignParentBottom="true" |
||||||
|
android:background="@drawable/rect_dialogx_material_bottom_bkg_night" |
||||||
|
android:clickable="true" |
||||||
|
android:focusableInTouchMode="true"> |
||||||
|
|
||||||
|
<ImageView |
||||||
|
android:id="@+id/img_tab" |
||||||
|
android:layout_width="30dp" |
||||||
|
android:layout_height="4dp" |
||||||
|
android:layout_centerHorizontal="true" |
||||||
|
android:layout_marginTop="10dp" |
||||||
|
android:layout_marginBottom="1dp" |
||||||
|
android:src="@drawable/rect_dialogx_material_dialogtap_night" /> |
||||||
|
|
||||||
|
<LinearLayout |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:orientation="vertical" |
||||||
|
android:paddingTop="15dp"> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/txt_dialog_title" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_gravity="center_horizontal" |
||||||
|
android:gravity="center_vertical" |
||||||
|
android:paddingLeft="20dp" |
||||||
|
android:paddingRight="20dp" |
||||||
|
android:paddingBottom="10dp" |
||||||
|
android:text="Title" |
||||||
|
android:textColor="@color/white" |
||||||
|
android:textSize="21dp" /> |
||||||
|
|
||||||
|
<com.kongzue.dialogx.util.views.BottomDialogScrollView |
||||||
|
android:id="@+id/scrollView" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_weight="1" |
||||||
|
android:overScrollMode="never" |
||||||
|
android:scrollbarSize="7dp" |
||||||
|
android:scrollbars="vertical"> |
||||||
|
|
||||||
|
<LinearLayout |
||||||
|
android:id="@+id/box_content" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:orientation="vertical"> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/txt_dialog_tip" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_marginLeft="20dp" |
||||||
|
android:layout_marginRight="20dp" |
||||||
|
android:layout_marginBottom="5dp" |
||||||
|
android:paddingBottom="5dp" |
||||||
|
android:text="This is content text." |
||||||
|
android:textColor="@color/white60" |
||||||
|
android:textSize="16dp" /> |
||||||
|
|
||||||
|
<RelativeLayout |
||||||
|
android:id="@+id/box_custom" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" /> |
||||||
|
|
||||||
|
<RelativeLayout |
||||||
|
android:id="@+id/box_list" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" /> |
||||||
|
|
||||||
|
</LinearLayout> |
||||||
|
|
||||||
|
</com.kongzue.dialogx.util.views.BottomDialogScrollView> |
||||||
|
|
||||||
|
<LinearLayout |
||||||
|
android:id="@+id/box_button" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_gravity="center_horizontal" |
||||||
|
android:gravity="right|center_vertical" |
||||||
|
android:orientation="horizontal" |
||||||
|
android:paddingLeft="10dp" |
||||||
|
android:paddingRight="10dp"> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="36dp" |
||||||
|
android:layout_marginTop="10dp" |
||||||
|
android:layout_marginBottom="10dp" |
||||||
|
android:background="@drawable/button_dialogx_material_night" |
||||||
|
android:clickable="true" |
||||||
|
android:gravity="center" |
||||||
|
android:paddingLeft="15dp" |
||||||
|
android:paddingRight="15dp" |
||||||
|
android:text="Other" |
||||||
|
android:textColor="@color/colorAccent" |
||||||
|
android:textSize="15dp" |
||||||
|
android:visibility="gone" /> |
||||||
|
|
||||||
|
<Space |
||||||
|
android:id="@+id/space_other_button" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_weight="1" /> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="36dp" |
||||||
|
android:layout_marginTop="10dp" |
||||||
|
android:layout_marginBottom="10dp" |
||||||
|
android:background="@drawable/button_dialogx_material_night" |
||||||
|
android:clickable="true" |
||||||
|
android:gravity="center" |
||||||
|
android:paddingLeft="15dp" |
||||||
|
android:paddingRight="15dp" |
||||||
|
android:tag="cancel" |
||||||
|
android:text="Cancel" |
||||||
|
android:textColor="@color/colorAccent" |
||||||
|
android:textSize="15dp" /> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/btn_selectPositive" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="36dp" |
||||||
|
android:layout_marginTop="10dp" |
||||||
|
android:layout_marginBottom="10dp" |
||||||
|
android:background="@drawable/button_dialogx_material_night" |
||||||
|
android:clickable="true" |
||||||
|
android:gravity="center" |
||||||
|
android:paddingLeft="15dp" |
||||||
|
android:paddingRight="15dp" |
||||||
|
android:text="OK" |
||||||
|
android:textColor="@color/colorAccent" |
||||||
|
android:textSize="15dp" /> |
||||||
|
|
||||||
|
</LinearLayout> |
||||||
|
|
||||||
|
</LinearLayout> |
||||||
|
|
||||||
|
</com.kongzue.dialogx.util.views.MaxRelativeLayout> |
||||||
|
|
||||||
|
</RelativeLayout> |
||||||
|
|
||||||
|
</com.kongzue.dialogx.util.views.DialogXBaseRelativeLayout> |
@ -0,0 +1,17 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<com.kongzue.dialogx.util.views.DialogXBaseRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
android:id="@+id/box_root" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="match_parent" |
||||||
|
android:orientation="vertical"> |
||||||
|
|
||||||
|
<RelativeLayout |
||||||
|
android:id="@+id/box_custom" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_centerInParent="true" |
||||||
|
android:clickable="true"> |
||||||
|
|
||||||
|
</RelativeLayout> |
||||||
|
|
||||||
|
</com.kongzue.dialogx.util.views.DialogXBaseRelativeLayout> |
@ -0,0 +1,47 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="match_parent" |
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto" |
||||||
|
android:background="@color/black"> |
||||||
|
|
||||||
|
<com.kongzue.dialogx.util.views.ActivityScreenShotImageView |
||||||
|
android:id="@+id/img_zoom_activity" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="match_parent" |
||||||
|
android:layout_centerInParent="true" /> |
||||||
|
|
||||||
|
<com.kongzue.dialogx.util.views.DialogXBaseRelativeLayout |
||||||
|
android:id="@+id/box_root" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="match_parent" |
||||||
|
android:background="@color/black20" |
||||||
|
android:orientation="vertical"> |
||||||
|
|
||||||
|
<RelativeLayout |
||||||
|
android:id="@+id/box_bkg" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="match_parent"> |
||||||
|
|
||||||
|
<com.kongzue.dialogx.util.views.MaxRelativeLayout |
||||||
|
android:id="@+id/bkg" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="match_parent" |
||||||
|
android:layout_alignParentBottom="true" |
||||||
|
android:background="@drawable/rect_dialogx_material_bottom_bkg_light" |
||||||
|
android:focusableInTouchMode="true"> |
||||||
|
|
||||||
|
<RelativeLayout |
||||||
|
android:id="@+id/box_custom" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:clickable="true" |
||||||
|
android:orientation="vertical"/> |
||||||
|
|
||||||
|
</com.kongzue.dialogx.util.views.MaxRelativeLayout> |
||||||
|
|
||||||
|
</RelativeLayout> |
||||||
|
|
||||||
|
</com.kongzue.dialogx.util.views.DialogXBaseRelativeLayout> |
||||||
|
|
||||||
|
</RelativeLayout> |
@ -0,0 +1,47 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="match_parent" |
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto" |
||||||
|
android:background="@color/black"> |
||||||
|
|
||||||
|
<com.kongzue.dialogx.util.views.ActivityScreenShotImageView |
||||||
|
android:id="@+id/img_zoom_activity" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="match_parent" |
||||||
|
android:layout_centerInParent="true" /> |
||||||
|
|
||||||
|
<com.kongzue.dialogx.util.views.DialogXBaseRelativeLayout |
||||||
|
android:id="@+id/box_root" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="match_parent" |
||||||
|
android:background="@color/black20" |
||||||
|
android:orientation="vertical"> |
||||||
|
|
||||||
|
<RelativeLayout |
||||||
|
android:id="@+id/box_bkg" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="match_parent"> |
||||||
|
|
||||||
|
<com.kongzue.dialogx.util.views.MaxRelativeLayout |
||||||
|
android:id="@+id/bkg" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="match_parent" |
||||||
|
android:layout_alignParentBottom="true" |
||||||
|
android:background="@drawable/rect_dialogx_material_bottom_bkg_night" |
||||||
|
android:focusableInTouchMode="true"> |
||||||
|
|
||||||
|
<RelativeLayout |
||||||
|
android:id="@+id/box_custom" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:clickable="true" |
||||||
|
android:orientation="vertical"/> |
||||||
|
|
||||||
|
</com.kongzue.dialogx.util.views.MaxRelativeLayout> |
||||||
|
|
||||||
|
</RelativeLayout> |
||||||
|
|
||||||
|
</com.kongzue.dialogx.util.views.DialogXBaseRelativeLayout> |
||||||
|
|
||||||
|
</RelativeLayout> |
@ -0,0 +1,160 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<com.kongzue.dialogx.util.views.DialogXBaseRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
android:id="@+id/box_root" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="match_parent" |
||||||
|
android:background="@color/black20" |
||||||
|
android:orientation="vertical"> |
||||||
|
|
||||||
|
<RelativeLayout |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="match_parent"> |
||||||
|
|
||||||
|
<com.kongzue.dialogx.util.views.MaxRelativeLayout |
||||||
|
android:id="@+id/bkg" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_centerInParent="true" |
||||||
|
android:layout_marginLeft="35dp" |
||||||
|
android:layout_marginRight="35dp" |
||||||
|
android:background="@drawable/rect_dialogx_material_bkg_light" |
||||||
|
android:elevation="27dp"> |
||||||
|
|
||||||
|
<LinearLayout |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:clickable="true" |
||||||
|
android:orientation="vertical"> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/txt_dialog_title" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_gravity="center_horizontal" |
||||||
|
android:gravity="center_vertical" |
||||||
|
android:paddingLeft="20dp" |
||||||
|
android:paddingTop="15dp" |
||||||
|
android:paddingRight="20dp" |
||||||
|
android:paddingBottom="15dp" |
||||||
|
android:text="Title" |
||||||
|
android:textColor="@color/black" |
||||||
|
android:textSize="21dp" /> |
||||||
|
|
||||||
|
<ScrollView |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_weight="1" |
||||||
|
android:overScrollMode="never"> |
||||||
|
|
||||||
|
<LinearLayout |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:orientation="vertical"> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/txt_dialog_tip" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_gravity="center_horizontal" |
||||||
|
android:layout_marginLeft="20dp" |
||||||
|
android:layout_marginRight="20dp" |
||||||
|
android:text="This is content text." |
||||||
|
android:textColor="@color/black70" |
||||||
|
android:textSize="16dp" /> |
||||||
|
|
||||||
|
<RelativeLayout |
||||||
|
android:id="@+id/box_custom" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:visibility="gone" /> |
||||||
|
|
||||||
|
<EditText |
||||||
|
android:id="@+id/txt_input" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_gravity="center_horizontal" |
||||||
|
android:layout_marginLeft="20dp" |
||||||
|
android:layout_marginTop="10dp" |
||||||
|
android:layout_marginRight="20dp" |
||||||
|
android:inputType="text" |
||||||
|
android:maxLines="1" |
||||||
|
android:paddingTop="10dp" |
||||||
|
android:paddingBottom="10dp" |
||||||
|
android:scrollbars="vertical" |
||||||
|
android:text="" |
||||||
|
android:textColor="@color/black90" |
||||||
|
android:textSize="18dp" |
||||||
|
android:theme="@style/DialogXCompatThemeLight" /> |
||||||
|
|
||||||
|
</LinearLayout> |
||||||
|
|
||||||
|
</ScrollView> |
||||||
|
|
||||||
|
<LinearLayout |
||||||
|
android:id="@+id/box_button" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_gravity="center_horizontal" |
||||||
|
android:layout_marginTop="5dp" |
||||||
|
android:gravity="right|center_vertical" |
||||||
|
android:orientation="horizontal" |
||||||
|
android:paddingLeft="10dp" |
||||||
|
android:paddingTop="10dp" |
||||||
|
android:paddingRight="10dp" |
||||||
|
android:paddingBottom="10dp"> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/btn_selectOther" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="36dp" |
||||||
|
android:background="@drawable/button_dialogx_material_light" |
||||||
|
android:clickable="true" |
||||||
|
android:gravity="center" |
||||||
|
android:paddingLeft="15dp" |
||||||
|
android:paddingRight="15dp" |
||||||
|
android:text="Other" |
||||||
|
android:textColor="@color/colorAccent" |
||||||
|
android:textSize="15dp" |
||||||
|
android:visibility="gone" /> |
||||||
|
|
||||||
|
<Space |
||||||
|
android:id="@+id/space_other_button" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_weight="1" /> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/btn_selectNegative" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="36dp" |
||||||
|
android:background="@drawable/button_dialogx_material_light" |
||||||
|
android:clickable="true" |
||||||
|
android:gravity="center" |
||||||
|
android:paddingLeft="15dp" |
||||||
|
android:paddingRight="15dp" |
||||||
|
android:text="Cancel" |
||||||
|
android:textColor="@color/colorAccent" |
||||||
|
android:textSize="15dp" /> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/btn_selectPositive" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="36dp" |
||||||
|
android:background="@drawable/button_dialogx_material_light" |
||||||
|
android:clickable="true" |
||||||
|
android:gravity="center" |
||||||
|
android:paddingLeft="15dp" |
||||||
|
android:paddingRight="15dp" |
||||||
|
android:text="OK" |
||||||
|
android:textColor="@color/colorAccent" |
||||||
|
android:textSize="15dp" /> |
||||||
|
|
||||||
|
</LinearLayout> |
||||||
|
|
||||||
|
</LinearLayout> |
||||||
|
|
||||||
|
</com.kongzue.dialogx.util.views.MaxRelativeLayout> |
||||||
|
|
||||||
|
</RelativeLayout> |
||||||
|
|
||||||
|
</com.kongzue.dialogx.util.views.DialogXBaseRelativeLayout> |
@ -0,0 +1,160 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<com.kongzue.dialogx.util.views.DialogXBaseRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
android:id="@+id/box_root" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="match_parent" |
||||||
|
android:background="@color/black40" |
||||||
|
android:orientation="vertical"> |
||||||
|
|
||||||
|
<RelativeLayout |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="match_parent"> |
||||||
|
|
||||||
|
<com.kongzue.dialogx.util.views.MaxRelativeLayout |
||||||
|
android:id="@+id/bkg" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_centerInParent="true" |
||||||
|
android:layout_marginLeft="35dp" |
||||||
|
android:layout_marginRight="35dp" |
||||||
|
android:background="@drawable/rect_dialogx_material_bkg_night" |
||||||
|
android:elevation="27dp"> |
||||||
|
|
||||||
|
<LinearLayout |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:clickable="true" |
||||||
|
android:orientation="vertical"> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/txt_dialog_title" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_gravity="center_horizontal" |
||||||
|
android:gravity="center_vertical" |
||||||
|
android:paddingLeft="20dp" |
||||||
|
android:paddingTop="15dp" |
||||||
|
android:paddingRight="20dp" |
||||||
|
android:paddingBottom="15dp" |
||||||
|
android:text="Title" |
||||||
|
android:textColor="@color/white" |
||||||
|
android:textSize="21dp" /> |
||||||
|
|
||||||
|
<ScrollView |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_weight="1" |
||||||
|
android:overScrollMode="never"> |
||||||
|
|
||||||
|
<LinearLayout |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:orientation="vertical"> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/txt_dialog_tip" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_gravity="center_horizontal" |
||||||
|
android:layout_marginLeft="20dp" |
||||||
|
android:layout_marginRight="20dp" |
||||||
|
android:text="This is content text." |
||||||
|
android:textColor="@color/white60" |
||||||
|
android:textSize="16dp" /> |
||||||
|
|
||||||
|
<RelativeLayout |
||||||
|
android:id="@+id/box_custom" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:visibility="gone" /> |
||||||
|
|
||||||
|
<EditText |
||||||
|
android:id="@+id/txt_input" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_gravity="center_horizontal" |
||||||
|
android:layout_marginLeft="20dp" |
||||||
|
android:layout_marginTop="10dp" |
||||||
|
android:layout_marginRight="20dp" |
||||||
|
android:inputType="text" |
||||||
|
android:maxLines="1" |
||||||
|
android:paddingTop="10dp" |
||||||
|
android:paddingBottom="10dp" |
||||||
|
android:scrollbars="vertical" |
||||||
|
android:text="" |
||||||
|
android:textColor="@color/white" |
||||||
|
android:textSize="18dp" |
||||||
|
android:theme="@style/DialogXCompatThemeDark" /> |
||||||
|
|
||||||
|
</LinearLayout> |
||||||
|
|
||||||
|
</ScrollView> |
||||||
|
|
||||||
|
<LinearLayout |
||||||
|
android:id="@+id/box_button" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_gravity="center_horizontal" |
||||||
|
android:layout_marginTop="5dp" |
||||||
|
android:gravity="right|center_vertical" |
||||||
|
android:orientation="horizontal" |
||||||
|
android:paddingLeft="10dp" |
||||||
|
android:paddingTop="10dp" |
||||||
|
android:paddingRight="10dp" |
||||||
|
android:paddingBottom="10dp"> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/btn_selectOther" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="36dp" |
||||||
|
android:background="@drawable/button_dialogx_material_night" |
||||||
|
android:clickable="true" |
||||||
|
android:gravity="center" |
||||||
|
android:paddingLeft="15dp" |
||||||
|
android:paddingRight="15dp" |
||||||
|
android:text="Other" |
||||||
|
android:textColor="@color/colorAccent" |
||||||
|
android:textSize="15dp" |
||||||
|
android:visibility="gone" /> |
||||||
|
|
||||||
|
<Space |
||||||
|
android:id="@+id/space_other_button" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_weight="1" /> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/btn_selectNegative" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="36dp" |
||||||
|
android:background="@drawable/button_dialogx_material_night" |
||||||
|
android:clickable="true" |
||||||
|
android:gravity="center" |
||||||
|
android:paddingLeft="15dp" |
||||||
|
android:paddingRight="15dp" |
||||||
|
android:text="Cancel" |
||||||
|
android:textColor="@color/colorAccent" |
||||||
|
android:textSize="15dp" /> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/btn_selectPositive" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="36dp" |
||||||
|
android:background="@drawable/button_dialogx_material_night" |
||||||
|
android:clickable="true" |
||||||
|
android:gravity="center" |
||||||
|
android:paddingLeft="15dp" |
||||||
|
android:paddingRight="15dp" |
||||||
|
android:text="OK" |
||||||
|
android:textColor="@color/colorAccent" |
||||||
|
android:textSize="15dp" /> |
||||||
|
|
||||||
|
</LinearLayout> |
||||||
|
|
||||||
|
</LinearLayout> |
||||||
|
|
||||||
|
</com.kongzue.dialogx.util.views.MaxRelativeLayout> |
||||||
|
|
||||||
|
</RelativeLayout> |
||||||
|
|
||||||
|
</com.kongzue.dialogx.util.views.DialogXBaseRelativeLayout> |
@ -0,0 +1,72 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<com.kongzue.dialogx.util.views.DialogXBaseRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto" |
||||||
|
android:id="@+id/box_root" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="match_parent" |
||||||
|
android:orientation="vertical" |
||||||
|
app:baseFocusable="false"> |
||||||
|
|
||||||
|
<LinearLayout |
||||||
|
android:id="@+id/box_body" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_alignParentBottom="true" |
||||||
|
android:layout_centerHorizontal="true" |
||||||
|
android:layout_marginLeft="35dp" |
||||||
|
android:layout_marginRight="35dp" |
||||||
|
android:layout_marginBottom="100dp" |
||||||
|
android:background="@drawable/rect_dialogx_material_poptip_bkg" |
||||||
|
android:elevation="20dp" |
||||||
|
android:gravity="center_vertical" |
||||||
|
android:minHeight="50dp" |
||||||
|
android:orientation="horizontal"> |
||||||
|
|
||||||
|
<ImageView |
||||||
|
android:id="@+id/img_dialogx_pop_icon" |
||||||
|
android:layout_width="26dp" |
||||||
|
android:layout_height="26dp" |
||||||
|
android:layout_marginLeft="15dp" |
||||||
|
android:layout_marginRight="-5dp" |
||||||
|
android:visibility="gone" /> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/txt_dialogx_pop_text" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_marginLeft="15dp" |
||||||
|
android:layout_marginTop="10dp" |
||||||
|
android:layout_marginRight="15dp" |
||||||
|
android:layout_marginBottom="10dp" |
||||||
|
android:gravity="left|center_vertical" |
||||||
|
android:text="Sure?" |
||||||
|
android:textColor="@color/black" |
||||||
|
android:textSize="14dp" /> |
||||||
|
|
||||||
|
<RelativeLayout |
||||||
|
android:id="@+id/box_custom" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:visibility="gone" /> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/txt_dialogx_button" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="match_parent" |
||||||
|
android:layout_marginLeft="-15dp" |
||||||
|
android:layout_marginTop="5dp" |
||||||
|
android:layout_marginRight="5dp" |
||||||
|
android:layout_marginBottom="5dp" |
||||||
|
android:background="@drawable/button_dialogx_material_light" |
||||||
|
android:gravity="left|center_vertical" |
||||||
|
android:paddingLeft="10dp" |
||||||
|
android:paddingRight="10dp" |
||||||
|
android:singleLine="true" |
||||||
|
android:text="Dismiss" |
||||||
|
android:textColor="@color/dialogxColorBlue" |
||||||
|
android:textSize="14dp" |
||||||
|
android:visibility="gone" /> |
||||||
|
|
||||||
|
</LinearLayout> |
||||||
|
|
||||||
|
</com.kongzue.dialogx.util.views.DialogXBaseRelativeLayout> |
@ -0,0 +1,72 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<com.kongzue.dialogx.util.views.DialogXBaseRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto" |
||||||
|
android:id="@+id/box_root" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="match_parent" |
||||||
|
android:orientation="vertical" |
||||||
|
app:baseFocusable="false"> |
||||||
|
|
||||||
|
<LinearLayout |
||||||
|
android:id="@+id/box_body" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_alignParentBottom="true" |
||||||
|
android:layout_centerHorizontal="true" |
||||||
|
android:layout_marginLeft="35dp" |
||||||
|
android:layout_marginRight="35dp" |
||||||
|
android:layout_marginBottom="100dp" |
||||||
|
android:background="@drawable/rect_dialogx_material_poptip_bkg_night" |
||||||
|
android:elevation="10dp" |
||||||
|
android:gravity="center_vertical" |
||||||
|
android:minHeight="50dp" |
||||||
|
android:orientation="horizontal"> |
||||||
|
|
||||||
|
<ImageView |
||||||
|
android:id="@+id/img_dialogx_pop_icon" |
||||||
|
android:layout_width="26dp" |
||||||
|
android:layout_height="26dp" |
||||||
|
android:layout_marginLeft="15dp" |
||||||
|
android:layout_marginRight="-5dp" |
||||||
|
android:visibility="gone" /> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/txt_dialogx_pop_text" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_marginLeft="15dp" |
||||||
|
android:layout_marginTop="10dp" |
||||||
|
android:layout_marginRight="15dp" |
||||||
|
android:layout_marginBottom="10dp" |
||||||
|
android:gravity="left|center_vertical" |
||||||
|
android:text="Sure?" |
||||||
|
android:textColor="@color/white" |
||||||
|
android:textSize="14dp" /> |
||||||
|
|
||||||
|
<RelativeLayout |
||||||
|
android:id="@+id/box_custom" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:visibility="gone" /> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/txt_dialogx_button" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="match_parent" |
||||||
|
android:layout_marginLeft="-15dp" |
||||||
|
android:layout_marginTop="5dp" |
||||||
|
android:layout_marginRight="5dp" |
||||||
|
android:layout_marginBottom="5dp" |
||||||
|
android:background="@drawable/button_dialogx_material_night" |
||||||
|
android:gravity="left|center_vertical" |
||||||
|
android:paddingLeft="10dp" |
||||||
|
android:paddingRight="10dp" |
||||||
|
android:singleLine="true" |
||||||
|
android:text="Dismiss" |
||||||
|
android:textColor="@color/dialogxPopButtonBlueDark" |
||||||
|
android:textSize="14dp" |
||||||
|
android:visibility="gone" /> |
||||||
|
|
||||||
|
</LinearLayout> |
||||||
|
|
||||||
|
</com.kongzue.dialogx.util.views.DialogXBaseRelativeLayout> |
@ -0,0 +1,60 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<com.kongzue.dialogx.util.views.DialogXBaseRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto" |
||||||
|
android:id="@+id/box_root" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="match_parent" |
||||||
|
android:background="@color/black40" |
||||||
|
android:orientation="vertical"> |
||||||
|
|
||||||
|
<com.kongzue.dialogx.util.views.MaxRelativeLayout |
||||||
|
android:id="@+id/bkg" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_centerInParent="true" |
||||||
|
android:minWidth="125dp" |
||||||
|
android:minHeight="125dp"> |
||||||
|
|
||||||
|
<com.kongzue.dialogx.util.views.BlurView |
||||||
|
android:id="@+id/blurView" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:tag="blurView" /> |
||||||
|
|
||||||
|
<LinearLayout |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_centerInParent="true" |
||||||
|
android:gravity="center_horizontal" |
||||||
|
android:paddingTop="1.5dp" |
||||||
|
android:orientation="vertical"> |
||||||
|
|
||||||
|
<RelativeLayout |
||||||
|
android:id="@+id/box_progress" |
||||||
|
android:layout_width="65dp" |
||||||
|
android:layout_height="65dp"/> |
||||||
|
|
||||||
|
<RelativeLayout |
||||||
|
android:id="@+id/box_customView" |
||||||
|
android:layout_width="65dp" |
||||||
|
android:layout_height="65dp" |
||||||
|
android:visibility="gone" /> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/txt_info" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_marginLeft="15dp" |
||||||
|
android:layout_marginTop="10dp" |
||||||
|
android:layout_marginRight="15dp" |
||||||
|
android:gravity="center" |
||||||
|
android:maxLines="3" |
||||||
|
android:text="Please Wait" |
||||||
|
android:textColor="@color/white" |
||||||
|
android:textSize="14dp" /> |
||||||
|
|
||||||
|
</LinearLayout> |
||||||
|
|
||||||
|
</com.kongzue.dialogx.util.views.MaxRelativeLayout> |
||||||
|
|
||||||
|
</com.kongzue.dialogx.util.views.DialogXBaseRelativeLayout> |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 2.9 KiB |
@ -0,0 +1,28 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<resources> |
||||||
|
|
||||||
|
<declare-styleable name="MaxRelativeLayout"> |
||||||
|
<attr name="maxLayoutWidth" format="dimension"/> |
||||||
|
<attr name="maxLayoutHeight" format="dimension"/> |
||||||
|
<attr name="lockWidth" format="boolean"/> |
||||||
|
<attr name="interceptTouch" format="boolean"/> |
||||||
|
</declare-styleable> |
||||||
|
|
||||||
|
<declare-styleable name="RealtimeBlurView"> |
||||||
|
<attr name="realtimeBlurRadius" format="dimension"/> |
||||||
|
<attr name="realtimeDownsampleFactor" format="float"/> |
||||||
|
<attr name="realtimeOverlayColor" format="color"/> |
||||||
|
<attr name="radius" format="dimension"/> |
||||||
|
</declare-styleable> |
||||||
|
|
||||||
|
<declare-styleable name="ProgressView"> |
||||||
|
<attr name="progressStrokeWidth" format="dimension"/> |
||||||
|
<attr name="progressStrokeColor" format="color"/> |
||||||
|
</declare-styleable> |
||||||
|
|
||||||
|
<declare-styleable name="DialogXBaseRelativeLayout"> |
||||||
|
<attr name="baseFocusable" format="boolean"/> |
||||||
|
</declare-styleable> |
||||||
|
|
||||||
|
|
||||||
|
</resources> |
@ -0,0 +1,40 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<resources> |
||||||
|
<color name="colorAccent">#2196F3</color> |
||||||
|
|
||||||
|
<color name="dark">#353535</color> |
||||||
|
<color name="black">#000</color> |
||||||
|
<color name="black90">#E6000000</color> |
||||||
|
<color name="black80">#CC000000</color> |
||||||
|
<color name="black75">#BF000000</color> |
||||||
|
<color name="black70">#B3000000</color> |
||||||
|
<color name="black60">#99000000</color> |
||||||
|
<color name="black50">#80000000</color> |
||||||
|
<color name="black40">#66000000</color> |
||||||
|
<color name="black30">#4D000000</color> |
||||||
|
<color name="black25">#40000000</color> |
||||||
|
<color name="black20">#33000000</color> |
||||||
|
<color name="black10">#1A000000</color> |
||||||
|
<color name="empty">#00000000</color> |
||||||
|
|
||||||
|
<color name="white">#fff</color> |
||||||
|
<color name="white90">#E6ffffff</color> |
||||||
|
<color name="white80">#CCffffff</color> |
||||||
|
<color name="white75">#BFffffff</color> |
||||||
|
<color name="white70">#B3ffffff</color> |
||||||
|
<color name="white60">#99ffffff</color> |
||||||
|
<color name="white50">#80ffffff</color> |
||||||
|
<color name="white40">#66ffffff</color> |
||||||
|
<color name="white30">#4Dffffff</color> |
||||||
|
<color name="white25">#40ffffff</color> |
||||||
|
<color name="white20">#33ffffff</color> |
||||||
|
<color name="white10">#1Affffff</color> |
||||||
|
|
||||||
|
<color name="dialogxColorBlue">#2196F3</color> |
||||||
|
|
||||||
|
<color name="dialogxMaterialDarkDialogBkgColor">#343434</color> |
||||||
|
<color name="dialogxWaitBkgLight">#F5F6F7</color> |
||||||
|
<color name="dialogxWaitBkgDark">#232323</color> |
||||||
|
|
||||||
|
<color name="dialogxPopButtonBlueDark">#86B3D6</color> |
||||||
|
</resources> |
@ -0,0 +1,6 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<resources> |
||||||
|
<style name="DialogXCompatThemeLight" parent="Theme.AppCompat.Light.NoActionBar"/> |
||||||
|
|
||||||
|
<style name="DialogXCompatThemeDark" parent="Theme.AppCompat.NoActionBar"/> |
||||||
|
</resources> |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue