-
+
+
+
+
+
diff --git a/README.md b/README.md
index 48f70ac..81075a2 100644
--- a/README.md
+++ b/README.md
@@ -1,75 +1,12 @@
-# ModuleBus
-Module Bus is use for diffent modules communication.
+# ModuleBus_Ex4
+ModuleBus_Ex4 is use for diffent modules display in one Activity or Fragment.
+One function one module ,to make module independence.
-ModuleBus in 3 steps
--------------------
-1. Define events:
-
- ```java
- public static class MessageClient extend IBaseClient { /* Additional fields if needed */ }
- ```
-
-2. Prepare ModuleEvent and function:
- Declare and annotate your subscribing method.
-
- ```java
- @ModuleEvent(coreClientClass = MessageClient.Class)
- public void fun(Object...args) {/* Do something */};
- ```
- Register and unregister your ModuleBus. For example on Android, activities and fragments should usually register according to their life cycle:
-
- ```java
- @Override
- public void onStart() {
- super.onStart();
- ModuleBus.getInstance().register(this);
- }
-
- @Override
- public void onDestroy() {
- super.onStop();
- ModuleBus.getInstance().unregister(this);
- }
- ```
-
-3. Post function:
-
- ```java
- ModuleBus.getInstance().post(MessageClient.class,"fun",Object...args);
- ```
-
-
-
-Add ModuleBus to your project
-----------------------------
-
-Gradle:
-```gradle
-compile 'com.cangwang.core:modulebus:2.0.0'
-```
-
-Maven:
-```xml
-
- com.cangwang.core
- modulebus
- 2.0.0
- pom
-
-```
+like this
*Important
-need to set base module depend with ModuleBus and ,other communicated modules depend with base module.
-
-
-*2016.12.12 update
-(1)Use ArrayMap to change with HashMap.
-(2)Add startModuleActivity function.
-(3)Fix bugs and develop speeds in ModuleBus.
+1.need to set base module depend with ModuleBus and other communicated modules depend with base module.
-*2017.2.27 update
-(1) Add Module architecture inclue activity,fragment and view.
-(2) Add Application util ModuleImpl.
-*2017.3.3 update moduleBus 2.0.0
-(1) update Module architecture inclue activity,fragment and view.
+*2018.2.24 update
+add many module exsamples as live app to show how modulebus can do with json config.
diff --git a/a/.gitignore b/a/.gitignore
deleted file mode 100644
index 2665975..0000000
--- a/a/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-*.iml
-.gradle
-/local.properties
-/.idea/workspace.xml
-/.idea/libraries
-.DS_Store
-/build
-/captures
\ No newline at end of file
diff --git a/a/a.iml b/a/a.iml
deleted file mode 100644
index 302f1b2..0000000
--- a/a/a.iml
+++ /dev/null
@@ -1,148 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- generateDebugSources
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/a/build.gradle b/a/build.gradle
deleted file mode 100644
index 8378fb6..0000000
--- a/a/build.gradle
+++ /dev/null
@@ -1,52 +0,0 @@
-apply from: "${rootProject.rootDir}/common_config.gradle"
-if(project.ext.isDebug) {
- apply plugin: 'com.android.application'
-}else{
- apply plugin: 'com.android.library'
-}
-
-android {
- compileSdkVersion project.ext.compileSdkVersion
- buildToolsVersion project.ext.buildToolsVersion
-
- defaultConfig {
- minSdkVersion project.ext.minSdkVersion
- targetSdkVersion project.ext.targetSdkVersion
- versionCode 1
- versionName "1.0"
-
- testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
-
- }
- buildTypes {
- release {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- }
- }
- sourceSets {
- main {
- if (project.ext.isDebug) {
- manifest.srcFile 'src/debug/AndroidManifest.xml'
- res.srcDirs = ['src/debug/res']
-
- } else {
- manifest.srcFile 'src/main/AndroidManifest.xml'
- java {
- //排除java/debug文件夹下的所有文件
- exclude 'src/debug/**'
- }
- }
- }
- }
-
-}
-
-dependencies {
- compile fileTree(include: ['*.jar'], dir: 'libs')
- androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
- exclude group: 'com.android.support', module: 'support-annotations'
- })
- compile 'com.android.support:appcompat-v7:25.0.1'
- compile project(':base')
-}
diff --git a/a/proguard-rules.pro b/a/proguard-rules.pro
deleted file mode 100644
index e5ae8d8..0000000
--- a/a/proguard-rules.pro
+++ /dev/null
@@ -1,17 +0,0 @@
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in /Users/air/Library/Android/sdk/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the proguardFiles
-# directive in build.gradle.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# Add any project specific keep options here:
-
-# 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 *;
-#}
diff --git a/a/src/debug/AndroidManifest.xml b/a/src/debug/AndroidManifest.xml
deleted file mode 100644
index 90ca3ca..0000000
--- a/a/src/debug/AndroidManifest.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/a/src/debug/java/com/cangwang/a/MainActivity.java b/a/src/debug/java/com/cangwang/a/MainActivity.java
deleted file mode 100644
index e211dab..0000000
--- a/a/src/debug/java/com/cangwang/a/MainActivity.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.cangwang.a;
-
-import android.os.Bundle;
-import android.os.PersistableBundle;
-import android.support.annotation.Nullable;
-import android.support.v7.app.AppCompatActivity;
-
-/**
- * Created by air on 2016/12/5.
- */
-
-public class MainActivity extends AppCompatActivity {
-
- @Override
- public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) {
- super.onCreate(savedInstanceState, persistentState);
- }
-
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- }
-}
diff --git a/a/src/debug/res/layout/activity_main.xml b/a/src/debug/res/layout/activity_main.xml
deleted file mode 100644
index a5ec44d..0000000
--- a/a/src/debug/res/layout/activity_main.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
diff --git a/a/src/debug/res/layout/layout_a.xml b/a/src/debug/res/layout/layout_a.xml
deleted file mode 100644
index 3842ef7..0000000
--- a/a/src/debug/res/layout/layout_a.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/a/src/debug/res/values/colors.xml b/a/src/debug/res/values/colors.xml
deleted file mode 100644
index 3ab3e9c..0000000
--- a/a/src/debug/res/values/colors.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
- #3F51B5
- #303F9F
- #FF4081
-
diff --git a/a/src/debug/res/values/strings.xml b/a/src/debug/res/values/strings.xml
deleted file mode 100644
index 9c22290..0000000
--- a/a/src/debug/res/values/strings.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-
- a
-
diff --git a/a/src/main/AndroidManifest.xml b/a/src/main/AndroidManifest.xml
deleted file mode 100644
index d358334..0000000
--- a/a/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
diff --git a/a/src/main/java/com/cangwang/a/FragmentA.java b/a/src/main/java/com/cangwang/a/FragmentA.java
deleted file mode 100644
index 03e66c3..0000000
--- a/a/src/main/java/com/cangwang/a/FragmentA.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package com.cangwang.a;
-
-import android.content.ComponentName;
-import android.content.Intent;
-import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Button;
-import android.widget.TextView;
-
-import com.cangwang.base.IFBClient;
-import com.cangwang.core.ModuleBus;
-import com.cangwang.core.ModuleEvent;
-
-
-/**
- * Created by air on 16/11/18.
- */
-
-public class FragmentA extends Fragment {
- Button aBtn;
- Button createBBtn;
- private TextView aTxt;
- int i=1;
- @Override
- public void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- }
-
- @Nullable
- @Override
- public View onCreateView(final LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.layout_a,container,false);
- aBtn =(Button) view.findViewById(R.id.a_btn);
- aBtn.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- ModuleBus.getInstance().post(IFBClient.class,"changeText",String.valueOf(i));
- i++;
- }
- });
- aTxt = (TextView) view.findViewById(R.id.a_txt);
- createBBtn = (Button) view.findViewById(R.id.create_btn);
- createBBtn.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
-// Intent intent = new Intent();
-// intent.setAction("com.cangwang.b.act");
-// intent.setClassName("com.cangwang.modulebus","com.cangwang.b.BActivity");
-// intent.setComponent(new ComponentName("com.cangwang.modulebus","com.cangwang.b.BActivity"));
-// startActivity(intent);
-// ModuleBus.getInstance().post(IFBClient.class,"startModuleActivity","com.cangwang.b.BActivity");
-
-// Bundle bundle = new Bundle();
-// bundle.putString("from","FragmentA");
-// ModuleBus.getInstance().startModuleActivity(this,"com.cangwang.b.BActivity",bundle);
- Intent intent = new Intent();
- intent.setClassName(ModuleBus.getInstance().getPacketName(),"com.cangwang.b.BActivity");
- startActivity(intent);
- }
- });
- return view;
- }
-
- @ModuleEvent(coreClientClass = IFBClient.class,single = true)
- public int addNum(int num){
- return num+1;
- }
-}
diff --git a/a/src/main/res/layout/layout_a.xml b/a/src/main/res/layout/layout_a.xml
deleted file mode 100644
index 3842ef7..0000000
--- a/a/src/main/res/layout/layout_a.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/a/src/main/res/values/strings.xml b/a/src/main/res/values/strings.xml
deleted file mode 100644
index 9c22290..0000000
--- a/a/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-
- a
-
diff --git a/a/src/release/AndroidManifest.xml b/a/src/release/AndroidManifest.xml
deleted file mode 100644
index d358334..0000000
--- a/a/src/release/AndroidManifest.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
diff --git a/page_body/.gitignore b/anchor/.gitignore
similarity index 100%
rename from page_body/.gitignore
rename to anchor/.gitignore
diff --git a/anchor/build.gradle b/anchor/build.gradle
new file mode 100644
index 0000000..d8ce186
--- /dev/null
+++ b/anchor/build.gradle
@@ -0,0 +1,37 @@
+apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
+apply from: "${rootProject.rootDir}/common_config.gradle"
+apply plugin: 'kotlin-kapt'
+
+android {
+ compileSdkVersion project.ext.compileSdkVersion
+ buildToolsVersion project.ext.buildToolsVersion
+
+ defaultConfig {
+ minSdkVersion project.ext.minSdkVersion
+ targetSdkVersion project.ext.targetSdkVersion
+
+ versionCode 1
+ versionName "1.0"
+
+ // 资源前缀名,所有资源文件都必须加上这个前缀,以防止与其他插件的资源名字冲突
+ resourcePrefix "anchor_"
+
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ }
+}
+
+kapt {
+ arguments {
+ arg("moduleName", project.getName())
+ }
+}
+
+dependencies {
+ api fileTree(include: ['*.jar'], dir: 'libs')
+ api project(':base')
+ kapt project(":compiler")
+}
+repositories {
+ mavenCentral()
+}
diff --git a/anchor/proguard-rules.pro b/anchor/proguard-rules.pro
new file mode 100644
index 0000000..f1b4245
--- /dev/null
+++ b/anchor/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
diff --git a/anchor/src/main/AndroidManifest.xml b/anchor/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..aab11d7
--- /dev/null
+++ b/anchor/src/main/AndroidManifest.xml
@@ -0,0 +1,2 @@
+
diff --git a/anchor/src/main/assets/center.json b/anchor/src/main/assets/center.json
new file mode 100644
index 0000000..8991257
--- /dev/null
+++ b/anchor/src/main/assets/center.json
@@ -0,0 +1,10 @@
+[
+ {
+ "path":"com.cangwang.anchor.AnchorModule",
+ "templet":"top",
+ "title":"AnchorModule",
+ "layoutLevel":200,
+ "extraLevel":0
+ }
+
+]
diff --git a/anchor/src/main/java/com/cangwang/anchor/AnchorModule.kt b/anchor/src/main/java/com/cangwang/anchor/AnchorModule.kt
new file mode 100644
index 0000000..95d2e73
--- /dev/null
+++ b/anchor/src/main/java/com/cangwang/anchor/AnchorModule.kt
@@ -0,0 +1,54 @@
+package com.cangwang.anchor
+
+import com.cangwang.core.ModuleApiManager.Companion.instance
+import android.os.Bundle
+import android.view.View
+import android.widget.ImageView
+import android.widget.TextView
+import com.cangwang.anchor.dialog.AnchorDialog
+import com.cangwang.annotation.ModuleGroup
+import com.cangwang.annotation.ModuleUnit
+import com.cangwang.enums.LayoutLevel
+import com.cangwang.core.cwmodule.ex.CWBasicExModule
+import com.cangwang.base.api.AnchorApi
+import com.cangwang.core.cwmodule.CWModuleContext
+import androidx.fragment.app.FragmentActivity
+import androidx.fragment.app.FragmentManager
+
+/**
+ * 信息页
+ * Created by cangwang on 2018/2/6.
+ */
+@ModuleGroup(ModuleUnit(templet = "top", layoutlevel = LayoutLevel.HIGHT))
+class AnchorModule : CWBasicExModule(), AnchorApi {
+ private val anchorLayout: View? = null
+ private var anchorImg: ImageView? = null
+ private var anchorName: TextView? = null
+ private var anchorCareBtn: ImageView? = null
+ override fun onCreate(moduleContext: CWModuleContext, extend: Bundle?): Boolean {
+ super.onCreate(moduleContext, extend)
+ initView()
+ instance.putApi(AnchorApi::class.java, this)
+ return true
+ }
+
+ private fun initView() {
+ setContentView(R.layout.anchor_title_layout, parentPlugin)
+ anchorImg = findViewById(R.id.anchor_img)
+ anchorName = findViewById(R.id.anchor_name)
+ anchorCareBtn = findViewById(R.id.anchor_care_btn)
+ anchorCareBtn!!.setOnClickListener { showDialog(context!!.supportFragmentManager) }
+ }
+
+ private fun showDialog(manager: FragmentManager) {
+ if (!AnchorDialog.isAnchorDialogShow) {
+ AnchorDialog.isAnchorDialogShow = true
+ val anchorDialog: AnchorDialog = AnchorDialog.newInstance()
+ anchorDialog.show(manager, AnchorDialog.TAG)
+ }
+ }
+
+ override fun showAnchor(context: FragmentActivity?, user: String?, url: String?) {
+ showDialog(context!!.supportFragmentManager)
+ }
+}
\ No newline at end of file
diff --git a/anchor/src/main/java/com/cangwang/anchor/dialog/AnchorDialog.kt b/anchor/src/main/java/com/cangwang/anchor/dialog/AnchorDialog.kt
new file mode 100644
index 0000000..a258acc
--- /dev/null
+++ b/anchor/src/main/java/com/cangwang/anchor/dialog/AnchorDialog.kt
@@ -0,0 +1,59 @@
+package com.cangwang.anchor.dialog
+
+import android.app.Dialog
+import android.graphics.Color
+import com.cangwang.core.ModuleApiManager.Companion.instance
+import android.os.Bundle
+import android.graphics.drawable.ColorDrawable
+import android.view.*
+import com.cangwang.anchor.R
+import android.widget.ImageView
+import android.widget.TextView
+import androidx.fragment.app.DialogFragment
+import com.cangwang.base.api.WebApi
+
+/**
+ * 个人信息弹框
+ * Created by cangwang on 2018/2/6.
+ */
+class AnchorDialog : DialogFragment() {
+ private var rootView: View? = null
+ private var blogAdress: TextView? = null
+ private var closeBtn: ImageView? = null
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+ val dialog = super.onCreateDialog(savedInstanceState)
+ dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
+ dialog.window!!.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ dialog.window!!.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
+ dialog.window!!.setGravity(Gravity.CENTER)
+ dialog.setCanceledOnTouchOutside(true)
+ dialog.window!!.setWindowAnimations(R.style.DialogAnimation)
+ dialog.window!!.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT)
+ return dialog
+ }
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
+ rootView = inflater.inflate(R.layout.anchor_dialog, container, false)
+ blogAdress = rootView?.findViewById(R.id.anchor_card_blog) as TextView
+ blogAdress!!.setOnClickListener {
+ instance.getApi(WebApi::class.java)!!.loadWeb(blogAdress!!.text.toString(), "Canwang主页")
+ dismiss()
+ }
+ closeBtn = rootView?.findViewById(R.id.anchor_close) as ImageView
+ closeBtn!!.setOnClickListener { dismiss() }
+ return rootView
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ isAnchorDialogShow = false
+ }
+
+ companion object {
+ var isAnchorDialogShow = false
+ const val TAG = "AnchorDialog"
+ fun newInstance(): AnchorDialog {
+ return AnchorDialog()
+ }
+ }
+}
\ No newline at end of file
diff --git a/anchor/src/main/res/drawable-xhdpi/anchor_img.jpg b/anchor/src/main/res/drawable-xhdpi/anchor_img.jpg
new file mode 100644
index 0000000..afb2cb1
Binary files /dev/null and b/anchor/src/main/res/drawable-xhdpi/anchor_img.jpg differ
diff --git a/anchor/src/main/res/drawable/anchor_coner.xml b/anchor/src/main/res/drawable/anchor_coner.xml
new file mode 100644
index 0000000..0ee6afe
--- /dev/null
+++ b/anchor/src/main/res/drawable/anchor_coner.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/anchor/src/main/res/layout/anchor_dialog.xml b/anchor/src/main/res/layout/anchor_dialog.xml
new file mode 100644
index 0000000..ec2d223
--- /dev/null
+++ b/anchor/src/main/res/layout/anchor_dialog.xml
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/anchor/src/main/res/layout/anchor_title_layout.xml b/anchor/src/main/res/layout/anchor_title_layout.xml
new file mode 100644
index 0000000..6347a98
--- /dev/null
+++ b/anchor/src/main/res/layout/anchor_title_layout.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
diff --git a/anchor/src/main/res/values/strings.xml b/anchor/src/main/res/values/strings.xml
new file mode 100644
index 0000000..db1efa9
--- /dev/null
+++ b/anchor/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ anchor
+
diff --git a/annotation/.gitignore b/annotation/.gitignore
new file mode 100644
index 0000000..3543521
--- /dev/null
+++ b/annotation/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/annotation/build.gradle b/annotation/build.gradle
new file mode 100644
index 0000000..1fc4ed0
--- /dev/null
+++ b/annotation/build.gradle
@@ -0,0 +1,8 @@
+apply plugin: 'java'
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+}
+
+sourceCompatibility = "1.7"
+targetCompatibility = "1.7"
diff --git a/annotation/src/main/java/com/cangwang/ModuleConfig.java b/annotation/src/main/java/com/cangwang/ModuleConfig.java
new file mode 100644
index 0000000..f567fb3
--- /dev/null
+++ b/annotation/src/main/java/com/cangwang/ModuleConfig.java
@@ -0,0 +1,4 @@
+package com.cangwang;
+
+public class ModuleConfig {
+}
diff --git a/annotation/src/main/java/com/cangwang/annotation/InjectBean.java b/annotation/src/main/java/com/cangwang/annotation/InjectBean.java
new file mode 100644
index 0000000..c7abd09
--- /dev/null
+++ b/annotation/src/main/java/com/cangwang/annotation/InjectBean.java
@@ -0,0 +1,16 @@
+package com.cangwang.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ *
+ * Created by cangwang on 2017/8/31.
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.SOURCE)
+public @interface InjectBean {
+
+}
diff --git a/annotation/src/main/java/com/cangwang/annotation/ModuleBean.java b/annotation/src/main/java/com/cangwang/annotation/ModuleBean.java
new file mode 100644
index 0000000..b861603
--- /dev/null
+++ b/annotation/src/main/java/com/cangwang/annotation/ModuleBean.java
@@ -0,0 +1,15 @@
+package com.cangwang.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Module
+ * Created by cangwang on
+ */
+@Target({ElementType.TYPE})
+@Retention(RetentionPolicy.CLASS)
+public @interface ModuleBean {
+}
diff --git a/annotation/src/main/java/com/cangwang/annotation/ModuleGroup.java b/annotation/src/main/java/com/cangwang/annotation/ModuleGroup.java
new file mode 100644
index 0000000..0dd1bbc
--- /dev/null
+++ b/annotation/src/main/java/com/cangwang/annotation/ModuleGroup.java
@@ -0,0 +1,16 @@
+package com.cangwang.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ *
+ * Created by cangwang on 2017/8/31.
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.SOURCE)
+public @interface ModuleGroup {
+ ModuleUnit[] value();
+}
diff --git a/annotation/src/main/java/com/cangwang/annotation/ModuleUnit.java b/annotation/src/main/java/com/cangwang/annotation/ModuleUnit.java
new file mode 100644
index 0000000..2103c42
--- /dev/null
+++ b/annotation/src/main/java/com/cangwang/annotation/ModuleUnit.java
@@ -0,0 +1,22 @@
+package com.cangwang.annotation;
+
+import com.cangwang.enums.LayoutLevel;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Module单元注解
+ * Created by cangwang on 2017/8/31.
+ */
+@Target({ElementType.TYPE})
+@Retention(RetentionPolicy.CLASS)
+public @interface ModuleUnit {
+ String templet() default "normal";
+ String title() default "CangWang";
+ LayoutLevel layoutlevel() default LayoutLevel.NORMAL;
+ int inflateLevel() default -1;
+ int extralevel() default 0;
+}
diff --git a/annotation/src/main/java/com/cangwang/bean/ModuleUnitBean.java b/annotation/src/main/java/com/cangwang/bean/ModuleUnitBean.java
new file mode 100644
index 0000000..66d3382
--- /dev/null
+++ b/annotation/src/main/java/com/cangwang/bean/ModuleUnitBean.java
@@ -0,0 +1,54 @@
+package com.cangwang.bean;
+
+/**
+ * Created by cangwang on 2017/12/8.
+ */
+public class ModuleUnitBean implements Comparable{
+ public String path; // 路径
+ public String templet; // 模板
+ public String title; // 模块
+ public int layoutLevel; // 布局层级
+ public int inflateLevel; // 布局优先
+ public int extraLevel; // 额外等级
+
+ public ModuleUnitBean(String path, String templet, String title, int layoutLevel, int inflateLevel, int extraLevel) {
+ this.path = path;
+ this.templet = templet;
+ this.title = title;
+ this.layoutLevel = layoutLevel;
+ this.inflateLevel = inflateLevel;
+ this.extraLevel = extraLevel;
+ }
+
+ @Override
+ public int compareTo(Object o) {
+ ModuleUnitBean b = (ModuleUnitBean) o;
+ if (inflateLevel > b.layoutLevel) {
+ return 1;
+ } else if (inflateLevel < b.layoutLevel) {
+ return -1;
+ } else {
+ if (layoutLevel < b.layoutLevel) {
+ return 1;
+ } else if (layoutLevel == b.layoutLevel) {
+ if (extraLevel <= b.extraLevel) {
+ return 1;
+ } else
+ return -1;
+ } else
+ return -1;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "ModuleUnitBean{" +
+ "path='" + path + '\'' +
+ ", templet='" + templet + '\'' +
+ ", title='" + title + '\'' +
+ ", layoutLevel=" + layoutLevel +
+ ", inflateLevel=" + inflateLevel +
+ ", extraLevel=" + extraLevel +
+ '}';
+ }
+}
diff --git a/annotation/src/main/java/com/cangwang/enums/LayoutLevel.java b/annotation/src/main/java/com/cangwang/enums/LayoutLevel.java
new file mode 100644
index 0000000..5b679c2
--- /dev/null
+++ b/annotation/src/main/java/com/cangwang/enums/LayoutLevel.java
@@ -0,0 +1,18 @@
+package com.cangwang.enums;
+
+/**
+ * 布局层级
+ * Created by cangwang on 2017/8/31.
+ */
+
+public enum LayoutLevel {
+ VERY_HIGHT(100),
+ HIGHT(200),
+ NORMAL(300),
+ LOW(400),
+ VERY_LOW(500);
+
+ public int getValue(){return value;}
+ private int value;
+ LayoutLevel(int value){this.value = value;}
+}
diff --git a/annotation/src/main/java/com/cangwang/model/ICWModule.java b/annotation/src/main/java/com/cangwang/model/ICWModule.java
new file mode 100644
index 0000000..ee09cf1
--- /dev/null
+++ b/annotation/src/main/java/com/cangwang/model/ICWModule.java
@@ -0,0 +1,8 @@
+package com.cangwang.model;
+
+/**
+ * Created by cangwang on 2017/12/5.
+ */
+
+public interface ICWModule {
+}
diff --git a/annotation/src/main/java/com/cangwang/model/IModuleFactory.java b/annotation/src/main/java/com/cangwang/model/IModuleFactory.java
new file mode 100644
index 0000000..dab5233
--- /dev/null
+++ b/annotation/src/main/java/com/cangwang/model/IModuleFactory.java
@@ -0,0 +1,12 @@
+package com.cangwang.model;
+
+import java.util.List;
+
+/**
+ * Created by cangwang on 2017/12/15.
+ */
+
+public interface IModuleFactory {
+// IModuleFactory getInstance();
+ List getTempleList(String templet);
+}
diff --git a/annotation/src/main/java/com/cangwang/model/IModuleProxy.java b/annotation/src/main/java/com/cangwang/model/IModuleProxy.java
new file mode 100644
index 0000000..01bb1a6
--- /dev/null
+++ b/annotation/src/main/java/com/cangwang/model/IModuleProxy.java
@@ -0,0 +1,9 @@
+package com.cangwang.model;
+
+/**
+ * Created by cangwang on 2017/12/5.
+ */
+
+public interface IModuleProxy {
+ ICWModule getModule();
+}
diff --git a/annotation/src/main/java/com/cangwang/model/ModuleMeta.java b/annotation/src/main/java/com/cangwang/model/ModuleMeta.java
new file mode 100644
index 0000000..17bb7ff
--- /dev/null
+++ b/annotation/src/main/java/com/cangwang/model/ModuleMeta.java
@@ -0,0 +1,64 @@
+package com.cangwang.model;
+
+import com.cangwang.annotation.ModuleUnit;
+import com.cangwang.enums.LayoutLevel;
+
+import javax.lang.model.element.Element;
+
+/**
+ * 模块信息
+ * Created by cangwang on 2017/9/1.
+ */
+
+public class ModuleMeta {
+// public Element rwaType;
+ public String templet;
+ public String moduleName;
+ public String title;
+ public LayoutLevel layoutlevel;
+ public int extralevel;
+
+ public ModuleMeta(String templet,String moduleName,String title,int layoutlevel,int extralevel){
+// this.rwaType = rawType;
+ this.templet = templet;
+ this.moduleName = moduleName;
+ this.title = title;
+ if (layoutlevel == 500){
+ this.layoutlevel = LayoutLevel.VERY_LOW;
+ }else if (layoutlevel == 400){
+ this.layoutlevel = LayoutLevel.LOW;
+ }else if (layoutlevel == 300){
+ this.layoutlevel = LayoutLevel.NORMAL;
+ }else if (layoutlevel == 200){
+ this.layoutlevel = LayoutLevel.HIGHT;
+ }else if (layoutlevel == 100){
+ this.layoutlevel = LayoutLevel.VERY_HIGHT;
+ }
+ this.extralevel = extralevel;
+ }
+
+ public ModuleMeta(ModuleUnit unit,String moduleName){
+// this.rwaType = rawType;
+ this.moduleName = moduleName;
+ this.templet = unit.templet();
+ this.layoutlevel = unit.layoutlevel();
+ this.extralevel = unit.extralevel();
+ this.title = unit.title();
+ }
+
+// public static ModuleMeta build(ModuleUnit unit, Element rawType){
+// return new ModuleMeta(unit,rawType);
+// }
+
+
+ @Override
+ public String toString() {
+ return "ModuleMeta{" +
+ "templet='" + templet + '\'' +
+ ", moduleName='" + moduleName + '\'' +
+ ", title='" + title + '\'' +
+ ", layoutlevel=" + layoutlevel +
+ ", extralevel=" + extralevel +
+ '}';
+ }
+}
diff --git a/app/app.iml b/app/app.iml
deleted file mode 100644
index 8e1766e..0000000
--- a/app/app.iml
+++ /dev/null
@@ -1,154 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- generateDebugSources
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 362cc58..827854f 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,58 +1,88 @@
-//apply from: rootProject.getRootDir().getAbsolutePath() + "/common_config.gradle"
-apply from: "${rootProject.rootDir}/common_config.gradle"
-if(project.ext.isLib){
- apply plugin: 'com.android.library'
- apply from: 'fat-aar.gradle'
-}else {
- apply plugin: 'com.android.application'
-}
-
-android {
- compileSdkVersion project.ext.compileSdkVersion
- buildToolsVersion project.ext.buildToolsVersion
- defaultConfig {
- if (!project.ext.isLib) {
- applicationId project.ext.applicationId
- }
- minSdkVersion project.ext.minSdkVersion
- targetSdkVersion project.ext.targetSdkVersion
- versionCode 1
- versionName "1.0"
- testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
- }
- buildTypes {
- release {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- }
- }
-}
-
-dependencies {
- compile fileTree(include: ['*.jar'], dir: 'libs')
- androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
- exclude group: 'com.android.support', module: 'support-annotations'
- })
- compile 'com.android.support:design:25.0.1'
- compile 'com.android.support:appcompat-v7:25.0.1'
-
- if(project.ext.isLib) {
- embedded project(':page_body')
- embedded project(':page_body_bt')
- embedded project(':page_name')
- embedded project(':page_view')
- }else{
- if (!project.ext.isDebug) {
- compile project(':a')
- compile project(':b')
- compile project(':page_body')
- compile project(':page_body_bt')
- compile project(':page_name')
- compile project(':page_view')
- }else{
- compile project(':core')
- }
- }
-}
-
-
+//apply from: rootProject.getRootDir().getAbsolutePath() + "/common_config.gradle"
+apply from: "${rootProject.rootDir}/common_config.gradle"
+if(project.ext.isLib){
+ apply plugin: 'com.android.library'
+ apply from: 'fat-aar.gradle'
+}else {
+ apply plugin: 'com.android.application'
+}
+apply plugin: 'kotlin-android'
+apply plugin: 'kotlin-android-extensions'
+apply plugin: 'kotlin-kapt'
+
+//apply plugin: "generate"
+
+android {
+ compileSdkVersion project.ext.compileSdkVersion
+ buildToolsVersion project.ext.buildToolsVersion
+ defaultConfig {
+ if (!project.ext.isLib) {
+ applicationId project.ext.applicationId
+ }
+ minSdkVersion project.ext.minSdkVersion
+ targetSdkVersion project.ext.targetSdkVersion
+ versionCode 1
+ versionName "1.0"
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+
+ gradle.taskGraph.whenReady {
+ tasks.each {
+ task ->
+ if(task.name.contains("Test")){
+ task.enabled=false
+ }
+ }
+ }
+
+ lintOptions {
+ abortOnError false
+ }
+
+}
+
+dependencies {
+ api fileTree(include: ['*.jar'], dir: 'libs')
+ kapt project(":compiler")
+
+ if(project.ext.isLib) {
+ embedded project(':page_body')
+ embedded project(':page_body_bt')
+ embedded project(':page_name')
+ embedded project(':page_view')
+ }else{
+ if (!project.ext.isDebug) {
+// compile project(':page_body')
+// compile project(':page_body_bt')
+// compile project(':page_name')
+// compile project(':page_view')
+// compile project(':bottom')
+// compile project(':chat')
+// compile project(':anchor')
+// compile project(':web')
+// compile project(':seat')
+ api project(':live')
+ api project(':template')
+// compile project(':lamp')
+// compile project(':slide')
+// compile project(':splash')
+ }else{
+ api project(':core')
+ }
+ }
+}
+
+kapt {
+ arguments {
+ arg("applicationName", project.getName())
+ }
+}
+
+
+
diff --git a/app/fat-aar.gradle b/app/fat-aar.gradle
index ea90408..8261ab7 100755
--- a/app/fat-aar.gradle
+++ b/app/fat-aar.gradle
@@ -1,11 +1,9 @@
/**
* This is free and unencumbered software released into the public domain.
-
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
-
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
@@ -13,7 +11,6 @@
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
@@ -21,7 +18,6 @@
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
-
For more information, please refer to
*/
@@ -54,7 +50,7 @@ buildscript {
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:manifest-merger:25.2.0'
+ classpath 'com.android.tools.build:manifest-merger:25.3.2'
}
}
@@ -67,15 +63,17 @@ dependencies {
}
// Paths to embedded jar files
-ext.embeddedJars = new ArrayList()
+ext.embeddedJars = new ArrayList()
// Paths to embedded aar projects
-ext.embeddedAarDirs = new ArrayList()
+ext.embeddedAarDirs = new ArrayList()
+// Embedded aar files dependencies
+ext.embeddedAarFiles = new ArrayList()
// List of embedded R classes
-ext.embeddedRClasses = new ArrayList()
+ext.embeddedRClasses = new ArrayList()
// Change backslash to forward slash on windows
ext.build_dir = buildDir.path.replace(File.separator, '/');
-
+ext.root_dir = project.rootDir.absolutePath.replace(File.separator, '/');
ext.exploded_aar_dir = "$build_dir/intermediates/exploded-aar";
ext.classs_release_dir = "$build_dir/intermediates/classes/release";
ext.bundle_release_dir = "$build_dir/intermediates/bundles/release";
@@ -84,15 +82,40 @@ ext.generated_rsrc_dir = "$build_dir/generated/source/r/release";
ext.base_r2x_dir = "$build_dir/fat-aar/release/";
+def gradleVersionStr = GradleVersion.current().getVersion();
+ext.gradleApiVersion = gradleVersionStr.substring(0, gradleVersionStr.lastIndexOf(".")).toFloat();
+
+println "Gradle version: " + gradleVersionStr;
+
afterEvaluate {
// the list of dependency must be reversed to use the right overlay order.
def dependencies = new ArrayList(configurations.embedded.resolvedConfiguration.firstLevelModuleDependencies)
dependencies.reverseEach {
- def aarPath = "${exploded_aar_dir}/${it.moduleGroup}/${it.moduleName}/${it.moduleVersion}"
+
+ def aarPath;
+ if (gradleApiVersion >= 2.3f)
+ aarPath = "${root_dir}/${it.moduleName}/build/intermediates/bundles/default"
+ else
+ aarPath = "${exploded_aar_dir}/${it.moduleGroup}/${it.moduleName}/${it.moduleVersion}"
it.moduleArtifacts.each {
artifact ->
+
+ println "ARTIFACT 3 : "
+ println artifact
if (artifact.type == 'aar') {
+ if (!embeddedAarFiles.contains(artifact)) {
+ embeddedAarFiles.add(artifact)
+ }
if (!embeddedAarDirs.contains(aarPath)) {
+ if( artifact.file.isFile() ){
+ println artifact.file
+ println aarPath
+
+ copy {
+ from zipTree( artifact.file )
+ into aarPath
+ }
+ }
embeddedAarDirs.add(aarPath)
}
} else if (artifact.type == 'jar') {
@@ -116,7 +139,14 @@ afterEvaluate {
// Embed JNI Libraries
bundleRelease.dependsOn embedJniLibs
- embedJniLibs.dependsOn transformNative_libsWithSyncJniLibsForRelease
+
+ if(gradleApiVersion >= 2.3f) {
+ embedJniLibs.dependsOn transformNativeLibsWithSyncJniLibsForRelease
+ ext.bundle_release_dir = "$build_dir/intermediates/bundles/default"
+ }else{
+ embedJniLibs.dependsOn transformNative_libsWithSyncJniLibsForRelease
+ ext.bundle_release_dir = "$build_dir/intermediates/bundles/release";
+ }
// Merge Embedded Manifests
bundleRelease.dependsOn embedManifests
@@ -159,12 +189,35 @@ private List getMergedInputResourceSets(List inputResourceSet) {
List newInputResourceSet = new ArrayList(inputResourceSet)
+ println "getMergedInputResourceSets"
+
+ println embeddedAarDirs
embeddedAarDirs.each { aarPath ->
try {
- def resname = (aarPath.split(exploded_aar_dir)[1]).replace('/', ':');
+ println aarPath
+ def resname
+ if (gradleApiVersion >= 2.3f) {
+ def parentProject = project.rootProject.name.toString()
+ println "parent: "
+ println parentProject
+
+ def startIndex = aarPath.indexOf('/' + parentProject)
+ def endIndex = aarPath.indexOf('/build/')
+
+ println "start"
+ println startIndex
+ println "end"
+ println endIndex
+ if (startIndex < 1 || endIndex < 1)
+ return;
+ resname = aarPath.substring(startIndex, endIndex).replace('/', ':')
+ }
+ else
+ resname = (aarPath.split(exploded_aar_dir)[1]).replace('/', ':');
def rs = ResourceSetClass.newInstance([resname, true] as Object[])
rs.addSource(file("$aarPath/res"))
- // println "ResourceSet is " + rs
+ println "ResourceSet is " + rs
+ println resname
newInputResourceSet += rs
} catch (Exception e) {
e.printStackTrace();
@@ -198,7 +251,7 @@ task embedProguard << {
try {
def proguardLibFile = file("$aarPath/proguard.txt")
if (proguardLibFile.exists())
- proguardRelease.append(proguardLibFile.text)
+ proguardRelease.append("\n" + proguardLibFile.text)
} catch (Exception e) {
e.printStackTrace();
throw e;
@@ -211,52 +264,68 @@ task generateRJava << {
println "Running FAT-AAR Task :generateRJava"
// Now generate the R.java file for each embedded dependency
- def libPackageName = new XmlParser().parse(android.sourceSets.main.manifest.srcFile).@package
+ def mainManifestFile = android.sourceSets.main.manifest.srcFile;
+ def libPackageName = "";
+
+ if(mainManifestFile.exists()) {
+
+ libPackageName = new XmlParser().parse(mainManifestFile).@package
+ }
embeddedAarDirs.each { aarPath ->
- def aarManifest = new XmlParser().parse(file("$aarPath/AndroidManifest.xml"));
- def aarPackageName = aarManifest.@package
- String packagePath = aarPackageName.replace('.', '/')
-
- // Generate the R.java file and map to current project's R.java
- // This will recreate the class file
- def rTxt = file("$aarPath/R.txt")
- def rMap = new ConfigObject()
-
- if (rTxt.exists()) {
- rTxt.eachLine {
- line ->
- //noinspection GroovyUnusedAssignment
- def (type, subclass, name, value) = line.tokenize(' ')
- rMap[subclass].putAt(name, type)
- }
+ def manifestFile = file("$aarPath/AndroidManifest.xml");
+ if(!manifestFile.exists()) {
+ manifestFile = file("./src/main/AndroidManifest.xml");
}
- def sb = "package $aarPackageName;" << '\n' << '\n'
- sb << 'public final class R {' << '\n'
+ if(manifestFile.exists()) {
+ def aarManifest = new XmlParser().parse(manifestFile);
+ def aarPackageName = aarManifest.@package
- rMap.each {
- subclass, values ->
- sb << " public static final class $subclass {" << '\n'
- values.each {
- name, type ->
- sb << " public static $type $name = ${libPackageName}.R.${subclass}.${name};" << '\n'
+ String packagePath = aarPackageName.replace('.', '/')
+
+ // Generate the R.java file and map to current project's R.java
+ // This will recreate the class file
+ def rTxt = file("$aarPath/R.txt")
+ def rMap = new ConfigObject()
+
+ if (rTxt.exists()) {
+ rTxt.eachLine {
+ line ->
+ //noinspection GroovyUnusedAssignment
+ def (type, subclass, name, value) = line.tokenize(' ')
+ rMap[subclass].putAt(name, type)
}
- sb << " }" << '\n'
- }
+ }
+
+ def sb = "package $aarPackageName;" << '\n' << '\n'
+ sb << 'public final class R {' << '\n'
- sb << '}' << '\n'
+ rMap.each {
+ subclass, values ->
+ sb << " public static final class $subclass {" << '\n'
+ values.each {
+ name, type ->
+ sb << " public static $type $name = ${libPackageName}.R.${subclass}.${name};" << '\n'
+ }
+ sb << " }" << '\n'
+ }
+
+ sb << '}' << '\n'
- mkdir("$generated_rsrc_dir/$packagePath")
- file("$generated_rsrc_dir/$packagePath/R.java").write(sb.toString())
+ mkdir("$generated_rsrc_dir/$packagePath")
+ file("$generated_rsrc_dir/$packagePath/R.java").write(sb.toString())
+
+ embeddedRClasses += "$packagePath/R.class"
+ embeddedRClasses += "$packagePath/R\$*.class"
+ }
- embeddedRClasses += "$packagePath/R.class"
- embeddedRClasses += "$packagePath/R\$*.class"
}
}
task collectRClass << {
+ println "COLLECTRCLASS"
delete base_r2x_dir
mkdir base_r2x_dir
@@ -268,8 +337,12 @@ task collectRClass << {
}
task embedRClass(type: org.gradle.jvm.tasks.Jar, dependsOn: collectRClass) {
+ println "EMBED R CLASS"
+
destinationDir file("$bundle_release_dir/libs/")
+ println destinationDir
from base_r2x_dir
+ println base_r2x_dir
}
/**
@@ -280,15 +353,44 @@ task embedJavaJars(dependsOn: embedRClass) << {
println "Running FAT-AAR Task :embedJavaJars"
embeddedAarDirs.each { aarPath ->
+
// Explode all classes.jar files to classes so that they can be proguarded
- copy {
- from zipTree("$aarPath/jars/classes.jar")
- into classs_release_dir
+ def jar_dir
+ if (gradleApiVersion >= 2.3f)
+ jar_dir = "$aarPath"
+ else
+ jar_dir = "$aarPath/jars"
+
+ if(embeddedAarFiles.size() > 0){
+
+ embeddedAarFiles.each {
+ artifact ->
+ FileTree aarFileTree = zipTree(artifact.file.getAbsolutePath());
+
+ def aarFile = aarFileTree.files.find { it.name.contains("classes.jar") }
+
+ copy {
+ from zipTree(aarFile)
+ into classs_release_dir
+ }
+ }
+
+ }else{
+
+ println jar_dir
+ println classs_release_dir
+ println bundle_release_dir
+ println embeddedJars
+
+ copy {
+ from zipTree(jar_dir + "/classes.jar")
+ into classs_release_dir
+ }
}
// Copy all additional jar files to bundle lib
- FileTree jars = fileTree(dir: "$aarPath/jars", include: '*.jar', exclude: 'classes.jar')
- jars += fileTree(dir: "$aarPath/jars/libs", include: '*.jar')
+ FileTree jars = fileTree(dir: jar_dir, include: '*.jar', exclude: 'classes.jar')
+ jars += fileTree(dir: jar_dir + "/libs", include: '*.jar')
jars += fileTree(dir: "$aarPath/libs", include: '*.jar')
copy {
@@ -324,11 +426,13 @@ task embedManifests << {
println "Running FAT-AAR Task :embedManifests"
ILogger mLogger = new MiLogger()
- List libraryManifests = new ArrayList<>()
+ List libraryManifests = new ArrayList<>()
embeddedAarDirs.each { aarPath ->
- if (!libraryManifests.contains(aarPath)) {
- libraryManifests.add(file("$aarPath/AndroidManifest.xml"))
+ File dependencyManifest = file("$aarPath/AndroidManifest.xml")
+
+ if (!libraryManifests.contains(aarPath) && dependencyManifest.exists()) {
+ libraryManifests.add(dependencyManifest)
}
}
@@ -338,6 +442,14 @@ task embedManifests << {
File copyManifest = file("$bundle_release_dir/AndroidManifest.orig.xml")
File aaptManifest = file("$manifest_aaapt_dir/AndroidManifest.xml")
+ if(!origManifest.exists()) {
+ origManifest = file("./src/main/AndroidManifest.xml")
+ }
+
+ if(!origManifest.exists()) {
+ return;
+ }
+
copy {
from origManifest.parentFile
into copyManifest.parentFile
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 169effa..da8b28b 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,48 +1,40 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/assets/center.json b/app/src/main/assets/center.json
new file mode 100644
index 0000000..74b087d
--- /dev/null
+++ b/app/src/main/assets/center.json
@@ -0,0 +1,81 @@
+{
+ "top":
+ [
+ {
+ "path":"com.cangwang.seat.SeatModule",
+ "templet":"top",
+ "title":"SeatModule",
+ "layoutLevel":400,
+ "extraLevel":0
+ },
+ {
+ "path":"com.cangwang.chat.ChatModule",
+ "templet":"top",
+ "title":"ChatModule",
+ "layoutLevel":400,
+ "extraLevel":0
+ },
+ {
+ "path":"com.cangwang.bottom.BottomModule",
+ "templet":"top",
+ "title":"BottomModule",
+ "layoutLevel":400,
+ "extraLevel":0
+ },
+ {
+ "path":"com.cangwang.lamp.LampModule",
+ "templet":"top",
+ "title":"LampModule",
+ "layoutLevel":400,
+ "extraLevel":0
+ },
+ {
+ "path":"com.cangwang.splash.SplashModule",
+ "templet":"top",
+ "title":"SplashModule",
+ "layoutLevel":300,
+ "extraLevel":0
+ },
+ {
+ "path":"com.cangwang.anchor.AnchorModule",
+ "templet":"top",
+ "title":"AnchorModule",
+ "layoutLevel":200,
+ "extraLevel":0
+ },
+ {
+ "path":"com.cangwang.web.WebModule",
+ "templet":"top",
+ "title":"WebModule",
+ "layoutLevel":100,
+ "extraLevel":0
+ },
+ {
+ "path":"cangwang.com.slide.SlideModule",
+ "templet":"top",
+ "title":"SlideModule",
+ "layoutLevel":100,
+ "extraLevel":0
+ },
+ {
+ "path":"com.cangwang.gift.GiftModule",
+ "templet":"top",
+ "title":"GiftModule",
+ "layoutLevel":100,
+ "extraLevel":0
+ }
+
+ ],
+ "video":
+ [
+ {
+ "path":"com.cangwang.live.LiveModule",
+ "templet":"video",
+ "title":"LiveModule",
+ "layoutLevel":500,
+ "extraLevel":0
+ }
+
+ ]
+
+}
diff --git a/app/src/main/ic_launcher-web.png b/app/src/main/ic_launcher-web.png
new file mode 100644
index 0000000..5ecd224
Binary files /dev/null and b/app/src/main/ic_launcher-web.png differ
diff --git a/app/src/main/java/com/cangwang/modulebus/AdaviceActivity.java b/app/src/main/java/com/cangwang/modulebus/AdaviceActivity.java
deleted file mode 100644
index 3caa145..0000000
--- a/app/src/main/java/com/cangwang/modulebus/AdaviceActivity.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.cangwang.modulebus;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.support.v7.app.AppCompatActivity;
-import android.view.Window;
-import android.view.WindowManager;
-
-/**
- * Created by cangwang on 2017/2/26.
- */
-
-public class AdaviceActivity extends AppCompatActivity{
- @Override
- public void onCreate(Bundle savedInstanceState) {
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_start);
- getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
- WindowManager.LayoutParams.FLAG_FULLSCREEN);
-
- startActivity(new Intent(this,ModuleMainActivity.class));
- finish();
- }
-}
diff --git a/app/src/main/java/com/cangwang/modulebus/AdviceActivity.kt b/app/src/main/java/com/cangwang/modulebus/AdviceActivity.kt
new file mode 100644
index 0000000..5a6a031
--- /dev/null
+++ b/app/src/main/java/com/cangwang/modulebus/AdviceActivity.kt
@@ -0,0 +1,24 @@
+package com.cangwang.modulebus
+
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatActivity
+import android.view.WindowManager
+import android.content.Intent
+import android.view.Window
+import com.cangwang.modulebus.ExModule.ModuleMainExActivity
+
+/**
+ * 启动页
+ * Created by cangwang on 2017/2/26.
+ */
+class AdviceActivity : AppCompatActivity() {
+ public override fun onCreate(savedInstanceState: Bundle?) {
+ requestWindowFeature(Window.FEATURE_NO_TITLE)
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_start)
+ window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
+ WindowManager.LayoutParams.FLAG_FULLSCREEN)
+ startActivity(Intent(this, ModuleMainExActivity::class.java))
+ finish()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/cangwang/modulebus/ExModule/BaseController.kt b/app/src/main/java/com/cangwang/modulebus/ExModule/BaseController.kt
new file mode 100644
index 0000000..1bf8df9
--- /dev/null
+++ b/app/src/main/java/com/cangwang/modulebus/ExModule/BaseController.kt
@@ -0,0 +1,24 @@
+package com.cangwang.modulebus.ExModule
+
+import android.app.Activity
+import android.content.Context
+import android.os.Bundle
+import android.view.View
+import android.view.ViewGroup
+
+/**
+ * Created by cangwang on 2017/6/15.
+ */
+class BaseController : IView {
+ private var context: Context? = null
+ fun onAttach(activity: Activity?) {
+ context = activity
+ }
+
+ fun create(saveInstanceState: Bundle?, activity: Activity?, container: ViewGroup?) {}
+ override val view: View?
+ get() = null
+
+ override fun hide() {}
+ override fun show() {}
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/cangwang/modulebus/ExModule/IView.kt b/app/src/main/java/com/cangwang/modulebus/ExModule/IView.kt
new file mode 100644
index 0000000..31820bf
--- /dev/null
+++ b/app/src/main/java/com/cangwang/modulebus/ExModule/IView.kt
@@ -0,0 +1,12 @@
+package com.cangwang.modulebus.ExModule
+
+import android.view.View
+
+/**
+ * Created by cangwang on 2017/6/15.
+ */
+interface IView {
+ val view: View?
+ fun show()
+ fun hide()
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/cangwang/modulebus/ExModule/ModuleExActivity.kt b/app/src/main/java/com/cangwang/modulebus/ExModule/ModuleExActivity.kt
new file mode 100644
index 0000000..e1f1ec7
--- /dev/null
+++ b/app/src/main/java/com/cangwang/modulebus/ExModule/ModuleExActivity.kt
@@ -0,0 +1,33 @@
+package com.cangwang.modulebus.ExModule
+
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatActivity
+import android.view.WindowManager
+import com.cangwang.modulebus.R
+import com.cangwang.base.util.ViewUtil
+import com.cangwang.template.TemplateFragment
+
+import android.content.res.Configuration
+
+/**
+ * Created by cangwang on 2017/6/15.
+ */
+class ModuleExActivity : AppCompatActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ if (this.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) { //横屏
+ val lp = window.attributes
+ lp.flags = lp.flags or WindowManager.LayoutParams.FLAG_FULLSCREEN
+ window.attributes = lp
+ window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)
+ } else if (this.resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) { //竖屏
+ val lp = window.attributes
+ lp.flags = lp.flags and WindowManager.LayoutParams.FLAG_FULLSCREEN.inv()
+ window.attributes = lp
+ window.clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)
+ }
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_example)
+ // getSupportFragmentManager().beginTransaction().replace(R.id.container,new TemplateFragment()).commit();
+ ViewUtil.replaceFragment(this, R.id.container, supportFragmentManager, null, TemplateFragment::class.java, TemplateFragment.TAG)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/cangwang/modulebus/ExModule/ModuleExFragment.kt b/app/src/main/java/com/cangwang/modulebus/ExModule/ModuleExFragment.kt
new file mode 100644
index 0000000..b000f92
--- /dev/null
+++ b/app/src/main/java/com/cangwang/modulebus/ExModule/ModuleExFragment.kt
@@ -0,0 +1,30 @@
+package com.cangwang.modulebus.ExModule
+
+import android.os.Bundle
+import com.cangwang.core.cwmodule.ex.ModuleManageExFragment
+
+/**
+ * Created by cangwang on 2017/6/15.
+ */
+class ModuleExFragment : ModuleManageExFragment() {
+ override fun moduleConfig(): String {
+ return "normal"
+ }
+
+ companion object {
+ fun newInstance(): ModuleExFragment {
+ val fragment = ModuleExFragment()
+ val bundle = Bundle()
+ fragment.arguments = bundle
+ return fragment
+ }
+
+ fun newInstance(modules: List?): ModuleExFragment {
+ PageExConfig.moduleList = modules
+ val fragment = ModuleExFragment()
+ val bundle = Bundle()
+ fragment.arguments = bundle
+ return fragment
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/cangwang/modulebus/ExModule/ModuleMainExActivity.kt b/app/src/main/java/com/cangwang/modulebus/ExModule/ModuleMainExActivity.kt
new file mode 100644
index 0000000..1d462cc
--- /dev/null
+++ b/app/src/main/java/com/cangwang/modulebus/ExModule/ModuleMainExActivity.kt
@@ -0,0 +1,39 @@
+package com.cangwang.modulebus.ExModule
+
+import android.os.Bundle
+import android.view.WindowManager
+import com.cangwang.modulebus.R
+import com.cangwang.base.util.ViewUtil
+import com.cangwang.template.TemplateFragment
+import com.cangwang.core.cwmodule.ex.ModuleManageExActivity
+import android.content.res.Configuration
+
+/**
+ * Created by cangwang on 2017/6/15.
+ */
+class ModuleMainExActivity : ModuleManageExActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ if (this.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) { //横屏
+ val lp = window.attributes
+ lp.flags = lp.flags or WindowManager.LayoutParams.FLAG_FULLSCREEN
+ window.attributes = lp
+ window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)
+ } else if (this.resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) { //竖屏
+ val lp = window.attributes
+ lp.flags = lp.flags and WindowManager.LayoutParams.FLAG_FULLSCREEN.inv()
+ window.attributes = lp
+ window.clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)
+ }
+ super.onCreate(savedInstanceState)
+ setBackGroundResouce(R.color.black)
+ ViewUtil.replaceFragment(this, R.id.layout_plugincenter, supportFragmentManager, null, TemplateFragment::class.java, TemplateFragment.TAG)
+ }
+
+ override fun onConfigurationChanged(newConfig: Configuration) {
+ super.onConfigurationChanged(newConfig)
+ }
+
+ override fun moduleConfig(): String {
+ return "video"
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/cangwang/modulebus/ExModule/PageExConfig.kt b/app/src/main/java/com/cangwang/modulebus/ExModule/PageExConfig.kt
new file mode 100644
index 0000000..9739976
--- /dev/null
+++ b/app/src/main/java/com/cangwang/modulebus/ExModule/PageExConfig.kt
@@ -0,0 +1,40 @@
+package com.cangwang.modulebus.ExModule
+
+import android.content.Context
+import java.util.ArrayList
+
+/**
+ * Created by cangeang on 17/6/15.
+ */
+object PageExConfig {
+ var pageTitles: MutableList = ArrayList()
+ fun getPageTitles(context: Context?): List {
+ pageTitles.clear()
+ pageTitles.add("a")
+ pageTitles.add("b")
+ pageTitles.add("b")
+ pageTitles.add("b")
+ return pageTitles
+ }
+
+ private const val FragmentA = "com.cangwang.a.FragmentA"
+ private const val FragmentB = "com.cangwang.b.FragmentB"
+ var fragmentNames = arrayOf(
+ FragmentA,
+ FragmentB,
+ FragmentB,
+ FragmentB
+ )
+ const val ActivityB = "com.cangwang.b.BActivity"
+ const val MODULE_PAGE_NAME = "com.cangwang.page_name.PageNameExModule"
+ const val MODULE_BODY_NAME = "com.cangwang.page_body.PageBodyExModule"
+ const val MODULE_BODY_BT_NAME = "com.cangwang.page_body_bt.PageBodyBTExModule"
+ const val MODULE_VIEW_PAGE_NAME = "com.cangwang.page_view.PageViewModule"
+ const val BODY_CREATE = "com.cangwang.page_body.BodyCreate"
+ const val NAME_CREATE = "com.cangwang.page_name.NameCreate"
+ var moduleList: List? = ArrayList()
+ val moduleCreate = arrayOf(
+ BODY_CREATE,
+ NAME_CREATE
+ )
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/cangwang/modulebus/MainActivity.java b/app/src/main/java/com/cangwang/modulebus/MainActivity.java
deleted file mode 100644
index 89273f4..0000000
--- a/app/src/main/java/com/cangwang/modulebus/MainActivity.java
+++ /dev/null
@@ -1,146 +0,0 @@
-package com.cangwang.modulebus;
-
-import android.content.Intent;
-import android.support.annotation.NonNull;
-import android.support.design.widget.BottomNavigationView;
-import android.support.v4.app.Fragment;
-import android.support.v4.view.ViewPager;
-import android.os.Bundle;
-import android.support.v7.app.AppCompatActivity;
-import android.view.MenuItem;
-
-import com.cangwang.core.IBaseClient;
-import com.cangwang.core.ModuleBus;
-import com.cangwang.core.ModuleEvent;
-import java.util.ArrayList;
-import java.util.List;
-
-public class MainActivity extends AppCompatActivity {
-
- private BottomNavigationView bottomNavigationView;
- private ViewPager mViewPager;
- private ViewPagerAdapter mViewPagerAdapter;
- private List pageFagments = new ArrayList();
- private List pageTitles = new ArrayList();
-
- private MenuItem prevMenuItem;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- ModuleBus.getInstance().setPackageName(getPackageName());
-
- setContentView(R.layout.activity_main);
-
- pageTitles = PageConfig.getPageTitles(this);
- try {
- //遍历Fragment地址
- for(String address:PageConfig.fragmentNames){
- //反射获得Class
- Class clazz = Class.forName(address);
- //创建类
- Fragment tab = (Fragment) clazz.newInstance();
- //添加到viewPagerAdapter的资源
- pageFagments.add(tab);
- }
-
- }catch (ClassNotFoundException e){
-
- }catch (IllegalAccessException e){
-
- }catch (InstantiationException e){
-
- }
-
- mViewPager = (ViewPager) findViewById(R.id.viewpager);
- bottomNavigationView = (BottomNavigationView) findViewById(R.id.navigation);
-
- mViewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager(),pageFagments,pageTitles);
- mViewPager.setAdapter(mViewPagerAdapter);
- mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
- @Override
- public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
-
- }
-
- @Override
- public void onPageSelected(int position) {
- if(prevMenuItem != null){
- prevMenuItem.setChecked(false);
- }else{
- bottomNavigationView.getMenu().getItem(0).setChecked(false);
- }
- bottomNavigationView.getMenu().getItem(position).setChecked(true);
- prevMenuItem = bottomNavigationView.getMenu().getItem(position);
- }
-
- @Override
- public void onPageScrollStateChanged(int state) {
-
- }
- });
- //全部预加载
- mViewPager.setOffscreenPageLimit(pageFagments.size());
-
- bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
- @Override
- public boolean onNavigationItemSelected(@NonNull MenuItem item) {
-// switch (item.getItemId()){
-// case R.id.a:
-// mViewPager.setCurrentItem(0);
-// break;
-// case R.id.b:
-// mViewPager.setCurrentItem(1);
-// break;
-// case R.id.c:
-// mViewPager.setCurrentItem(2);
-// break;
-// case R.id.d:
-// mViewPager.setCurrentItem(3);
-// break;
-//
-// }
- int id = item.getItemId();
- if (id == R.id.a){
- mViewPager.setCurrentItem(0);
- }else if (id == R.id.b){
- mViewPager.setCurrentItem(1);
- }else if (id == R.id.c){
- mViewPager.setCurrentItem(2);
- }else if (id == R.id.d){
- mViewPager.setCurrentItem(3);
- }
-
- return true;
- }
- });
- ModuleBus.getInstance().register(this);
- }
-
- @Override
- protected void onDestroy() {
- ModuleBus.getInstance().unregister(this);
- super.onDestroy();
- }
-
- @ModuleEvent(coreClientClass = IBaseClient.class)
- public void startModuleActivity(String className,Bundle bundle){
- try {
- Class clazz = Class.forName(className);
- Intent intent = new Intent(this,clazz);
- if (bundle!=null)
- intent.putExtras(bundle);
- startActivityForResult(intent,ModuleBus.MODULE_RESULT);
- }catch (ClassNotFoundException e){
- e.printStackTrace();
- }
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (requestCode == ModuleBus.MODULE_RESULT){
- ModuleBus.getInstance().moduleResult(this,data);
- }
- super.onActivityResult(requestCode, resultCode, data);
- }
-}
diff --git a/app/src/main/java/com/cangwang/modulebus/ModuleApplication.java b/app/src/main/java/com/cangwang/modulebus/ModuleApplication.java
deleted file mode 100644
index 63c5158..0000000
--- a/app/src/main/java/com/cangwang/modulebus/ModuleApplication.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package com.cangwang.modulebus;
-
-import android.app.Application;
-import android.util.Log;
-
-import com.cangwang.core.util.ModuleImpl;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-/**
- * Created by cangwang on 2017/2/25.
- */
-
-public class ModuleApplication extends Application{
- private static final String TAG="ModuleApplication";
-
- @Override
- public void onCreate() {
- super.onCreate();
- long time = System.currentTimeMillis();
-// for (String implName:PageConfig.moduleCreate){
-// try {
-// Class> clazz = Class.forName(implName);
-// Object impl = clazz.newInstance();
-// if (clazz.newInstance() instanceof ModuleImpl){
-// Method m = clazz.getDeclaredMethod("onLoad",Application.class);
-// m.invoke(impl,this);
-// }
-// }catch (ClassNotFoundException e){
-// e.printStackTrace();
-// }catch (IllegalAccessException e){
-// e.printStackTrace();
-// }catch (InstantiationException e){
-// e.printStackTrace();
-// }catch (NoSuchMethodException e){
-// e.printStackTrace();
-// }catch (InvocationTargetException e){
-// e.printStackTrace();
-// }
-// }
-// Log.v(TAG,"invoke load time = " +(System.currentTimeMillis()-time));
-// time=System.currentTimeMillis();
- for (String implName:PageConfig.moduleCreate){
- try {
- Class> clazz = Class.forName(implName);
- if (clazz.newInstance() instanceof ModuleImpl){
- ModuleImpl impl = (ModuleImpl) clazz.newInstance();
- impl.onLoad(this);
- }
- }catch (ClassNotFoundException e){
- e.printStackTrace();
- }catch (IllegalAccessException e){
- e.printStackTrace();
- }catch (InstantiationException e){
- e.printStackTrace();
- }
- }
- Log.v(TAG,"interface load time = " +(System.currentTimeMillis()-time));
- }
-}
diff --git a/app/src/main/java/com/cangwang/modulebus/ModuleApplication.kt b/app/src/main/java/com/cangwang/modulebus/ModuleApplication.kt
new file mode 100644
index 0000000..7cfbca7
--- /dev/null
+++ b/app/src/main/java/com/cangwang/modulebus/ModuleApplication.kt
@@ -0,0 +1,43 @@
+package com.cangwang.modulebus
+
+import android.app.Application
+import android.content.Context
+import com.cangwang.modulebus.ExModule.PageExConfig
+import android.util.Log
+import com.cangwang.core.ModuleBus
+import com.cangwang.core.util.ModuleImpl
+
+/**
+ * Created by cangwang on 2017/2/25.
+ */
+class ModuleApplication : Application() {
+ override fun attachBaseContext(base: Context) {
+ super.attachBaseContext(base)
+ ModuleBus.init(base)
+ }
+
+ override fun onCreate() {
+ super.onCreate()
+ val time = System.currentTimeMillis()
+ for (implName in PageExConfig.moduleCreate) {
+ try {
+ val clazz = Class.forName(implName)
+ if (clazz.newInstance() is ModuleImpl) {
+ val impl = clazz.newInstance() as ModuleImpl
+ impl.onLoad(this)
+ }
+ } catch (e: ClassNotFoundException) {
+ e.printStackTrace()
+ } catch (e: IllegalAccessException) {
+ e.printStackTrace()
+ } catch (e: InstantiationException) {
+ e.printStackTrace()
+ }
+ }
+ Log.v(TAG, "interface load time = " + (System.currentTimeMillis() - time))
+ }
+
+ companion object {
+ private const val TAG = "ModuleApplication"
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/cangwang/modulebus/ModuleExampleActivity.java b/app/src/main/java/com/cangwang/modulebus/ModuleExampleActivity.java
deleted file mode 100644
index a0f9cfb..0000000
--- a/app/src/main/java/com/cangwang/modulebus/ModuleExampleActivity.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.cangwang.modulebus;
-
-import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.v4.util.ArrayMap;
-import android.support.v7.app.AppCompatActivity;
-
-import com.cangwang.core.cwmodule.ModuleManageActivity;
-
-import java.util.ArrayList;
-
-/**
- * Created by air on 2016/12/28.
- */
-
-public class ModuleExampleActivity extends AppCompatActivity{
-
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_example);
- getSupportFragmentManager().beginTransaction().replace(R.id.container,new ModuleExampleFragment()).commit();
- }
-}
diff --git a/app/src/main/java/com/cangwang/modulebus/ModuleExampleFragment.java b/app/src/main/java/com/cangwang/modulebus/ModuleExampleFragment.java
deleted file mode 100644
index 3a85a5c..0000000
--- a/app/src/main/java/com/cangwang/modulebus/ModuleExampleFragment.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package com.cangwang.modulebus;
-
-import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.v4.util.ArrayMap;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.cangwang.core.cwmodule.ModuleManageFragment;
-import com.cangwang.core.cwmodule.ModuleManagerView;
-
-import java.util.ArrayList;
-
-/**
- * Created by zjl on 2017/1/3.
- */
-
-public class ModuleExampleFragment extends ModuleManageFragment {
-
- private ModuleManagerView moduleManagerView;
-
- @Override
- public int getContentViewId() {
- return R.layout.fragment_module;
- }
-
- @Override
- public ArrayMap> moduleConfig() {
- ArrayMap> map = new ArrayMap<>();
- map.put(PageConfig.MODULE_PAGE_NAME,new ArrayList(){{add(R.id.page_name);}});
- map.put(PageConfig.MODULE_BODY_BT_NAME,new ArrayList(){{add(R.id.page_bodyT);add(R.id.page_bodyB);}});
- return map;
- }
-
- @Nullable
- @Override
- public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
- View view = super.onCreateView(inflater, container, savedInstanceState);
- moduleManagerView = new ModuleManagerView(getActivity(),savedInstanceState,view.findViewById(R.id.page_view)) {
- @Override
- public ArrayMap> moduleConfig() {
- ArrayMap> map = new ArrayMap<>();
- map.put(PageConfig.MODULE_VIEW_PAGE_NAME,new ArrayList(){{add(R.id.page_view);}});
- return map;
- }
- };
- return view;
- }
-
- @Override
- public void onStop() {
- super.onStop();
- if (moduleManagerView !=null)
- moduleManagerView.onStop();
- }
-
- @Override
- public void onPause() {
- super.onPause();
- if (moduleManagerView !=null)
- moduleManagerView.onPause();
- }
-
- @Override
- public void onResume() {
- super.onResume();
- if (moduleManagerView !=null)
- moduleManagerView.onResume();
- }
-
-// @Override
-// public void onDestroy() {
-// if (moduleManagerView !=null)
-// moduleManagerView.onDestroy();
-// super.onDestroy();
-// }
-}
diff --git a/app/src/main/java/com/cangwang/modulebus/ModuleMainActivity.java b/app/src/main/java/com/cangwang/modulebus/ModuleMainActivity.java
deleted file mode 100644
index d624a8b..0000000
--- a/app/src/main/java/com/cangwang/modulebus/ModuleMainActivity.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.cangwang.modulebus;
-
-import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.v4.util.ArrayMap;
-
-import com.cangwang.core.cwmodule.ModuleManageActivity;
-
-import java.util.ArrayList;
-
-/**
- * Created by air on 2016/12/28.
- */
-
-public class ModuleMainActivity extends ModuleManageActivity{
-
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- }
-
- @Override
- public int getContentViewId() {
- return R.layout.activity_main_module;
- }
-
-
- @Override
- public ArrayMap> moduleConfig() {
- ArrayMap> map = new ArrayMap<>();
- map.put(PageConfig.MODULE_PAGE_NAME,new ArrayList(){{add(R.id.page_name);}});
- map.put(PageConfig.MODULE_BODY_NAME,new ArrayList(){{add(R.id.page_bodyT);add(R.id.page_bodyB);}});
- return map;
- }
-}
diff --git a/app/src/main/java/com/cangwang/modulebus/PageConfig.java b/app/src/main/java/com/cangwang/modulebus/PageConfig.java
deleted file mode 100644
index dc92df9..0000000
--- a/app/src/main/java/com/cangwang/modulebus/PageConfig.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package com.cangwang.modulebus;
-
-import android.content.Context;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Created by zjl on 16/7/6.
- */
-public class PageConfig {
- public static List pageTitles = new ArrayList();
-
- public static List getPageTitles(Context context) {
- pageTitles.clear();
- pageTitles.add("a");
- pageTitles.add("b");
- pageTitles.add("b");
- pageTitles.add("b");
- return pageTitles;
- }
-
- private static final String FragmentA = "com.cangwang.a.FragmentA";
-
- private static final String FragmentB = "com.cangwang.b.FragmentB";
-
- public static String[] fragmentNames = {
- FragmentA,
- FragmentB,
- FragmentB,
- FragmentB
- };
-
- public static final String ActivityB = "com.cangwang.b.BActivity";
-
-
- public static final String MODULE_PAGE_NAME ="com.cangwang.page_name.PageNameModule";
- public static final String MODULE_BODY_NAME ="com.cangwang.page_body.PageBodyModule";
- public static final String MODULE_BODY_BT_NAME ="com.cangwang.page_body_bt.PageBodyBTModule";
-
- public static final String MODULE_VIEW_PAGE_NAME ="com.cangwang.page_view.PageViewModule";
-
- public static final String BODY_CREATE ="com.cangwang.page_body.BodyCreate";
- public static final String NAME_CREATE ="com.cangwang.page_name.NameCreate";
-
- public static final String[] modulesList = {
- MODULE_PAGE_NAME,
- MODULE_BODY_NAME,
- MODULE_BODY_BT_NAME
- };
-
-
- public static final String[] moduleCreate = {
- BODY_CREATE,
- NAME_CREATE
- };
-
-}
diff --git a/app/src/main/java/com/cangwang/modulebus/ViewPagerAdapter.java b/app/src/main/java/com/cangwang/modulebus/ViewPagerAdapter.java
deleted file mode 100644
index 4bd92e5..0000000
--- a/app/src/main/java/com/cangwang/modulebus/ViewPagerAdapter.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.cangwang.modulebus;
-
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentManager;
-import android.support.v4.app.FragmentPagerAdapter;
-
-import java.util.List;
-
-/**
- * Created by air on 16/7/6.
- */
-public class ViewPagerAdapter extends FragmentPagerAdapter {
- private List titles;
- private List fragmentList;
-
- public ViewPagerAdapter(FragmentManager fm){
- super(fm);
- }
-
- public ViewPagerAdapter(FragmentManager fm, List lf, List titles){
- super(fm);
- this.titles = titles;
- fragmentList = lf;
- }
-
- @Override
- public Fragment getItem(int position) {
- return fragmentList.get(position);
- }
-
- @Override
- public CharSequence getPageTitle(int position) {
- return titles.get(position);
- }
-
- @Override
- public int getCount() {
- return fragmentList.size();
- }
-}
diff --git a/app/src/main/java/com/cangwang/modulebus/ViewPagerAdapter.kt b/app/src/main/java/com/cangwang/modulebus/ViewPagerAdapter.kt
new file mode 100644
index 0000000..4f68546
--- /dev/null
+++ b/app/src/main/java/com/cangwang/modulebus/ViewPagerAdapter.kt
@@ -0,0 +1,31 @@
+package com.cangwang.modulebus
+
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.FragmentManager
+import androidx.fragment.app.FragmentPagerAdapter
+
+/**
+ * Created by air on 16/7/6.
+ */
+class ViewPagerAdapter : FragmentPagerAdapter {
+ private var titles: List? = null
+ private var fragmentList: List? = null
+
+ constructor(fm: FragmentManager?) : super(fm!!) {}
+ constructor(fm: FragmentManager?, lf: List?, titles: List?) : super(fm!!) {
+ this.titles = titles
+ fragmentList = lf
+ }
+
+ override fun getItem(position: Int): Fragment {
+ return fragmentList!![position]
+ }
+
+ override fun getPageTitle(position: Int): CharSequence? {
+ return titles!![position]
+ }
+
+ override fun getCount(): Int {
+ return fragmentList!!.size
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_example.xml b/app/src/main/res/layout/activity_example.xml
index b0afc9a..ec1bf01 100644
--- a/app/src/main/res/layout/activity_example.xml
+++ b/app/src/main/res/layout/activity_example.xml
@@ -5,6 +5,7 @@
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:background="@color/black"
tools:context="com.cangwang.modulebus.ModuleExampleActivity">
+ tools:context="com.cangwang.modulebus.AdviceActivity">
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png
index cde69bc..7377ed1 100644
Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png
index c133a0c..529ecf5 100644
Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
index bfa42f0..4e0a609 100644
Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
index 324e72c..75de77c 100644
Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
index aee44e1..33f066d 100644
Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/b/.gitignore b/b/.gitignore
deleted file mode 100644
index c6cbe56..0000000
--- a/b/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-*.iml
-.gradle
-/local.properties
-/.idea/workspace.xml
-/.idea/libraries
-.DS_Store
-/build
-/captures
diff --git a/b/b.iml b/b/b.iml
deleted file mode 100644
index ae05e44..0000000
--- a/b/b.iml
+++ /dev/null
@@ -1,148 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- generateDebugSources
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/b/proguard-rules.pro b/b/proguard-rules.pro
deleted file mode 100644
index e5ae8d8..0000000
--- a/b/proguard-rules.pro
+++ /dev/null
@@ -1,17 +0,0 @@
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in /Users/air/Library/Android/sdk/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the proguardFiles
-# directive in build.gradle.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# Add any project specific keep options here:
-
-# 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 *;
-#}
diff --git a/b/src/main/AndroidManifest.xml b/b/src/main/AndroidManifest.xml
deleted file mode 100644
index 424fce1..0000000
--- a/b/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/b/src/main/java/com/cangwang/b/BActivity.java b/b/src/main/java/com/cangwang/b/BActivity.java
deleted file mode 100644
index 6317c76..0000000
--- a/b/src/main/java/com/cangwang/b/BActivity.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package com.cangwang.b;
-
-import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.v7.app.AppCompatActivity;
-import android.util.Log;
-import android.widget.TextView;
-
-
-/**
- * Created by air on 2016/12/5.
- */
-public class BActivity extends AppCompatActivity {
- private static final String TAG = "BActivity";
- TextView textView;
-
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_b);
- Bundle bundle = getIntent().getExtras();
- textView = (TextView) findViewById(R.id.b_act_text);
- textView.setText(bundle.getString("from"));
-
- Log.v(TAG,"onCreate");
- }
-
-
- @Override
- protected void onResume() {
- Log.v(TAG,"onResume");
- super.onResume();
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- }
-}
diff --git a/b/src/main/java/com/cangwang/b/FragmentB.java b/b/src/main/java/com/cangwang/b/FragmentB.java
deleted file mode 100644
index 91bea99..0000000
--- a/b/src/main/java/com/cangwang/b/FragmentB.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package com.cangwang.b;
-
-import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Button;
-import android.widget.TextView;
-
-import com.cangwang.base.IFBClient;
-import com.cangwang.core.IBaseClient;
-import com.cangwang.core.ModuleBus;
-import com.cangwang.core.ModuleEvent;
-
-/**
- * Created by air on 16/11/18.
- */
-
-public class FragmentB extends Fragment {
- private TextView bText;
- private Button bAdd;
- int i=0;
- @Override
- public void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- }
-
- @Nullable
- @Override
- public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.layout_b,container,false);
- bText = (TextView) view.findViewById(R.id.b_txt);
- bAdd = (Button) view.findViewById(R.id.b_add);
- bAdd.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- int number = (int)ModuleBus.getInstance().postSingle(IFBClient.class,"addNum",i);
- bText.setText("N:"+number);
- }
- });
- ModuleBus.getInstance().register(this);
- return view;
- }
-
- @Override
- public void onDestroyView() {
- ModuleBus.getInstance().unregister(this);
- super.onDestroyView();
- }
-
- @ModuleEvent(coreClientClass = IFBClient.class)
- public void changeText(String text){
- bText.setText("N:"+text);
- }
-
-
-}
diff --git a/b/src/main/res/layout/layout_b.xml b/b/src/main/res/layout/layout_b.xml
deleted file mode 100644
index 3cb8882..0000000
--- a/b/src/main/res/layout/layout_b.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/b/src/main/res/values/strings.xml b/b/src/main/res/values/strings.xml
deleted file mode 100644
index 718d765..0000000
--- a/b/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-
- b
-
diff --git a/base/base.iml b/base/base.iml
deleted file mode 100644
index 5e06982..0000000
--- a/base/base.iml
+++ /dev/null
@@ -1,146 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- generateDebugSources
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/base/build.gradle b/base/build.gradle
index 546335b..e489be6 100644
--- a/base/build.gradle
+++ b/base/build.gradle
@@ -5,6 +5,7 @@ if(isDebug) {
apply plugin: 'com.android.library'
}
apply from: "${rootProject.rootDir}/common_config.gradle"
+apply plugin: 'kotlin-android'
android {
compileSdkVersion project.ext.compileSdkVersion
@@ -15,7 +16,6 @@ android {
targetSdkVersion project.ext.targetSdkVersion
versionCode 1
versionName "1.0"
-
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
@@ -25,15 +25,29 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
-
+ lintOptions {
+ abortOnError false
+ }
}
dependencies {
- compile fileTree(include: ['*.jar'], dir: 'libs')
- androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
- exclude group: 'com.android.support', module: 'support-annotations'
- })
+ api fileTree(include: ['*.jar'], dir: 'libs')
// compile 'com.cangwang.core:modulebus:1.0'
- compile 'com.android.support:appcompat-v7:25.0.1'
- compile project(':core')
+ api 'androidx.appcompat:appcompat:1.3.1'
+ api 'com.google.android.material:material:1.4.0'
+ api 'io.reactivex.rxjava2:rxjava:2.1.11'
+ api 'androidx.recyclerview:recyclerview:1.2.1'
+ api 'io.reactivex.rxjava2:rxandroid:2.0.2'
+ api "androidx.core:core-ktx:1.6.0"
+ api project(':core')
+ api "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+}
+
+tasks.whenTaskAdded { task ->
+ if (task.name.equals("lint")) {
+ task.enabled = false
+ }
}
+repositories {
+ mavenCentral()
+}
\ No newline at end of file
diff --git a/base/src/main/java/com/cangwang/base/IFBClient.java b/base/src/main/java/com/cangwang/base/IFBClient.java
deleted file mode 100644
index d3a460b..0000000
--- a/base/src/main/java/com/cangwang/base/IFBClient.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.cangwang.base;
-
-
-import com.cangwang.core.IBaseClient;
-
-/**
- * Created by air on 16/11/22.
- */
-
-public class IFBClient extends IBaseClient {
-}
diff --git a/base/src/main/java/com/cangwang/base/IFBClient.kt b/base/src/main/java/com/cangwang/base/IFBClient.kt
new file mode 100644
index 0000000..c0df6aa
--- /dev/null
+++ b/base/src/main/java/com/cangwang/base/IFBClient.kt
@@ -0,0 +1,8 @@
+package com.cangwang.base
+
+import com.cangwang.core.IBaseClient
+
+/**
+ * Created by air on 16/11/22.
+ */
+class IFBClient : IBaseClient()
\ No newline at end of file
diff --git a/base/src/main/java/com/cangwang/base/api/AnchorApi.kt b/base/src/main/java/com/cangwang/base/api/AnchorApi.kt
new file mode 100644
index 0000000..66fbb73
--- /dev/null
+++ b/base/src/main/java/com/cangwang/base/api/AnchorApi.kt
@@ -0,0 +1,11 @@
+package com.cangwang.base.api
+
+import androidx.fragment.app.FragmentActivity
+import com.cangwang.core.MBaseApi
+
+/**
+ * Created by cangwang on 2018/2/7.
+ */
+interface AnchorApi : MBaseApi {
+ fun showAnchor(context: FragmentActivity?, user: String?, url: String?)
+}
\ No newline at end of file
diff --git a/base/src/main/java/com/cangwang/base/api/BottomApi.kt b/base/src/main/java/com/cangwang/base/api/BottomApi.kt
new file mode 100644
index 0000000..3e56a06
--- /dev/null
+++ b/base/src/main/java/com/cangwang/base/api/BottomApi.kt
@@ -0,0 +1,10 @@
+package com.cangwang.base.api
+
+import com.cangwang.core.MBaseApi
+
+/**
+ * Created by cangwang on 2018/2/24.
+ */
+interface BottomApi : MBaseApi {
+ fun show()
+}
\ No newline at end of file
diff --git a/base/src/main/java/com/cangwang/base/api/ChatApi.kt b/base/src/main/java/com/cangwang/base/api/ChatApi.kt
new file mode 100644
index 0000000..8dff8c2
--- /dev/null
+++ b/base/src/main/java/com/cangwang/base/api/ChatApi.kt
@@ -0,0 +1,10 @@
+package com.cangwang.base.api
+
+import com.cangwang.core.MBaseApi
+
+/**
+ * Created by cangwang on 2018/2/5.
+ */
+interface ChatApi : MBaseApi {
+ fun addChatMsg(user: String?, text: String?): Boolean
+}
\ No newline at end of file
diff --git a/base/src/main/java/com/cangwang/base/api/GiftApi.kt b/base/src/main/java/com/cangwang/base/api/GiftApi.kt
new file mode 100644
index 0000000..804b57b
--- /dev/null
+++ b/base/src/main/java/com/cangwang/base/api/GiftApi.kt
@@ -0,0 +1,11 @@
+package com.cangwang.base.api
+
+import com.cangwang.core.MBaseApi
+
+/**
+ * Created by cangwang on 2018/2/24.
+ */
+interface GiftApi : MBaseApi {
+ fun show()
+ fun hide()
+}
\ No newline at end of file
diff --git a/base/src/main/java/com/cangwang/base/api/PageNameApi.kt b/base/src/main/java/com/cangwang/base/api/PageNameApi.kt
new file mode 100644
index 0000000..9a3aaba
--- /dev/null
+++ b/base/src/main/java/com/cangwang/base/api/PageNameApi.kt
@@ -0,0 +1,10 @@
+package com.cangwang.base.api
+
+import com.cangwang.core.MBaseApi
+
+/**
+ * Created by cangwang on 2018/1/7.
+ */
+interface PageNameApi : MBaseApi {
+ fun changeNameTxt(name: String?)
+}
\ No newline at end of file
diff --git a/base/src/main/java/com/cangwang/base/api/SlideApi.kt b/base/src/main/java/com/cangwang/base/api/SlideApi.kt
new file mode 100644
index 0000000..7e37956
--- /dev/null
+++ b/base/src/main/java/com/cangwang/base/api/SlideApi.kt
@@ -0,0 +1,11 @@
+package com.cangwang.base.api
+
+import com.cangwang.core.MBaseApi
+
+/**
+ * Created by cangwang on 2018/2/10.
+ */
+interface SlideApi : MBaseApi {
+ fun show()
+ fun hide()
+}
\ No newline at end of file
diff --git a/base/src/main/java/com/cangwang/base/api/SplashApi.kt b/base/src/main/java/com/cangwang/base/api/SplashApi.kt
new file mode 100644
index 0000000..4b8356b
--- /dev/null
+++ b/base/src/main/java/com/cangwang/base/api/SplashApi.kt
@@ -0,0 +1,10 @@
+package com.cangwang.base.api
+
+import com.cangwang.core.MBaseApi
+
+/**
+ * Created by cangwang on 2018/2/11.
+ */
+interface SplashApi : MBaseApi {
+ fun splash()
+}
\ No newline at end of file
diff --git a/base/src/main/java/com/cangwang/base/api/WebApi.kt b/base/src/main/java/com/cangwang/base/api/WebApi.kt
new file mode 100644
index 0000000..68f0734
--- /dev/null
+++ b/base/src/main/java/com/cangwang/base/api/WebApi.kt
@@ -0,0 +1,11 @@
+package com.cangwang.base.api
+
+import com.cangwang.core.MBaseApi
+
+/**
+ * Created by cangwang on 2018/2/6.
+ */
+interface WebApi : MBaseApi {
+ fun loadWeb(url: String?, title: String?)
+ fun removeWeb()
+}
\ No newline at end of file
diff --git a/base/src/main/java/com/cangwang/base/ui/CircleImageView.kt b/base/src/main/java/com/cangwang/base/ui/CircleImageView.kt
new file mode 100644
index 0000000..35f4a74
--- /dev/null
+++ b/base/src/main/java/com/cangwang/base/ui/CircleImageView.kt
@@ -0,0 +1,378 @@
+/*
+ * Copyright 2014 - 2017 Henning Dodenhof
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.cangwang.base.ui
+
+import androidx.appcompat.widget.AppCompatImageView
+
+import com.cangwang.base.R
+import android.content.Context
+import android.graphics.*
+import android.graphics.drawable.Drawable
+import androidx.annotation.ColorRes
+import androidx.annotation.DrawableRes
+import android.graphics.drawable.BitmapDrawable
+import android.graphics.drawable.ColorDrawable
+import android.net.Uri
+import android.os.Build
+import androidx.annotation.RequiresApi
+import android.view.ViewOutlineProvider
+import android.util.AttributeSet
+import android.view.View
+import java.lang.Exception
+
+class CircleImageView : AppCompatImageView {
+ private val mDrawableRect = RectF()
+ private val mBorderRect = RectF()
+ private val mShaderMatrix = Matrix()
+ private val mBitmapPaint: Paint? = Paint()
+ private val mBorderPaint = Paint()
+ private val mCircleBackgroundPaint = Paint()
+ private var mBorderColor = DEFAULT_BORDER_COLOR
+ private var mBorderWidth = DEFAULT_BORDER_WIDTH
+ private var mCircleBackgroundColor = DEFAULT_CIRCLE_BACKGROUND_COLOR
+ private var mBitmap: Bitmap? = null
+ private var mBitmapShader: BitmapShader? = null
+ private var mBitmapWidth = 0
+ private var mBitmapHeight = 0
+ private var mDrawableRadius = 0f
+ private var mBorderRadius = 0f
+ private var mColorFilter: ColorFilter? = null
+ private var mReady = false
+ private var mSetupPending = false
+ private var mBorderOverlay = false
+ private var mDisableCircularTransformation = false
+
+ constructor(context: Context?) : super(context!!) {
+ init()
+ }
+
+ @JvmOverloads
+ constructor(context: Context, attrs: AttributeSet?, defStyle: Int = 0) : super(context, attrs, defStyle) {
+ val a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0)
+ mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_civ_border_width, DEFAULT_BORDER_WIDTH)
+ mBorderColor = a.getColor(R.styleable.CircleImageView_civ_border_color, DEFAULT_BORDER_COLOR)
+ mBorderOverlay = a.getBoolean(R.styleable.CircleImageView_civ_border_overlay, DEFAULT_BORDER_OVERLAY)
+
+ // Look for deprecated civ_fill_color if civ_circle_background_color is not set
+ if (a.hasValue(R.styleable.CircleImageView_civ_circle_background_color)) {
+ mCircleBackgroundColor = a.getColor(R.styleable.CircleImageView_civ_circle_background_color,
+ DEFAULT_CIRCLE_BACKGROUND_COLOR)
+ } else if (a.hasValue(R.styleable.CircleImageView_civ_fill_color)) {
+ mCircleBackgroundColor = a.getColor(R.styleable.CircleImageView_civ_fill_color,
+ DEFAULT_CIRCLE_BACKGROUND_COLOR)
+ }
+ a.recycle()
+ init()
+ }
+
+ private fun init() {
+ super.setScaleType(SCALE_TYPE)
+ mReady = true
+ outlineProvider = OutlineProvider()
+ if (mSetupPending) {
+ setup()
+ mSetupPending = false
+ }
+ }
+
+ override fun getScaleType(): ScaleType {
+ return SCALE_TYPE
+ }
+
+ override fun setScaleType(scaleType: ScaleType) {
+ require(scaleType == SCALE_TYPE) { String.format("ScaleType %s not supported.", scaleType) }
+ }
+
+ override fun setAdjustViewBounds(adjustViewBounds: Boolean) {
+ require(!adjustViewBounds) { "adjustViewBounds not supported." }
+ }
+
+ override fun onDraw(canvas: Canvas) {
+ if (mDisableCircularTransformation) {
+ super.onDraw(canvas)
+ return
+ }
+ if (mBitmap == null) {
+ return
+ }
+ if (mCircleBackgroundColor != Color.TRANSPARENT) {
+ canvas.drawCircle(mDrawableRect.centerX(), mDrawableRect.centerY(), mDrawableRadius, mCircleBackgroundPaint)
+ }
+ canvas.drawCircle(mDrawableRect.centerX(), mDrawableRect.centerY(), mDrawableRadius, mBitmapPaint!!)
+ if (mBorderWidth > 0) {
+ canvas.drawCircle(mBorderRect.centerX(), mBorderRect.centerY(), mBorderRadius, mBorderPaint)
+ }
+ }
+
+ override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
+ super.onSizeChanged(w, h, oldw, oldh)
+ setup()
+ }
+
+ override fun setPadding(left: Int, top: Int, right: Int, bottom: Int) {
+ super.setPadding(left, top, right, bottom)
+ setup()
+ }
+
+ override fun setPaddingRelative(start: Int, top: Int, end: Int, bottom: Int) {
+ super.setPaddingRelative(start, top, end, bottom)
+ setup()
+ }
+
+ var borderColor: Int
+ get() = mBorderColor
+ set(borderColor) {
+ if (borderColor == mBorderColor) {
+ return
+ }
+ mBorderColor = borderColor
+ mBorderPaint.color = mBorderColor
+ invalidate()
+ }
+
+ @Deprecated("Use {@link #setBorderColor(int)} instead")
+ fun setBorderColorResource(@ColorRes borderColorRes: Int) {
+ borderColor = context.resources.getColor(borderColorRes)
+ }
+
+ var circleBackgroundColor: Int
+ get() = mCircleBackgroundColor
+ set(circleBackgroundColor) {
+ if (circleBackgroundColor == mCircleBackgroundColor) {
+ return
+ }
+ mCircleBackgroundColor = circleBackgroundColor
+ mCircleBackgroundPaint.color = circleBackgroundColor
+ invalidate()
+ }
+
+ fun setCircleBackgroundColorResource(@ColorRes circleBackgroundRes: Int) {
+ circleBackgroundColor = context.resources.getColor(circleBackgroundRes)
+ }
+ /**
+ * Return the color drawn behind the circle-shaped drawable.
+ *
+ * @return The color drawn behind the drawable
+ *
+ */
+ /**
+ * Set a color to be drawn behind the circle-shaped drawable. Note that
+ * this has no effect if the drawable is opaque or no drawable is set.
+ *
+ * @param fillColor The color to be drawn behind the drawable
+ *
+ */
+ @get:Deprecated("Use {@link #getCircleBackgroundColor()} instead.")
+ @set:Deprecated("Use {@link #setCircleBackgroundColor(int)} instead.")
+ var fillColor: Int
+ get() = circleBackgroundColor
+ set(fillColor) {
+ circleBackgroundColor = fillColor
+ }
+
+ /**
+ * Set a color to be drawn behind the circle-shaped drawable. Note that
+ * this has no effect if the drawable is opaque or no drawable is set.
+ *
+ * @param fillColorRes The color resource to be resolved to a color and
+ * drawn behind the drawable
+ *
+ */
+ @Deprecated("Use {@link #setCircleBackgroundColorResource(int)} instead.")
+ fun setFillColorResource(@ColorRes fillColorRes: Int) {
+ setCircleBackgroundColorResource(fillColorRes)
+ }
+
+ var borderWidth: Int
+ get() = mBorderWidth
+ set(borderWidth) {
+ if (borderWidth == mBorderWidth) {
+ return
+ }
+ mBorderWidth = borderWidth
+ setup()
+ }
+ var isBorderOverlay: Boolean
+ get() = mBorderOverlay
+ set(borderOverlay) {
+ if (borderOverlay == mBorderOverlay) {
+ return
+ }
+ mBorderOverlay = borderOverlay
+ setup()
+ }
+ var isDisableCircularTransformation: Boolean
+ get() = mDisableCircularTransformation
+ set(disableCircularTransformation) {
+ if (mDisableCircularTransformation == disableCircularTransformation) {
+ return
+ }
+ mDisableCircularTransformation = disableCircularTransformation
+ initializeBitmap()
+ }
+
+ override fun setImageBitmap(bm: Bitmap) {
+ super.setImageBitmap(bm)
+ initializeBitmap()
+ }
+
+ override fun setImageDrawable(drawable: Drawable?) {
+ super.setImageDrawable(drawable)
+ initializeBitmap()
+ }
+
+ override fun setImageResource(@DrawableRes resId: Int) {
+ super.setImageResource(resId)
+ initializeBitmap()
+ }
+
+ override fun setImageURI(uri: Uri?) {
+ super.setImageURI(uri)
+ initializeBitmap()
+ }
+
+ override fun setColorFilter(cf: ColorFilter) {
+ if (cf === mColorFilter) {
+ return
+ }
+ mColorFilter = cf
+ applyColorFilter()
+ invalidate()
+ }
+
+ override fun getColorFilter(): ColorFilter {
+ return mColorFilter!!
+ }
+
+ private fun applyColorFilter() {
+ if (mBitmapPaint != null) {
+ mBitmapPaint.colorFilter = mColorFilter
+ }
+ }
+
+ private fun getBitmapFromDrawable(drawable: Drawable?): Bitmap? {
+ if (drawable == null) {
+ return null
+ }
+ return if (drawable is BitmapDrawable) {
+ drawable.bitmap
+ } else try {
+ val bitmap: Bitmap
+ bitmap = if (drawable is ColorDrawable) {
+ Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG)
+ } else {
+ Bitmap.createBitmap(drawable.intrinsicWidth, drawable.intrinsicHeight, BITMAP_CONFIG)
+ }
+ val canvas = Canvas(bitmap)
+ drawable.setBounds(0, 0, canvas.width, canvas.height)
+ drawable.draw(canvas)
+ bitmap
+ } catch (e: Exception) {
+ e.printStackTrace()
+ null
+ }
+ }
+
+ private fun initializeBitmap() {
+ mBitmap = if (mDisableCircularTransformation) {
+ null
+ } else {
+ getBitmapFromDrawable(drawable)
+ }
+ setup()
+ }
+
+ private fun setup() {
+ if (!mReady) {
+ mSetupPending = true
+ return
+ }
+ if (width == 0 && height == 0) {
+ return
+ }
+ if (mBitmap == null) {
+ invalidate()
+ return
+ }
+ mBitmapShader = BitmapShader(mBitmap!!, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)
+ mBitmapPaint!!.isAntiAlias = true
+ mBitmapPaint.shader = mBitmapShader
+ mBorderPaint.style = Paint.Style.STROKE
+ mBorderPaint.isAntiAlias = true
+ mBorderPaint.color = mBorderColor
+ mBorderPaint.strokeWidth = mBorderWidth.toFloat()
+ mCircleBackgroundPaint.style = Paint.Style.FILL
+ mCircleBackgroundPaint.isAntiAlias = true
+ mCircleBackgroundPaint.color = mCircleBackgroundColor
+ mBitmapHeight = mBitmap!!.height
+ mBitmapWidth = mBitmap!!.width
+ mBorderRect.set(calculateBounds())
+ mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2.0f, (mBorderRect.width() - mBorderWidth) / 2.0f)
+ mDrawableRect.set(mBorderRect)
+ if (!mBorderOverlay && mBorderWidth > 0) {
+ mDrawableRect.inset(mBorderWidth - 1.0f, mBorderWidth - 1.0f)
+ }
+ mDrawableRadius = Math.min(mDrawableRect.height() / 2.0f, mDrawableRect.width() / 2.0f)
+ applyColorFilter()
+ updateShaderMatrix()
+ invalidate()
+ }
+
+ private fun calculateBounds(): RectF {
+ val availableWidth = width - paddingLeft - paddingRight
+ val availableHeight = height - paddingTop - paddingBottom
+ val sideLength = Math.min(availableWidth, availableHeight)
+ val left = paddingLeft + (availableWidth - sideLength) / 2f
+ val top = paddingTop + (availableHeight - sideLength) / 2f
+ return RectF(left, top, left + sideLength, top + sideLength)
+ }
+
+ private fun updateShaderMatrix() {
+ val scale: Float
+ var dx = 0f
+ var dy = 0f
+ mShaderMatrix.set(null)
+ if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) {
+ scale = mDrawableRect.height() / mBitmapHeight.toFloat()
+ dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f
+ } else {
+ scale = mDrawableRect.width() / mBitmapWidth.toFloat()
+ dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f
+ }
+ mShaderMatrix.setScale(scale, scale)
+ mShaderMatrix.postTranslate((dx + 0.5f).toInt() + mDrawableRect.left, (dy + 0.5f).toInt() + mDrawableRect.top)
+ mBitmapShader!!.setLocalMatrix(mShaderMatrix)
+ }
+
+ @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
+ private inner class OutlineProvider : ViewOutlineProvider() {
+ override fun getOutline(view: View, outline: Outline) {
+ val bounds = Rect()
+ mBorderRect.roundOut(bounds)
+ outline.setRoundRect(bounds, bounds.width() / 2.0f)
+ }
+ }
+
+ companion object {
+ private val SCALE_TYPE = ScaleType.CENTER_CROP
+ private val BITMAP_CONFIG = Bitmap.Config.ARGB_8888
+ private const val COLORDRAWABLE_DIMENSION = 2
+ private const val DEFAULT_BORDER_WIDTH = 0
+ private const val DEFAULT_BORDER_COLOR = Color.BLACK
+ private const val DEFAULT_CIRCLE_BACKGROUND_COLOR = Color.TRANSPARENT
+ private const val DEFAULT_BORDER_OVERLAY = false
+ }
+}
\ No newline at end of file
diff --git a/base/src/main/java/com/cangwang/base/ui/circleprogress/CircleProgressBar.kt b/base/src/main/java/com/cangwang/base/ui/circleprogress/CircleProgressBar.kt
new file mode 100644
index 0000000..a3dd320
--- /dev/null
+++ b/base/src/main/java/com/cangwang/base/ui/circleprogress/CircleProgressBar.kt
@@ -0,0 +1,345 @@
+package com.cangwang.base.ui.circleprogress
+
+import androidx.appcompat.widget.AppCompatImageView
+import android.view.animation.Animation
+import android.graphics.drawable.ShapeDrawable
+import com.cangwang.base.R
+import android.annotation.SuppressLint
+import android.content.Context
+import android.graphics.*
+import android.graphics.drawable.shapes.OvalShape
+import android.graphics.drawable.Drawable
+import androidx.annotation.ColorRes
+import android.net.Uri
+import android.os.Build
+import android.util.AttributeSet
+import androidx.core.view.ViewCompat
+
+/**
+ * Created by cangwang on 2017/3/31.
+ */
+/**
+ * Private class created to work around issues with AnimationListeners being
+ * called before the animation is actually complete and support shadows on older
+ * platforms.
+ */
+class CircleProgressBar : AppCompatImageView {
+ private var mListener: Animation.AnimationListener? = null
+ private var mShadowRadius = 0
+ private var mBackGroundColor = 0
+ private var mProgressColor = 0
+ private var mProgressStokeWidth = 0
+ private var mArrowWidth = 0
+ private var mArrowHeight = 0
+ private var mProgress = 0
+ var max = 0
+ private var mDiameter = 0
+ private var mInnerRadius = 0
+ private var mTextPaint: Paint? = null
+ private var mTextColor = 0
+ private var mTextSize = 0
+ var isShowProgressText = false
+ var isShowArrow = false
+ private var mProgressDrawable: MaterialProgressDrawable? = null
+ private var mBgCircle: ShapeDrawable? = null
+ private var mCircleBackgroundEnabled = false
+ private var mColors = intArrayOf(Color.BLACK)
+
+ constructor(context: Context) : super(context) {
+ init(context, null, 0)
+ }
+
+ constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
+ init(context, attrs, 0)
+ }
+
+ constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
+ init(context, attrs, defStyleAttr)
+ }
+
+ private fun init(context: Context, attrs: AttributeSet?, defStyleAttr: Int) {
+ val a = context.obtainStyledAttributes(
+ attrs, R.styleable.CircleProgressBar, defStyleAttr, 0)
+ //
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+ val density = getContext().resources.displayMetrics.density
+ mBackGroundColor = a.getColor(
+ R.styleable.CircleProgressBar_mlpb_background_color, DEFAULT_CIRCLE_BG_LIGHT)
+ mProgressColor = a.getColor(
+ R.styleable.CircleProgressBar_mlpb_progress_color, DEFAULT_CIRCLE_BG_LIGHT)
+ mColors = intArrayOf(mProgressColor)
+ mInnerRadius = a.getDimensionPixelOffset(
+ R.styleable.CircleProgressBar_mlpb_inner_radius, -1)
+ mProgressStokeWidth = a.getDimensionPixelOffset(
+ R.styleable.CircleProgressBar_mlpb_progress_stoke_width, (STROKE_WIDTH_LARGE * density).toInt())
+ mArrowWidth = a.getDimensionPixelOffset(
+ R.styleable.CircleProgressBar_mlpb_arrow_width, -1)
+ mArrowHeight = a.getDimensionPixelOffset(
+ R.styleable.CircleProgressBar_mlpb_arrow_height, -1)
+ mTextSize = a.getDimensionPixelOffset(
+ R.styleable.CircleProgressBar_mlpb_progress_text_size, (DEFAULT_TEXT_SIZE * density).toInt())
+ mTextColor = a.getColor(
+ R.styleable.CircleProgressBar_mlpb_progress_text_color, Color.BLACK)
+ isShowArrow = a.getBoolean(R.styleable.CircleProgressBar_mlpb_show_arrow, false)
+ mCircleBackgroundEnabled = a.getBoolean(R.styleable.CircleProgressBar_mlpb_enable_circle_background, true)
+ mProgress = a.getInt(R.styleable.CircleProgressBar_mlpb_progress, 0)
+ max = a.getInt(R.styleable.CircleProgressBar_mlpb_max, 100)
+ val textVisible = a.getInt(R.styleable.CircleProgressBar_mlpb_progress_text_visibility, 1)
+ if (textVisible != 1) {
+ isShowProgressText = true
+ }
+ mTextPaint = Paint()
+ mTextPaint!!.style = Paint.Style.FILL
+ mTextPaint!!.color = mTextColor
+ mTextPaint!!.textSize = mTextSize.toFloat()
+ mTextPaint!!.isAntiAlias = true
+ a.recycle()
+ mProgressDrawable = MaterialProgressDrawable(getContext(), this)
+ super.setImageDrawable(mProgressDrawable)
+ }
+
+ private fun elevationSupported(): Boolean {
+ return Build.VERSION.SDK_INT >= 21
+ }
+
+ override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec)
+ if (!elevationSupported()) {
+ setMeasuredDimension(measuredWidth + mShadowRadius * 2, measuredHeight
+ + mShadowRadius * 2)
+ }
+ }
+
+ @SuppressLint("WrongConstant")
+ override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
+ super.onLayout(changed, left, top, right, bottom)
+ val density = context.resources.displayMetrics.density
+ mDiameter = Math.min(measuredWidth, measuredHeight)
+ if (mDiameter <= 0) {
+ mDiameter = density.toInt() * DEFAULT_CIRCLE_DIAMETER
+ }
+ if (background == null && mCircleBackgroundEnabled) {
+ val shadowYOffset = (density * Y_OFFSET).toInt()
+ val shadowXOffset = (density * X_OFFSET).toInt()
+ mShadowRadius = (density * SHADOW_RADIUS).toInt()
+ if (elevationSupported()) {
+ mBgCircle = ShapeDrawable(OvalShape())
+ ViewCompat.setElevation(this, SHADOW_ELEVATION * density)
+ } else {
+ val oval: OvalShape = OvalShadow(mShadowRadius, mDiameter - mShadowRadius * 2)
+ mBgCircle = ShapeDrawable(oval)
+ ViewCompat.setLayerType(this, ViewCompat.LAYER_TYPE_SOFTWARE, mBgCircle!!.paint)
+ mBgCircle!!.paint.setShadowLayer(mShadowRadius.toFloat(), shadowXOffset.toFloat(), shadowYOffset.toFloat(),
+ KEY_SHADOW_COLOR)
+ val padding = mShadowRadius
+ // set padding so the inner image sits correctly within the shadow.
+ setPadding(padding, padding, padding, padding)
+ }
+ mBgCircle!!.paint.color = mBackGroundColor
+ setBackgroundDrawable(mBgCircle)
+ }
+ mProgressDrawable!!.setBackgroundColor(mBackGroundColor)
+ mProgressDrawable!!.setColorSchemeColors(*mColors)
+ mProgressDrawable!!.setSizeParameters(mDiameter.toDouble(), mDiameter.toDouble(),
+ if (mInnerRadius <= 0) ((mDiameter - mProgressStokeWidth * 2) / 4).toDouble() else mInnerRadius.toDouble(),
+ mProgressStokeWidth.toDouble(),
+ if (mArrowWidth < 0) (mProgressStokeWidth * 4).toFloat() else mArrowWidth.toFloat(),
+ if (mArrowHeight < 0) (mProgressStokeWidth * 2).toFloat() else mArrowHeight.toFloat())
+ if (isShowArrow) {
+ mProgressDrawable!!.showArrowOnFirstStart(true)
+ mProgressDrawable!!.setArrowScale(1f)
+ mProgressDrawable!!.showArrow(true)
+ }
+ super.setImageDrawable(null)
+ super.setImageDrawable(mProgressDrawable)
+ mProgressDrawable!!.alpha = 255
+ if (visibility == VISIBLE) {
+ mProgressDrawable!!.start()
+ }
+ }
+
+ override fun onDraw(canvas: Canvas) {
+ super.onDraw(canvas)
+ if (isShowProgressText) {
+ val text = String.format("%s%%", mProgress)
+ val x = width / 2 - text.length * mTextSize / 4
+ val y = height / 2 + mTextSize / 4
+ canvas.drawText(text, x.toFloat(), y.toFloat(), mTextPaint!!)
+ }
+ }
+
+ override fun setImageResource(resId: Int) {}
+ override fun setImageURI(uri: Uri?) {
+ super.setImageURI(uri)
+ }
+
+ override fun setImageDrawable(drawable: Drawable?) {}
+ fun setAnimationListener(listener: Animation.AnimationListener?) {
+ mListener = listener
+ }
+
+ public override fun onAnimationStart() {
+ super.onAnimationStart()
+ if (mListener != null) {
+ mListener!!.onAnimationStart(animation)
+ }
+ }
+
+ public override fun onAnimationEnd() {
+ super.onAnimationEnd()
+ if (mListener != null) {
+ mListener!!.onAnimationEnd(animation)
+ }
+ }
+
+ /**
+ * Set the color resources used in the progress animation from color resources.
+ * The first color will also be the color of the bar that grows in response
+ * to a user swipe gesture.
+ *
+ * @param colorResIds
+ */
+ fun setColorSchemeResources(vararg colorResIds: Int) {
+ val res = resources
+ val colorRes = IntArray(colorResIds.size)
+ for (i in 0 until colorResIds.size) {
+ colorRes[i] = res.getColor(colorResIds[i])
+ }
+ setColorSchemeColors(*colorRes)
+ }
+
+ /**
+ * Set the colors used in the progress animation. The first
+ * color will also be the color of the bar that grows in response to a user
+ * swipe gesture.
+ *
+ * @param colors
+ */
+ fun setColorSchemeColors(vararg colors: Int) {
+ mColors = colors
+ if (mProgressDrawable != null) {
+ mProgressDrawable!!.setColorSchemeColors(*colors)
+ }
+ }
+
+ /**
+ * Update the background color of the mBgCircle image view.
+ */
+ @SuppressLint("ResourceType")
+ override fun setBackgroundColor(@ColorRes colorRes: Int) {
+ if (background is ShapeDrawable) {
+ val res = resources
+ (background as ShapeDrawable).paint.color = res.getColor(colorRes)
+ }
+ }
+
+ var progress: Int
+ get() = mProgress
+ set(progress) {
+ if (max > 0) {
+ mProgress = progress
+ }
+ }
+
+ fun circleBackgroundEnabled(): Boolean {
+ return mCircleBackgroundEnabled
+ }
+
+ fun setCircleBackgroundEnabled(enableCircleBackground: Boolean) {
+ mCircleBackgroundEnabled = enableCircleBackground
+ }
+
+ override fun getVisibility(): Int {
+ return super.getVisibility()
+ }
+
+ override fun setVisibility(visibility: Int) {
+ super.setVisibility(visibility)
+ if (mProgressDrawable != null) {
+ mProgressDrawable!!.setVisible(visibility == VISIBLE, false)
+ if (visibility != VISIBLE) {
+ mProgressDrawable!!.stop()
+ } else {
+ if (mProgressDrawable!!.isRunning) {
+ mProgressDrawable!!.stop()
+ }
+ mProgressDrawable!!.start()
+ }
+ }
+ }
+
+ override fun onAttachedToWindow() {
+ super.onAttachedToWindow()
+ if (mProgressDrawable != null) {
+ mProgressDrawable!!.stop()
+ mProgressDrawable!!.setVisible(visibility == VISIBLE, false)
+ requestLayout()
+ }
+ }
+
+ override fun onDetachedFromWindow() {
+ super.onDetachedFromWindow()
+ if (mProgressDrawable != null) {
+ mProgressDrawable!!.stop()
+ mProgressDrawable!!.setVisible(false, false)
+ }
+ }
+
+ private inner class OvalShadow(shadowRadius: Int, circleDiameter: Int) : OvalShape() {
+ private val mRadialGradient: RadialGradient
+ private val mShadowRadius: Int
+ private val mShadowPaint: Paint
+ private val mCircleDiameter: Int
+ override fun draw(canvas: Canvas, paint: Paint) {
+ val viewWidth = this@CircleProgressBar.width
+ val viewHeight = this@CircleProgressBar.height
+ canvas.drawCircle((viewWidth / 2).toFloat(), (viewHeight / 2).toFloat(), (mCircleDiameter / 2 + mShadowRadius).toFloat(),
+ mShadowPaint)
+ canvas.drawCircle((viewWidth / 2).toFloat(), (viewHeight / 2).toFloat(), (mCircleDiameter / 2).toFloat(), paint)
+ }
+
+ init {
+ mShadowPaint = Paint()
+ mShadowRadius = shadowRadius
+ mCircleDiameter = circleDiameter
+ mRadialGradient = RadialGradient((mCircleDiameter / 2).toFloat(), (mCircleDiameter / 2).toFloat(),
+ mShadowRadius.toFloat(), intArrayOf(
+ FILL_SHADOW_COLOR, Color.TRANSPARENT
+ ), null, Shader.TileMode.CLAMP)
+ mShadowPaint.shader = mRadialGradient
+ }
+ }
+
+ companion object {
+ private const val KEY_SHADOW_COLOR = 0x1E000000
+ private const val FILL_SHADOW_COLOR = 0x3D000000
+
+ // PX
+ private const val X_OFFSET = 0f
+ private const val Y_OFFSET = 1.75f
+ private const val SHADOW_RADIUS = 3.5f
+ private const val SHADOW_ELEVATION = 4
+ private const val DEFAULT_CIRCLE_BG_LIGHT = -0x50506
+ private const val DEFAULT_CIRCLE_DIAMETER = 56
+ private const val STROKE_WIDTH_LARGE = 3
+ const val DEFAULT_TEXT_SIZE = 9
+ }
+}
\ No newline at end of file
diff --git a/base/src/main/java/com/cangwang/base/ui/circleprogress/MaterialProgressDrawable.kt b/base/src/main/java/com/cangwang/base/ui/circleprogress/MaterialProgressDrawable.kt
new file mode 100644
index 0000000..82153ae
--- /dev/null
+++ b/base/src/main/java/com/cangwang/base/ui/circleprogress/MaterialProgressDrawable.kt
@@ -0,0 +1,631 @@
+package com.cangwang.base.ui.circleprogress
+
+import android.view.animation.Animation
+import android.content.Context
+import android.content.res.Resources
+import android.graphics.*
+import androidx.annotation.IntDef
+import android.view.animation.AccelerateDecelerateInterpolator
+import android.view.animation.LinearInterpolator
+import android.graphics.drawable.*
+import android.view.View
+import android.view.animation.Interpolator
+import android.view.animation.Transformation
+import java.lang.annotation.Retention
+import java.lang.annotation.RetentionPolicy
+import java.util.ArrayList
+
+/**
+ * Created by Administrator on 2017/3/31.
+ */
+/**
+ * Fancy progress indicator for Material theme.
+ *
+ * @hide
+ */
+class MaterialProgressDrawable(context: Context, private val mAnimExcutor: View) : Drawable(), Animatable {
+ private val COLORS = intArrayOf(
+ Color.BLACK
+ )
+
+ /**
+ * The list of animators operating on this drawable.
+ */
+ private val mAnimators = ArrayList()
+
+ /**
+ * The indicator ring, used to manage animation state.
+ */
+ private val mRing: Ring
+ private val mCallback: Callback = object : Callback {
+ override fun invalidateDrawable(d: Drawable) {
+ invalidateSelf()
+ }
+
+ override fun scheduleDrawable(d: Drawable, what: Runnable, `when`: Long) {
+ scheduleSelf(what, `when`)
+ }
+
+ override fun unscheduleDrawable(d: Drawable, what: Runnable) {
+ unscheduleSelf(what)
+ }
+ }
+ var mFinishing = false
+
+ /**
+ * Canvas rotation in degrees.
+ */
+ private var mRotation = 0f
+ private val mResources: Resources
+ private var mAnimation: Animation? = null
+ private var mRotationCount = 0f
+ private var mWidth = 0.0
+ private var mHeight = 0.0
+ private var mShowArrowOnFirstStart = false
+ fun setSizeParameters(progressCircleWidth: Double, progressCircleHeight: Double,
+ centerRadius: Double, strokeWidth: Double, arrowWidth: Float, arrowHeight: Float) {
+ val ring = mRing
+ mWidth = progressCircleWidth
+ mHeight = progressCircleHeight
+ ring.strokeWidth = strokeWidth.toFloat()
+ ring.centerRadius = centerRadius
+ ring.setColorIndex(0)
+ ring.setArrowDimensions(arrowWidth, arrowHeight)
+ ring.setInsets(mWidth.toInt(), mHeight.toInt())
+ }
+
+ /**
+ * Set the overall size for the progress spinner. This updates the radius
+ * and stroke width of the ring.
+ *
+ * @param size One of [MaterialProgressDrawable.LARGE] or
+ * [MaterialProgressDrawable.DEFAULT]
+ */
+ fun updateSizes(@ProgressDrawableSize size: Int) {
+ val metrics = mResources.displayMetrics
+ val screenDensity = metrics.density
+ if (size == LARGE) {
+ setSizeParameters((CIRCLE_DIAMETER_LARGE * screenDensity).toDouble(), (CIRCLE_DIAMETER_LARGE * screenDensity).toDouble(), (CENTER_RADIUS_LARGE * screenDensity).toDouble(), (
+ STROKE_WIDTH_LARGE * screenDensity).toDouble(), ARROW_WIDTH_LARGE * screenDensity, ARROW_HEIGHT_LARGE * screenDensity)
+ } else {
+ setSizeParameters((CIRCLE_DIAMETER * screenDensity).toDouble(), (CIRCLE_DIAMETER * screenDensity).toDouble(), (CENTER_RADIUS * screenDensity).toDouble(), (STROKE_WIDTH * screenDensity).toDouble(),
+ ARROW_WIDTH * screenDensity, ARROW_HEIGHT * screenDensity)
+ }
+ }
+
+ /**
+ * @param show Set to true to display the arrowhead on the progress spinner.
+ */
+ fun showArrow(show: Boolean) {
+ mRing.setShowArrow(show)
+ }
+
+ /**
+ * @param scale Set the scale of the arrowhead for the spinner.
+ */
+ fun setArrowScale(scale: Float) {
+ mRing.setArrowScale(scale)
+ }
+
+ /**
+ * Set the start and end trim for the progress spinner arc.
+ *
+ * @param startAngle start angle
+ * @param endAngle end angle
+ */
+ fun setStartEndTrim(startAngle: Float, endAngle: Float) {
+ mRing.startTrim = startAngle
+ mRing.endTrim = endAngle
+ }
+
+ /**
+ * Set the amount of rotation to apply to the progress spinner.
+ *
+ * @param rotation Rotation is from [0..1]
+ */
+ fun setProgressRotation(rotation: Float) {
+ mRing.rotation = rotation
+ }
+
+ /**
+ * Update the background color of the circle image view.
+ */
+ fun setBackgroundColor(color: Int) {
+ mRing.setBackgroundColor(color)
+ }
+
+ /**
+ * Set the colors used in the progress animation from color resources.
+ * The first color will also be the color of the bar that grows in response
+ * to a user swipe gesture.
+ *
+ * @param colors
+ */
+ fun setColorSchemeColors(vararg colors: Int) {
+ mRing.setColors(colors)
+ mRing.setColorIndex(0)
+ }
+
+ override fun getIntrinsicHeight(): Int {
+ return mHeight.toInt()
+ }
+
+ override fun getIntrinsicWidth(): Int {
+ return mWidth.toInt()
+ }
+
+ override fun draw(c: Canvas) {
+ val bounds = bounds
+ val saveCount = c.save()
+ c.rotate(mRotation, bounds.exactCenterX(), bounds.exactCenterY())
+ mRing.draw(c, bounds)
+ c.restoreToCount(saveCount)
+ }
+
+ override fun getAlpha(): Int {
+ return mRing.alpha
+ }
+
+ override fun setAlpha(alpha: Int) {
+ mRing.alpha = alpha
+ }
+
+ override fun setColorFilter(colorFilter: ColorFilter?) {
+ mRing.setColorFilter(colorFilter)
+ }
+
+ private var rotation: Float
+ private get() = mRotation
+ set(rotation) {
+ mRotation = rotation
+ invalidateSelf()
+ }
+
+ override fun getOpacity(): Int {
+ return PixelFormat.TRANSLUCENT
+ }
+
+ override fun isRunning(): Boolean {
+ return mAnimation!!.hasStarted() && !mAnimation!!.hasEnded()
+ }
+
+ override fun start() {
+ mAnimation!!.reset()
+ mRing.storeOriginals()
+ mRing.setShowArrow(mShowArrowOnFirstStart)
+
+ // Already showing some part of the ring
+ if (mRing.endTrim != mRing.startTrim) {
+ mFinishing = true
+ mAnimation!!.duration = (ANIMATION_DURATION / 2).toLong()
+ mAnimExcutor.startAnimation(mAnimation)
+ } else {
+ mRing.setColorIndex(0)
+ mRing.resetOriginals()
+ mAnimation!!.duration = ANIMATION_DURATION.toLong()
+ mAnimExcutor.startAnimation(mAnimation)
+ }
+ }
+
+ override fun stop() {
+ mAnimExcutor.clearAnimation()
+ rotation = 0f
+ mRing.setShowArrow(false)
+ mRing.setColorIndex(0)
+ mRing.resetOriginals()
+ }
+
+ private fun applyFinishTranslation(interpolatedTime: Float, ring: Ring) {
+ // shrink back down and complete a full rotation before
+ // starting other circles
+ // Rotation goes between [0..1].
+ val targetRotation = (Math.floor((ring.startingRotation / MAX_PROGRESS_ARC).toDouble())
+ + 1f).toFloat()
+ val startTrim = (ring.startingStartTrim
+ + (ring.startingEndTrim - ring.startingStartTrim) * interpolatedTime)
+ ring.startTrim = startTrim
+ val rotation = (ring.startingRotation
+ + (targetRotation - ring.startingRotation) * interpolatedTime)
+ ring.rotation = rotation
+ }
+
+ private fun setupAnimators() {
+ val ring = mRing
+ val animation: Animation = object : Animation() {
+ public override fun applyTransformation(interpolatedTime: Float, t: Transformation) {
+ if (mFinishing) {
+ applyFinishTranslation(interpolatedTime, ring)
+ } else {
+ // The minProgressArc is calculated from 0 to create an
+ // angle that
+ // matches the stroke width.
+ val minProgressArc = Math.toRadians(
+ ring.strokeWidth / (2 * Math.PI * ring.centerRadius)).toFloat()
+ val startingEndTrim = ring.startingEndTrim
+ val startingTrim = ring.startingStartTrim
+ val startingRotation = ring.startingRotation
+
+ // Offset the minProgressArc to where the endTrim is
+ // located.
+ val minArc = MAX_PROGRESS_ARC - minProgressArc
+ var endTrim = startingEndTrim + (minArc
+ * START_CURVE_INTERPOLATOR.getInterpolation(interpolatedTime))
+ val startTrim = startingTrim + (MAX_PROGRESS_ARC
+ * END_CURVE_INTERPOLATOR.getInterpolation(interpolatedTime))
+ val sweepTrim = endTrim - startTrim
+ //Avoid the ring to be a full circle
+ if (Math.abs(sweepTrim) >= 1) {
+ endTrim = startTrim + 0.5f
+ }
+ ring.endTrim = endTrim
+ ring.startTrim = startTrim
+ var rotation = startingRotation + 0.25f * interpolatedTime
+ ring.rotation = rotation
+ val groupRotation = (720.0f / NUM_POINTS * interpolatedTime
+ + 720.0f * (mRotationCount / NUM_POINTS))
+ rotation = groupRotation
+
+ // If this view is removed by parent
+ // clear the anim
+ if (mAnimExcutor.parent == null) stop()
+ }
+ }
+ }
+ animation.repeatCount = Animation.INFINITE
+ animation.repeatMode = Animation.RESTART
+ animation.interpolator = LINEAR_INTERPOLATOR
+ animation.setAnimationListener(object : Animation.AnimationListener {
+ override fun onAnimationStart(animation: Animation) {
+ mRotationCount = 0f
+ }
+
+ override fun onAnimationEnd(animation: Animation) {
+ // do nothing
+ }
+
+ override fun onAnimationRepeat(animation: Animation) {
+ ring.storeOriginals()
+ ring.goToNextColor()
+ ring.startTrim = ring.endTrim
+ if (mFinishing) {
+ // finished closing the last ring from the swipe gesture; go
+ // into progress mode
+ mFinishing = false
+ animation.duration = ANIMATION_DURATION.toLong()
+ ring.setShowArrow(false)
+ } else {
+ mRotationCount = (mRotationCount + 1) % NUM_POINTS
+ }
+ }
+ })
+ mAnimation = animation
+ }
+
+ fun showArrowOnFirstStart(showArrowOnFirstStart: Boolean) {
+ mShowArrowOnFirstStart = showArrowOnFirstStart
+ }
+
+ @Retention(RetentionPolicy.CLASS)
+ @IntDef(LARGE, DEFAULT)
+ annotation class ProgressDrawableSize
+ private class Ring(private val mCallback: Callback) {
+ private val mTempBounds = RectF()
+ private val mPaint = Paint()
+ private val mArrowPaint = Paint()
+ private val mCirclePaint = Paint()
+ private var mStartTrim = 0.0f
+ private var mEndTrim = 0.0f
+ private var mRotation = 0.0f
+ private var mStrokeWidth = 5.0f
+ private var mDrawable: Drawable? = null
+ var insets = 2.5f
+ private set
+ private lateinit var mColors: IntArray
+
+ // mColorIndex represents the offset into the available mColors that the
+ // progress circle should currently display. As the progress circle is
+ // animating, the mColorIndex moves by one to the next available color.
+ private var mColorIndex = 0
+ var startingStartTrim = 0f
+ private set
+ var startingEndTrim = 0f
+ private set
+
+ /**
+ * @return The amount the progress spinner is currently rotated, between [0..1].
+ */
+ var startingRotation = 0f
+ private set
+ private var mShowArrow = false
+ private var mArrow: Path? = null
+ private var mArrowScale = 0f
+
+ /**
+ * @param centerRadius Inner radius in px of the circle the progress
+ * spinner arc traces.
+ */
+ var centerRadius = 0.0
+ private var mArrowWidth = 0
+ private var mArrowHeight = 0
+ /**
+ * @return Current alpha of the progress spinner and arrowhead.
+ */
+ /**
+ * @param alpha Set the alpha of the progress spinner and associated arrowhead.
+ */
+ var alpha = 0
+ private var mBackgroundColor = 0
+ fun setBackgroundColor(color: Int) {
+ mBackgroundColor = color
+ }
+
+ /**
+ * Set the dimensions of the arrowhead.
+ *
+ * @param width Width of the hypotenuse of the arrow head
+ * @param height Height of the arrow point
+ */
+ fun setArrowDimensions(width: Float, height: Float) {
+ mArrowWidth = width.toInt()
+ mArrowHeight = height.toInt()
+ }
+
+ /**
+ * Draw the progress spinner
+ */
+ fun draw(c: Canvas, bounds: Rect) {
+ val arcBounds = mTempBounds
+ arcBounds.set(bounds)
+ arcBounds.inset(insets, insets)
+ val startAngle = (mStartTrim + mRotation) * 360
+ val endAngle = (mEndTrim + mRotation) * 360
+ val sweepAngle = endAngle - startAngle
+ mPaint.color = mColors[mColorIndex]
+ c.drawArc(arcBounds, startAngle, sweepAngle, false, mPaint)
+ drawTriangle(c, startAngle, sweepAngle, bounds)
+ if (alpha < 255) {
+ mCirclePaint.color = mBackgroundColor
+ mCirclePaint.alpha = 255 - alpha
+ c.drawCircle(bounds.exactCenterX(), bounds.exactCenterY(), (bounds.width() / 2).toFloat(),
+ mCirclePaint)
+ }
+ }
+
+ private fun drawTriangle(c: Canvas, startAngle: Float, sweepAngle: Float, bounds: Rect) {
+ if (mShowArrow) {
+ if (mArrow == null) {
+ mArrow = Path()
+ mArrow!!.fillType = Path.FillType.EVEN_ODD
+ } else {
+ mArrow!!.reset()
+ }
+
+ // Adjust the position of the triangle so that it is inset as
+ // much as the arc, but also centered on the arc.
+ val x = (centerRadius * Math.cos(0.0) + bounds.exactCenterX()).toFloat()
+ val y = (centerRadius * Math.sin(0.0) + bounds.exactCenterY()).toFloat()
+
+ // Update the path each time. This works around an issue in SKIA
+ // where concatenating a rotation matrix to a scale matrix
+ // ignored a starting negative rotation. This appears to have
+ // been fixed as of API 21.
+ mArrow!!.moveTo(0f, 0f)
+ mArrow!!.lineTo(mArrowWidth * mArrowScale, 0f)
+ mArrow!!.lineTo(mArrowWidth * mArrowScale / 2, mArrowHeight
+ * mArrowScale)
+ mArrow!!.offset(x - mArrowWidth * mArrowScale / 2, y)
+ mArrow!!.close()
+ // draw a triangle
+ mArrowPaint.color = mColors[mColorIndex]
+ //when sweepAngle < 0 adjust the position of the arrow
+ c.rotate(startAngle + (if (sweepAngle < 0f) 0f else sweepAngle) - ARROW_OFFSET_ANGLE, bounds.exactCenterX(),
+ bounds.exactCenterY())
+ c.drawPath(mArrow!!, mArrowPaint)
+ }
+ }
+
+ /**
+ * Set the colors the progress spinner alternates between.
+ *
+ * @param colors Array of integers describing the colors. Must be non-`null`.
+ */
+ fun setColors(colors: IntArray) {
+ mColors = colors
+ // if colors are reset, make sure to reset the color index as well
+ setColorIndex(0)
+ }
+
+ /**
+ * @param index Index into the color array of the color to display in
+ * the progress spinner.
+ */
+ fun setColorIndex(index: Int) {
+ mColorIndex = index
+ }
+ fun setDrawable(drawable: Drawable) {
+ mDrawable = drawable
+ }
+
+ /**
+ * Proceed to the next available ring color. This will automatically
+ * wrap back to the beginning of colors.
+ */
+ fun goToNextColor() {
+ mColorIndex = (mColorIndex + 1) % mColors.size
+ }
+
+ fun setColorFilter(filter: ColorFilter?) {
+ mPaint.colorFilter = filter
+ invalidateSelf()
+ }
+
+ /**
+ * @param strokeWidth Set the stroke width of the progress spinner in pixels.
+ */
+ var strokeWidth: Float
+ get() = mStrokeWidth
+ set(strokeWidth) {
+ mStrokeWidth = strokeWidth
+ mPaint.strokeWidth = strokeWidth
+ invalidateSelf()
+ }
+ var startTrim: Float
+ get() = mStartTrim
+ set(startTrim) {
+ mStartTrim = startTrim
+ invalidateSelf()
+ }
+ var endTrim: Float
+ get() = mEndTrim
+ set(endTrim) {
+ mEndTrim = endTrim
+ invalidateSelf()
+ }
+ var rotation: Float
+ get() = mRotation
+ set(rotation) {
+ mRotation = rotation
+ invalidateSelf()
+ }
+
+ fun setInsets(width: Int, height: Int) {
+ val minEdge = Math.min(width, height).toFloat()
+ val insets: Float
+ insets = if (centerRadius <= 0 || minEdge < 0) {
+ Math.ceil((mStrokeWidth / 2.0f).toDouble()).toFloat()
+ } else {
+ (minEdge / 2.0f - centerRadius).toFloat()
+ }
+ this.insets = insets
+ }
+
+ /**
+ * @param show Set to true to show the arrow head on the progress spinner.
+ */
+ fun setShowArrow(show: Boolean) {
+ if (mShowArrow != show) {
+ mShowArrow = show
+ invalidateSelf()
+ }
+ }
+
+ /**
+ * @param scale Set the scale of the arrowhead for the spinner.
+ */
+ fun setArrowScale(scale: Float) {
+ if (scale != mArrowScale) {
+ mArrowScale = scale
+ invalidateSelf()
+ }
+ }
+
+ /**
+ * If the start / end trim are offset to begin with, store them so that
+ * animation starts from that offset.
+ */
+ fun storeOriginals() {
+ startingStartTrim = mStartTrim
+ startingEndTrim = mEndTrim
+ startingRotation = mRotation
+ }
+
+ /**
+ * Reset the progress spinner to default rotation, start and end angles.
+ */
+ fun resetOriginals() {
+ startingStartTrim = 0f
+ startingEndTrim = 0f
+ startingRotation = 0f
+ startTrim = 0f
+ endTrim = 0f
+ rotation = 0f
+ }
+
+ private fun invalidateSelf() {
+ if (mDrawable != null) {
+ mCallback.invalidateDrawable(mDrawable!!)
+ }
+ }
+
+ init {
+ mPaint.strokeCap = Paint.Cap.SQUARE
+ mPaint.isAntiAlias = true
+ mPaint.style = Paint.Style.STROKE
+ mArrowPaint.style = Paint.Style.FILL
+ mArrowPaint.isAntiAlias = true
+ }
+ }
+
+ /**
+ * Squishes the interpolation curve into the second half of the animation.
+ */
+ private class EndCurveInterpolator : AccelerateDecelerateInterpolator() {
+ override fun getInterpolation(input: Float): Float {
+ return super.getInterpolation(Math.max(0f, (input - 0.5f) * 2.0f))
+ }
+ }
+
+ /**
+ * Squishes the interpolation curve into the first half of the animation.
+ */
+ private class StartCurveInterpolator : AccelerateDecelerateInterpolator() {
+ override fun getInterpolation(input: Float): Float {
+ return super.getInterpolation(Math.min(1f, input * 2.0f))
+ }
+ }
+
+ companion object {
+ // Maps to ProgressBar.Large style
+ const val LARGE = 0
+
+ // Maps to ProgressBar default style
+ const val DEFAULT = 1
+ private val LINEAR_INTERPOLATOR: Interpolator = LinearInterpolator()
+ private val END_CURVE_INTERPOLATOR: Interpolator = EndCurveInterpolator()
+ private val START_CURVE_INTERPOLATOR: Interpolator = StartCurveInterpolator()
+ private val EASE_INTERPOLATOR: Interpolator = AccelerateDecelerateInterpolator()
+
+ // Maps to ProgressBar default style
+ private const val CIRCLE_DIAMETER = 40
+ private const val CENTER_RADIUS = 8.75f //should add up to 10 when + stroke_width
+ private const val STROKE_WIDTH = 2.5f
+
+ // Maps to ProgressBar.Large style
+ private const val CIRCLE_DIAMETER_LARGE = 56
+ private const val CENTER_RADIUS_LARGE = 12.5f
+ const val STROKE_WIDTH_LARGE = 3f
+
+ /**
+ * The duration of a single progress spin in milliseconds.
+ */
+ private const val ANIMATION_DURATION = 1000 * 80 / 60
+
+ /**
+ * The number of points in the progress "star".
+ */
+ private const val NUM_POINTS = 5f
+
+ /**
+ * Layout info for the arrowhead in dp
+ */
+ private const val ARROW_WIDTH = 10
+ private const val ARROW_HEIGHT = 5
+ private const val ARROW_OFFSET_ANGLE = 0f
+
+ /**
+ * Layout info for the arrowhead for the large spinner in dp
+ */
+ const val ARROW_WIDTH_LARGE = 12
+ const val ARROW_HEIGHT_LARGE = 6
+ private const val MAX_PROGRESS_ARC = .8f
+ }
+
+ init {
+ mResources = context.resources
+ mRing = Ring(mCallback)
+ mRing.setColors(COLORS)
+ mRing.setDrawable(this)
+ updateSizes(DEFAULT)
+ setupAnimators()
+ }
+}
\ No newline at end of file
diff --git a/base/src/main/java/com/cangwang/base/util/ColorUtil.kt b/base/src/main/java/com/cangwang/base/util/ColorUtil.kt
new file mode 100644
index 0000000..ce47b27
--- /dev/null
+++ b/base/src/main/java/com/cangwang/base/util/ColorUtil.kt
@@ -0,0 +1,25 @@
+package com.cangwang.base.util
+
+import android.graphics.*
+import java.util.*
+
+/**颜色工具
+ * Created by cangwang on 2018/2/5.
+ */
+object ColorUtil {
+ @JvmStatic
+ val randomColor: Int
+ get() {
+ var r: String
+ var g: String
+ var b: String
+ val random = Random()
+ r = Integer.toHexString(random.nextInt(256)).uppercase()
+ g = Integer.toHexString(random.nextInt(256)).uppercase()
+ b = Integer.toHexString(random.nextInt(256)).uppercase()
+ r = if (r.length == 1) "0$r" else r
+ g = if (g.length == 1) "0$g" else g
+ b = if (b.length == 1) "0$b" else b
+ return Color.parseColor("#$r$g$b")
+ }
+}
\ No newline at end of file
diff --git a/base/src/main/java/com/cangwang/base/util/ViewUtil.kt b/base/src/main/java/com/cangwang/base/util/ViewUtil.kt
new file mode 100644
index 0000000..d6b249f
--- /dev/null
+++ b/base/src/main/java/com/cangwang/base/util/ViewUtil.kt
@@ -0,0 +1,59 @@
+package com.cangwang.base.util
+
+import android.app.Activity
+import android.os.Bundle
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.FragmentManager
+
+/**
+ * Created by cangwang on 2018/2/6.
+ */
+object ViewUtil {
+ @JvmStatic
+ fun replaceFragment(act: Activity?, containerId: Int, manager: FragmentManager?, bundle: Bundle?, cls: Class?, tag: String): Fragment? {
+ if (act == null || act.isFinishing) return null
+ if (act.isDestroyed) return null
+ if (manager == null || cls == null) return null
+ val ft = manager.beginTransaction()
+ val fragment: Fragment = if (bundle != null) Fragment.instantiate(act, cls.canonicalName, bundle) else {
+ Fragment.instantiate(act, cls.canonicalName)
+ }
+ if (!tag.isEmpty()) {
+ ft.replace(containerId, fragment, tag)
+ } else {
+ ft.replace(containerId, fragment)
+ }
+ ft.commitAllowingStateLoss()
+ return fragment
+ }
+
+ @JvmStatic
+ fun removeFragment(act: Activity?, manager: FragmentManager?, tag: String?, executePendingTransactions: Boolean): Fragment? {
+ if (act == null || act.isFinishing) return null
+ if (act.isDestroyed) return null
+ if (manager == null || tag == null) return null
+ val fragment = manager.findFragmentByTag(tag)
+ val ft = manager.beginTransaction()
+ if (fragment != null) {
+ ft.remove(fragment).commitAllowingStateLoss()
+ }
+ if (fragment != null && executePendingTransactions) manager.executePendingTransactions()
+ return fragment
+ }
+
+ @JvmStatic
+ fun hide(manager: FragmentManager, fm: Fragment?) {
+ val transaction = manager.beginTransaction() //Activity中
+ if (fm != null) {
+ transaction.hide(fm)
+ }
+ }
+
+ @JvmStatic
+ fun show(manager: FragmentManager, fm: Fragment?) {
+ val transaction = manager.beginTransaction() //Activity中
+ if (fm != null) {
+ transaction.show(fm)
+ }
+ }
+}
\ No newline at end of file
diff --git a/base/src/main/res/anim/anim_dialog_push_down.xml b/base/src/main/res/anim/anim_dialog_push_down.xml
new file mode 100644
index 0000000..509d09d
--- /dev/null
+++ b/base/src/main/res/anim/anim_dialog_push_down.xml
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/base/src/main/res/anim/anim_dialog_push_up.xml b/base/src/main/res/anim/anim_dialog_push_up.xml
new file mode 100644
index 0000000..2960d37
--- /dev/null
+++ b/base/src/main/res/anim/anim_dialog_push_up.xml
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/base/src/main/res/mipmap-xhdpi/ic_launcher.png b/base/src/main/res/drawable-xhdpi/launcher.png
similarity index 100%
rename from base/src/main/res/mipmap-xhdpi/ic_launcher.png
rename to base/src/main/res/drawable-xhdpi/launcher.png
diff --git a/base/src/main/res/drawable-xhdpi/title.jpg b/base/src/main/res/drawable-xhdpi/title.jpg
new file mode 100644
index 0000000..42d5b69
Binary files /dev/null and b/base/src/main/res/drawable-xhdpi/title.jpg differ
diff --git a/base/src/main/res/values/attrs.xml b/base/src/main/res/values/attrs.xml
new file mode 100644
index 0000000..484322b
--- /dev/null
+++ b/base/src/main/res/values/attrs.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/src/main/res/values/colors.xml b/base/src/main/res/values/colors.xml
index 3ab3e9c..46df547 100644
--- a/base/src/main/res/values/colors.xml
+++ b/base/src/main/res/values/colors.xml
@@ -3,4 +3,41 @@
#3F51B5#303F9F#FF4081
+ #00000000
+ #000001
+
+
+ #BBDEFB
+ #90CAF9
+ #64B5F6
+ #42A5F5
+ #2196F3
+ #1E88E5
+ #1976D2
+ #1565C0
+ #0D47A1
+
+ #82B1FF
+ #448aff
+ #2979ff
+ #2962ff
+
+ #e91e63
+
+ #e8f5e9
+ #c8e6c9
+
+ #b2ebf2
+ #80deea
+ #4dd0e1
+ #26c6da
+ #00bcd4
+ #00acc1
+ #0097a7
+ #00838f
+ #006064
+ #84ffff
+ #18ffff
+ #00e5ff
+ #00b8d4
diff --git a/base/src/main/res/values/styles.xml b/base/src/main/res/values/styles.xml
index 5885930..df66bb3 100644
--- a/base/src/main/res/values/styles.xml
+++ b/base/src/main/res/values/styles.xml
@@ -7,5 +7,8 @@
@color/colorPrimaryDark@color/colorAccent
-
+
diff --git a/page_body_bt/.gitignore b/bottom/.gitignore
similarity index 100%
rename from page_body_bt/.gitignore
rename to bottom/.gitignore
diff --git a/bottom/build.gradle b/bottom/build.gradle
new file mode 100644
index 0000000..7c07309
--- /dev/null
+++ b/bottom/build.gradle
@@ -0,0 +1,50 @@
+apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
+apply from: "${rootProject.rootDir}/common_config.gradle"
+apply plugin: 'kotlin-kapt'
+
+android {
+ compileSdkVersion project.ext.compileSdkVersion
+ buildToolsVersion project.ext.buildToolsVersion
+
+ defaultConfig {
+ minSdkVersion project.ext.minSdkVersion
+ targetSdkVersion project.ext.targetSdkVersion
+
+ versionCode 1
+ versionName "1.0"
+
+ // 资源前缀名,所有资源文件都必须加上这个前缀,以防止与其他插件的资源名字冲突
+ resourcePrefix "bottom_"
+
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ javaCompileOptions {
+ annotationProcessorOptions {
+ arguments = [ moduleName : project.getName() ]
+ }
+ }
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+
+}
+
+kapt {
+ arguments {
+ arg("moduleName", project.getName())
+ }
+}
+
+dependencies {
+ api fileTree(include: ['*.jar'], dir: 'libs')
+ api project(':base')
+ kapt project(":compiler")
+}
+repositories {
+ mavenCentral()
+}
diff --git a/bottom/proguard-rules.pro b/bottom/proguard-rules.pro
new file mode 100644
index 0000000..f1b4245
--- /dev/null
+++ b/bottom/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
diff --git a/bottom/src/main/AndroidManifest.xml b/bottom/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..fd1296c
--- /dev/null
+++ b/bottom/src/main/AndroidManifest.xml
@@ -0,0 +1,2 @@
+
diff --git a/bottom/src/main/assets/center.json b/bottom/src/main/assets/center.json
new file mode 100644
index 0000000..16ba077
--- /dev/null
+++ b/bottom/src/main/assets/center.json
@@ -0,0 +1,10 @@
+[
+ {
+ "path":"com.cangwang.bottom.BottomModule",
+ "templet":"top",
+ "title":"BottomModule",
+ "layoutLevel":400,
+ "extraLevel":0
+ }
+
+]
diff --git a/bottom/src/main/java/com/cangwang/bottom/BottomModule.kt b/bottom/src/main/java/com/cangwang/bottom/BottomModule.kt
new file mode 100644
index 0000000..3ca1474
--- /dev/null
+++ b/bottom/src/main/java/com/cangwang/bottom/BottomModule.kt
@@ -0,0 +1,74 @@
+package com.cangwang.bottom
+
+import com.cangwang.core.cwmodule.ex.CWBasicExModule
+import com.cangwang.core.cwmodule.CWModuleContext
+import android.os.Bundle
+import android.view.View
+import com.cangwang.core.ModuleApiManager
+import com.cangwang.base.api.BottomApi
+import com.cangwang.annotation.ModuleGroup
+import com.cangwang.annotation.ModuleUnit
+import com.cangwang.enums.LayoutLevel
+import com.cangwang.base.ui.CircleImageView
+import com.cangwang.base.api.SlideApi
+import com.cangwang.base.api.GiftApi
+
+/**
+ * 底部栏
+ * Created by cangwang on 2018/2/10.
+ */
+@ModuleGroup(ModuleUnit(templet = "top", layoutlevel = LayoutLevel.LOW))
+class BottomModule : CWBasicExModule(), BottomApi {
+ private var moreBtn: CircleImageView? = null
+ private var chatBtn: CircleImageView? = null
+ private var giftBtn: CircleImageView? = null
+ private var bottomLayout: View? = null
+ private var ipM: InputModule? = null
+ override fun onCreate(moduleContext: CWModuleContext, extend: Bundle?): Boolean {
+ super.onCreate(moduleContext, extend)
+ initView()
+ registerMApi(BottomApi::class.java, this)
+ return true
+ }
+
+ fun initView() {
+ setContentView(R.layout.bottom_layout)
+ bottomLayout = findViewById(R.id.bottom_layout)
+ bottomLayout?.setOnClickListener(View.OnClickListener { })
+ chatBtn = findViewById(R.id.bottom_chat)
+ chatBtn?.setOnClickListener(View.OnClickListener {
+ bottomLayout?.visibility = View.GONE
+ if (ipM == null) {
+ ipM = InputModule()
+ ipM?.onCreate(moduleContext!!, null)
+ } else {
+ ipM?.setVisible(true)
+ }
+ })
+ moreBtn = findViewById(R.id.bottom_more_btn)
+ moreBtn?.setOnClickListener(View.OnClickListener { ModuleApiManager.instance.getApi(SlideApi::class.java)?.show() })
+ giftBtn = findViewById(R.id.bottom_gift)
+ giftBtn?.setOnClickListener(View.OnClickListener { // ModuleApiManager.getInstance().getApi(SplashApi.class).splash();
+ ModuleApiManager.instance.getApi(GiftApi::class.java)?.show()
+ })
+ }
+
+ // @Override
+ // public boolean onBackPress() {
+ // if (ipM!=null && ipM.isVisible()){
+ // ipM.setVisible(false);
+ // if (bottomLayout.getVisibility() == View.GONE)
+ // bottomLayout.setVisibility(View.VISIBLE);
+ // return true;
+ // }
+ // return false;
+ // }
+ override fun onDestroy() {
+ ipM = null
+ super.onDestroy()
+ }
+
+ override fun show() {
+ if (bottomLayout!!.visibility == View.GONE) bottomLayout!!.visibility = View.VISIBLE
+ }
+}
\ No newline at end of file
diff --git a/bottom/src/main/java/com/cangwang/bottom/InputModule.kt b/bottom/src/main/java/com/cangwang/bottom/InputModule.kt
new file mode 100644
index 0000000..3bc95ab
--- /dev/null
+++ b/bottom/src/main/java/com/cangwang/bottom/InputModule.kt
@@ -0,0 +1,73 @@
+package com.cangwang.bottom
+
+import com.cangwang.core.cwmodule.ex.CWBasicExModule
+import com.cangwang.core.cwmodule.api.ModuleBackpress
+import android.widget.EditText
+import com.cangwang.core.cwmodule.CWModuleContext
+import android.os.Bundle
+import android.view.View
+import android.widget.ImageView
+import com.cangwang.core.ModuleApiManager
+import com.cangwang.base.api.ChatApi
+import android.widget.Toast
+import android.widget.TextView.OnEditorActionListener
+import com.cangwang.base.api.BottomApi
+
+/**输入模块
+ * Created by cangwang on 2018/2/5.
+ */
+//@ModuleUnit(templet = "top",layoutlevel = LayoutLevel.LOW)
+class InputModule : CWBasicExModule(), ModuleBackpress {
+ private var inputText: EditText? = null
+ private var inputBtn: ImageView? = null
+ override fun onCreate(moduleContext: CWModuleContext, extend: Bundle?): Boolean {
+ super.onCreate(moduleContext, extend)
+ initView()
+ return true
+ }
+
+ fun initView() {
+ setContentView(R.layout.bottom_input_layout)
+ inputText = findViewById(R.id.bottom_input_txt)
+ inputBtn = findViewById(R.id.bottom_input_btn)
+ inputBtn?.setOnClickListener(View.OnClickListener {
+ val text = inputText?.text.toString()
+ if (text.isNotEmpty()) {
+ val result = ModuleApiManager.instance.getApi(ChatApi::class.java)?.addChatMsg("cangwang", text) ?: false
+ if (result) {
+ Toast.makeText(context, "发送成功", Toast.LENGTH_SHORT).show()
+ inputText?.setText("")
+ }
+ }
+ })
+ inputText?.setOnEditorActionListener(OnEditorActionListener { textView, i, keyEvent ->
+ val text = inputText?.text.toString()
+ if (text.isNotEmpty()) {
+ val result = ModuleApiManager.instance.getApi(ChatApi::class.java)?.addChatMsg("cangwang", text) ?: false
+ if (result) {
+ Toast.makeText(context, "发送成功", Toast.LENGTH_SHORT).show()
+ inputText?.setText("")
+ }
+ }
+ true
+ })
+ }
+
+ override fun onBackPress(): Boolean {
+ hideModule()
+ ModuleApiManager.instance.getApi(BottomApi::class.java)?.show()
+ return true
+ }
+
+ override fun hideModule() {
+ super.hideModule()
+ }
+
+ override fun showModule() {
+ super.showModule()
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ }
+}
\ No newline at end of file
diff --git a/bottom/src/main/res/layout/bottom_input_layout.xml b/bottom/src/main/res/layout/bottom_input_layout.xml
new file mode 100644
index 0000000..be4d5ba
--- /dev/null
+++ b/bottom/src/main/res/layout/bottom_input_layout.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
diff --git a/bottom/src/main/res/layout/bottom_layout.xml b/bottom/src/main/res/layout/bottom_layout.xml
new file mode 100644
index 0000000..f2da3b7
--- /dev/null
+++ b/bottom/src/main/res/layout/bottom_layout.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
diff --git a/bottom/src/main/res/values/strings.xml b/bottom/src/main/res/values/strings.xml
new file mode 100644
index 0000000..08cbc74
--- /dev/null
+++ b/bottom/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ bottom
+
diff --git a/build.gradle b/build.gradle
index 53f4fad..f2f2e7a 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,23 +1,63 @@
-// Top-level build file where you can add configuration options common to all sub-projects/modules.
-
-buildscript {
- repositories {
- jcenter()
- }
- dependencies {
- classpath 'com.android.tools.build:gradle:2.2.1'
-
- // NOTE: Do not place your application dependencies here; they belong
- // in the individual module build.gradle files
- }
-}
-
-allprojects {
- repositories {
- jcenter()
- }
-}
-
-task clean(type: Delete) {
- delete rootProject.buildDir
-}
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+buildscript {
+ ext.kotlin_version = '1.5.31'
+ repositories {
+ jcenter()
+ maven {
+ url "https://plugins.gradle.org/m2/"
+ }
+ maven {
+ url 'https://maven.google.com/'
+ name 'Google'
+ }
+
+ repositories {
+ maven {
+ url uri(rootProject.rootDir.absolutePath+"/repo")
+ }
+ }
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:4.2.2'
+// classpath "gradle.plugin.com.dorongold.plugins:task-tree:1.3"
+// classpath 'cz.malohlava:visteg:1.0.3'
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+// classpath 'com.cangwang.plugins:generate:1.0.0'
+// classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
+// NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ maven {
+ url 'https://maven.google.com/'
+ name 'Google'
+ }
+ }
+// apply plugin: "com.dorongold.task-tree"
+// apply plugin: 'cz.malohlava.visteg'
+// plugins {
+// id 'cz.malohlava.visteg' version '1.0.3'
+// }
+
+}
+
+//visteg {
+// enabled = true
+// colouredNodes = true
+// colouredEdges = true
+// destination = 'build/reports/visteg.dot'
+// exporter = 'dot'
+// colorscheme = 'spectral11'
+// nodeShape = 'box'
+// startNodeShape = 'hexagon'
+// endNodeShape = 'doubleoctagon'
+//}
+
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/page_name/.gitignore b/chat/.gitignore
similarity index 100%
rename from page_name/.gitignore
rename to chat/.gitignore
diff --git a/chat/build.gradle b/chat/build.gradle
new file mode 100644
index 0000000..2bd22ab
--- /dev/null
+++ b/chat/build.gradle
@@ -0,0 +1,47 @@
+apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
+apply from: "${rootProject.rootDir}/common_config.gradle"
+apply plugin: 'kotlin-kapt'
+
+android {
+ compileSdkVersion project.ext.compileSdkVersion
+ buildToolsVersion project.ext.buildToolsVersion
+
+ defaultConfig {
+ minSdkVersion project.ext.minSdkVersion
+ targetSdkVersion project.ext.targetSdkVersion
+
+ versionCode 1
+ versionName "1.0"
+
+ // 资源前缀名,所有资源文件都必须加上这个前缀,以防止与其他插件的资源名字冲突
+ resourcePrefix "chat_"
+
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+
+}
+
+kapt {
+ arguments {
+ arg("moduleName", project.getName())
+ }
+}
+
+dependencies {
+ api fileTree(include: ['*.jar'], dir: 'libs')
+ api project(':base')
+ kapt project(":compiler")
+}
+repositories {
+ mavenCentral()
+}
+
+//apply plugin: "generate"
diff --git a/chat/proguard-rules.pro b/chat/proguard-rules.pro
new file mode 100644
index 0000000..f1b4245
--- /dev/null
+++ b/chat/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
diff --git a/chat/src/main/AndroidManifest.xml b/chat/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..3c0b498
--- /dev/null
+++ b/chat/src/main/AndroidManifest.xml
@@ -0,0 +1,2 @@
+
diff --git a/chat/src/main/assets/center.json b/chat/src/main/assets/center.json
new file mode 100644
index 0000000..580fce4
--- /dev/null
+++ b/chat/src/main/assets/center.json
@@ -0,0 +1,10 @@
+[
+ {
+ "path":"com.cangwang.chat.ChatModule",
+ "templet":"top",
+ "title":"ChatModule",
+ "layoutLevel":400,
+ "extraLevel":0
+ }
+
+]
diff --git a/chat/src/main/java/com/cangwang/chat/ChatImpl.kt b/chat/src/main/java/com/cangwang/chat/ChatImpl.kt
new file mode 100644
index 0000000..05007f0
--- /dev/null
+++ b/chat/src/main/java/com/cangwang/chat/ChatImpl.kt
@@ -0,0 +1,6 @@
+package com.cangwang.chat
+
+/**
+ * Created by cangwang on 2018/2/5.
+ */
+class ChatImpl
\ No newline at end of file
diff --git a/chat/src/main/java/com/cangwang/chat/ChatModule.kt b/chat/src/main/java/com/cangwang/chat/ChatModule.kt
new file mode 100644
index 0000000..b3c1ef8
--- /dev/null
+++ b/chat/src/main/java/com/cangwang/chat/ChatModule.kt
@@ -0,0 +1,94 @@
+package com.cangwang.chat
+
+import androidx.recyclerview.widget.RecyclerView
+import com.cangwang.chat.bean.ChatMessage
+import com.cangwang.annotation.ModuleGroup
+import com.cangwang.annotation.ModuleUnit
+import com.cangwang.enums.LayoutLevel
+import com.cangwang.core.cwmodule.ex.CWBasicExModule
+import com.cangwang.base.api.ChatApi
+import com.cangwang.chat.recycle.ChatAdapter
+import com.cangwang.core.cwmodule.CWModuleContext
+import android.os.Bundle
+import androidx.recyclerview.widget.LinearLayoutManager
+import java.util.ArrayList
+
+/**
+ * 发言模块
+ * Created by cangwang on 2018/2/3.
+ */
+@ModuleGroup(ModuleUnit(templet = "top", layoutlevel = LayoutLevel.LOW))
+class ChatModule : CWBasicExModule(), ChatApi {
+ private var chatRecyle: RecyclerView? = null
+ private var adapter: ChatAdapter? = null
+ private var i = 10
+ private var isScolling = false
+ override fun onCreate(moduleContext: CWModuleContext, extend: Bundle?): Boolean {
+ super.onCreate(moduleContext, extend)
+ initView()
+ initData()
+ registerMApi(ChatApi::class.java, this)
+ return true
+ }
+
+ private fun initView() {
+ setContentView(R.layout.chat_layout)
+ chatRecyle = findViewById(R.id.chat_recyle)
+ adapter = ChatAdapter(context)
+ chatRecyle?.layoutManager = LinearLayoutManager(context)
+ chatRecyle?.addOnScrollListener(object : RecyclerView.OnScrollListener() {
+ override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
+ super.onScrollStateChanged(recyclerView, newState)
+ isScolling = newState == RecyclerView.SCROLL_STATE_IDLE
+ }
+
+ override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
+ super.onScrolled(recyclerView, dx, dy)
+ }
+ })
+ chatRecyle?.adapter = adapter
+ }
+
+ private fun initData() {
+ val list: MutableList = ArrayList()
+ for (i in 0..9) {
+ val m = ChatMessage("cw", "abc $i")
+ list.add(m)
+ }
+ adapter!!.addMsgList(list)
+ chatRecyle!!.smoothScrollToPosition(10)
+ handler?.post(runChat)
+ }
+
+ var runChat: Runnable = object : Runnable {
+ override fun run() {
+ if (i < 50) {
+ adapter!!.addMsg(ChatMessage("cw", "efg" + i++))
+ if (isScolling) chatRecyle!!.smoothScrollToPosition(adapter!!.itemCount)
+ handler?.postDelayed(this, 3000)
+ }
+ }
+ }
+
+ override fun onResume() {
+ super.onResume()
+ handler?.post(runChat)
+ }
+
+ override fun onPause() {
+ super.onPause()
+ handler?.removeCallbacks(runChat)
+ }
+
+ override fun addChatMsg(user: String?, text: String?): Boolean {
+ adapter?.addMsg(ChatMessage(user, text))
+ chatRecyle?.smoothScrollToPosition(adapter!!.itemCount)
+ return true
+ }
+
+ override fun onDestroy() {
+ handler?.removeCallbacks(runChat)
+ unregisterMApi(ChatApi::class.java)
+ super.onDestroy()
+ }
+}
\ No newline at end of file
diff --git a/chat/src/main/java/com/cangwang/chat/bean/ChatMessage.kt b/chat/src/main/java/com/cangwang/chat/bean/ChatMessage.kt
new file mode 100644
index 0000000..751afe7
--- /dev/null
+++ b/chat/src/main/java/com/cangwang/chat/bean/ChatMessage.kt
@@ -0,0 +1,31 @@
+package com.cangwang.chat.bean
+
+import com.cangwang.base.util.ColorUtil.randomColor
+import com.cangwang.annotation.ModuleBean
+import com.cangwang.base.util.ColorUtil
+import androidx.recyclerview.widget.RecyclerView
+import com.cangwang.chat.recycle.ChatAdapter.ChatHolder
+import com.cangwang.chat.bean.ChatMessage
+import android.view.LayoutInflater
+import com.cangwang.chat.R
+import com.cangwang.annotation.ModuleGroup
+import com.cangwang.annotation.ModuleUnit
+import com.cangwang.enums.LayoutLevel
+import com.cangwang.core.cwmodule.ex.CWBasicExModule
+import com.cangwang.base.api.ChatApi
+import com.cangwang.chat.recycle.ChatAdapter
+import com.cangwang.core.cwmodule.CWModuleContext
+import android.os.Bundle
+import androidx.recyclerview.widget.LinearLayoutManager
+
+/**发言条目
+ * Created by cangwang on 2018/2/5.
+ */
+@ModuleBean
+class ChatMessage(var user: String?, var text: String?) {
+ var color: Int
+
+ init {
+ color = randomColor
+ }
+}
\ No newline at end of file
diff --git a/chat/src/main/java/com/cangwang/chat/recycle/ChatAdapter.kt b/chat/src/main/java/com/cangwang/chat/recycle/ChatAdapter.kt
new file mode 100644
index 0000000..cbe3ceb
--- /dev/null
+++ b/chat/src/main/java/com/cangwang/chat/recycle/ChatAdapter.kt
@@ -0,0 +1,53 @@
+package com.cangwang.chat.recycle
+
+import android.content.Context
+import androidx.recyclerview.widget.RecyclerView
+import com.cangwang.chat.recycle.ChatAdapter.ChatHolder
+import com.cangwang.chat.bean.ChatMessage
+import android.view.LayoutInflater
+import com.cangwang.chat.R
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import java.util.ArrayList
+
+/**发言适配器
+ * Created by cangwang on 2018/2/5.
+ */
+class ChatAdapter(private val context: Context?) : RecyclerView.Adapter() {
+ private val list: MutableList = ArrayList()
+ fun addMsg(message: ChatMessage?) {
+ if (message != null) {
+ list.add(message)
+ notifyDataSetChanged()
+ }
+ }
+
+ fun addMsgList(list: List?) {
+ this.list.addAll(list!!)
+ notifyDataSetChanged()
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChatHolder {
+ val view = LayoutInflater.from(parent.context).inflate(R.layout.chat_item, parent, false)
+ return ChatHolder(view)
+ }
+
+ override fun onBindViewHolder(holder: ChatHolder, position: Int) {
+ val message = list[position]
+ holder.chatText.text = message.user + ": " + message.text
+ holder.chatText.setTextColor(message.color)
+ }
+
+ override fun getItemCount(): Int {
+ return list.size
+ }
+
+ inner class ChatHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+ var chatText: TextView
+
+ init {
+ chatText = itemView.findViewById(R.id.chat_item) as TextView
+ }
+ }
+}
\ No newline at end of file
diff --git a/chat/src/main/res/drawable/chat_item_coner.xml b/chat/src/main/res/drawable/chat_item_coner.xml
new file mode 100644
index 0000000..ac394e1
--- /dev/null
+++ b/chat/src/main/res/drawable/chat_item_coner.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/chat/src/main/res/layout/chat_item.xml b/chat/src/main/res/layout/chat_item.xml
new file mode 100644
index 0000000..0c59720
--- /dev/null
+++ b/chat/src/main/res/layout/chat_item.xml
@@ -0,0 +1,9 @@
+
+
diff --git a/chat/src/main/res/layout/chat_layout.xml b/chat/src/main/res/layout/chat_layout.xml
new file mode 100644
index 0000000..510042d
--- /dev/null
+++ b/chat/src/main/res/layout/chat_layout.xml
@@ -0,0 +1,12 @@
+
+
+
diff --git a/chat/src/main/res/values/strings.xml b/chat/src/main/res/values/strings.xml
new file mode 100644
index 0000000..1afbf05
--- /dev/null
+++ b/chat/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ chat
+
diff --git a/common_config.gradle b/common_config.gradle
index b3fee13..a1a1c07 100644
--- a/common_config.gradle
+++ b/common_config.gradle
@@ -1,15 +1,15 @@
-// Top-level build file where you can add configuration options common to all sub-projects/modules.
-project.ext {
- compileSdkVersion = 25
- buildToolsVersion = "24.0.2"
- minSdkVersion = 15
- targetSdkVersion = 25
- applicationId = "com.cangwang.modulebus"
-
- isDebug = false;
- isLib = false;
-
- //混淆
-// minifyEnable = true
-// shrinkResEnable = minifyEnable
-}
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+project.ext {
+ compileSdkVersion = 30
+ buildToolsVersion = "30.0.2"
+ minSdkVersion = 21
+ targetSdkVersion = 30
+ applicationId = "com.cangwang.modulebus"
+
+ isDebug = false;
+ isLib = false;
+
+ //混淆
+// minifyEnable = true
+// shrinkResEnable = minifyEnable
+}
diff --git a/compiler/.gitignore b/compiler/.gitignore
new file mode 100644
index 0000000..3543521
--- /dev/null
+++ b/compiler/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/compiler/build.gradle b/compiler/build.gradle
new file mode 100644
index 0000000..aee3ee9
--- /dev/null
+++ b/compiler/build.gradle
@@ -0,0 +1,19 @@
+apply plugin: 'java'
+
+dependencies {
+ implementation fileTree(include: ['*.jar'], dir: 'libs')
+ implementation 'com.google.auto.service:auto-service:1.0-rc6'
+ implementation 'com.squareup:javapoet:1.11.1'
+ implementation project(':annotation')
+ implementation 'org.apache.commons:commons-lang3:3.4'
+ implementation 'org.apache.commons:commons-collections4:4.1'
+ implementation 'com.google.code.gson:gson:2.8.6'
+}
+
+sourceCompatibility = "1.7"
+targetCompatibility = "1.7"
+
+tasks.withType(JavaCompile) {
+ options.encoding = "UTF-8"
+}
+
diff --git a/compiler/src/main/java/com/cangwang/process/InjectJarProcessor.java b/compiler/src/main/java/com/cangwang/process/InjectJarProcessor.java
new file mode 100644
index 0000000..6fe5113
--- /dev/null
+++ b/compiler/src/main/java/com/cangwang/process/InjectJarProcessor.java
@@ -0,0 +1,49 @@
+package com.cangwang.process;
+
+import com.cangwang.utils.Logger;
+import com.squareup.javapoet.ClassName;
+
+import org.apache.commons.collections4.CollectionUtils;
+
+import java.io.IOException;
+import java.util.Set;
+
+import javax.annotation.processing.Filer;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+
+/**
+ * Make info class to Jar
+ * Created by cangwang on 2017/12/22.
+ */
+
+public class InjectJarProcessor {
+ public static void parseModulesGroup(Set extends Element> modulesElements, Logger logger, Filer mFiler, Elements elements,Types types) throws IOException {
+ if (CollectionUtils.isNotEmpty(modulesElements)) {
+ for (Element e:modulesElements){
+ TypeElement typeElement = (TypeElement)e;
+ ClassName name = ClassName.get(typeElement);
+ String path = name.packageName()+"."+name.simpleName(); //真实模块入口地址 包名+类名
+ logger.info("inject path = "+path);
+// TypeMirror typeMirror = (((TypeElement)e).getSuperclass());
+// TypeElement tE = (TypeElement) types.asElement(typeMirror);
+// ClassName nameex = ClassName.get(tE);
+// String pathex = nameex.packageName()+"."+nameex.simpleName(); //真实模块入口地址 包名+类名
+// logger.info("inject path = "+pathex);
+ TypeMirror typeMirror;
+ while (true){
+ typeMirror = typeElement.getSuperclass();
+ TypeElement tE = (TypeElement) types.asElement(typeMirror);
+ ClassName nameex = ClassName.get(tE);
+ if (nameex.simpleName().equals("Object")) break;
+ String pathex = nameex.packageName()+"."+nameex.simpleName(); //真实模块入口地址 包名+类名
+ logger.info("inject path = "+pathex);
+ typeElement = (TypeElement) types.asElement(typeMirror);
+ }
+ }
+ }
+ }
+}
diff --git a/compiler/src/main/java/com/cangwang/process/ModuleGroupProcessor.java b/compiler/src/main/java/com/cangwang/process/ModuleGroupProcessor.java
new file mode 100644
index 0000000..c37f2de
--- /dev/null
+++ b/compiler/src/main/java/com/cangwang/process/ModuleGroupProcessor.java
@@ -0,0 +1,59 @@
+package com.cangwang.process;
+
+import com.cangwang.annotation.ModuleGroup;
+import com.cangwang.annotation.ModuleUnit;
+import com.cangwang.utils.Logger;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.squareup.javapoet.ClassName;
+import org.apache.commons.collections4.CollectionUtils;
+import java.io.IOException;
+import java.util.Set;
+import javax.annotation.processing.Filer;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.Elements;
+
+/**
+ * 解析ModuleGroup注解
+ */
+public class ModuleGroupProcessor {
+
+ public static JsonArray parseModulesGroup(Set extends Element> modulesElements, Logger logger, Filer mFiler, Elements elements) throws IOException{
+ if (CollectionUtils.isNotEmpty(modulesElements)) {
+ logger.info(">>> Found moduleGroup, size is " + modulesElements.size() + " <<<");
+ ModuleUnitProcessor.parseModuleFile(modulesElements,logger,mFiler,elements);
+ for (Element element:modulesElements){
+ ModuleGroup group = element.getAnnotation(ModuleGroup.class);
+ ModuleUnit[] units = group.value();
+ return parseModules(units,element,logger,mFiler,elements);
+ }
+ }
+ return null;
+ }
+
+ public static JsonArray parseModules(ModuleUnit[] modulesElements,Element element,Logger logger,Filer mFiler,Elements elements) throws IOException {
+ if (modulesElements.length > 0){
+ logger.info(">>> Found moduleUnit, size is " + modulesElements.length + " <<<");
+
+ ModuleUnit moduleUnit;
+ JsonArray array = new JsonArray();
+ for (int i = 0;i> map =new HashMap<>();
+
+ @Override
+ public synchronized void init(ProcessingEnvironment processingEnvironment) {
+ super.init(processingEnvironment);
+ System.out.println("------------------------------");
+ System.out.println("ModuleProcess init");
+
+ mFiler = processingEnv.getFiler(); // Generate class.
+ logger = new Logger(processingEnv.getMessager()); // Package the log utils.
+ ModuleUtil.logger = logger;
+ types = processingEnv.getTypeUtils(); // Get type utils.
+ elements = processingEnv.getElementUtils(); // Get class meta.
+ Map options = processingEnv.getOptions();
+ if (MapUtils.isNotEmpty(options)) {
+ applicationName = options.get("applicationName");
+ if (applicationName == null) {
+ moduleName = options.get("moduleName");
+ System.out.println("moduleName = " +moduleName);
+ }else {
+ System.out.println("applicationName = " +applicationName);
+ initAppJson();
+ }
+ }
+ }
+
+
+ @Override
+ public Set getSupportedAnnotationTypes() {
+ Set annotations = new LinkedHashSet<>();
+ annotations.add(ModuleUnit.class.getCanonicalName());
+ annotations.add(ModuleGroup.class.getCanonicalName());
+// annotations.add(InjectBean.class.getCanonicalName());
+ return annotations;
+ }
+
+ @Override
+ public SourceVersion getSupportedSourceVersion() {
+ return SourceVersion.latestSupported();
+ }
+
+ @Override
+ public boolean process(Set extends TypeElement> set, RoundEnvironment roundEnvironment) {
+ if(CollectionUtils.isNotEmpty(set)){
+ Set extends Element> moduleUnitElements = roundEnvironment.getElementsAnnotatedWith(ModuleUnit.class);
+ Set extends Element> moduleGroupElements = roundEnvironment.getElementsAnnotatedWith(ModuleGroup.class);
+// Set extends Element> injectBeanElements = roundEnvironment.getElementsAnnotatedWith(InjectBean.class);
+ try {
+ //遍历注解
+ logger.info(">>> Found moduleUnit, start get jsonArray <<<");
+ JsonArray units = ModuleUnitProcessor.parseModules(moduleUnitElements, logger, mFiler, elements);
+ logger.info(">>> Found moduleGroup, start get jsonArray <<<");
+ JsonArray groups = ModuleGroupProcessor.parseModulesGroup(moduleGroupElements, logger, mFiler, elements);
+
+ if (moduleName != null) {
+ JsonArray moduleArrary = new JsonArray();
+ if (units != null)
+ moduleArrary.addAll(units);
+ if (groups != null)
+ moduleArrary.addAll(groups);
+ if (moduleArrary.size() > 0) {
+ //写入每个json文件
+ ModuleUtil.createCenterJson(moduleName);
+ ModuleUtil.writeJsonFile(ModuleUtil.getJsonAddress(moduleName), moduleArrary.toString());
+ }
+ logger.info(moduleArrary.toString());
+ }
+
+// InjectJarProcessor.parseModulesGroup(injectBeanElements, logger, mFiler, elements,types);
+ } catch (Exception e) {
+ logger.error(e);
+ }
+
+ }
+
+ return true;
+ }
+
+ private void initAppJson(){
+ if (applicationName != null ) {
+ String path = ModuleUtil.getJsonAddress(applicationName);
+ try {
+ //先清理app center.json缓存数据
+ ModuleUtil.createCenterJson(applicationName);
+ //获取引用module的列表
+ List moduleNameList = ModuleUtil.readSetting();
+ logger.info("读取 module list:"+moduleNameList.toString());
+ JsonArray jsonArray = new JsonArray();
+ if (moduleNameList != null) {
+ for (String name : moduleNameList) {
+ //读取module center.json列表
+ String json = ModuleUtil.readJsonFile(ModuleUtil.getJsonAddress(name));
+ if (json.isEmpty()) continue;
+ jsonArray.addAll(ModuleUtil.parserJsonArray(json));
+ }
+ }
+ logger.info("读取"+path+" module center.json列表:"+jsonArray.toString());
+ //转换为对象做类型排序
+// Map> map =new HashMap<>();
+ for (int i = 0;i list = new LinkedList(){{add(bean);}};
+ map.put(bean.templet,list);
+ }
+ }
+ if (!map.isEmpty()) {
+ JsonObject o = new JsonObject();
+ for (Map.Entry> entry : map.entrySet()) {
+ //排列层级
+ Collections.sort(entry.getValue());
+ o.add(entry.getKey(), ModuleUtil.listToJson(entry.getValue()));
+ }
+ //写入到center.json
+ ModuleUtil.writeJsonFile(path, o.toString());
+ }
+ parseCenter(null,logger,mFiler,elements);
+ }catch (IOException e){
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public void parseCenter(Set extends Element> modulesElements,Logger logger,Filer mFiler,Elements elements) throws IOException{
+
+ logger.info("init factory");
+
+ TypeName templateMap = ParameterizedTypeName.get(ClassName.get(HashMap.class),
+ ClassName.get(String.class),
+ ParameterizedTypeName.get(ClassName.get(List.class),ClassName.get(ICWModule.class)));
+
+ FieldSpec.Builder fieldMapBuilder = FieldSpec.builder(templateMap,"moduleMap",Modifier.PRIVATE,STATIC);
+ fieldMapBuilder.initializer("new HashMap<>()");
+ FieldSpec.Builder fieldInstanceBuilder = FieldSpec.builder(IModuleFactory.class, "sInstance", Modifier.PRIVATE, Modifier.STATIC);
+ //添加loadInto方法
+ MethodSpec.Builder getInstanceBuilder = MethodSpec.methodBuilder(ModuleUtil.METHOD_FACTROY_GET_INSTANCE)
+ .returns(IModuleFactory.class)
+ .addModifiers(Modifier.PUBLIC,Modifier.STATIC)
+ .beginControlFlow("if (null == sInstance)")
+ .addStatement("sInstance = new ModuleCenterFactory()")
+ .endControlFlow()
+ .addStatement("return sInstance");
+
+ TypeName templateList = ParameterizedTypeName.get(ClassName.get(List.class),ClassName.get(ICWModule.class));
+ ParameterSpec templateName = ParameterSpec.builder(String.class, "templateName").build();
+
+ MethodSpec.Builder getModuleListBuilder = MethodSpec.methodBuilder(ModuleUtil.METHOD_FACTROY_GET_TEMPLE_LIST)
+ .addAnnotation(Override.class)
+ .addModifiers(Modifier.PUBLIC)
+ .addParameter(templateName)
+ .returns(templateList)
+ .addStatement("return moduleMap.get(templateName)");
+
+ CodeBlock.Builder code = CodeBlock.builder();
+// code.addStatement("List list = new $T<>()",LinkedList.class);
+
+ int index=0;
+ try {
+ for (Map.Entry> entry : map.entrySet()) {
+ //排列层级
+ Collections.sort(entry.getValue());
+ String key = entry.getKey();
+ code.addStatement("List list$L = new $T<>()",index,LinkedList.class);
+ for (ModuleUnitBean b :entry.getValue()){
+ logger.info(b.path);
+ code.addStatement("list$L.add(new $T().getModule())",index,ClassName.get(ModuleUtil.FACADE_PACKAGE,ModuleUtil.MODULE_UNIT+ModuleUtil.SEPARATOR+b.title));
+ }
+ code.addStatement("moduleMap.put($S,list$L)",key,index);
+ index++;
+// code.addStatement("list.clear();");
+ }
+ }catch (Exception e){
+ logger.info(e.toString());
+ }
+
+
+ //构造java文件
+ JavaFile.builder(ModuleUtil.FACADE_PACKAGE,
+ TypeSpec.classBuilder("ModuleCenterFactory")
+ .addJavadoc(ModuleUtil.WARNING_TIPS)
+ .addSuperinterface(ClassName.get(elements.getTypeElement(ModuleUtil.IMODULE_FACTORY)))
+ .addModifiers(Modifier.PUBLIC)
+ .addField(fieldInstanceBuilder.build())
+ .addField(fieldMapBuilder.build())
+ .addStaticBlock(code.build())
+ .addMethod(getInstanceBuilder.build())
+ .addMethod(getModuleListBuilder.build())
+ .build()
+ ).build().writeTo(mFiler);
+ }
+
+}
diff --git a/compiler/src/main/java/com/cangwang/process/ModuleUnitProcessor.java b/compiler/src/main/java/com/cangwang/process/ModuleUnitProcessor.java
new file mode 100644
index 0000000..380df16
--- /dev/null
+++ b/compiler/src/main/java/com/cangwang/process/ModuleUnitProcessor.java
@@ -0,0 +1,78 @@
+package com.cangwang.process;
+
+import com.cangwang.annotation.ModuleUnit;
+import com.cangwang.model.ICWModule;
+import com.cangwang.utils.Logger;
+import com.cangwang.utils.ModuleUtil;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.JavaFile;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.TypeSpec;
+
+import org.apache.commons.collections4.CollectionUtils;
+import java.io.IOException;
+import java.util.Set;
+import javax.annotation.processing.Filer;
+
+import javax.lang.model.element.Element;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.Elements;
+
+
+/**
+ * 解析ModuleUnit注解
+ * Created by cangwang on 2017/8/30.
+ */
+public class ModuleUnitProcessor {
+
+ public static JsonArray parseModules(Set extends Element> modulesElements,Logger logger,Filer mFiler,Elements elements) throws IOException {
+ if (CollectionUtils.isNotEmpty(modulesElements)){
+ logger.info(">>> Found moduleUnit, size is " + modulesElements.size() + " <<<");
+ parseModuleFile(modulesElements,logger,mFiler,elements);
+ JsonArray array = new JsonArray();
+ for (Element element:modulesElements) {
+ ModuleUnit moduleUnit= element.getAnnotation(ModuleUnit.class);
+ ClassName name = ClassName.get(((TypeElement)element));
+ String path = name.packageName()+"."+name.simpleName(); //真实模块入口地址 包名+类名
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.addProperty("path",path);
+ jsonObject.addProperty("templet",moduleUnit.templet());
+ jsonObject.addProperty("title",name.simpleName());
+ jsonObject.addProperty("layoutLevel",moduleUnit.layoutlevel().getValue());
+ jsonObject.addProperty("inflateLevel", moduleUnit.inflateLevel());
+ jsonObject.addProperty("extraLevel",moduleUnit.extralevel());
+ array.add(jsonObject);
+ }
+ logger.info(array.toString());
+ return array;
+ }
+ return null;
+ }
+
+ public static void parseModuleFile(Set extends Element> modulesElements,Logger logger,Filer mFiler,Elements elements) throws IOException{
+ //添加loadInto方法
+ MethodSpec.Builder loadIntoMethodOfRootBuilder = MethodSpec.methodBuilder(ModuleUtil.METHOD_GET_MODULE)
+ .returns(ICWModule.class)
+ .addAnnotation(Override.class)
+ .addModifiers(Modifier.PUBLIC);
+
+ for (Element element:modulesElements){
+ ClassName name = ClassName.get(((TypeElement)element));
+
+ loadIntoMethodOfRootBuilder.addStatement("return new $T()", (TypeElement)element);
+
+ //构造java文件
+ JavaFile.builder(ModuleUtil.FACADE_PACKAGE,
+ TypeSpec.classBuilder(ModuleUtil.NAME_OF_MODULEUNIT+name.simpleName())
+ .addJavadoc(ModuleUtil.WARNING_TIPS)
+ .addSuperinterface(ClassName.get(elements.getTypeElement(ModuleUtil.IMODULE_PROXY)))
+ .addModifiers(Modifier.PUBLIC)
+ .addMethod(loadIntoMethodOfRootBuilder.build())
+ .build()
+ ).build().writeTo(mFiler);
+ }
+ }
+}
diff --git a/compiler/src/main/java/com/cangwang/utils/Logger.java b/compiler/src/main/java/com/cangwang/utils/Logger.java
new file mode 100644
index 0000000..2aa11b9
--- /dev/null
+++ b/compiler/src/main/java/com/cangwang/utils/Logger.java
@@ -0,0 +1,56 @@
+package com.cangwang.utils;
+
+import org.apache.commons.lang3.StringUtils;
+
+import javax.annotation.processing.Messager;
+import javax.tools.Diagnostic;
+
+/**
+ *
+ * Created by cangwang on 2017/8/30.
+ */
+public class Logger {
+ public static final String PROJECT = "ModuleBus";
+ static final String PREFIX_OF_LOGGER = PROJECT + "::Compiler ";
+ private Messager msg;
+
+ public Logger(Messager messager) {
+ msg = messager;
+ }
+
+ /**
+ * Print info log.
+ */
+ public void info(CharSequence info) {
+ if (StringUtils.isNotEmpty(info)) {
+ msg.printMessage(Diagnostic.Kind.NOTE, PREFIX_OF_LOGGER + info);
+ }
+ }
+
+ public void error(CharSequence error) {
+ if (StringUtils.isNotEmpty(error)) {
+ msg.printMessage(Diagnostic.Kind.ERROR, PREFIX_OF_LOGGER + "An exception is encountered, [" + error + "]");
+ }
+ }
+
+ public void error(Throwable error) {
+ if (null != error) {
+ msg.printMessage(Diagnostic.Kind.ERROR, PREFIX_OF_LOGGER + "An exception is encountered, [" + error.getMessage() + "]" + "\n" + formatStackTrace(error.getStackTrace()));
+ }
+ }
+
+ public void warning(CharSequence warning) {
+ if (StringUtils.isNotEmpty(warning)) {
+ msg.printMessage(Diagnostic.Kind.WARNING, PREFIX_OF_LOGGER + warning);
+ }
+ }
+
+ private String formatStackTrace(StackTraceElement[] stackTrace) {
+ StringBuilder sb = new StringBuilder();
+ for (StackTraceElement element : stackTrace) {
+ sb.append(" at ").append(element.toString());
+ sb.append("\n");
+ }
+ return sb.toString();
+ }
+}
diff --git a/compiler/src/main/java/com/cangwang/utils/ModuleUtil.java b/compiler/src/main/java/com/cangwang/utils/ModuleUtil.java
new file mode 100644
index 0000000..cf7b8ee
--- /dev/null
+++ b/compiler/src/main/java/com/cangwang/utils/ModuleUtil.java
@@ -0,0 +1,309 @@
+package com.cangwang.utils;
+
+import com.cangwang.bean.ModuleUnitBean;
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+public class ModuleUtil {
+
+ public static final String PROJECT = "ModuleBus";
+ public static final String MODULE_UNIT = "ModuleUnit";
+ public static final String SEPARATOR = "$$";
+
+ public static final String FACADE_PACKAGE = "com.cangwang.core";
+ public static final String MODULE_ANNOTATION = "com.cangwang.annotation";
+ public static final String MODULE_MODEL = "com.cangwang.model";
+ private static final String TEMPLATE_PACKAGE = ".template";
+ public static final String NAME_OF_MODULEGROUP = PROJECT + SEPARATOR + "Group" + SEPARATOR;
+ public static final String WARNING_TIPS = "DO NOT EDIT THIS FILE!!! IT WAS GENERATED BY MODULEBUS.";
+
+
+ public static final String IMODULE_GROUP = FACADE_PACKAGE + TEMPLATE_PACKAGE + ".IModuleGroup";
+ public static final String IMODULE_UNIT = FACADE_PACKAGE + TEMPLATE_PACKAGE + ".IModuleUnit";
+ public static final String IMODULE_PROXY = MODULE_MODEL + ".IModuleProxy";
+ public static final String IMODULE_FACTORY = MODULE_MODEL + ".IModuleFactory";
+ public static final String METHOD_GET_MODULE = "getModule";
+ public static final String METHOD_FACTROY_GET_INSTANCE = "getInstance";
+ public static final String METHOD_FACTROY_GET_TEMPLE_LIST = "getTempleList";
+
+ public static final String NAME_OF_MODULEUNIT = MODULE_UNIT + SEPARATOR;
+
+ public static final String ANNOTATION_TYPE_MODULEUNIT = MODULE_ANNOTATION + "ModuleUnit";
+
+ public static String[] splitDot(String groupName){
+ return groupName.split("\\.");
+ }
+
+ public static String[] split(String groupName){
+ return groupName.split(",");
+ }
+
+ public static final String rootPath = System.getProperty("user.dir");
+ public static final String ceterFile = "/src/main/assets/center.json";
+ public static final String settingFile = System.getProperty("user.dir")+"/settings.gradle";
+
+ public static Logger logger;
+
+ public static Gson gson = new Gson();
+
+ /**
+ * 写json文件
+ * @param filePath
+ * @param sets
+ * @throws IOException
+ */
+ public static void writeJsonFile(String filePath,String sets) throws IOException{
+ sets = formatJson(sets,true);
+ logger.info(sets);
+ writeFile(filePath,sets);
+ }
+
+
+ public static void writeFile(String filePath, String sets)
+ throws IOException {
+ FileWriter fw = new FileWriter(filePath);
+ PrintWriter out = new PrintWriter(fw);
+ out.write(sets);
+ out.println();
+ fw.close();
+ out.close();
+ }
+
+ public static String readJsonFile(String path){
+ File file=new File(path);
+ if (!file.exists()) return "";
+ BufferedReader reader=null;
+ String jsonContent="";
+ try {
+ reader=new BufferedReader(new FileReader(file));
+ String tempString=null;
+ while((tempString=reader.readLine())!=null){
+ jsonContent+=tempString;
+ }
+ } catch (Exception e) {
+ // TODO: handle exception
+ e.printStackTrace();
+ }
+ finally {
+ if(reader!=null){
+ try {
+ reader.close();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ return jsonContent;
+ }
+
+ }
+
+ /**
+ * 单位缩进字符串。
+ */
+ private static String SPACE = " ";
+
+ /**
+ * 返回格式化JSON字符串。
+ *
+ * @param json 未格式化的JSON字符串。
+ * @return 格式化的JSON字符串。
+ */
+ public static String formatJson(String json,boolean isSort)
+ {
+ StringBuffer result = new StringBuffer();
+
+ int length = json.length();
+ int number = 0;
+ char key = 0;
+ //遍历输入字符串。
+ for (int i = 0; i < length; i++)
+ {
+ //1、获取当前字符。
+ key = json.charAt(i);
+
+ //2、如果当前字符是前方括号、前花括号做如下处理:
+ if((key == '[') || (key == '{') )
+ {
+ //(1)如果前面还有字符,并且字符为“:”,打印:换行和缩进字符字符串。
+ if((i - 1 > 0) && (json.charAt(i - 1) == ':'))
+ {
+ result.append('\n');
+ if (isSort)
+ result.append(indent(number));
+ }
+
+ //(2)打印:当前字符。
+ result.append(key);
+
+ //(3)前方括号、前花括号,的后面必须换行。打印:换行。
+ result.append('\n');
+
+ //(4)每出现一次前方括号、前花括号;缩进次数增加一次。打印:新行缩进。
+ number++;
+ if (isSort)
+ result.append(indent(number));
+
+ //(5)进行下一次循环。
+ continue;
+ }
+
+ //3、如果当前字符是后方括号、后花括号做如下处理:
+ if((key == ']') || (key == '}') )
+ {
+ //(1)后方括号、后花括号,的前面必须换行。打印:换行。
+ result.append('\n');
+
+ //(2)每出现一次后方括号、后花括号;缩进次数减少一次。打印:缩进。
+ number--;
+ result.append(indent(number));
+
+ //(3)打印:当前字符。
+ result.append(key);
+
+ //(4)如果当前字符后面还有字符,并且字符不为“,”,打印:换行。
+ if(((i + 1) < length) && (json.charAt(i + 1) != ','))
+ {
+ result.append('\n');
+ }
+
+ //(5)继续下一次循环。
+ continue;
+ }
+
+ //4、如果当前字符是逗号。逗号后面换行,并缩进,不改变缩进次数。
+ if((key == ','))
+ {
+ result.append(key);
+ result.append('\n');
+ if (isSort)
+ result.append(indent(number));
+ continue;
+ }
+
+ //5、打印:当前字符。
+ result.append(key);
+ }
+
+ return result.toString();
+ }
+
+ /**
+ * 返回指定次数的缩进字符串。每一次缩进三个空格,即SPACE。
+ *
+ * @param number 缩进次数。
+ * @return 指定缩进次数的字符串。
+ */
+ private static String indent(int number)
+ {
+ StringBuffer result = new StringBuffer();
+ for(int i = 0; i < number; i++)
+ {
+ result.append(SPACE);
+ }
+ return result.toString();
+ }
+
+ public static JsonArray parserJsonArray(String strJson){
+ //创建一个Gson对象
+// Gson gson = new Gson();
+ //创建一个JsonParser
+ JsonParser parser = new JsonParser();
+ //通过JsonParser对象可以把json格式的字符串解析成一个JsonElement对象
+ JsonElement el = parser.parse(strJson);
+
+// //把JsonElement对象转换成JsonObject
+// JsonObject jsonObj = null;
+// if(el.isJsonObject()){
+// jsonObj = el.getAsJsonObject();
+// }
+//
+// //把JsonElement对象转换成JsonArray
+// JsonArray jsonArray = null;
+ if(el.isJsonArray()){
+ return el.getAsJsonArray();
+ }
+
+ return null;
+
+// //遍历JsonArray对象
+// Iterator it = jsonArray.iterator();
+// while(it.hasNext()){
+// JsonElement e = (JsonElement)it.next();
+// //JsonElement转换为JavaBean对象
+// ModuleUnitBean bean= gson.fromJson(e, ModuleUnitBean.class);
+// }
+ }
+
+ public static void createCenterJson(String moduleName) throws IOException{
+ String directory = System.getProperty("user.dir") +"/"+moduleName + "/src/main/assets";
+ File dirFile = new File(directory);
+ if (!dirFile.exists() && !dirFile.isDirectory()){
+ logger.info(directory +" is not exists,to create");
+ dirFile.mkdir();
+ }
+ String path = getJsonAddress(moduleName);
+ File file =new File(path);
+ boolean deleteResult =file.delete();
+ boolean success = file.createNewFile();
+ logger.info("deleteResult = "+deleteResult+", path = "+path+",success = "+success);
+ }
+
+ public static List readSetting() throws IOException{
+ File file = new File(settingFile);
+ BufferedReader reader=null;
+ String settingContent="";
+ try {
+ reader=new BufferedReader(new FileReader(file));
+ String tempString=null;
+ while((tempString=reader.readLine())!=null){
+ settingContent+=tempString;
+ }
+ logger.info(settingContent);
+ List moduleNameList = new ArrayList<>();
+ String[] moduleList = settingContent.split("':");
+ for (int i = 1;i list){
+ JsonArray templetArray = new JsonArray();
+ for (ModuleUnitBean b:list){
+ templetArray.add(beanToObject(b));
+ }
+ return templetArray;
+ }
+
+ public static JsonObject beanToObject(ModuleUnitBean b){
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.addProperty("path",b.path);
+ jsonObject.addProperty("templet",b.templet);
+ jsonObject.addProperty("title",b.title);
+ jsonObject.addProperty("layoutLevel",b.layoutLevel);
+ jsonObject.addProperty("extraLevel",b.extraLevel);
+ return jsonObject;
+ }
+
+ public static String getJsonAddress(String moduleName){
+ return rootPath+"/"+moduleName+ceterFile;
+ }
+}
diff --git a/compiler/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/compiler/src/main/resources/META-INF/services/javax.annotation.processing.Processor
new file mode 100644
index 0000000..0672a38
--- /dev/null
+++ b/compiler/src/main/resources/META-INF/services/javax.annotation.processing.Processor
@@ -0,0 +1 @@
+com.cangwang.process.ModuleProcessor
\ No newline at end of file
diff --git a/core/build.gradle b/core/build.gradle
index 0985154..b5bd833 100644
--- a/core/build.gradle
+++ b/core/build.gradle
@@ -1,40 +1,79 @@
-apply plugin: 'com.android.library'
-apply from: "${rootProject.rootDir}/common_config.gradle"
-
-android {
- compileSdkVersion project.ext.compileSdkVersion
- buildToolsVersion project.ext.buildToolsVersion
-
- defaultConfig {
- minSdkVersion project.ext.minSdkVersion
- targetSdkVersion project.ext.targetSdkVersion
- versionCode 1
- versionName "1.0"
-
- testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
-
- }
- buildTypes {
- release {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- }
- }
-}
-
-dependencies {
- compile fileTree(include: ['*.jar'], dir: 'libs')
- androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
- exclude group: 'com.android.support', module: 'support-annotations'
- })
- compile 'com.android.support:appcompat-v7:25.0.1'
- compile 'com.android.support:support-v4:25.0.1'
-}
-
-ext {
- PUBLISH_GROUP_ID = 'com.cangwang.core'
- PUBLISH_ARTIFACT_ID = 'modulebus'
- PUBLISH_VERSION = '2.0.0'
-}
-
-apply from: 'https://raw.githubusercontent.com/blundell/release-android-library/master/android-release-aar.gradle'
+apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
+apply from: "${rootProject.rootDir}/common_config.gradle"
+
+android {
+ compileSdkVersion project.ext.compileSdkVersion
+ buildToolsVersion project.ext.buildToolsVersion
+
+ defaultConfig {
+ minSdkVersion project.ext.minSdkVersion
+ targetSdkVersion project.ext.targetSdkVersion
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ }
+
+ lintOptions {
+ abortOnError false
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+repositories{
+ flatDir{
+ dirs 'libs'
+ }
+ mavenCentral()
+}
+
+dependencies {
+ api fileTree(include: ['*.jar'], dir: 'libs')
+ api project(':annotation')
+ api 'androidx.appcompat:appcompat:1.3.1'
+ api 'androidx.fragment:fragment:1.3.6'
+ annotationProcessor project(":compiler")
+ api "androidx.core:core-ktx:1.6.0"
+ api "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+}
+
+task clearJar(type: Delete) {
+ delete 'libs/modulebus.jar' //sdk是jar包的名字,随便命名
+}
+
+task makeJar(type:org.gradle.api.tasks.bundling.Jar) {
+ //指定生成的jar名
+ baseName 'modulebus'
+ //从哪里打包class文件
+ from('build/intermediates/classes/debug/')
+ //打包到jar后的目录结构
+ into('build/outputs/')
+ //去掉不需要打包的目录和文件
+ exclude('test/','BuildConfig.class','R.class')
+ //去掉R开头的文件
+ exclude{
+ it.name.startsWith('R');
+ }
+}
+
+makeJar.dependsOn(clearJar, build)
+
+ext {
+ PUBLISH_GROUP_ID = 'com.cangwang.core'
+ PUBLISH_ARTIFACT_ID = 'modulebus'
+ PUBLISH_VERSION = '3.0.0'
+}
+
+//apply from: 'https://raw.githubusercontent.com/blundell/release-android-library/master/android-release-aar.gradle'
+
+tasks.whenTaskAdded { task ->
+ if (task.name.equals("lint")) {
+ task.enabled = false
+ }
+}
\ No newline at end of file
diff --git a/core/core.iml b/core/core.iml
deleted file mode 100644
index 7dbb035..0000000
--- a/core/core.iml
+++ /dev/null
@@ -1,145 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- generateDebugSources
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/core/src/main/java/com/cangwang/core/IBaseClient.java b/core/src/main/java/com/cangwang/core/IBaseClient.java
deleted file mode 100644
index db7e5bf..0000000
--- a/core/src/main/java/com/cangwang/core/IBaseClient.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package com.cangwang.core;
-
-/**
- * Created by zjl on 16/11/18.
- */
-
-public class IBaseClient {
-}
diff --git a/core/src/main/java/com/cangwang/core/IBaseClient.kt b/core/src/main/java/com/cangwang/core/IBaseClient.kt
new file mode 100644
index 0000000..684cf69
--- /dev/null
+++ b/core/src/main/java/com/cangwang/core/IBaseClient.kt
@@ -0,0 +1,6 @@
+package com.cangwang.core
+
+/**
+ * Created by zjl on 16/11/18.
+ */
+open class IBaseClient
\ No newline at end of file
diff --git a/core/src/main/java/com/cangwang/core/MBaseApi.kt b/core/src/main/java/com/cangwang/core/MBaseApi.kt
new file mode 100644
index 0000000..659d896
--- /dev/null
+++ b/core/src/main/java/com/cangwang/core/MBaseApi.kt
@@ -0,0 +1,6 @@
+package com.cangwang.core
+
+/**
+ * Created by cangwang on 2018/1/7.
+ */
+interface MBaseApi
\ No newline at end of file
diff --git a/core/src/main/java/com/cangwang/core/ModuleApiManager.kt b/core/src/main/java/com/cangwang/core/ModuleApiManager.kt
new file mode 100644
index 0000000..f32e50d
--- /dev/null
+++ b/core/src/main/java/com/cangwang/core/ModuleApiManager.kt
@@ -0,0 +1,31 @@
+package com.cangwang.core
+
+import java.util.HashMap
+
+/**
+ *
+ * Created by cangwang on 2018/1/7.
+ */
+class ModuleApiManager private constructor() {
+ var aMap: HashMap?, MBaseApi?> = HashMap()
+ fun containsApi(clazz: Class?): Boolean {
+ return aMap.containsKey(clazz)
+ }
+
+ fun getApi(clazz: Class?): T? {
+ return aMap[clazz] as T?
+ }
+
+ fun putApi(key: Class?, value: MBaseApi?) {
+ aMap[key] = value
+ }
+
+ fun removeApi(key: Class?) {
+ aMap.remove(key)
+ }
+
+ companion object {
+ @kotlin.jvm.JvmStatic
+ var instance = ModuleApiManager()
+ }
+}
\ No newline at end of file
diff --git a/core/src/main/java/com/cangwang/core/ModuleBus.java b/core/src/main/java/com/cangwang/core/ModuleBus.java
deleted file mode 100644
index 5e4d9a0..0000000
--- a/core/src/main/java/com/cangwang/core/ModuleBus.java
+++ /dev/null
@@ -1,268 +0,0 @@
-package com.cangwang.core;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.support.v4.util.ArrayMap;
-import android.util.Log;
-
-import com.cangwang.core.info.MethodInfo;
-
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-/**
- * Created by zjl on 16/10/19.
- */
-public class ModuleBus {
- private static final String TAG = "ModuleBus";
-
- public static final int MODULE_RESULT = 1001;
-
-// private static ArrayMap