From be2d45174748bcb983a91436e2f35fc31a9d0813 Mon Sep 17 00:00:00 2001 From: yangfeng Date: Thu, 17 Mar 2022 09:45:31 +0800 Subject: [PATCH] =?UTF-8?q?=E7=AC=AC=E4=B8=80=E4=B8=AA=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E4=B8=8A=E7=BA=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/.gitignore | 3 + .idea/compiler.xml | 6 + .idea/jarRepositories.xml | 25 +++ .idea/misc.xml | 20 ++ app/.gitignore | 1 + app/build.gradle | 44 +++++ app/proguard-rules.pro | 21 ++ .../dialogmanager/ExampleInstrumentedTest.kt | 24 +++ app/src/main/AndroidManifest.xml | 24 +++ .../yf/dialogmanager/BaseDialogFragment.kt | 139 +++++++++++++ .../java/com/yf/dialogmanager/FistActivity.kt | 50 +++++ .../java/com/yf/dialogmanager/FistDialog.java | 51 +++++ .../yf/dialogmanager/FistDialogFragment.kt | 40 ++++ .../java/com/yf/dialogmanager/MainActivity.kt | 57 ++++++ .../drawable-v24/ic_launcher_foreground.xml | 30 +++ .../res/drawable/ic_launcher_background.xml | 170 ++++++++++++++++ app/src/main/res/layout/activity_fist.xml | 10 + app/src/main/res/layout/activity_main.xml | 17 ++ app/src/main/res/layout/dialog_fister.xml | 17 ++ .../res/layout/dialog_fragment_fister.xml | 17 ++ .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 + app/src/main/res/mipmap-hdpi/ic_launcher.webp | Bin 0 -> 1404 bytes .../res/mipmap-hdpi/ic_launcher_round.webp | Bin 0 -> 2898 bytes app/src/main/res/mipmap-mdpi/ic_launcher.webp | Bin 0 -> 982 bytes .../res/mipmap-mdpi/ic_launcher_round.webp | Bin 0 -> 1772 bytes .../main/res/mipmap-xhdpi/ic_launcher.webp | Bin 0 -> 1900 bytes .../res/mipmap-xhdpi/ic_launcher_round.webp | Bin 0 -> 3918 bytes .../main/res/mipmap-xxhdpi/ic_launcher.webp | Bin 0 -> 2884 bytes .../res/mipmap-xxhdpi/ic_launcher_round.webp | Bin 0 -> 5914 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.webp | Bin 0 -> 3844 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.webp | Bin 0 -> 7778 bytes app/src/main/res/values-night/themes.xml | 16 ++ app/src/main/res/values/colors.xml | 10 + app/src/main/res/values/strings.xml | 3 + app/src/main/res/values/themes.xml | 16 ++ .../com/yf/dialogmanager/ExampleUnitTest.kt | 17 ++ build.gradle | 27 +++ dialogqueue/.gitignore | 1 + dialogqueue/build.gradle | 43 ++++ dialogqueue/consumer-rules.pro | 0 dialogqueue/proguard-rules.pro | 21 ++ .../dialog/queue/ExampleInstrumentedTest.java | 26 +++ dialogqueue/src/main/AndroidManifest.xml | 5 + .../com/dialog/queue/ActivityController.java | 14 ++ .../dialog/queue/ActivityControllerImpl.java | 170 ++++++++++++++++ .../com/dialog/queue/DialogController.java | 13 ++ .../dialog/queue/DialogDismissCallback.java | 7 + .../java/com/dialog/queue/DialogManager.java | 96 +++++++++ .../com/dialog/queue/ExampleUnitTest.java | 17 ++ gradle.properties | 21 ++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 59203 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 185 ++++++++++++++++++ gradlew.bat | 89 +++++++++ settings.gradle | 4 + 56 files changed, 1583 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/compiler.xml create mode 100644 .idea/jarRepositories.xml create mode 100644 .idea/misc.xml create mode 100644 app/.gitignore create mode 100644 app/build.gradle create mode 100644 app/proguard-rules.pro create mode 100644 app/src/androidTest/java/com/yf/dialogmanager/ExampleInstrumentedTest.kt create mode 100644 app/src/main/AndroidManifest.xml create mode 100644 app/src/main/java/com/yf/dialogmanager/BaseDialogFragment.kt create mode 100644 app/src/main/java/com/yf/dialogmanager/FistActivity.kt create mode 100644 app/src/main/java/com/yf/dialogmanager/FistDialog.java create mode 100644 app/src/main/java/com/yf/dialogmanager/FistDialogFragment.kt create mode 100644 app/src/main/java/com/yf/dialogmanager/MainActivity.kt create mode 100644 app/src/main/res/drawable-v24/ic_launcher_foreground.xml create mode 100644 app/src/main/res/drawable/ic_launcher_background.xml create mode 100644 app/src/main/res/layout/activity_fist.xml create mode 100644 app/src/main/res/layout/activity_main.xml create mode 100644 app/src/main/res/layout/dialog_fister.xml create mode 100644 app/src/main/res/layout/dialog_fragment_fister.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/values-night/themes.xml create mode 100644 app/src/main/res/values/colors.xml create mode 100644 app/src/main/res/values/strings.xml create mode 100644 app/src/main/res/values/themes.xml create mode 100644 app/src/test/java/com/yf/dialogmanager/ExampleUnitTest.kt create mode 100644 build.gradle create mode 100644 dialogqueue/.gitignore create mode 100644 dialogqueue/build.gradle create mode 100644 dialogqueue/consumer-rules.pro create mode 100644 dialogqueue/proguard-rules.pro create mode 100644 dialogqueue/src/androidTest/java/com/dialog/queue/ExampleInstrumentedTest.java create mode 100644 dialogqueue/src/main/AndroidManifest.xml create mode 100644 dialogqueue/src/main/java/com/dialog/queue/ActivityController.java create mode 100644 dialogqueue/src/main/java/com/dialog/queue/ActivityControllerImpl.java create mode 100644 dialogqueue/src/main/java/com/dialog/queue/DialogController.java create mode 100644 dialogqueue/src/main/java/com/dialog/queue/DialogDismissCallback.java create mode 100644 dialogqueue/src/main/java/com/dialog/queue/DialogManager.java create mode 100644 dialogqueue/src/test/java/com/dialog/queue/ExampleUnitTest.java create mode 100644 gradle.properties create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 gradlew create mode 100644 gradlew.bat create mode 100644 settings.gradle diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..fb7f4a8 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 0000000..d2ce72d --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..db77a3f --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..714ef6e --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,44 @@ +plugins { + id 'com.android.application' + id 'kotlin-android' +} + +android { + compileSdk 31 + + defaultConfig { + applicationId "com.yf.dialogmanager" + minSdk 26 + targetSdk 31 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = '1.8' + } +} + +dependencies { + + implementation 'androidx.core:core-ktx:1.3.2' + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.3.0' + implementation 'androidx.constraintlayout:constraintlayout:2.0.4' + implementation project(path: ':dialogqueue') + testImplementation 'junit:junit:4.+' + androidTestImplementation 'androidx.test.ext:junit:1.1.2' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/app/proguard-rules.pro @@ -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 \ No newline at end of file diff --git a/app/src/androidTest/java/com/yf/dialogmanager/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/yf/dialogmanager/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..89c4cdc --- /dev/null +++ b/app/src/androidTest/java/com/yf/dialogmanager/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package com.yf.dialogmanager + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("com.yf.dialogmanager", appContext.packageName) + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..1d2b48f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/yf/dialogmanager/BaseDialogFragment.kt b/app/src/main/java/com/yf/dialogmanager/BaseDialogFragment.kt new file mode 100644 index 0000000..54d5515 --- /dev/null +++ b/app/src/main/java/com/yf/dialogmanager/BaseDialogFragment.kt @@ -0,0 +1,139 @@ +package com.yf.dialogmanager + + +import android.content.DialogInterface +import android.graphics.Color +import android.graphics.drawable.ColorDrawable +import android.graphics.drawable.Drawable +import android.os.Bundle +import android.view.Gravity +import android.view.KeyEvent +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.view.WindowManager +import androidx.fragment.app.DialogFragment +import androidx.fragment.app.FragmentManager + + +/** + * dialog的基类 + */ + +abstract class BaseDialogFragment : DialogFragment() { + + open var isShow = false + + override fun onDismiss(dialog: DialogInterface) { + super.onDismiss(dialog) + isShow = false + mOnDismissListener?.onDismiss(dialog) + } + + private var mOnDismissListener: DialogInterface.OnDismissListener? = null + + open fun setOnDismissListener(listener: DialogInterface.OnDismissListener?) { + mOnDismissListener = listener + } + + protected abstract val layoutRes: Int + + open fun isCancelableOutside(): Boolean { + return true + } + + open fun getDialogWidth(): Int { + return WindowManager.LayoutParams.MATCH_PARENT + } + + open fun getDialogHeight(): Int { + return WindowManager.LayoutParams.WRAP_CONTENT + } + + + open fun dimAmount(): Float { + return 0.3f + } + + + open fun getGravity(): Int { + return Gravity.CENTER + } + + open fun animRes(): Int { + return 0 + } + + open fun getBackgroundDrawable(): Drawable { + return ColorDrawable(Color.TRANSPARENT) + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + return if (layoutRes > 0) { + //调用方通过xml获取view + inflater.inflate(layoutRes, container, false) + } else { + super.onCreateView(inflater, container, savedInstanceState) + } + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + dialog?.let { + //如果isCancelable()是false 则会屏蔽物理返回键 + it.setCancelable(isCancelable) + //如果isCancelableOutside()为false 点击屏幕外Dialog不会消失;反之会消失 + it.setCanceledOnTouchOutside(isCancelableOutside()) + //如果isCancelable()设置的是false 会屏蔽物理返回键 + it.setOnKeyListener { _, keyCode, event -> keyCode == KeyEvent.KEYCODE_BACK && event.action == KeyEvent.ACTION_DOWN && !isCancelable } + } + onInitFastData() + } + + /** + * 初始化数据 + */ + protected abstract fun onInitFastData() + + + override fun onStart() { + super.onStart() + dialog?.let { + val window = it.window ?: return + //设置背景色透明 + window.setBackgroundDrawable(getBackgroundDrawable()) + //设置Dialog动画效果 + if (animRes() > 0) { + window.setWindowAnimations(animRes()) + } + val params = window.attributes + //设置Dialog的Width + params.width = getDialogWidth() + //设置Dialog的Height + params.height = getDialogHeight() + //设置屏幕透明度 0.0f~1.0f(完全透明~完全不透明) + params.dimAmount = dimAmount() + params.gravity = getGravity() + window.attributes = params + } + } + + override fun show(manager: FragmentManager, tag: String?) { + super.show(manager, tag) + isShow = true + } + + + + open fun isShowing(): Boolean { + dialog?.let { + return it.isShowing && !isRemoving + } + return false + } + +} diff --git a/app/src/main/java/com/yf/dialogmanager/FistActivity.kt b/app/src/main/java/com/yf/dialogmanager/FistActivity.kt new file mode 100644 index 0000000..114cfce --- /dev/null +++ b/app/src/main/java/com/yf/dialogmanager/FistActivity.kt @@ -0,0 +1,50 @@ +package com.yf.dialogmanager + +import androidx.appcompat.app.AppCompatActivity +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import androidx.fragment.app.FragmentManager +import androidx.lifecycle.Lifecycle +import com.dialog.queue.ActivityController +import com.dialog.queue.DialogManager + +class FistActivity : AppCompatActivity(), ActivityController { + val dialogManager = DialogManager.getInstance() + val mHandler = Handler(Looper.getMainLooper()) + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_fist) + dialogManager.addLifecycle(this) + showDialog() + } + + override fun getControllerLifecycle(): Lifecycle { + return lifecycle + } + + override fun onDestroy() { + super.onDestroy() + dialogManager.removeLifecycle(this) + mHandler.removeCallbacksAndMessages(null) + } + + override fun getControllerClass(): Class<*> { + return this.javaClass + } + + override fun getControllerFragmentManager(): FragmentManager { + return supportFragmentManager + } + + private fun showDialog() { + mHandler.postDelayed({ + val mFistDialogFragment = FistDialogFragment.newInstance(1) + dialogManager.addQueue(1,false, mFistDialogFragment, this) + }, 2000) + mHandler.postDelayed({ + val mFistDialogFragment = FistDialogFragment.newInstance(2) + dialogManager.addQueue(0, mFistDialogFragment, this) + }, 3000) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/yf/dialogmanager/FistDialog.java b/app/src/main/java/com/yf/dialogmanager/FistDialog.java new file mode 100644 index 0000000..1c6f5e6 --- /dev/null +++ b/app/src/main/java/com/yf/dialogmanager/FistDialog.java @@ -0,0 +1,51 @@ +package com.yf.dialogmanager; + +import android.app.Dialog; +import android.content.Context; +import android.content.DialogInterface; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentManager; + +import com.dialog.queue.DialogController; +import com.dialog.queue.DialogDismissCallback; + +public class FistDialog extends Dialog implements DialogController, DialogInterface.OnDismissListener { + private DialogDismissCallback callback; + + public FistDialog(@NonNull Context context) { + super(context); + setContentView(R.layout.dialog_fister); + setOnDismissListener(this); + } + + public FistDialog(@NonNull Context context, int themeResId) { + super(context, themeResId); + setContentView(R.layout.dialog_fister); + setOnDismissListener(this); + } + + protected FistDialog(@NonNull Context context, boolean cancelable, @Nullable OnCancelListener cancelListener) { + super(context, cancelable, cancelListener); + setContentView(R.layout.dialog_fister); + setOnDismissListener(this); + } + + @Override + public void doShow(@NonNull FragmentManager fragmentManager) { + show(); + } + + @Override + public void doDismiss(DialogDismissCallback callback) { + this.callback = callback; + } + + @Override + public void onDismiss(DialogInterface dialog) { + if (null != callback) { + callback.onDismiss(); + } + } +} diff --git a/app/src/main/java/com/yf/dialogmanager/FistDialogFragment.kt b/app/src/main/java/com/yf/dialogmanager/FistDialogFragment.kt new file mode 100644 index 0000000..d8df8d4 --- /dev/null +++ b/app/src/main/java/com/yf/dialogmanager/FistDialogFragment.kt @@ -0,0 +1,40 @@ +package com.yf.dialogmanager + +import android.content.DialogInterface +import android.widget.TextView +import androidx.fragment.app.FragmentManager +import com.dialog.queue.DialogController +import com.dialog.queue.DialogDismissCallback + +class FistDialogFragment : BaseDialogFragment(), DialogController { + var callback: DialogDismissCallback? = null + var number: Int = 1 + val mTVNumberDialog by lazy { view?.findViewById(R.id.mTVNumberDialog) } + + companion object { + fun newInstance(number: Int = 1) = FistDialogFragment().apply { + this.number = number + } + } + + override val layoutRes: Int + get() = R.layout.dialog_fragment_fister + + override fun onInitFastData() { + mTVNumberDialog?.text = "第${number}个DialogFragment弹窗" + } + + override fun doShow(fragmentManager: FragmentManager) { + show(fragmentManager, javaClass.simpleName) + } + + override fun doDismiss(callback: DialogDismissCallback?) { + this.callback = callback + } + + override fun onDismiss(dialog: DialogInterface) { + super.onDismiss(dialog) + callback?.onDismiss() + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/yf/dialogmanager/MainActivity.kt b/app/src/main/java/com/yf/dialogmanager/MainActivity.kt new file mode 100644 index 0000000..9152745 --- /dev/null +++ b/app/src/main/java/com/yf/dialogmanager/MainActivity.kt @@ -0,0 +1,57 @@ +package com.yf.dialogmanager + +import android.content.Intent +import androidx.appcompat.app.AppCompatActivity +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import android.widget.Button +import androidx.fragment.app.FragmentManager +import androidx.lifecycle.Lifecycle +import com.dialog.queue.ActivityController +import com.dialog.queue.DialogManager + +class MainActivity : AppCompatActivity(), ActivityController { + val dialogManager = DialogManager.getInstance() + val mBTStart by lazy { findViewById