diff --git a/.gitignore b/.gitignore
index eef2d45..63fc54f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -39,5 +39,6 @@ captures/
.idea/vcs.xml
.idea/libraries
+
# Keystore files
*.jks
diff --git a/README.md b/README.md
index 052995d..438a057 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,72 @@
+
+# 应用截图
+
+
# AndroidModulePattern
+
Android项目组件化示例代码
-博客:http://blog.csdn.net/guiying712/article/details/55213884
+**Android组件化方案**:http://blog.csdn.net/guiying712/article/details/55213884
+
+**Android组件化之终极方案**:http://blog.csdn.net/guiying712/article/details/78057120
+
+1. 现在的 AndroidModulePattern 使用 阿里ARouter作为路由;
+
+2. Android组件化方案已经支持 **Fragment组件化**,使用方法请下载Demo查看;
+
+3. 本项目已适配Android Studio 3.0.1版本(Google仓库会带来一定影响)
+
+
+## 集成开发模式和组件开发模式转换
+
+**1、首先打开Android项目的 gradle.properties 文件,然后将 isModule 改为你需要的开发模式(true/false),
+然后点击 "Sync Project" 按钮同步项目;**
+
+**2、 在运行之前,请先按照图中选择一个能够运行的组件;**
+
+
+## 组件功能介绍
+
+### app组件功能(空壳工程):
+1. 配置整个项目的Gradle脚本,例如 混淆、签名等;
+2. app组件中可以初始化全局的库,例如Lib.init(this);
+3. 添加 multiDex 功能
+4. 业务组件管理(组装);
+
+### main组件功能(业务组件):
+1. 声明应用的launcherActivity----->android.intent.category.LAUNCHER;
+2. 添加SplashActivity;
+3. 添加LoginActivity;
+4. 添加MainActivity;
+
+### girls/news组件功能(业务组件):
+1. 这两个组件都是业务组件,根据产品的业务逻辑独立成一个组件;
+
+### common组件功能(功能组件):
+1. common组件是基础库,添加一些公用的类;
+2. 例如:网络请求、图片加载、工具类、base类等等;
+3. 声明APP需要的uses-permission;
+4. 定义全局通用的主题(Theme);
+
+## License
+
+ Copyright 2017 guiying712, AndroidModulePattern Open Source Project
+
+ 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.
diff --git a/app/build.gradle b/app/build.gradle
deleted file mode 100644
index cbe047f..0000000
--- a/app/build.gradle
+++ /dev/null
@@ -1,63 +0,0 @@
-apply plugin: 'com.android.application'
-apply plugin: 'com.neenbedankt.android-apt'
-
-def buildTime() {
- return new Date().format("yyyyMMdd");
-}
-
-android {
- compileSdkVersion rootProject.ext.compileSdkVersion
- buildToolsVersion rootProject.ext.buildToolsVersion
- defaultConfig {
- applicationId "com.guiying.androidmodulepattern"
- minSdkVersion rootProject.ext.minSdkVersion
- targetSdkVersion rootProject.ext.targetSdkVersion
- versionCode rootProject.ext.versionCode
- versionName rootProject.ext.versionName
- //multiDexEnabled true
- //打包时间
- resValue "string", "build_time", buildTime()
- }
-
- buildTypes {
- release {
- //更改AndroidManifest.xml中预先定义好占位符信息
- //manifestPlaceholders = [app_icon: "@drawable/icon"]
- // 不显示Log
- buildConfigField "boolean", "LEO_DEBUG", "false"
- //是否zip对齐
- zipAlignEnabled true
- // 缩减resource文件
- shrinkResources true
- //Proguard
- minifyEnabled true
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- //签名
- //signingConfig signingConfigs.release
- }
-
- debug {
- //给applicationId添加后缀“.debug”
- applicationIdSuffix ".debug"
- //manifestPlaceholders = [app_icon: "@drawable/launch_beta"]
- buildConfigField "boolean", "LOG_DEBUG", "true"
- zipAlignEnabled false
- shrinkResources false
- minifyEnabled false
- debuggable true
- }
- }
-}
-
-dependencies {
- compile fileTree(dir: 'libs', include: ['*.jar'])
-
- if (!isModule.toBoolean()) {
- compile project(':girls')
- compile project(':news')
- } else {
- compile project(':common')
- }
- //router
- apt "com.github.mzule.activityrouter:compiler:$rootProject.aptCompilerVersion"
-}
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
deleted file mode 100644
index 1fa287c..0000000
--- a/app/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 D:\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/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
deleted file mode 100644
index e90ddfb..0000000
--- a/app/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/java/com/guiying/androidmodulepattern/AppModule.java b/app/src/main/java/com/guiying/androidmodulepattern/AppModule.java
deleted file mode 100644
index 08257b5..0000000
--- a/app/src/main/java/com/guiying/androidmodulepattern/AppModule.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.guiying.androidmodulepattern;
-
-import com.github.mzule.activityrouter.annotation.Module;
-
-/**
- * 类说明
- *
- * @author 张华洋 2017/2/15 20:42
- * @version V1.2.0
- * @name AppModule
- */
-
-@Module("app")
-public class AppModule {
-}
diff --git a/app/src/main/java/com/guiying/androidmodulepattern/MainActivity.java b/app/src/main/java/com/guiying/androidmodulepattern/MainActivity.java
deleted file mode 100644
index b751ae9..0000000
--- a/app/src/main/java/com/guiying/androidmodulepattern/MainActivity.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package com.guiying.androidmodulepattern;
-
-import android.os.Bundle;
-import android.support.design.widget.Snackbar;
-import android.view.KeyEvent;
-import android.view.View;
-import android.widget.Button;
-
-import com.github.mzule.activityrouter.router.Routers;
-import com.guiying.common.base.BaseActivity;
-import com.guiying.common.base.BaseApplication;
-
-public class MainActivity extends BaseActivity implements View.OnClickListener {
-
-
- private long exitTime = 0;
-
- protected Button newsButton;
- protected Button girlsButton;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- newsButton = (Button) findViewById(R.id.news_button);
- newsButton.setOnClickListener(MainActivity.this);
- girlsButton = (Button) findViewById(R.id.girls_button);
- girlsButton.setOnClickListener(MainActivity.this);
- }
-
- @Override
- public void onClick(View view) {
- if (view.getId() == R.id.news_button) {
- Routers.open(MainActivity.this, "module://news");
- } else if (view.getId() == R.id.girls_button) {
- Routers.open(MainActivity.this, "module://girls");
- }
- }
-
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
- //两秒之内按返回键就会退出
- if ((System.currentTimeMillis() - exitTime) > 2000) {
- Snackbar.make(girlsButton, getString(R.string.app_exit_hint), Snackbar.LENGTH_LONG).show();
- exitTime = System.currentTimeMillis();
- } else {
- BaseApplication.getIns().exitApp(this);
- }
- return true;
- }
- return super.onKeyDown(keyCode, event);
- }
-
-}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
deleted file mode 100644
index 1c37bea..0000000
--- a/app/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
- 组件化项目
-
- module
-
- 再按一次退出程序哦~
-
-
diff --git a/build.gradle b/build.gradle
index 15257b7..40fe932 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,58 +1,38 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
- repositories {
- jcenter()
- mavenCentral()
- }
-
+ apply from: 'versions.gradle'
+ addRepos(repositories)
dependencies {
- classpath "com.android.tools.build:gradle:$localGradlePluginVersion"
- classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
+ /* classpath deps.android_gradle_plugin*/
+ classpath deps.android_gradle_plugin
+ classpath deps.kotlin.plugin
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
- repositories {
- jcenter()
- mavenCentral()
- //Add the JitPack repository
- maven { url "https://jitpack.io" }
- //支持arr包
- flatDir {
- dirs 'libs'
+ addRepos(repositories)
+ // Android dependency 'com.android.support:design' has different version for the compile (25.3.1) and runtime (25.4.0) classpath.
+ // You should manually set the same version via DependencyResolution
+ subprojects {
+ project.configurations.all {
+ resolutionStrategy.eachDependency { details ->
+ if (details.requested.group == 'com.android.support'
+ && !details.requested.name.contains('multidex')) {
+ details.useVersion "27.0.2"
+ }
+ }
}
}
+
+ // 组件缓存更新时间设置(默认每次build都更新)
+ configurations.all {
+ resolutionStrategy.cacheChangingModulesFor 0, 'minutes'
+ }
}
task clean(type: Delete) {
delete rootProject.buildDir
-}
-
-// Define versions in a single place
-ext {
- // Sdk and tools
- buildToolsVersion = localBuildToolsVersion
- compileSdkVersion = 25
- minSdkVersion = 15
- targetSdkVersion = 25
- versionCode = 1
- versionName = "1.0"
- javaVersion = JavaVersion.VERSION_1_8
-
- // App dependencies version
- supportLibraryVersion = "25.2.0"
- retrofitVersion = "2.1.0"
- glideVersion = "3.7.0"
- loggerVersion = "1.15"
- eventbusVersion = "3.0.0"
- gsonVersion = "2.8.0"
-
- //不成熟开源库,需经常检查升级版本
- aptCompilerVersion = "1.1.7"
- routerVersion = "1.2.2"
- easyRecyclerVersion = "4.3.8"
- cookieVersion = "v1.0.1"
-}
+}
\ No newline at end of file
diff --git a/common/build.gradle b/common/build.gradle
deleted file mode 100644
index 6393bd6..0000000
--- a/common/build.gradle
+++ /dev/null
@@ -1,42 +0,0 @@
-apply plugin: 'com.android.library'
-
-android {
- compileSdkVersion rootProject.ext.compileSdkVersion
- buildToolsVersion rootProject.ext.buildToolsVersion
-
- defaultConfig {
- minSdkVersion rootProject.ext.minSdkVersion
- targetSdkVersion rootProject.ext.targetSdkVersion
- versionCode rootProject.ext.versionCode
- versionName rootProject.ext.versionName
- }
-
- buildTypes {
- release {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- }
- }
-}
-
-dependencies {
- compile fileTree(dir: 'libs', include: ['*.jar'])
- //Android Support
- compile "com.android.support:appcompat-v7:$rootProject.supportLibraryVersion"
- compile "com.android.support:design:$rootProject.supportLibraryVersion"
- compile "com.android.support:percent:$rootProject.supportLibraryVersion"
- //网络请求相关
- compile "com.squareup.retrofit2:retrofit:$rootProject.retrofitVersion"
- compile "com.squareup.retrofit2:retrofit-mock:$rootProject.retrofitVersion"
- compile "com.github.franmontiel:PersistentCookieJar:$rootProject.cookieVersion"
- //稳定的
- compile "com.github.bumptech.glide:glide:$rootProject.glideVersion"
- compile "com.orhanobut:logger:$rootProject.loggerVersion"
- compile "org.greenrobot:eventbus:$rootProject.eventbusVersion"
- compile "com.google.code.gson:gson:$rootProject.gsonVersion"
- //不稳定的
- compile "com.github.mzule.activityrouter:activityrouter:$rootProject.routerVersion"
- compile "com.jude:easyrecyclerview:$rootProject.easyRecyclerVersion"
-
- compile 'com.github.GrenderG:Toasty:1.1.3'
-}
diff --git a/common/proguard-rules.pro b/common/proguard-rules.pro
deleted file mode 100644
index 1fa287c..0000000
--- a/common/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 D:\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/common/src/main/AndroidManifest.xml b/common/src/main/AndroidManifest.xml
deleted file mode 100644
index 19d2195..0000000
--- a/common/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/common/src/main/java/com/guiying/common/base/BaseActionBarActivity.java b/common/src/main/java/com/guiying/common/base/BaseActionBarActivity.java
deleted file mode 100644
index 7c0f4c1..0000000
--- a/common/src/main/java/com/guiying/common/base/BaseActionBarActivity.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * @ProjectName: ISMS_Petrel_MCU
- * @Copyright: 2017 HangZhou Hikvision System Technology Co., Ltd. All Right Reserved.
- * @address: http://www.hikvision.com
- * @Description: 本内容仅限于杭州海康威视系统技术公有限司内部使用,禁止转发.
- */
-
-package com.guiying.common.base;
-
-import android.os.Bundle;
-import android.support.annotation.StringRes;
-import android.support.v7.app.ActionBar;
-
-/**
- * BaseActionBarActivity继承于BaseActivity,封装了actionBar的逻辑;
- * 继承于ActionBarBaseActivity的Activity都将默认带有ActionBar,并且只能使用AppTheme主题;
- * 只有那些ActionBar只带有Title和返回按钮的Activity方可继承
- *
- * @author 张华洋 2017/3/7 18:36
- * @version V1.2.0
- * @name BaseActionBarActivity
- */
-public abstract class BaseActionBarActivity extends BaseActivity {
-
- protected abstract
- @StringRes
- int setTitleId();
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- //标题栏设置
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setHomeButtonEnabled(true);
- actionBar.setTitle(setTitleId());
- }
- }
-
- @Override
- public boolean onSupportNavigateUp() {
- onBackPressed();
- return true;
- }
-}
diff --git a/common/src/main/java/com/guiying/common/base/BaseActivity.java b/common/src/main/java/com/guiying/common/base/BaseActivity.java
deleted file mode 100644
index b5d76a4..0000000
--- a/common/src/main/java/com/guiying/common/base/BaseActivity.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.guiying.common.base;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.support.annotation.IdRes;
-import android.support.v7.app.AppCompatActivity;
-import android.view.View;
-
-/**
- * Activity基类
- *
- * @author 2016/12/2 17:33
- * @version V1.0.0
- * @name BaseActivity
- */
-public abstract class BaseActivity extends AppCompatActivity {
-
- /**
- * 处理Intent,防止开发人员没做Intent判空
- */
- protected void handleIntent(Intent intent) {
- }
-
- /**
- * 封装的findViewByID方法
- */
- @SuppressWarnings("unchecked")
- protected T $(@IdRes int id) {
- return (T) super.findViewById(id);
- }
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- BaseApplication.getIns().addActivity(this);
- //强制在基类Intent判空
- if (null != getIntent()) {
- handleIntent(getIntent());
- }
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- BaseApplication.getIns().finishActivity(this);
- }
-
-}
diff --git a/common/src/main/java/com/guiying/common/base/BasePresenter.java b/common/src/main/java/com/guiying/common/base/BasePresenter.java
deleted file mode 100644
index c05c925..0000000
--- a/common/src/main/java/com/guiying/common/base/BasePresenter.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.guiying.common.base;
-
-public interface BasePresenter {
-
- void start();
-
-}
diff --git a/common/src/main/java/com/guiying/common/base/BaseView.java b/common/src/main/java/com/guiying/common/base/BaseView.java
deleted file mode 100644
index debd151..0000000
--- a/common/src/main/java/com/guiying/common/base/BaseView.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.guiying.common.base;
-
-public interface BaseView {
-
- void setPresenter(T presenter);
-
-}
diff --git a/common/src/main/java/com/guiying/common/http/HttpsUtil.java b/common/src/main/java/com/guiying/common/http/HttpsUtil.java
deleted file mode 100644
index 6085aae..0000000
--- a/common/src/main/java/com/guiying/common/http/HttpsUtil.java
+++ /dev/null
@@ -1,296 +0,0 @@
-package com.guiying.common.http;
-
-import android.annotation.SuppressLint;
-import android.content.Context;
-import android.os.Build;
-import android.support.annotation.RawRes;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.UnknownHostException;
-import java.security.KeyManagementException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.UnrecoverableKeyException;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSocket;
-import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-import javax.net.ssl.X509TrustManager;
-
-/**
- * HttpsUtils来自于鸿洋的: https://github.com/hongyangAndroid/okhttputils;
- * 增加了主机名校验方法getHostnameVerifier();
- * 其他参考的文章有:http://android.jobbole.com/83787/;
- *
- * Android 4.X 对TLS1.1、TLS1.2的支持参考了http://blog.csdn.net/joye123/article/details/53888252
- */
-public class HttpsUtil {
-
- /**
- * 包装的 SSL(Secure Socket Layer)参数类
- */
- public static class SSLParams {
- public SSLSocketFactory sSLSocketFactory;
- public X509TrustManager trustManager;
- }
-
- /**
- * @param context 上下文
- * @param certificatesId "XXX.cer" 文件 (文件位置res/raw/XXX.cer)
- * @param bksFileId "XXX.bks"文件(文件位置res/raw/XXX.bks)
- * @param password The certificate's password.
- * @return SSLParams
- */
- public static SSLParams getSslSocketFactory(Context context, @RawRes int[] certificatesId, @RawRes int bksFileId, String password) {
- if (context == null) {
- throw new NullPointerException("context == null");
- }
- SSLParams sslParams = new SSLParams();
- try {
- TrustManager[] trustManagers = prepareTrustManager(context, certificatesId);
- KeyManager[] keyManagers = prepareKeyManager(context, bksFileId, password);
-
- //创建TLS类型的SSLContext对象,that uses our TrustManager
- SSLContext sslContext = SSLContext.getInstance("TLS");
-
- X509TrustManager x509TrustManager;
- if (trustManagers != null) {
- x509TrustManager = new MyTrustManager(chooseTrustManager(trustManagers));
- } else {
- x509TrustManager = new UnSafeTrustManager();
- }
- //用上面得到的trustManagers初始化SSLContext,这样sslContext就会信任keyStore中的证书
- sslContext.init(keyManagers, new TrustManager[]{x509TrustManager}, null);
-
- //通过sslContext获取SSLSocketFactory对象
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
- /*Android 4.X 对TLS1.1、TLS1.2的支持*/
- sslParams.sSLSocketFactory = new Tls12SocketFactory(sslContext.getSocketFactory());
- sslParams.trustManager = x509TrustManager;
- return sslParams;
- }
-
- sslParams.sSLSocketFactory = sslContext.getSocketFactory();
- sslParams.trustManager = x509TrustManager;
- return sslParams;
- } catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException e) {
- throw new AssertionError(e);
- }
- }
-
-
- /**
- * 主机名校验方法
- */
- public static HostnameVerifier getHostnameVerifier() {
- return new HostnameVerifier() {
- @Override
- public boolean verify(String hostname, SSLSession session) {
- return hostname.equalsIgnoreCase(session.getPeerHost());
- }
- };
- }
-
-
- private static TrustManager[] prepareTrustManager(Context context, int[] certificatesId) {
- if (certificatesId == null || certificatesId.length <= 0) {
- return null;
- }
-
- try {
- //创建X.509格式的CertificateFactory
- CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
- // 创建一个默认类型的KeyStore,存储我们信任的证书
- KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
- keyStore.load(null);
- int index = 0;
- for (int certificateId : certificatesId) {
- //从本地资源中获取证书的流
- InputStream cerInputStream = context.getResources().openRawResource(certificateId);
- String certificateAlias = Integer.toString(index++);
-
- //certificate是java.security.cert.Certificate,而不是其他Certificate
- //证书工厂根据证书文件的流生成证书Certificate
- Certificate certificate = certificateFactory.generateCertificate(cerInputStream);
- //将证书certificate作为信任的证书放入到keyStore中
- keyStore.setCertificateEntry(certificateAlias, certificate);
- try {
- if (cerInputStream != null)
- cerInputStream.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- //TrustManagerFactory是用于生成TrustManager的,这里创建一个默认类型的TrustManagerFactory
- TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
- //用我们之前的keyStore实例初始化TrustManagerFactory,这样trustManagerFactory就会信任keyStore中的证书
- trustManagerFactory.init(keyStore);
- return trustManagerFactory.getTrustManagers();
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
-
-
- private static KeyManager[] prepareKeyManager(Context context, @RawRes int bksFileId, String password) {
-
- try {
- KeyStore clientKeyStore = KeyStore.getInstance("BKS");
- clientKeyStore.load(context.getResources().openRawResource(bksFileId), password.toCharArray());
- KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
- keyManagerFactory.init(clientKeyStore, password.toCharArray());
- return keyManagerFactory.getKeyManagers();
-
- } catch (KeyStoreException | NoSuchAlgorithmException | UnrecoverableKeyException | CertificateException | IOException e) {
- e.printStackTrace();
- }
- return null;
- }
-
-
- private static X509TrustManager chooseTrustManager(TrustManager[] trustManagers) {
- for (TrustManager trustManager : trustManagers) {
- if (trustManager instanceof X509TrustManager) {
- return (X509TrustManager) trustManager;
- }
- }
- return null;
- }
-
-
- /**
- * 客户端不对证书做任何检查;
- * 客户端不对证书做任何验证的做法有很大的安全漏洞。
- */
- private static class UnSafeTrustManager implements X509TrustManager {
-
- @SuppressLint("TrustAllX509TrustManager")
- @Override
- public void checkClientTrusted(X509Certificate[] chain, String authType)
- throws CertificateException {
- }
-
- @SuppressLint("TrustAllX509TrustManager")
- @Override
- public void checkServerTrusted(X509Certificate[] chain, String authType)
- throws CertificateException {
- }
-
- @Override
- public X509Certificate[] getAcceptedIssuers() {
- return new X509Certificate[]{};
- }
- }
-
-
- private static class MyTrustManager implements X509TrustManager {
- private X509TrustManager defaultTrustManager;
- private X509TrustManager localTrustManager;
-
- private MyTrustManager(X509TrustManager localTrustManager) throws NoSuchAlgorithmException, KeyStoreException {
- //TrustManagerFactory是用于生成TrustManager的,创建一个默认类型的TrustManagerFactory
- TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
- trustManagerFactory.init((KeyStore) null);
- defaultTrustManager = chooseTrustManager(trustManagerFactory.getTrustManagers());
- this.localTrustManager = localTrustManager;
- }
-
-
- @SuppressLint("TrustAllX509TrustManager")
- @Override
- public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
-
- }
-
- @Override
- public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
- try {
- defaultTrustManager.checkServerTrusted(chain, authType);
- } catch (CertificateException ce) {
- localTrustManager.checkServerTrusted(chain, authType);
- }
- }
-
-
- @Override
- public X509Certificate[] getAcceptedIssuers() {
- return new X509Certificate[0];
- }
- }
-
-
- /**
- * 自行实现SSLSocketFactory ,实现Android 4.X 对TLSv1.1、TLSv1.2的支持
- */
- private static class Tls12SocketFactory extends SSLSocketFactory {
-
- private static final String[] TLS_SUPPORT_VERSION = {"TLSv1.1", "TLSv1.2"};
-
- final SSLSocketFactory delegate;
-
- private Tls12SocketFactory(SSLSocketFactory base) {
- this.delegate = base;
- }
-
- @Override
- public String[] getDefaultCipherSuites() {
- return delegate.getDefaultCipherSuites();
- }
-
- @Override
- public String[] getSupportedCipherSuites() {
- return delegate.getSupportedCipherSuites();
- }
-
- @Override
- public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
- return patch(delegate.createSocket(s, host, port, autoClose));
- }
-
- @Override
- public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
- return patch(delegate.createSocket(host, port));
- }
-
- @Override
- public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
- return patch(delegate.createSocket(host, port, localHost, localPort));
- }
-
- @Override
- public Socket createSocket(InetAddress host, int port) throws IOException {
- return patch(delegate.createSocket(host, port));
- }
-
- @Override
- public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
- return patch(delegate.createSocket(address, port, localAddress, localPort));
- }
-
- private Socket patch(Socket s) {
- //代理SSLSocketFactory在创建一个Socket连接的时候,会设置Socket的可用的TLS版本。
- if (s instanceof SSLSocket) {
- ((SSLSocket) s).setEnabledProtocols(TLS_SUPPORT_VERSION);
- }
- return s;
- }
- }
-
-
-}
diff --git a/girls/build.gradle b/girls/build.gradle
deleted file mode 100644
index 7fd1812..0000000
--- a/girls/build.gradle
+++ /dev/null
@@ -1,50 +0,0 @@
-if (isModule.toBoolean()) {
- apply plugin: 'com.android.application'
-} else {
- apply plugin: 'com.android.library'
-}
-
-apply plugin: 'com.neenbedankt.android-apt'
-
-android {
- compileSdkVersion rootProject.ext.compileSdkVersion
- buildToolsVersion rootProject.ext.buildToolsVersion
-
- defaultConfig {
- minSdkVersion rootProject.ext.minSdkVersion
- targetSdkVersion rootProject.ext.targetSdkVersion
- versionCode rootProject.ext.versionCode
- versionName rootProject.ext.versionName
- }
-
- buildTypes {
- release {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- }
- }
-
- sourceSets {
- main {
- if (isModule.toBoolean()) {
- manifest.srcFile 'src/main/debug/AndroidManifest.xml'
- } else {
- manifest.srcFile 'src/main/release/AndroidManifest.xml'
- //release模式下排除debug文件夹中的所有Java文件
- java {
- exclude 'debug/**'
- }
- }
- }
- }
- //设置了resourcePrefix值后,所有的资源名必须以指定的字符串做前缀,否则会报错。
- //但是resourcePrefix这个值只能限定xml里面的资源,并不能限定图片资源,所有图片资源仍然需要手动去修改资源名。
- //resourcePrefix "girls_"
-}
-
-dependencies {
- compile fileTree(dir: 'libs', include: ['*.jar'])
- compile project(':common')
- //router
- apt "com.github.mzule.activityrouter:compiler:$rootProject.aptCompilerVersion"
-}
diff --git a/girls/proguard-rules.pro b/girls/proguard-rules.pro
deleted file mode 100644
index 1fa287c..0000000
--- a/girls/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 D:\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/girls/src/main/java/com/guiying/girls/Girls.java b/girls/src/main/java/com/guiying/girls/Girls.java
deleted file mode 100644
index 3386507..0000000
--- a/girls/src/main/java/com/guiying/girls/Girls.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.guiying.girls;
-
-import com.github.mzule.activityrouter.annotation.Module;
-
-/**
- * 类说明
- *
- * @author 张华洋 2017/2/15 16:34
- * @version V1.2.0
- * @name Girls
- */
-@Module("girls")
-public class Girls {
-}
diff --git a/gradle.properties b/gradle.properties
index 68cc1c2..9b51cd5 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -9,17 +9,18 @@
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
-org.gradle.jvmargs=-Xmx1536m
+org.gradle.jvmargs=-Xmx2048m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+
org.gradle.daemon=true
org.gradle.configureondemand=true
org.gradle.parallel=true
-# ΪԶ(ΪÿĵԻһ)
-localBuildToolsVersion=25.0.2
-localGradlePluginVersion=2.3.0
+# ֵһAndroidStudio汾һ
+localGradlePluginVersion=3.0.1
# ÿθġisModuleֵҪ "Sync Project" ť
-isModule=false
\ No newline at end of file
+# isModuleǡɿģʽ͡ģʽл
+isModule=false
diff --git a/keystore.properties b/keystore.properties
new file mode 100644
index 0000000..dabd93e
--- /dev/null
+++ b/keystore.properties
@@ -0,0 +1,4 @@
+storePassword=guiying712
+keyPassword=guiying712
+keyAlias=guiying712
+storeFile=/mykey.jks
\ No newline at end of file
diff --git a/common/.gitignore b/lib_common/.gitignore
similarity index 100%
rename from common/.gitignore
rename to lib_common/.gitignore
diff --git a/lib_common/build.gradle b/lib_common/build.gradle
new file mode 100644
index 0000000..87eb2af
--- /dev/null
+++ b/lib_common/build.gradle
@@ -0,0 +1,76 @@
+apply plugin: 'com.android.library'
+
+android {
+ compileSdkVersion build_versions.target_sdk
+ defaultConfig {
+ minSdkVersion build_versions.min_sdk
+ targetSdkVersion build_versions.target_sdk
+ versionCode 1
+ versionName "1.0"
+ }
+
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+
+ buildTypes {
+ release {
+ buildConfigField "boolean", "LOG_DEBUG", "true"
+ zipAlignEnabled false
+ shrinkResources false
+ minifyEnabled false
+ debuggable true
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+
+}
+
+dependencies {
+ api fileTree(include: ['*.jar'], dir: 'libs')
+ // Support libraries
+ api deps.support.app_compat
+ api deps.support.v4
+ api deps.support.v13
+ api deps.support.design
+ api deps.support.cardview
+ api deps.support.percent
+ api deps.support.recyclerview
+ api deps.constraint_layout
+
+ // RxJava and retrofit
+ api deps.rx_android
+ api deps.rxjava2
+ api deps.retrofit.runtime
+ api deps.retrofit.gson
+ api deps.persistent_cookie
+
+ //Dagger
+ api deps.dagger.runtime
+ api deps.dagger.android
+ api deps.dagger.android_support
+
+ // other
+ api deps.kotlin.stdlib
+ api deps.event_bus
+ api deps.gson
+ api deps.permission
+ api deps.utils
+ api deps.glide
+
+ //view
+ api deps.photo_view
+ api deps.easy_recycler
+ api deps.material_dialog
+ api deps.logger
+ api deps.toasty
+
+ //router
+ api deps.arouter_api
+
+ //annotationProcessor
+ annotationProcessor deps.dagger.android_support_compiler
+ annotationProcessor deps.dagger.compiler
+}
diff --git a/common/libs/simple-xml-core.jar b/lib_common/libs/simple-xml-core.jar
similarity index 100%
rename from common/libs/simple-xml-core.jar
rename to lib_common/libs/simple-xml-core.jar
diff --git a/lib_common/src/main/AndroidManifest.xml b/lib_common/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..8039311
--- /dev/null
+++ b/lib_common/src/main/AndroidManifest.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib_common/src/main/java/com/guiying/module/common/base/BaseActionBarActivity.java b/lib_common/src/main/java/com/guiying/module/common/base/BaseActionBarActivity.java
new file mode 100644
index 0000000..85c8570
--- /dev/null
+++ b/lib_common/src/main/java/com/guiying/module/common/base/BaseActionBarActivity.java
@@ -0,0 +1,58 @@
+package com.guiying.module.common.base;
+
+import android.os.Bundle;
+import android.support.annotation.Keep;
+import android.support.annotation.StringRes;
+import android.support.v7.app.ActionBar;
+
+import com.guiying.module.common.R;
+
+/**
+ * BaseActionBarActivity继承于BaseActivity,封装了actionBar的逻辑;
+ * 继承于ActionBarBaseActivity的Activity都将默认带有ActionBar,并且只能使用AppTheme主题;
+ * 只有那些ActionBar只带有Title和返回按钮的Activity方可继承
+ *
+ * @author 张华洋 2017/3/7 18:36
+ * @version V1.2.0
+ * @name BaseActionBarActivity
+ */
+@Keep
+public abstract class BaseActionBarActivity extends BaseActivity {
+
+ /*默认的ActionBar*/
+ protected ActionBar mActionBar;
+
+ /**
+ * 设置默认标题id
+ *
+ * @return 标题id
+ */
+ @StringRes
+ protected abstract int setTitleId();
+
+
+ /**
+ * 更新标题
+ *
+ * @param title String标题
+ */
+ protected void setTitle(String title) {
+ if (mActionBar != null) {
+ mActionBar.setTitle(title);
+ }
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ //标题栏设置
+ mActionBar = getSupportActionBar();
+ if (mActionBar != null) {
+ mActionBar.setHomeAsUpIndicator(R.drawable.ic_arrow_back);
+ mActionBar.setDisplayHomeAsUpEnabled(true);
+ mActionBar.setHomeButtonEnabled(true);
+ mActionBar.setTitle(setTitleId());
+ }
+ }
+
+}
diff --git a/lib_common/src/main/java/com/guiying/module/common/base/BaseActivity.java b/lib_common/src/main/java/com/guiying/module/common/base/BaseActivity.java
new file mode 100644
index 0000000..32ffebe
--- /dev/null
+++ b/lib_common/src/main/java/com/guiying/module/common/base/BaseActivity.java
@@ -0,0 +1,157 @@
+package com.guiying.module.common.base;
+
+import android.os.Bundle;
+import android.support.annotation.IdRes;
+import android.support.annotation.Keep;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.Toolbar;
+import android.view.View;
+
+import com.guiying.module.common.R;
+import com.guiying.module.common.utils.Utils;
+
+/**
+ * Activity基类
+ *
+ * @author 2016/12/2 17:33
+ * @version V1.0.0
+ * @name BaseActivity
+ */
+@Keep
+public abstract class BaseActivity extends AppCompatActivity {
+
+
+ /**
+ * 封装的findViewByID方法
+ */
+ @SuppressWarnings("unchecked")
+ protected T $(@IdRes int id) {
+ return (T) super.findViewById(id);
+ }
+
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ ViewManager.getInstance().addActivity(this);
+ }
+
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ ViewManager.getInstance().finishActivity(this);
+ }
+
+ @Override
+ public boolean onSupportNavigateUp() {
+ onBackPressed();
+ return true;
+ }
+
+
+ /**
+ * Setup the toolbar.
+ *
+ * @param toolbar toolbar
+ * @param hideTitle 是否隐藏Title
+ */
+ protected void setupToolBar(Toolbar toolbar, boolean hideTitle) {
+ setSupportActionBar(toolbar);
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setHomeAsUpIndicator(R.drawable.ic_arrow_back);
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
+ if (hideTitle) {
+ //隐藏Title
+ actionBar.setDisplayShowTitleEnabled(false);
+ }
+ }
+ }
+
+
+ /**
+ * 添加fragment
+ *
+ * @param fragment
+ * @param frameId
+ */
+ protected void addFragment(BaseFragment fragment, @IdRes int frameId) {
+ Utils.checkNotNull(fragment);
+ getSupportFragmentManager().beginTransaction()
+ .add(frameId, fragment, fragment.getClass().getSimpleName())
+ .addToBackStack(fragment.getClass().getSimpleName())
+ .commitAllowingStateLoss();
+
+ }
+
+
+ /**
+ * 替换fragment
+ * @param fragment
+ * @param frameId
+ */
+ protected void replaceFragment(BaseFragment fragment, @IdRes int frameId) {
+ Utils.checkNotNull(fragment);
+ getSupportFragmentManager().beginTransaction()
+ .replace(frameId, fragment, fragment.getClass().getSimpleName())
+ .addToBackStack(fragment.getClass().getSimpleName())
+ .commitAllowingStateLoss();
+
+ }
+
+
+ /**
+ * 隐藏fragment
+ * @param fragment
+ */
+ protected void hideFragment(BaseFragment fragment) {
+ Utils.checkNotNull(fragment);
+ getSupportFragmentManager().beginTransaction()
+ .hide(fragment)
+ .commitAllowingStateLoss();
+
+ }
+
+
+ /**
+ * 显示fragment
+ * @param fragment
+ */
+ protected void showFragment(BaseFragment fragment) {
+ Utils.checkNotNull(fragment);
+ getSupportFragmentManager().beginTransaction()
+ .show(fragment)
+ .commitAllowingStateLoss();
+
+ }
+
+
+ /**
+ * 移除fragment
+ * @param fragment
+ */
+ protected void removeFragment(BaseFragment fragment) {
+ Utils.checkNotNull(fragment);
+ getSupportFragmentManager().beginTransaction()
+ .remove(fragment)
+ .commitAllowingStateLoss();
+
+ }
+
+
+ /**
+ * 弹出栈顶部的Fragment
+ */
+ protected void popFragment() {
+ if (getSupportFragmentManager().getBackStackEntryCount() > 1) {
+ getSupportFragmentManager().popBackStack();
+ } else {
+ finish();
+ }
+ }
+
+
+}
diff --git a/lib_common/src/main/java/com/guiying/module/common/base/BaseApplication.java b/lib_common/src/main/java/com/guiying/module/common/base/BaseApplication.java
new file mode 100644
index 0000000..5c183ee
--- /dev/null
+++ b/lib_common/src/main/java/com/guiying/module/common/base/BaseApplication.java
@@ -0,0 +1,71 @@
+package com.guiying.module.common.base;
+
+import android.app.Application;
+
+import com.guiying.module.common.utils.Utils;
+import com.orhanobut.logger.LogLevel;
+import com.orhanobut.logger.Logger;
+
+import java.util.List;
+
+/**
+ * 要想使用BaseApplication,必须在组件中实现自己的Application,并且继承BaseApplication;
+ * 组件中实现的Application必须在debug包中的AndroidManifest.xml中注册,否则无法使用;
+ * 组件的Application需置于java/debug文件夹中,不得放于主代码;
+ * 组件中获取Context的方法必须为:Utils.getContext(),不允许其他写法;
+ *
+ * @author 2016/12/2 17:02
+ * @version V1.0.0
+ * @name BaseApplication
+ */
+public class BaseApplication extends Application {
+
+ public static final String ROOT_PACKAGE = "com.guiying.module";
+
+ private static BaseApplication sInstance;
+
+ private List mAppDelegateList;
+
+
+ public static BaseApplication getIns() {
+ return sInstance;
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ sInstance = this;
+ Logger.init("pattern").logLevel(LogLevel.FULL);
+ Utils.init(this);
+ mAppDelegateList = ClassUtils.getObjectsWithInterface(this, IApplicationDelegate.class, ROOT_PACKAGE);
+ for (IApplicationDelegate delegate : mAppDelegateList) {
+ delegate.onCreate();
+ }
+
+ }
+
+ @Override
+ public void onTerminate() {
+ super.onTerminate();
+ for (IApplicationDelegate delegate : mAppDelegateList) {
+ delegate.onTerminate();
+ }
+ }
+
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ for (IApplicationDelegate delegate : mAppDelegateList) {
+ delegate.onLowMemory();
+ }
+ }
+
+ @Override
+ public void onTrimMemory(int level) {
+ super.onTrimMemory(level);
+ for (IApplicationDelegate delegate : mAppDelegateList) {
+ delegate.onTrimMemory(level);
+ }
+ }
+}
diff --git a/lib_common/src/main/java/com/guiying/module/common/base/BaseFragment.java b/lib_common/src/main/java/com/guiying/module/common/base/BaseFragment.java
new file mode 100644
index 0000000..5ec3cb5
--- /dev/null
+++ b/lib_common/src/main/java/com/guiying/module/common/base/BaseFragment.java
@@ -0,0 +1,104 @@
+package com.guiying.module.common.base;
+
+import android.content.Context;
+import android.support.annotation.IdRes;
+import android.support.annotation.Keep;
+import android.support.v4.app.Fragment;
+
+import com.guiying.module.common.utils.Utils;
+
+/**
+ * Fragment的基类
+ *
+ * @author 张华洋
+ * @name BaseFragment
+ */
+@Keep
+public abstract class BaseFragment extends Fragment {
+
+ protected BaseActivity mActivity;
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ this.mActivity = (BaseActivity) context;
+ }
+
+
+ /**
+ * 获取宿主Activity
+ *
+ * @return BaseActivity
+ */
+ protected BaseActivity getHoldingActivity() {
+ return mActivity;
+ }
+
+
+ /**
+ * 添加fragment
+ *
+ * @param fragment
+ * @param frameId
+ */
+ protected void addFragment(BaseFragment fragment, @IdRes int frameId) {
+ Utils.checkNotNull(fragment);
+ getHoldingActivity().addFragment(fragment, frameId);
+
+ }
+
+
+ /**
+ * 替换fragment
+ *
+ * @param fragment
+ * @param frameId
+ */
+ protected void replaceFragment(BaseFragment fragment, @IdRes int frameId) {
+ Utils.checkNotNull(fragment);
+ getHoldingActivity().replaceFragment(fragment, frameId);
+ }
+
+
+ /**
+ * 隐藏fragment
+ *
+ * @param fragment
+ */
+ protected void hideFragment(BaseFragment fragment) {
+ Utils.checkNotNull(fragment);
+ getHoldingActivity().hideFragment(fragment);
+ }
+
+
+ /**
+ * 显示fragment
+ *
+ * @param fragment
+ */
+ protected void showFragment(BaseFragment fragment) {
+ Utils.checkNotNull(fragment);
+ getHoldingActivity().showFragment(fragment);
+ }
+
+
+ /**
+ * 移除Fragment
+ *
+ * @param fragment
+ */
+ protected void removeFragment(BaseFragment fragment) {
+ Utils.checkNotNull(fragment);
+ getHoldingActivity().removeFragment(fragment);
+
+ }
+
+
+ /**
+ * 弹出栈顶部的Fragment
+ */
+ protected void popFragment() {
+ getHoldingActivity().popFragment();
+ }
+
+}
diff --git a/lib_common/src/main/java/com/guiying/module/common/base/BasePresenter.java b/lib_common/src/main/java/com/guiying/module/common/base/BasePresenter.java
new file mode 100644
index 0000000..be56ad9
--- /dev/null
+++ b/lib_common/src/main/java/com/guiying/module/common/base/BasePresenter.java
@@ -0,0 +1,16 @@
+package com.guiying.module.common.base;
+
+import android.support.annotation.Keep;
+
+/**
+ * Presenter的基类
+ *
+ * @author 张华洋
+ * @name BasePresenter
+ */
+@Keep
+public interface BasePresenter {
+
+ void start();
+
+}
diff --git a/lib_common/src/main/java/com/guiying/module/common/base/BaseView.java b/lib_common/src/main/java/com/guiying/module/common/base/BaseView.java
new file mode 100644
index 0000000..e1b0b21
--- /dev/null
+++ b/lib_common/src/main/java/com/guiying/module/common/base/BaseView.java
@@ -0,0 +1,17 @@
+package com.guiying.module.common.base;
+
+
+import android.support.annotation.Keep;
+
+/**
+ * View接口的基类
+ *
+ * @author 张华洋
+ * @name BaseView
+ */
+@Keep
+public interface BaseView {
+
+ void setPresenter(T presenter);
+
+}
diff --git a/lib_common/src/main/java/com/guiying/module/common/base/ClassUtils.java b/lib_common/src/main/java/com/guiying/module/common/base/ClassUtils.java
new file mode 100644
index 0000000..7e65de6
--- /dev/null
+++ b/lib_common/src/main/java/com/guiying/module/common/base/ClassUtils.java
@@ -0,0 +1,296 @@
+package com.guiying.module.common.base;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.support.annotation.Keep;
+import android.util.Log;
+
+import com.guiying.module.common.utils.Utils;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import dalvik.system.DexFile;
+
+/**
+ * Copy from galaxy sdk ${com.alibaba.android.galaxy.utils.ClassUtils}
+ * Scanner, find out class with any conditions, copy from google source code.
+ */
+@Keep
+public class ClassUtils {
+ private static final String TAG = "ClassUtils";
+
+ private static final String EXTRACTED_NAME_EXT = ".classes";
+ private static final String EXTRACTED_SUFFIX = ".zip";
+
+ private static final String SECONDARY_FOLDER_NAME = "code_cache" + File.separator + "secondary-dexes";
+
+ private static final String PREFS_FILE = "multidex.version";
+ private static final String KEY_DEX_NUMBER = "dex.number";
+
+ private static final int VM_WITH_MULTIDEX_VERSION_MAJOR = 2;
+ private static final int VM_WITH_MULTIDEX_VERSION_MINOR = 1;
+
+ private static SharedPreferences getMultiDexPreferences(Context context) {
+ return context.getSharedPreferences(PREFS_FILE, Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB ? Context.MODE_PRIVATE : Context.MODE_PRIVATE | Context.MODE_MULTI_PROCESS);
+ }
+
+
+ /**
+ * 获取单一路径下所有实现了接口的类对象
+ *
+ * @param context U know
+ * @param clazz 接口
+ * @param path 包路径
+ * @param U know
+ * @return 对象列表
+ */
+ public static List
+ getObjectsWithInterface(Context context, Class clazz, String path) {
+ List objectList = new ArrayList<>();
+ try {
+ //找出所有路径中的类名,主要用于各个组件根包名一致的情况
+ List classFileNames = getFileNameByPackageName(context, path);
+
+ for (String className : classFileNames) {
+ Class aClass = Class.forName(className);
+ if (clazz.isAssignableFrom(aClass) && !clazz.equals(aClass) && !aClass.isInterface()) {
+ objectList.add((T) Class.forName(className).getConstructor().newInstance());
+ }
+ }
+
+ if (objectList.size() == 0) {
+ Log.e(TAG, "No files were found, check your configuration please!");
+ }
+ } catch (Exception e) {
+ e.getStackTrace();
+ Log.e(TAG, "getObjectsWithInterface error, " + e.getMessage());
+ }
+
+ return objectList;
+ }
+
+
+ /**
+ * 获取多路径下所有实现了接口的类对象
+ *
+ * @param context U know
+ * @param clazz 接口
+ * @param pathList 包路径列表
+ * @param U know
+ * @return 对象列表
+ */
+ public static List getObjectsWithInterface(Context context, Class clazz, List pathList) {
+ List objectList = new ArrayList<>();
+ try {
+ for (String path : pathList) {
+ //找出所有路径中的类名,主要用于各个组件根包名不一致的情况
+ List classFileNames = getFileNameByPackageName(context, path);
+
+ for (String className : classFileNames) {
+ Class aClass = Class.forName(className);
+ if (clazz.isAssignableFrom(aClass) && !clazz.equals(aClass) && !aClass.isInterface()) {
+ objectList.add((T) Class.forName(className).getConstructor().newInstance());
+ }
+ }
+ }
+
+ if (objectList.size() == 0) {
+ Log.e(TAG, "No files were found, check your configuration please!");
+ }
+ } catch (Exception e) {
+ e.getStackTrace();
+ Log.e(TAG, "getObjectsWithInterface error, " + e.getMessage());
+ }
+
+ return objectList;
+ }
+
+
+ /**
+ * 通过指定包名,扫描包下面包含的所有的ClassName
+ *
+ * @param context U know
+ * @param packageName 包名
+ * @return 所有class的集合
+ */
+ public static List getFileNameByPackageName(Context context, String packageName) throws PackageManager.NameNotFoundException, IOException {
+ List classNames = new ArrayList<>();
+ for (String path : getSourcePaths(context)) {
+ DexFile dexfile = null;
+
+ try {
+ if (path.endsWith(EXTRACTED_SUFFIX)) {
+ //NOT use new DexFile(path), because it will throw "permission error in /data/dalvik-cache"
+ dexfile = DexFile.loadDex(path, path + ".tmp", 0);
+ } else {
+ dexfile = new DexFile(path);
+ }
+ Enumeration dexEntries = dexfile.entries();
+ while (dexEntries.hasMoreElements()) {
+ String className = dexEntries.nextElement();
+ if (className.contains(packageName)) {
+ classNames.add(className);
+ }
+ }
+ } catch (Throwable ignore) {
+ Log.e(TAG, "Scan map file in dex files made error.", ignore);
+ } finally {
+ if (null != dexfile) {
+ try {
+ dexfile.close();
+ } catch (Throwable ignore) {
+ }
+ }
+ }
+ }
+
+ Log.d(TAG, "Filter " + classNames.size() + " classes by packageName <" + packageName + ">");
+ return classNames;
+ }
+
+ /**
+ * get all the dex path
+ *
+ * @param context the application context
+ * @return all the dex path
+ * @throws PackageManager.NameNotFoundException Exception
+ * @throws IOException Exception
+ */
+ public static List getSourcePaths(Context context) throws PackageManager.NameNotFoundException, IOException {
+ ApplicationInfo applicationInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(), 0);
+ File sourceApk = new File(applicationInfo.sourceDir);
+
+ List sourcePaths = new ArrayList<>();
+ sourcePaths.add(applicationInfo.sourceDir); //add the default apk path
+
+ //the prefix of extracted file, ie: test.classes
+ String extractedFilePrefix = sourceApk.getName() + EXTRACTED_NAME_EXT;
+
+ //如果VM已经支持了MultiDex,就不要去Secondary Folder加载 Classesx.zip了,那里已经么有了
+ //通过是否存在sp中的multidex.version是不准确的,因为从低版本升级上来的用户,是包含这个sp配置的
+ if (!isVMMultidexCapable()) {
+ //the total dex numbers
+ int totalDexNumber = getMultiDexPreferences(context).getInt(KEY_DEX_NUMBER, 1);
+ File dexDir = new File(applicationInfo.dataDir, SECONDARY_FOLDER_NAME);
+
+ for (int secondaryNumber = 2; secondaryNumber <= totalDexNumber; secondaryNumber++) {
+ //for each dex file, ie: test.classes2.zip, test.classes3.zip...
+ String fileName = extractedFilePrefix + secondaryNumber + EXTRACTED_SUFFIX;
+ File extractedFile = new File(dexDir, fileName);
+ if (extractedFile.isFile()) {
+ sourcePaths.add(extractedFile.getAbsolutePath());
+ //we ignore the verify zip part
+ } else {
+ throw new IOException("Missing extracted secondary dex file '" + extractedFile.getPath() + "'");
+ }
+ }
+ }
+
+ if (Utils.isAppDebug()) {
+ // Search instant run support only debuggable
+ sourcePaths.addAll(tryLoadInstantRunDexFile(applicationInfo));
+ }
+ return sourcePaths;
+ }
+
+ /**
+ * Get instant run dex path, used to catch the branch usingApkSplits=false.
+ */
+ private static List tryLoadInstantRunDexFile(ApplicationInfo applicationInfo) {
+ List instantRunSourcePaths = new ArrayList<>();
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && null != applicationInfo.splitSourceDirs) {
+ // add the splite apk, normally for InstantRun, and newest version.
+ instantRunSourcePaths.addAll(Arrays.asList(applicationInfo.splitSourceDirs));
+ Log.d(TAG, "Found InstantRun support");
+ } else {
+ try {
+ // This man is reflection from Google instant run sdk, he will tell me where the dex files go.
+ Class pathsByInstantRun = Class.forName("com.android.tools.fd.runtime.Paths");
+ Method getDexFileDirectory = pathsByInstantRun.getMethod("getDexFileDirectory", String.class);
+ String instantRunDexPath = (String) getDexFileDirectory.invoke(null, applicationInfo.packageName);
+
+ File instantRunFilePath = new File(instantRunDexPath);
+ if (instantRunFilePath.exists() && instantRunFilePath.isDirectory()) {
+ File[] dexFile = instantRunFilePath.listFiles();
+ for (File file : dexFile) {
+ if (null != file && file.exists() && file.isFile() && file.getName().endsWith(".dex")) {
+ instantRunSourcePaths.add(file.getAbsolutePath());
+ }
+ }
+ Log.d(TAG, "Found InstantRun support");
+ }
+
+ } catch (Exception e) {
+ Log.e(TAG, "InstantRun support error, " + e.getMessage());
+ }
+ }
+
+ return instantRunSourcePaths;
+ }
+
+ /**
+ * Identifies if the current VM has a native support for multidex, meaning there is no need for
+ * additional installation by this library.
+ *
+ * @return true if the VM handles multidex
+ */
+ private static boolean isVMMultidexCapable() {
+ boolean isMultidexCapable = false;
+ String vmName = null;
+
+ try {
+ if (isYunOS()) { // YunOS需要特殊判断
+ vmName = "'YunOS'";
+ isMultidexCapable = Integer.valueOf(System.getProperty("ro.build.version.sdk")) >= 21;
+ } else { // 非YunOS原生Android
+ vmName = "'Android'";
+ String versionString = System.getProperty("java.vm.version");
+ if (versionString != null) {
+ Matcher matcher = Pattern.compile("(\\d+)\\.(\\d+)(\\.\\d+)?").matcher(versionString);
+ if (matcher.matches()) {
+ try {
+ int major = Integer.parseInt(matcher.group(1));
+ int minor = Integer.parseInt(matcher.group(2));
+ isMultidexCapable = (major > VM_WITH_MULTIDEX_VERSION_MAJOR)
+ || ((major == VM_WITH_MULTIDEX_VERSION_MAJOR)
+ && (minor >= VM_WITH_MULTIDEX_VERSION_MINOR));
+ } catch (NumberFormatException ignore) {
+ // let isMultidexCapable be false
+ }
+ }
+ }
+ }
+ } catch (Exception ignore) {
+
+ }
+
+ Log.i(TAG, "VM with name " + vmName + (isMultidexCapable ? " has multidex support" : " does not have multidex support"));
+ return isMultidexCapable;
+ }
+
+ /**
+ * 判断系统是否为YunOS系统
+ */
+ private static boolean isYunOS() {
+ try {
+ String version = System.getProperty("ro.yunos.version");
+ String vmName = System.getProperty("java.vm.name");
+ return (vmName != null && vmName.toLowerCase().contains("lemur"))
+ || (version != null && version.trim().length() > 0);
+ } catch (Exception ignore) {
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib_common/src/main/java/com/guiying/module/common/base/IApplicationDelegate.java b/lib_common/src/main/java/com/guiying/module/common/base/IApplicationDelegate.java
new file mode 100644
index 0000000..1ea31b6
--- /dev/null
+++ b/lib_common/src/main/java/com/guiying/module/common/base/IApplicationDelegate.java
@@ -0,0 +1,23 @@
+package com.guiying.module.common.base;
+
+import android.support.annotation.Keep;
+
+/**
+ * 类说明
+ *
+ * @author 张华洋 2017/9/20 22:23
+ * @version V2.8.3
+ * @name ApplicationDelegate
+ */
+@Keep
+public interface IApplicationDelegate {
+
+ void onCreate();
+
+ void onTerminate();
+
+ void onLowMemory();
+
+ void onTrimMemory(int level);
+
+}
diff --git a/lib_common/src/main/java/com/guiying/module/common/base/IViewDelegate.java b/lib_common/src/main/java/com/guiying/module/common/base/IViewDelegate.java
new file mode 100644
index 0000000..3c35b8e
--- /dev/null
+++ b/lib_common/src/main/java/com/guiying/module/common/base/IViewDelegate.java
@@ -0,0 +1,21 @@
+package com.guiying.module.common.base;
+
+
+import android.support.annotation.Keep;
+import android.view.View;
+
+/**
+ * 类说明
+ *
+ * @author 张华洋 2018/1/4 22:10
+ * @version V2.8.3
+ * @name IFragmentDelegate
+ */
+@Keep
+public interface IViewDelegate {
+
+ BaseFragment getFragment(String name);
+
+ View getView(String name);
+
+}
diff --git a/lib_common/src/main/java/com/guiying/module/common/base/InfoCallback.java b/lib_common/src/main/java/com/guiying/module/common/base/InfoCallback.java
new file mode 100644
index 0000000..8a5cf9b
--- /dev/null
+++ b/lib_common/src/main/java/com/guiying/module/common/base/InfoCallback.java
@@ -0,0 +1,19 @@
+package com.guiying.module.common.base;
+
+import android.support.annotation.Keep;
+
+/**
+ * 数据回调接口
+ *
+ * @author 张华洋 2017/3/22 13:36
+ * @version V1.2.0
+ * @name InfoCallback
+ */
+@Keep
+public interface InfoCallback {
+
+ void onSuccess(T info);
+
+ void onError(int code, String message);
+
+}
diff --git a/common/src/main/java/com/guiying/common/base/BaseApplication.java b/lib_common/src/main/java/com/guiying/module/common/base/ViewManager.java
similarity index 51%
rename from common/src/main/java/com/guiying/common/base/BaseApplication.java
rename to lib_common/src/main/java/com/guiying/module/common/base/ViewManager.java
index 3bfefbb..8f221a0 100644
--- a/common/src/main/java/com/guiying/common/base/BaseApplication.java
+++ b/lib_common/src/main/java/com/guiying/module/common/base/ViewManager.java
@@ -1,67 +1,82 @@
-package com.guiying.common.base;
+package com.guiying.module.common.base;
import android.app.Activity;
-import android.app.Application;
import android.content.Context;
+import android.support.annotation.Keep;
import android.util.Log;
-import com.guiying.common.utils.Utils;
-import com.orhanobut.logger.LogLevel;
-import com.orhanobut.logger.Logger;
-
+import java.util.ArrayList;
+import java.util.List;
import java.util.Stack;
/**
- * 要想使用BaseApplication,必须在组件中实现自己的Application,并且继承BaseApplication;
- * 组件中实现的Application必须在AndroidManifest.xml中注册,否则无法使用;
- * 组件的Application需置于java/debug文件夹中,不得放于主代码;
- * 组件中获取Context的方法必须为:Utils.getContext(),不允许其他写法;
- * BaseApplication主要用来管理全局Activity;
+ *
*
- * @author 2016/12/2 17:02
- * @version V1.0.0
- * @name BaseApplication
+ * @author 张华洋 2017/9/26 22:26
+ * @version V1.1
+ * @name ViewManager
*/
-public class BaseApplication extends Application {
+@Keep
+public class ViewManager {
+
+ private static Stack activityStack;
+ private static List fragmentList;
+
+ public static ViewManager getInstance() {
+ return ViewManagerHolder.sInstance;
+ }
- private static BaseApplication sInstance;
+ private static class ViewManagerHolder {
+ private static final ViewManager sInstance = new ViewManager();
+ }
- private Stack activityStack;
+ private ViewManager() {
+ }
- public static BaseApplication getIns() {
- return sInstance;
+ public void addFragment(int index, BaseFragment fragment) {
+ if (fragmentList == null) {
+ fragmentList = new ArrayList<>();
+ }
+ fragmentList.add(index, fragment);
+ }
+
+
+ public BaseFragment getFragment(int index) {
+ if (fragmentList != null) {
+ return fragmentList.get(index);
+ }
+ return null;
}
- @Override
- public void onCreate() {
- super.onCreate();
- sInstance = this;
- Utils.init(this);
- if (Utils.isAppDebug()) {
- //只有debug模式才会打印日志
- Logger.init("Petrel").logLevel(LogLevel.FULL);
- } else {
- Logger.init("Petrel").logLevel(LogLevel.NONE);
+
+ public List getAllFragment() {
+ if (fragmentList != null) {
+ return fragmentList;
}
+ return null;
}
+
/**
* 添加指定Activity到堆栈
*/
public void addActivity(Activity activity) {
if (activityStack == null) {
- activityStack = new Stack<>();
+ activityStack = new Stack();
}
activityStack.add(activity);
}
+
/**
* 获取当前Activity
*/
public Activity currentActivity() {
- return activityStack.lastElement();
+ Activity activity = activityStack.lastElement();
+ return activity;
}
+
/**
* 结束当前Activity
*/
@@ -70,6 +85,7 @@ public void finishActivity() {
finishActivity(activity);
}
+
/**
* 结束指定的Activity
*/
@@ -81,6 +97,7 @@ public void finishActivity(Activity activity) {
}
}
+
/**
* 结束指定Class的Activity
*/
@@ -93,6 +110,7 @@ public void finishActivity(Class> cls) {
}
}
+
/**
* 结束全部的Activity
*/
@@ -105,19 +123,19 @@ public void finishAllActivity() {
activityStack.clear();
}
+
/**
* 退出应用程序
*/
public void exitApp(Context context) {
try {
finishAllActivity();
- android.app.ActivityManager activityMgr = (android.app.ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
- activityMgr.restartPackage(context.getPackageName());
- System.exit(0);
+ //杀死后台进程需要在AndroidManifest中声明android.permission.KILL_BACKGROUND_PROCESSES;
+ android.app.ActivityManager activityManager = (android.app.ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+ activityManager.killBackgroundProcesses(context.getPackageName());
+ //System.exit(0);
} catch (Exception e) {
Log.e("ActivityManager", "app exit" + e.getMessage());
}
}
-
-
}
diff --git a/lib_common/src/main/java/com/guiying/module/common/glide/ImageUtils.java b/lib_common/src/main/java/com/guiying/module/common/glide/ImageUtils.java
new file mode 100644
index 0000000..6bd37ee
--- /dev/null
+++ b/lib_common/src/main/java/com/guiying/module/common/glide/ImageUtils.java
@@ -0,0 +1,133 @@
+package com.guiying.module.common.glide;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
+import android.view.View;
+import android.widget.ImageView;
+
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.load.engine.DiskCacheStrategy;
+import com.bumptech.glide.load.resource.drawable.GlideDrawable;
+import com.bumptech.glide.request.animation.GlideAnimation;
+import com.bumptech.glide.request.target.GlideDrawableImageViewTarget;
+import com.bumptech.glide.request.target.SimpleTarget;
+import com.guiying.module.common.utils.Utils;
+
+/**
+ * 图片加载工具类
+ *
+ * @name ImageUtils
+ */
+public class ImageUtils {
+
+ /**
+ * 默认加载
+ */
+ public static void loadImageView(String path, ImageView mImageView) {
+ Glide.with(mImageView.getContext()).load(path).into(mImageView);
+ }
+
+ public static void loadImageWithError(String path, int errorRes, ImageView mImageView) {
+ Glide.with(mImageView.getContext())
+ .load(path)
+ .crossFade()
+ .diskCacheStrategy(DiskCacheStrategy.SOURCE)
+ .error(errorRes)
+ .into(mImageView);
+ }
+
+ /**
+ * 设置加载中以及加载失败图片
+ */
+ public static void loadImageWithLoading(String path, ImageView mImageView, int lodingImage, int errorRes) {
+ Glide.with(mImageView.getContext()).load(path).placeholder(lodingImage).
+ error(errorRes).into(mImageView);
+ }
+
+ /**
+ * 设置加载动画
+ * api也提供了几个常用的动画:比如crossFade()
+ */
+ public static void loadImageViewAnim(String path, int anim, ImageView mImageView) {
+ Glide.with(mImageView.getContext()).load(path).animate(anim).into(mImageView);
+ }
+
+
+ /**
+ * 加载为bitmap
+ *
+ * @param path 图片地址
+ * @param listener 回调
+ */
+ public static void loadBitMap(String path, final onLoadBitmap listener) {
+ Glide.with(Utils.getContext()).load(path).asBitmap().into(new SimpleTarget() {
+
+ @Override
+ public void onResourceReady(Bitmap bitmap, GlideAnimation super Bitmap> glideAnimation) {
+ listener.onReady(bitmap);
+ }
+
+ @Override
+ public void onLoadFailed(Exception e, Drawable errorDrawable) {
+ listener.onFailed();
+ }
+ });
+ }
+
+ /**
+ * 显示加载进度
+ *
+ * @param path 图片地址
+ * @param mImageView 图片控件
+ * @param loadView 加载view
+ */
+ public static void loadImageWithProgress(String path, final ImageView mImageView, final View loadView, int errorRes) {
+ Glide.with(mImageView.getContext()).load(path).error(errorRes).into(new GlideDrawableImageViewTarget(mImageView) {
+ @Override
+ public void onResourceReady(GlideDrawable resource, GlideAnimation super GlideDrawable> animation) {
+ super.onResourceReady(resource, animation);
+ loadView.setVisibility(View.GONE);
+ }
+
+ @Override
+ public void onLoadFailed(Exception e, Drawable errorDrawable) {
+ super.onLoadFailed(e, errorDrawable);
+ loadView.setVisibility(View.GONE);
+ }
+ });
+ }
+
+ /**
+ * 清除view上的图片
+ *
+ * @param view 视图
+ */
+ public static void clearImageView(View view) {
+ Glide.clear(view);
+ }
+
+ /**
+ * 清理磁盘缓存需要在子线程中执行
+ */
+ public static void GuideClearDiskCache(Context mContext) {
+ Glide.get(mContext).clearDiskCache();
+ }
+
+ /**
+ * 清理内存缓存可以在UI主线程中进行
+ */
+ public static void GuideClearMemory(Context mContext) {
+ Glide.get(mContext).clearMemory();
+ }
+
+ /**
+ * 加载bitmap回调
+ */
+ public interface onLoadBitmap {
+ void onReady(Bitmap resource);
+
+ void onFailed();
+ }
+
+}
\ No newline at end of file
diff --git a/common/src/main/java/com/guiying/common/glide/OkHttpGlideModule.java b/lib_common/src/main/java/com/guiying/module/common/glide/OkHttpGlideModule.java
similarity index 98%
rename from common/src/main/java/com/guiying/common/glide/OkHttpGlideModule.java
rename to lib_common/src/main/java/com/guiying/module/common/glide/OkHttpGlideModule.java
index ba8969a..1fedd2e 100644
--- a/common/src/main/java/com/guiying/common/glide/OkHttpGlideModule.java
+++ b/lib_common/src/main/java/com/guiying/module/common/glide/OkHttpGlideModule.java
@@ -1,4 +1,4 @@
-package com.guiying.common.glide;
+package com.guiying.module.common.glide;
import android.content.Context;
diff --git a/common/src/main/java/com/guiying/common/glide/OkHttpStreamFetcher.java b/lib_common/src/main/java/com/guiying/module/common/glide/OkHttpStreamFetcher.java
similarity index 95%
rename from common/src/main/java/com/guiying/common/glide/OkHttpStreamFetcher.java
rename to lib_common/src/main/java/com/guiying/module/common/glide/OkHttpStreamFetcher.java
index 358afd3..efd1560 100644
--- a/common/src/main/java/com/guiying/common/glide/OkHttpStreamFetcher.java
+++ b/lib_common/src/main/java/com/guiying/module/common/glide/OkHttpStreamFetcher.java
@@ -1,10 +1,10 @@
-package com.guiying.common.glide;
+package com.guiying.module.common.glide;
import com.bumptech.glide.Priority;
import com.bumptech.glide.load.data.DataFetcher;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.util.ContentLengthInputStream;
-import com.guiying.common.utils.CloseUtils;
+import com.guiying.module.common.utils.CloseUtils;
import java.io.IOException;
import java.io.InputStream;
diff --git a/common/src/main/java/com/guiying/common/glide/OkHttpUrlLoader.java b/lib_common/src/main/java/com/guiying/module/common/glide/OkHttpUrlLoader.java
similarity index 98%
rename from common/src/main/java/com/guiying/common/glide/OkHttpUrlLoader.java
rename to lib_common/src/main/java/com/guiying/module/common/glide/OkHttpUrlLoader.java
index 89f166d..c456435 100644
--- a/common/src/main/java/com/guiying/common/glide/OkHttpUrlLoader.java
+++ b/lib_common/src/main/java/com/guiying/module/common/glide/OkHttpUrlLoader.java
@@ -1,4 +1,4 @@
-package com.guiying.common.glide;
+package com.guiying.module.common.glide;
import android.content.Context;
diff --git a/common/src/main/java/com/guiying/common/http/ApiService.java b/lib_common/src/main/java/com/guiying/module/common/http/ApiService.java
similarity index 97%
rename from common/src/main/java/com/guiying/common/http/ApiService.java
rename to lib_common/src/main/java/com/guiying/module/common/http/ApiService.java
index fa73d0a..895b72e 100644
--- a/common/src/main/java/com/guiying/common/http/ApiService.java
+++ b/lib_common/src/main/java/com/guiying/module/common/http/ApiService.java
@@ -1,4 +1,4 @@
-package com.guiying.common.http;
+package com.guiying.module.common.http;
import java.util.Map;
diff --git a/common/src/main/java/com/guiying/common/http/DataParseUtil.java b/lib_common/src/main/java/com/guiying/module/common/http/DataParseUtil.java
similarity index 98%
rename from common/src/main/java/com/guiying/common/http/DataParseUtil.java
rename to lib_common/src/main/java/com/guiying/module/common/http/DataParseUtil.java
index dafb631..9cbc61b 100644
--- a/common/src/main/java/com/guiying/common/http/DataParseUtil.java
+++ b/lib_common/src/main/java/com/guiying/module/common/http/DataParseUtil.java
@@ -1,4 +1,4 @@
-package com.guiying.common.http;
+package com.guiying.module.common.http;
import android.text.TextUtils;
diff --git a/lib_common/src/main/java/com/guiying/module/common/http/DataType.java b/lib_common/src/main/java/com/guiying/module/common/http/DataType.java
new file mode 100644
index 0000000..7847996
--- /dev/null
+++ b/lib_common/src/main/java/com/guiying/module/common/http/DataType.java
@@ -0,0 +1,34 @@
+package com.guiying.module.common.http;
+
+import android.support.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * 服务端响应的数据类型
+ *
+ * @author 张华洋 2017/5/2 21:53
+ * @version V1.2.0
+ * @name DataType
+ */
+public class DataType {
+
+ /*返回数据为String*/
+ public static final int STRING = 1;
+ /*返回数据为xml类型*/
+ public static final int XML = 2;
+ /*返回数据为json对象*/
+ public static final int JSON_OBJECT = 3;
+ /*返回数据为json数组*/
+ public static final int JSON_ARRAY = 4;
+
+ /**
+ * 自定义一个播放器状态注解
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({STRING, XML, JSON_OBJECT, JSON_ARRAY})
+ public @interface Type {
+ }
+
+}
diff --git a/common/src/main/java/com/guiying/common/http/HttpClient.java b/lib_common/src/main/java/com/guiying/module/common/http/HttpClient.java
similarity index 84%
rename from common/src/main/java/com/guiying/common/http/HttpClient.java
rename to lib_common/src/main/java/com/guiying/module/common/http/HttpClient.java
index 2713c31..2be900b 100644
--- a/common/src/main/java/com/guiying/common/http/HttpClient.java
+++ b/lib_common/src/main/java/com/guiying/module/common/http/HttpClient.java
@@ -1,16 +1,17 @@
-package com.guiying.common.http;
+package com.guiying.module.common.http;
+import android.support.annotation.NonNull;
import android.text.TextUtils;
import com.franmontiel.persistentcookiejar.ClearableCookieJar;
import com.franmontiel.persistentcookiejar.PersistentCookieJar;
import com.franmontiel.persistentcookiejar.cache.SetCookieCache;
import com.franmontiel.persistentcookiejar.persistence.SharedPrefsCookiePersistor;
-import com.guiying.common.R;
-import com.guiying.common.utils.NetworkUtils;
-import com.guiying.common.utils.StringUtils;
-import com.guiying.common.utils.ToastUtils;
-import com.guiying.common.utils.Utils;
+import com.guiying.module.common.R;
+import com.guiying.module.common.utils.NetworkUtils;
+import com.guiying.module.common.utils.StringUtils;
+import com.guiying.module.common.utils.ToastUtils;
+import com.guiying.module.common.utils.Utils;
import com.orhanobut.logger.Logger;
import java.io.IOException;
@@ -37,15 +38,8 @@
public class HttpClient {
/*The certificate's password*/
- private static final String STORE_PASS = "4444444";
- /*返回数据为String*/
- public static final int STRING = 0;
- /*返回数据为json对象*/
- public static final int OBJECT = 1;
- /*返回数据为json数组*/
- public static final int ARRAY = 2;
- /*返回数据为xml类型*/
- public static final int XML = 3;
+ private static final String STORE_PASS = "6666666";
+ private static final String STORE_ALIAS = "666666";
/*用户设置的BASE_URL*/
private static String BASE_URL = "";
/*本地使用的baseUrl*/
@@ -74,11 +68,11 @@ private static class HttpClientHolder {
private HttpClient() {
ClearableCookieJar cookieJar = new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(Utils.getContext()));
- //HttpsUtil.SSLParams sslParams = HttpsUtil.getSslSocketFactory(Utils.getContext(), new int[0], , STORE_PASS);
+ //HttpsUtil.SSLParams sslParams = HttpsUtil.getSslSocketFactory(Utils.getContext(), R.raw.cer,STORE_PASS , STORE_ALIAS);
okHttpClient = new OkHttpClient.Builder()
.connectTimeout(10000L, TimeUnit.MILLISECONDS)
//.sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager)
- .hostnameVerifier(HttpsUtil.getHostnameVerifier())
+ // .hostnameVerifier(HttpsUtil.getHostnameVerifier())
.addInterceptor(new LoggerInterceptor(null, true))
.cookieJar(cookieJar)
.build();
@@ -146,8 +140,8 @@ public void onResponse(Call call, Response response)
if (200 == response.code()) {
try {
String result = response.body().string();
- parseJson(result, builder.clazz, builder.bodyType, onResultListener);
- } catch (IOException e) {
+ parseData(result, builder.clazz, builder.bodyType, onResultListener);
+ } catch (IOException | IllegalStateException e) {
e.printStackTrace();
}
}
@@ -234,8 +228,9 @@ public static final class Builder {
private String url;
private Object tag;
private Map params = new HashMap<>();
- /*返回数据的类型*/
- private int bodyType = STRING;
+ /*返回数据的类型,默认是string类型*/
+ @DataType.Type
+ private int bodyType = DataType.STRING;
/*解析类*/
private Class clazz;
@@ -254,7 +249,7 @@ public Builder baseUrl(String baseUrl) {
/**
* 除baseUrl以外的部分,
- * 例如:"msp/mobile/login"
+ * 例如:"mobile/login"
*
* @param url path路径
*/
@@ -285,13 +280,13 @@ public Builder params(String key, String value) {
}
/**
- * 响应体类型设置
+ * 响应体类型设置,如果要响应体类型为STRING,请不要使用这个方法
*
- * @param bodyType 响应体类型,分别为STRING,OBJECT,ARRAY,XML
+ * @param bodyType 响应体类型,分别:STRING,JSON_OBJECT,JSON_ARRAY,XML
* @param clazz 指定的解析类
* @param 解析类
*/
- public Builder bodyType(int bodyType, Class clazz) {
+ public Builder bodyType(@DataType.Type int bodyType, @NonNull Class clazz) {
this.bodyType = bodyType;
this.clazz = clazz;
return this;
@@ -308,19 +303,27 @@ public HttpClient build() {
}
}
+ /**
+ * 数据解析方法
+ *
+ * @param data 要解析的数据
+ * @param clazz 解析类
+ * @param bodyType 解析数据类型
+ * @param onResultListener 回调方数据接口
+ */
@SuppressWarnings("unchecked")
- private void parseJson(String data, Class clazz, int bodyType, OnResultListener onResultListener) {
+ private void parseData(String data, Class clazz, @DataType.Type int bodyType, OnResultListener onResultListener) {
switch (bodyType) {
- case STRING:
+ case DataType.STRING:
onResultListener.onSuccess(data);
break;
- case OBJECT:
+ case DataType.JSON_OBJECT:
onResultListener.onSuccess(DataParseUtil.parseObject(data, clazz));
break;
- case ARRAY:
+ case DataType.JSON_ARRAY:
onResultListener.onSuccess(DataParseUtil.parseToArrayList(data, clazz));
break;
- case XML:
+ case DataType.XML:
onResultListener.onSuccess(DataParseUtil.parseXml(data, clazz));
break;
default:
diff --git a/lib_common/src/main/java/com/guiying/module/common/http/HttpsUtils.java b/lib_common/src/main/java/com/guiying/module/common/http/HttpsUtils.java
new file mode 100644
index 0000000..314d6ce
--- /dev/null
+++ b/lib_common/src/main/java/com/guiying/module/common/http/HttpsUtils.java
@@ -0,0 +1,269 @@
+package com.guiying.module.common.http;
+
+import android.content.Context;
+import android.support.annotation.RawRes;
+import android.text.TextUtils;
+
+import com.guiying.module.common.utils.CloseUtils;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.security.InvalidKeyException;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.SecureRandom;
+import java.security.SignatureException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+
+/**
+ * Https证书校验工具类
+ *
+ * @author 张华洋 2017/5/11 16:14
+ * @version V1.2.0
+ * @name HttpsUtils
+ */
+public class HttpsUtils {
+
+
+ public static class SSLParams {
+ public SSLSocketFactory sSLSocketFactory;
+ public X509TrustManager trustManager;
+ }
+
+ /**
+ * @param context 上下文
+ * @param bksFileId "XXX.bks"文件(文件位置res/raw/XXX.bks)
+ * @param password The certificate's password.
+ * @return SSLParams
+ */
+ public static SSLParams getSslSocketFactory(Context context, @RawRes int bksFileId, String password, String alias) {
+ if (context == null) {
+ throw new NullPointerException("context == null");
+ }
+ if (TextUtils.isEmpty(password) || TextUtils.isEmpty(alias)) {
+ throw new NullPointerException("password == null or alias == null!");
+ }
+ SSLParams sslParams = new SSLParams();
+ try {
+ // 创建一个BKS类型的KeyStore,存储我们信任的证书
+ KeyStore clientKeyStore = KeyStore.getInstance("BKS");
+ clientKeyStore.load(context.getResources().openRawResource(bksFileId), password.toCharArray());
+ //通过alias直接从密钥库中读取证书
+ Certificate rootCA = clientKeyStore.getCertificate(alias);
+ // Turn it to X509 format.
+ InputStream certInput = new ByteArrayInputStream(rootCA.getEncoded());
+ X509Certificate serverCert = (X509Certificate) CertificateFactory.getInstance("X.509").generateCertificate(certInput);
+ //关闭流
+ CloseUtils.closeIO(certInput);
+
+ TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+ //用我们之前的keyStore实例初始化TrustManagerFactory,这样trustManagerFactory就会信任keyStore中的证书
+ trustManagerFactory.init(clientKeyStore);
+
+ KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+ keyManagerFactory.init(clientKeyStore, password.toCharArray());
+
+ X509TrustManager x509TrustManager = new SafeTrustManager(serverCert);
+
+ //创建TLS类型的SSLContext对象,that uses our TrustManager
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+
+ //用上面得到的trustManagers初始化SSLContext,这样sslContext就会信任keyStore中的证书
+ sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());
+
+ //Android 4.X 对TLS1.1、TLS1.2的支持
+ sslParams.sSLSocketFactory = new Tls12SocketFactory(sslContext.getSocketFactory());
+ sslParams.trustManager = x509TrustManager;
+ return sslParams;
+ } catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException | UnrecoverableKeyException | IOException | CertificateException e) {
+ throw new AssertionError(e);
+ }
+ }
+
+ /**
+ * 不做证书校验,信任所有证书
+ */
+ public static SSLParams getSslSocketFactoryUnsafe() {
+ SSLParams sslParams = new SSLParams();
+ try {
+ X509TrustManager x509TrustManager = new UnSafeTrustManager();
+
+ //创建TLS类型的SSLContext对象,that uses our TrustManager
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+
+ //用上面得到的trustManagers初始化SSLContext,这样sslContext就会信任keyStore中的证书
+ sslContext.init(null, new TrustManager[]{x509TrustManager}, null);
+
+ //Android 4.X 对TLS1.1、TLS1.2的支持
+ sslParams.sSLSocketFactory = new Tls12SocketFactory(sslContext.getSocketFactory());
+ sslParams.trustManager = x509TrustManager;
+ return sslParams;
+ } catch (NoSuchAlgorithmException | KeyManagementException e) {
+ throw new AssertionError(e);
+ }
+ }
+
+
+ /**
+ * 主机名校验方法,请把”192.168.0.10”换成你们公司的主机IP:
+ */
+ public static HostnameVerifier getHostnameVerifier() {
+ return new HostnameVerifier() {
+ @Override
+ public boolean verify(String hostname, SSLSession session) {
+ if ("192.168.0.10".equals(hostname)) {
+ return true;
+ } else {
+ HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier();
+ return hv.verify(hostname, session);
+ }
+ }
+ };
+ }
+
+
+ /**
+ * 对服务器证书域名进行强校验
+ */
+ private static class SafeTrustManager implements X509TrustManager {
+ private X509Certificate mCertificate;
+
+ private SafeTrustManager(X509Certificate serverCert) {
+ mCertificate = serverCert;
+ }
+
+ @Override
+ public void checkClientTrusted(X509Certificate[] x509Certificates, String authType) throws CertificateException {
+
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] x509Certificates, String authType) throws CertificateException {
+ if (x509Certificates == null) {
+ throw new IllegalArgumentException("Check Server x509Certificates is null");
+ }
+
+ if (x509Certificates.length < 0) {
+ throw new IllegalArgumentException("Check Server x509Certificates is empty");
+ }
+
+ try {
+ for (X509Certificate cert : x509Certificates) {
+ // Make sure that it hasn't expired.
+ cert.checkValidity();
+ //和App预埋的证书做对比
+ cert.verify(mCertificate.getPublicKey());
+ }
+ } catch (NoSuchAlgorithmException | InvalidKeyException | NoSuchProviderException | SignatureException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public X509Certificate[] getAcceptedIssuers() {
+ return new X509Certificate[0];
+ }
+ }
+
+
+ /**
+ * 客户端不对证书做任何验证的做法有很大的安全漏洞。
+ */
+ private static class UnSafeTrustManager implements X509TrustManager {
+
+ @Override
+ public void checkClientTrusted(X509Certificate[] chain, String authType)
+ throws CertificateException {
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] chain, String authType)
+ throws CertificateException {
+ }
+
+ @Override
+ public X509Certificate[] getAcceptedIssuers() {
+ return new X509Certificate[]{};
+ }
+ }
+
+
+ /**
+ * 自定义SSLSocketFactory ,实现Android 4.X 对TLSv1.1、TLSv1.2的支持
+ */
+ private static class Tls12SocketFactory extends SSLSocketFactory {
+
+ private static final String[] TLS_SUPPORT_VERSION = {"TLSv1.1", "TLSv1.2"};
+
+ final SSLSocketFactory delegate;
+
+ private Tls12SocketFactory(SSLSocketFactory base) {
+ this.delegate = base;
+ }
+
+ @Override
+ public String[] getDefaultCipherSuites() {
+ return delegate.getDefaultCipherSuites();
+ }
+
+ @Override
+ public String[] getSupportedCipherSuites() {
+ return delegate.getSupportedCipherSuites();
+ }
+
+ @Override
+ public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
+ return patch(delegate.createSocket(s, host, port, autoClose));
+ }
+
+ @Override
+ public Socket createSocket(String host, int port) throws IOException {
+ return patch(delegate.createSocket(host, port));
+ }
+
+ @Override
+ public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException {
+ return patch(delegate.createSocket(host, port, localHost, localPort));
+ }
+
+ @Override
+ public Socket createSocket(InetAddress host, int port) throws IOException {
+ return patch(delegate.createSocket(host, port));
+ }
+
+ @Override
+ public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
+ return patch(delegate.createSocket(address, port, localAddress, localPort));
+ }
+
+ private Socket patch(Socket s) {
+ //代理SSLSocketFactory在创建一个Socket连接的时候,会设置Socket的可用的TLS版本。
+ if (s instanceof SSLSocket) {
+ ((SSLSocket) s).setEnabledProtocols(TLS_SUPPORT_VERSION);
+ }
+ return s;
+ }
+ }
+
+}
diff --git a/common/src/main/java/com/guiying/common/http/LoggerInterceptor.java b/lib_common/src/main/java/com/guiying/module/common/http/LoggerInterceptor.java
similarity index 99%
rename from common/src/main/java/com/guiying/common/http/LoggerInterceptor.java
rename to lib_common/src/main/java/com/guiying/module/common/http/LoggerInterceptor.java
index 46cbff8..16d0660 100644
--- a/common/src/main/java/com/guiying/common/http/LoggerInterceptor.java
+++ b/lib_common/src/main/java/com/guiying/module/common/http/LoggerInterceptor.java
@@ -1,4 +1,4 @@
-package com.guiying.common.http;
+package com.guiying.module.common.http;
import android.text.TextUtils;
diff --git a/common/src/main/java/com/guiying/common/http/OnResultListener.java b/lib_common/src/main/java/com/guiying/module/common/http/OnResultListener.java
similarity index 94%
rename from common/src/main/java/com/guiying/common/http/OnResultListener.java
rename to lib_common/src/main/java/com/guiying/module/common/http/OnResultListener.java
index 6274b58..527f5f0 100644
--- a/common/src/main/java/com/guiying/common/http/OnResultListener.java
+++ b/lib_common/src/main/java/com/guiying/module/common/http/OnResultListener.java
@@ -1,4 +1,4 @@
-package com.guiying.common.http;
+package com.guiying.module.common.http;
/**
* 在Retrofit中接口会导致泛型擦除,所以这里回调使用Class
diff --git a/common/src/main/java/com/guiying/common/utils/CloseUtils.java b/lib_common/src/main/java/com/guiying/module/common/utils/CloseUtils.java
similarity index 96%
rename from common/src/main/java/com/guiying/common/utils/CloseUtils.java
rename to lib_common/src/main/java/com/guiying/module/common/utils/CloseUtils.java
index dae8eca..336cde0 100644
--- a/common/src/main/java/com/guiying/common/utils/CloseUtils.java
+++ b/lib_common/src/main/java/com/guiying/module/common/utils/CloseUtils.java
@@ -1,4 +1,4 @@
-package com.guiying.common.utils;
+package com.guiying.module.common.utils;
import java.io.Closeable;
import java.io.IOException;
diff --git a/common/src/main/java/com/guiying/common/utils/NetworkUtils.java b/lib_common/src/main/java/com/guiying/module/common/utils/NetworkUtils.java
similarity index 98%
rename from common/src/main/java/com/guiying/common/utils/NetworkUtils.java
rename to lib_common/src/main/java/com/guiying/module/common/utils/NetworkUtils.java
index 842a52e..e788077 100644
--- a/common/src/main/java/com/guiying/common/utils/NetworkUtils.java
+++ b/lib_common/src/main/java/com/guiying/module/common/utils/NetworkUtils.java
@@ -1,4 +1,4 @@
-package com.guiying.common.utils;
+package com.guiying.module.common.utils;
import android.content.Context;
import android.content.Intent;
@@ -144,7 +144,7 @@ public static boolean is4G() {
* @return {@code true}: 是
{@code false}: 否
*/
public static boolean getWifiEnabled() {
- WifiManager wifiManager = (WifiManager) Utils.getContext().getSystemService(Context.WIFI_SERVICE);
+ WifiManager wifiManager = (WifiManager) Utils.getContext().getApplicationContext().getSystemService(Context.WIFI_SERVICE);
return wifiManager.isWifiEnabled();
}
@@ -155,7 +155,7 @@ public static boolean getWifiEnabled() {
* @param enabled {@code true}: 打开
{@code false}: 关闭
*/
public static void setWifiEnabled(boolean enabled) {
- WifiManager wifiManager = (WifiManager) Utils.getContext().getSystemService(Context.WIFI_SERVICE);
+ WifiManager wifiManager = (WifiManager) Utils.getContext().getApplicationContext().getSystemService(Context.WIFI_SERVICE);
if (enabled) {
if (!wifiManager.isWifiEnabled()) {
wifiManager.setWifiEnabled(true);
diff --git a/lib_common/src/main/java/com/guiying/module/common/utils/ScreenLockUtil.java b/lib_common/src/main/java/com/guiying/module/common/utils/ScreenLockUtil.java
new file mode 100644
index 0000000..d85c106
--- /dev/null
+++ b/lib_common/src/main/java/com/guiying/module/common/utils/ScreenLockUtil.java
@@ -0,0 +1,84 @@
+package com.guiying.module.common.utils;
+
+import android.app.Activity;
+import android.app.KeyguardManager;
+import android.app.KeyguardManager.KeyguardLock;
+import android.content.Context;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
+import android.util.Log;
+
+import java.util.HashMap;
+
+/**
+ * 用于保持屏幕高亮的工具
+ */
+public class ScreenLockUtil {
+ private static final String TAG = "ScreenLockUtil";
+
+ private ScreenLockUtil() {
+ throw new UnsupportedOperationException("cannot be instantiated");
+ }
+
+ static private HashMap mWakeLockArray = new HashMap<>();
+ static private HashMap mIsUnlockArray = new HashMap<>();
+
+
+ /**
+ * 保持屏幕常亮
+ *
+ * @param activity you know
+ */
+ public static void keepScreenOn(Activity activity) {
+ WakeLock wakeLock = mWakeLockArray.get(activity);
+ if (wakeLock == null) {
+ PowerManager powerManager = (PowerManager) activity.getSystemService(Context.POWER_SERVICE);
+ wakeLock = powerManager.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.FULL_WAKE_LOCK,
+ activity.getClass().getName());
+ }
+
+ if (!wakeLock.isHeld()) {
+ wakeLock.acquire();
+ }
+
+ mWakeLockArray.put(activity, wakeLock);
+
+ cancelLockScreen(activity);
+
+ Log.i(TAG, "开启屏幕常亮");
+ }
+
+
+ /**
+ * 取消屏幕常亮
+ *
+ * @param activity you know
+ */
+ public static void cancelKeepScreen(Activity activity) {
+ WakeLock wakeLock = mWakeLockArray.get(activity);
+ if (wakeLock != null) {
+ if (wakeLock.isHeld()) {
+ wakeLock.release();
+ }
+ }
+
+ Log.i(TAG, "取消屏幕常亮");
+ }
+
+ /**
+ * 取消锁屏限制
+ *
+ * @param activity you know
+ */
+ private static void cancelLockScreen(Activity activity) {
+ Boolean isUnlock = mIsUnlockArray.get(activity);
+ if (isUnlock != null && isUnlock) {
+ return;
+ }
+ KeyguardManager mKeyguardManager = (KeyguardManager) activity.getSystemService(Context.KEYGUARD_SERVICE);
+ KeyguardLock mKeyguardLock = mKeyguardManager.newKeyguardLock(activity.getClass().getName());
+ mKeyguardLock.disableKeyguard();
+
+ mIsUnlockArray.put(activity, true);
+ }
+}
diff --git a/common/src/main/java/com/guiying/common/utils/ShellUtils.java b/lib_common/src/main/java/com/guiying/module/common/utils/ShellUtils.java
similarity index 99%
rename from common/src/main/java/com/guiying/common/utils/ShellUtils.java
rename to lib_common/src/main/java/com/guiying/module/common/utils/ShellUtils.java
index 138f7d5..ff326cc 100644
--- a/common/src/main/java/com/guiying/common/utils/ShellUtils.java
+++ b/lib_common/src/main/java/com/guiying/module/common/utils/ShellUtils.java
@@ -1,4 +1,4 @@
-package com.guiying.common.utils;
+package com.guiying.module.common.utils;
import java.io.BufferedReader;
import java.io.DataOutputStream;
diff --git a/common/src/main/java/com/guiying/common/utils/StringUtils.java b/lib_common/src/main/java/com/guiying/module/common/utils/StringUtils.java
similarity index 99%
rename from common/src/main/java/com/guiying/common/utils/StringUtils.java
rename to lib_common/src/main/java/com/guiying/module/common/utils/StringUtils.java
index ccfbd93..e09c3ae 100644
--- a/common/src/main/java/com/guiying/common/utils/StringUtils.java
+++ b/lib_common/src/main/java/com/guiying/module/common/utils/StringUtils.java
@@ -1,4 +1,4 @@
-package com.guiying.common.utils;
+package com.guiying.module.common.utils;
/**
* 字符串相关工具类
diff --git a/common/src/main/java/com/guiying/common/utils/ToastUtils.java b/lib_common/src/main/java/com/guiying/module/common/utils/ToastUtils.java
similarity index 96%
rename from common/src/main/java/com/guiying/common/utils/ToastUtils.java
rename to lib_common/src/main/java/com/guiying/module/common/utils/ToastUtils.java
index 61e09e4..1fd0cdb 100644
--- a/common/src/main/java/com/guiying/common/utils/ToastUtils.java
+++ b/lib_common/src/main/java/com/guiying/module/common/utils/ToastUtils.java
@@ -1,8 +1,10 @@
-package com.guiying.common.utils;
+package com.guiying.module.common.utils;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.StringRes;
+import android.view.Gravity;
+import android.widget.TextView;
import android.widget.Toast;
/**
@@ -263,6 +265,9 @@ private static void showToast(CharSequence text, int duration) {
if (isJumpWhenMore) cancelToast();
if (sToast == null) {
sToast = Toast.makeText(Utils.getContext(), text, duration);
+ TextView tv = (TextView) sToast.getView().findViewById(android.R.id.message);
+ tv.setTextSize(18);
+ sToast.setGravity(Gravity.CENTER, 0, 0);
} else {
sToast.setText(text);
sToast.setDuration(duration);
diff --git a/common/src/main/java/com/guiying/common/utils/Utils.java b/lib_common/src/main/java/com/guiying/module/common/utils/Utils.java
similarity index 71%
rename from common/src/main/java/com/guiying/common/utils/Utils.java
rename to lib_common/src/main/java/com/guiying/module/common/utils/Utils.java
index 6c8b104..a06d64d 100644
--- a/common/src/main/java/com/guiying/common/utils/Utils.java
+++ b/lib_common/src/main/java/com/guiying/module/common/utils/Utils.java
@@ -1,4 +1,5 @@
-package com.guiying.common.utils;
+package com.guiying.module.common.utils;
+
import android.app.Activity;
import android.content.Context;
@@ -7,6 +8,9 @@
import android.content.pm.PackageManager;
import android.support.annotation.NonNull;
import android.support.annotation.StringRes;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentTransaction;
import android.view.View;
/**
@@ -87,4 +91,26 @@ public static boolean isAppDebug() {
}
}
+
+ /**
+ * The {@code fragment} is added to the container view with id {@code frameId}. The operation is
+ * performed by the {@code fragmentManager}.
+ */
+ public static void addFragmentToActivity(@NonNull FragmentManager fragmentManager,
+ @NonNull Fragment fragment, int frameId) {
+ checkNotNull(fragmentManager);
+ checkNotNull(fragment);
+ FragmentTransaction transaction = fragmentManager.beginTransaction();
+ transaction.add(frameId, fragment);
+ transaction.commit();
+ }
+
+
+ public static T checkNotNull(T obj) {
+ if (obj == null) {
+ throw new NullPointerException();
+ }
+ return obj;
+ }
+
}
\ No newline at end of file
diff --git a/lib_common/src/main/java/com/guiying/module/common/widget/HackyViewPager.java b/lib_common/src/main/java/com/guiying/module/common/widget/HackyViewPager.java
new file mode 100644
index 0000000..a9ace60
--- /dev/null
+++ b/lib_common/src/main/java/com/guiying/module/common/widget/HackyViewPager.java
@@ -0,0 +1,33 @@
+package com.guiying.module.common.widget;
+
+import android.content.Context;
+import android.support.v4.view.ViewPager;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+
+/**
+ * 解决图片缩放崩溃的问题
+ * @name HackyViewPager
+ * @author 张华洋 2017/9/27 10:10
+ * @version V1.1
+ */
+public class HackyViewPager extends ViewPager {
+
+ public HackyViewPager(Context context) {
+ super(context);
+ }
+
+ public HackyViewPager(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ try {
+ return super.onInterceptTouchEvent(ev);
+ } catch (IllegalArgumentException | ArrayIndexOutOfBoundsException e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+}
diff --git a/lib_common/src/main/java/com/guiying/module/common/widget/NoScrollViewPager.java b/lib_common/src/main/java/com/guiying/module/common/widget/NoScrollViewPager.java
new file mode 100644
index 0000000..be8f2b9
--- /dev/null
+++ b/lib_common/src/main/java/com/guiying/module/common/widget/NoScrollViewPager.java
@@ -0,0 +1,41 @@
+package com.guiying.module.common.widget;
+
+import android.content.Context;
+import android.support.v4.view.ViewPager;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+
+/**
+ * 可以禁止滑动翻页的ViewPager
+ *
+ * @author 张华洋 2017/9/27 10:10
+ * @version V1.1
+ * @name NoScrollViewPager
+ */
+public class NoScrollViewPager extends ViewPager {
+
+ private boolean isPagingEnabled = true;
+
+ public NoScrollViewPager(Context context) {
+ super(context);
+ }
+
+ public NoScrollViewPager(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ return this.isPagingEnabled && super.onTouchEvent(event);
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent event) {
+ return this.isPagingEnabled && super.onInterceptTouchEvent(event);
+ }
+
+ public void setPagerEnabled(boolean b) {
+ this.isPagingEnabled = b;
+ }
+
+}
diff --git a/lib_common/src/main/res/drawable-xxhdpi/ic_arrow_back.png b/lib_common/src/main/res/drawable-xxhdpi/ic_arrow_back.png
new file mode 100644
index 0000000..38c9a6d
Binary files /dev/null and b/lib_common/src/main/res/drawable-xxhdpi/ic_arrow_back.png differ
diff --git a/common/src/main/res/drawable/shape_loading_bg.xml b/lib_common/src/main/res/drawable/shape_loading_bg.xml
similarity index 100%
rename from common/src/main/res/drawable/shape_loading_bg.xml
rename to lib_common/src/main/res/drawable/shape_loading_bg.xml
diff --git a/common/src/main/res/layout/layout_load_error.xml b/lib_common/src/main/res/layout/layout_load_error.xml
similarity index 100%
rename from common/src/main/res/layout/layout_load_error.xml
rename to lib_common/src/main/res/layout/layout_load_error.xml
diff --git a/common/src/main/res/layout/layout_load_more.xml b/lib_common/src/main/res/layout/layout_load_more.xml
similarity index 72%
rename from common/src/main/res/layout/layout_load_more.xml
rename to lib_common/src/main/res/layout/layout_load_more.xml
index 46425fa..b6c5d09 100644
--- a/common/src/main/res/layout/layout_load_more.xml
+++ b/lib_common/src/main/res/layout/layout_load_more.xml
@@ -7,14 +7,14 @@
android:layout_height="50dp">
+ android:layout_width="30dp"
+ android:layout_height="30dp" />
diff --git a/common/src/main/res/layout/layout_load_no_more.xml b/lib_common/src/main/res/layout/layout_load_no_more.xml
similarity index 100%
rename from common/src/main/res/layout/layout_load_no_more.xml
rename to lib_common/src/main/res/layout/layout_load_no_more.xml
diff --git a/common/src/main/res/layout/layout_load_progress.xml b/lib_common/src/main/res/layout/layout_load_progress.xml
similarity index 100%
rename from common/src/main/res/layout/layout_load_progress.xml
rename to lib_common/src/main/res/layout/layout_load_progress.xml
diff --git a/common/src/main/res/layout/layout_view_empty.xml b/lib_common/src/main/res/layout/layout_view_empty.xml
similarity index 100%
rename from common/src/main/res/layout/layout_view_empty.xml
rename to lib_common/src/main/res/layout/layout_view_empty.xml
diff --git a/common/src/main/res/layout/progress_dialog.xml b/lib_common/src/main/res/layout/progress_dialog.xml
similarity index 100%
rename from common/src/main/res/layout/progress_dialog.xml
rename to lib_common/src/main/res/layout/progress_dialog.xml
diff --git a/common/src/main/res/layout/toolbar.xml b/lib_common/src/main/res/layout/toolbar.xml
similarity index 100%
rename from common/src/main/res/layout/toolbar.xml
rename to lib_common/src/main/res/layout/toolbar.xml
diff --git a/common/src/main/res/mipmap-xxhdpi/ic_launcher.jpg b/lib_common/src/main/res/mipmap-xxhdpi/ic_launcher.jpg
similarity index 100%
rename from common/src/main/res/mipmap-xxhdpi/ic_launcher.jpg
rename to lib_common/src/main/res/mipmap-xxhdpi/ic_launcher.jpg
diff --git a/common/src/main/res/values-v21/styles.xml b/lib_common/src/main/res/values-v21/styles.xml
similarity index 100%
rename from common/src/main/res/values-v21/styles.xml
rename to lib_common/src/main/res/values-v21/styles.xml
diff --git a/common/src/main/res/values/colors.xml b/lib_common/src/main/res/values/colors.xml
similarity index 100%
rename from common/src/main/res/values/colors.xml
rename to lib_common/src/main/res/values/colors.xml
diff --git a/common/src/main/res/values/dimens.xml b/lib_common/src/main/res/values/dimens.xml
similarity index 100%
rename from common/src/main/res/values/dimens.xml
rename to lib_common/src/main/res/values/dimens.xml
diff --git a/common/src/main/res/values/strings.xml b/lib_common/src/main/res/values/strings.xml
similarity index 100%
rename from common/src/main/res/values/strings.xml
rename to lib_common/src/main/res/values/strings.xml
diff --git a/common/src/main/res/values/styles.xml b/lib_common/src/main/res/values/styles.xml
similarity index 100%
rename from common/src/main/res/values/styles.xml
rename to lib_common/src/main/res/values/styles.xml
diff --git a/app/.gitignore b/module_app/.gitignore
similarity index 100%
rename from app/.gitignore
rename to module_app/.gitignore
diff --git a/module_app/build.gradle b/module_app/build.gradle
new file mode 100644
index 0000000..2776c5c
--- /dev/null
+++ b/module_app/build.gradle
@@ -0,0 +1,84 @@
+apply plugin: 'com.android.application'
+
+// Create a variable called keystorePropertiesFile, and initialize it to your
+// keystore.properties file, in the rootProject folder.
+def keystorePropertiesFile = rootProject.file("keystore.properties")
+// Initialize a new Properties() object called keystoreProperties.
+def keystoreProperties = new Properties()
+// Load your keystore.properties file into the keystoreProperties object.
+keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
+
+static def buildTime() {
+ return new Date().format("yyyyMMdd");
+}
+
+android {
+ signingConfigs {
+ release {
+ keyAlias keystoreProperties['keyAlias']
+ keyPassword keystoreProperties['keyPassword']
+ storeFile file(keystoreProperties['storeFile'])
+ storePassword keystoreProperties['storePassword']
+ }
+ }
+
+ compileSdkVersion build_versions.target_sdk
+ defaultConfig {
+ applicationId "com.guiying.module"
+ minSdkVersion build_versions.min_sdk
+ targetSdkVersion build_versions.target_sdk
+ versionCode 1
+ versionName "1.0"
+ multiDexEnabled true
+ //打包时间
+ resValue "string", "build_time", buildTime()
+ }
+
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+
+ buildTypes {
+ release {
+ //更改AndroidManifest.xml中预先定义好占位符信息
+ //manifestPlaceholders = [app_icon: "@drawable/icon"]
+ // 不显示Log
+ buildConfigField "boolean", "LEO_DEBUG", "false"
+ //是否zip对齐
+ zipAlignEnabled true
+ // 缩减resource文件
+ shrinkResources true
+ //Proguard
+ minifyEnabled true
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ //签名
+ signingConfig signingConfigs.release
+ }
+
+ debug {
+ //给applicationId添加后缀“.debug”
+ applicationIdSuffix ".debug"
+ //manifestPlaceholders = [app_icon: "@drawable/launch_beta"]
+ buildConfigField "boolean", "LOG_DEBUG", "true"
+ zipAlignEnabled false
+ shrinkResources false
+ minifyEnabled false
+ debuggable true
+ }
+ }
+
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation deps.support.multidex
+ implementation project(':lib_common')
+ if (!isModule.toBoolean()) {
+ implementation project(':module_main')
+ implementation project(':module_girls')
+ implementation project(':module_news')
+ }
+}
diff --git a/module_app/libs/acra-4.5.0.jar b/module_app/libs/acra-4.5.0.jar
new file mode 100644
index 0000000..f5100d6
Binary files /dev/null and b/module_app/libs/acra-4.5.0.jar differ
diff --git a/module_app/proguard-rules.pro b/module_app/proguard-rules.pro
new file mode 100644
index 0000000..7715cfe
--- /dev/null
+++ b/module_app/proguard-rules.pro
@@ -0,0 +1,335 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in D:\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 *;
+#}
+#---------------------------------基本指令区----------------------------------
+-ignorewarnings
+-dontusemixedcaseclassnames # 是否使用大小写混合
+-dontpreverify # 混淆时是否做预校验
+-verbose # 混淆时是否记录日志
+-printmapping proguardMapping.txt
+-optimizationpasses 5 # 指定代码的压缩级别
+-dontskipnonpubliclibraryclassmembers
+
+
+-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
+-keepattributes *Annotation*,InnerClasses
+-keepattributes Signature # 避免混淆泛型
+-keepattributes EnclosingMethod
+-keepattributes SourceFile,LineNumberTable #运行抛出异常时保留代码行号
+-keepattributes Exceptions # 解决AGPBI警告
+
+#继承自activity,application,service,broadcastReceiver,contentprovider....不进行混淆
+-keep public class * extends android.app.Activity
+-keep public class * extends android.app.Application
+-keep public class * extends android.support.multidex.MultiDexApplication
+-keep public class * extends android.app.Service
+-keep public class * extends android.content.BroadcastReceiver
+-keep public class * extends android.content.ContentProvider
+-keep public class * extends android.app.backup.BackupAgentHelper
+-keep public class * extends android.preference.Preference
+-keep public class * extends android.view.View
+-keep public class com.android.vending.licensing.ILicensingService
+-keep class android.support.** {*;}
+
+# 所有View的子类及其子类的get、set方法都不进行混淆
+-keep public class * extends android.view.View{
+ *** get*();
+ void set*(***);
+ public (android.content.Context);
+ public (android.content.Context, android.util.AttributeSet);
+ public (android.content.Context, android.util.AttributeSet, int);
+}
+
+# 这个主要是在layout 中写的onclick方法android:onclick="onClick",不进行混淆
+-keepclassmembers class * extends android.app.Activity {
+ public void *(android.view.View);
+}
+
+
+# 对于带有回调函数onXXEvent的,不能被混淆
+-keepclassmembers class * {
+ void *(*Event);
+}
+
+# 枚举类不能被混淆
+-keepclassmembers enum * {
+ public static **[] values();
+ public static ** valueOf(java.lang.String);
+}
+
+# natvie 方法不混淆
+-keepclasseswithmembernames class * {
+ native ;
+}
+
+# 保持 Parcelable 不被混淆
+-keep class * implements android.os.Parcelable {
+ public static final android.os.Parcelable$Creator *;
+}
+
+
+#不混淆Serializable接口的子类中指定的某些成员变量和方法
+-keepclassmembers class * implements java.io.Serializable {
+ static final long serialVersionUID;
+ private static final java.io.ObjectStreamField[] serialPersistentFields;
+ !static !transient ;
+ private void writeObject(java.io.ObjectOutputStream);
+ private void readObject(java.io.ObjectInputStream);
+ java.lang.Object writeReplace();
+ java.lang.Object readResolve();
+}
+
+
+-keepclassmembers class * {
+ public (org.json.JSONObject);
+}
+
+
+# 不混淆R类里及其所有内部static类中的所有static变量字段,$是用来分割内嵌类与其母体的标志
+-keep public class **.R$*{
+ public static final int *;
+}
+
+
+#(可选)避免Log打印输出
+-assumenosideeffects class android.util.Log {
+ public static *** v(...);
+ public static *** d(...);
+ public static *** i(...);
+ public static *** w(...);
+ }
+
+#---------------------------------webview------------------------------------
+-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+ public *;
+}
+-keepclassmembers class * extends android.webkit.webViewClient {
+ public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);
+ public boolean *(android.webkit.WebView, java.lang.String);
+}
+
+#---------------------------------业务组件实体类---------------------------------
+
+-keep class com.guiying.news.data.bean.** {*;}
+-keep class com.guiying.girls.data.bean.** {*;}
+
+#---------------------------------第三方库及jar包-------------------------------
+
+#litepal数据库不能被混淆
+-keep class org.litepal.** {*;}
+-keep class * extends org.litepal.crud.DataSupport {*;}
+
+#Glide不能被混淆
+-keep public class * implements com.bumptech.glide.module.GlideModule
+-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
+ **[] $VALUES;
+ public *;
+}
+
+
+#PersistentCookieJar
+-dontwarn com.franmontiel.persistentcookiejar.**
+-keep class com.franmontiel.persistentcookiejar.**
+
+
+#activityrouter
+-keep class com.github.mzule.activityrouter.router.** { *; }
+
+#友盟统计
+-keep class com.umeng.analytics.** {*;}
+-dontwarn com.umeng.analytics.**
+#友盟推送
+-dontwarn com.taobao.**
+-dontwarn anet.channel.**
+-dontwarn anetwork.channel.**
+-dontwarn org.android.**
+-dontwarn org.apache.thrift.**
+-dontwarn com.xiaomi.**
+-dontwarn com.huawei.**
+-keep class com.taobao.** {*;}
+-keep class org.android.** {*;}
+-keep class anet.channel.** {*;}
+-keep class com.umeng.** {*;}
+-keep class com.xiaomi.** {*;}
+-keep class com.huawei.** {*;}
+-keep class org.apache.thrift.** {*;}
+-keep class com.alibaba.sdk.android.**{*;}
+-keep class com.ut.**{*;}
+-keep class com.ta.**{*;}
+
+
+#换肤框架的混淆文件
+-keep class solid.ren.skinlibrary.** {*;}
+-dontwarn solid.ren.skinlibrary.**
+
+
+#高德相关混淆文件
+#3D 地图
+-keep class com.amap.api.** {*;}
+-keep class com.autonavi.** {*;}
+-keep class com.a.a.** {*;}
+-keep class com.loc.** {*;}
+-dontwarn com.amap.api.**
+-dontwarn com.autonavi.**
+-dontwarn com.a.a.**
+-dontwarn com.loc.**
+
+
+# simple-xml-core的SDK
+-keep class org.simpleframework.xml.** {*;}
+-dontwarn org.simpleframework.xml.**
+
+# acra的 SDK
+-keep class org.acra.** {*;}
+-dontwarn org.acra.**
+
+# 网络请求库async-http
+-keep class com.loopj.android.http.** {*;}
+-dontwarn com.loopj.android.http.**
+
+
+#pinyin4j
+-dontwarn net.soureceforge.pinyin4j.**
+-dontwarn demo.**
+-keep class net.sourceforge.pinyin4j.** { *;}
+-keep class demo.** { *;}
+-keep class com.hp.** { *;}
+
+#httpclient (org.apache.http.legacy.jar)
+-dontwarn android.net.compatibility.**
+-dontwarn android.net.http.**
+-dontwarn com.android.internal.http.multipart.**
+-dontwarn org.apache.commons.**
+-dontwarn org.apache.http.**
+-dontwarn org.apache.http.protocol.**
+-keep class android.net.compatibility.**{*;}
+-keep class android.net.http.**{*;}
+-keep class com.android.internal.http.multipart.**{*;}
+-keep class org.apache.commons.**{*;}
+-keep class org.apache.org.**{*;}
+-keep class org.apache.harmony.**{*;}
+
+#图表库
+-keep class com.github.mikephil.charting.** {*;}
+-dontwarn com.github.mikephil.charting.**
+
+# 讯飞语音
+-keep class com.chinaMobile.** {*;}
+-keep class com.iflytek.** {*;}
+-keep class com.iflytek.sunflower.** {*;}
+-dontwarn com.iflytek.sunflower.**
+-dontwarn com.chinaMobile.**
+-dontwarn com.iflytek.**
+
+# greenDao混淆
+-keep class de.greenrobot.dao.** {*;}
+-keepclassmembers class * extends de.greenrobot.dao.AbstractDao {
+ public static Java.lang.String TABLENAME;
+}
+-keep class **$Properties
+
+# gson
+-keep class com.google.gson.** {*;}
+-keep class com.google.**{*;}
+-keep class sun.misc.Unsafe { *; }
+-keep class com.google.gson.stream.** { *; }
+-keep class com.google.gson.examples.android.model.** { *; }
+
+# zxing
+-keep class com.google.zxing.** {*;}
+-dontwarn com.google.zxing.**
+
+##百度定位
+-keep class com.baidu.** {*;}
+-keep class vi.com.** {*;}
+-dontwarn com.baidu.**
+
+## okhttp
+-dontwarn com.squareup.okhttp.**
+-keep class com.squareup.okhttp.{*;}
+
+#okhttp3.x
+-dontwarn com.squareup.okhttp3.**
+-keep class com.squareup.okhttp3.** { *;}
+-dontwarn okio.**
+
+#retrofit
+-dontwarn retrofit.**
+-keep class retrofit.** { *; }
+-dontwarn okio.**
+
+
+#recyclerview-animators
+-keep class jp.wasabeef.** {*;}
+-dontwarn jp.wasabeef.*
+
+#multistateview
+-keep class com.kennyc.view.** { *; }
+-dontwarn com.kennyc.view.*
+
+# universal-image-loader 混淆
+-dontwarn com.nostra13.universalimageloader.**
+-keep class com.nostra13.universalimageloader.** { *; }
+
+
+#-ButterKnife 7.0
+ -keep class butterknife.** { *; }
+ -dontwarn butterknife.internal.**
+ -keep class **$$ViewBinder { *; }
+ -keepclasseswithmembernames class * {
+ @butterknife.* ;
+ }
+ -keepclasseswithmembernames class * {
+ @butterknife.* ;
+ }
+
+#eventbus 3.0
+-keepattributes *Annotation*
+-keepclassmembers class ** {
+ @org.greenrobot.eventbus.Subscribe ;
+}
+-keep enum org.greenrobot.eventbus.ThreadMode { *; }
+-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
+ (java.lang.Throwable);
+}
+
+#EventBus
+-keepclassmembers class ** {
+ public void onEvent*(**);
+}
+-keepclassmembers class ** {
+public void xxxxxx(**);
+}
+
+# support-v4
+-dontwarn android.support.v4.**
+-keep class android.support.v4.app.** { *; }
+-keep interface android.support.v4.app.** { *; }
+-keep class android.support.v4.** { *; }
+
+
+# support-v7
+-dontwarn android.support.v7.**
+-keep class android.support.v7.internal.** { *; }
+-keep interface android.support.v7.internal.** { *; }
+-keep class android.support.v7.** { *; }
+
+# support design
+-dontwarn android.support.design.**
+-keep class android.support.design.** { *; }
+-keep interface android.support.design.** { *; }
+-keep public class android.support.design.R$* { *; }
diff --git a/module_app/src/main/AndroidManifest.xml b/module_app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..315d6cb
--- /dev/null
+++ b/module_app/src/main/AndroidManifest.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/module_app/src/main/java/com/guiying/module/MyApplication.java b/module_app/src/main/java/com/guiying/module/MyApplication.java
new file mode 100644
index 0000000..72e9506
--- /dev/null
+++ b/module_app/src/main/java/com/guiying/module/MyApplication.java
@@ -0,0 +1,84 @@
+package com.guiying.module;
+
+import android.content.Context;
+import android.support.multidex.MultiDex;
+
+import com.alibaba.android.arouter.launcher.ARouter;
+import com.guiying.module.common.base.BaseApplication;
+import com.guiying.module.common.utils.Utils;
+
+import org.acra.ACRA;
+import org.acra.ReportField;
+import org.acra.ReportingInteractionMode;
+import org.acra.annotation.ReportsCrashes;
+import org.acra.collector.CrashReportData;
+import org.acra.sender.EmailIntentSender;
+import org.acra.sender.ReportSender;
+import org.acra.sender.ReportSenderException;
+
+/**
+ * 这里仅需做一些初始化的工作
+ *
+ * @author 张华洋 2017/2/15 20:14
+ * @version V1.2.0
+ * @name MyApplication
+ */
+@ReportsCrashes(
+ mailTo = "guiying705@Gmail.com",
+ mode = ReportingInteractionMode.DIALOG,
+ customReportContent = {
+ ReportField.APP_VERSION_NAME,
+ ReportField.ANDROID_VERSION,
+ ReportField.PHONE_MODEL,
+ ReportField.CUSTOM_DATA,
+ ReportField.BRAND,
+ ReportField.STACK_TRACE,
+ ReportField.LOGCAT,
+ ReportField.USER_COMMENT},
+ resToastText = R.string.crash_toast_text,
+ resDialogText = R.string.crash_dialog_text,
+ resDialogTitle = R.string.crash_dialog_title)
+public class MyApplication extends BaseApplication {
+
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ if (Utils.isAppDebug()) {
+ //开启InstantRun之后,一定要在ARouter.init之前调用openDebug
+ ARouter.openDebug();
+ ARouter.openLog();
+ }
+ ARouter.init(this);
+ //崩溃日志记录初始化
+ ACRA.init(this);
+ ACRA.getErrorReporter().removeAllReportSenders();
+ ACRA.getErrorReporter().setReportSender(new CrashReportSender());
+ }
+
+
+ @Override
+ protected void attachBaseContext(Context base) {
+ super.attachBaseContext(base);
+ // dex突破65535的限制
+ MultiDex.install(this);
+ }
+
+
+ /**
+ * 发送崩溃日志
+ */
+ private class CrashReportSender implements ReportSender {
+ CrashReportSender() {
+ ACRA.getErrorReporter().putCustomData("PLATFORM", "ANDROID");
+ ACRA.getErrorReporter().putCustomData("BUILD_ID", android.os.Build.ID);
+ ACRA.getErrorReporter().putCustomData("DEVICE_NAME", android.os.Build.PRODUCT);
+ }
+
+ @Override
+ public void send(Context context, CrashReportData crashReportData) throws ReportSenderException {
+ EmailIntentSender emailSender = new EmailIntentSender(getApplicationContext());
+ emailSender.send(context, crashReportData);
+ }
+ }
+}
diff --git a/module_app/src/main/res/values/strings.xml b/module_app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..9b547db
--- /dev/null
+++ b/module_app/src/main/res/values/strings.xml
@@ -0,0 +1,12 @@
+
+ 组件化项目
+
+ module
+
+
+ 程序崩溃了
+ 感谢您对我们的支持!
+ 发送崩溃日志
+ 发送成功
+
+
diff --git a/girls/.gitignore b/module_girls/.gitignore
similarity index 100%
rename from girls/.gitignore
rename to module_girls/.gitignore
diff --git a/module_girls/build.gradle b/module_girls/build.gradle
new file mode 100644
index 0000000..a1838bd
--- /dev/null
+++ b/module_girls/build.gradle
@@ -0,0 +1,53 @@
+if (isModule.toBoolean()) {
+ apply plugin: 'com.android.application'
+} else {
+ apply plugin: 'com.android.library'
+}
+
+android {
+ compileSdkVersion build_versions.target_sdk
+ defaultConfig {
+ minSdkVersion build_versions.min_sdk
+ targetSdkVersion build_versions.target_sdk
+ versionCode 1
+ versionName "1.0"
+
+ javaCompileOptions {
+ annotationProcessorOptions {
+ arguments = [ moduleName : project.getName() ]
+ }
+ }
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+
+ sourceSets {
+ main {
+ if (isModule.toBoolean()) {
+ manifest.srcFile 'src/main/module/AndroidManifest.xml'
+ } else {
+ manifest.srcFile 'src/main/AndroidManifest.xml'
+ //集成开发模式下排除debug文件夹中的所有Java文件
+ java {
+ exclude 'debug/**'
+ }
+ }
+ }
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ annotationProcessor deps.arouter_compiler
+ implementation project(':lib_common')
+}
diff --git a/girls/src/main/release/AndroidManifest.xml b/module_girls/src/main/AndroidManifest.xml
similarity index 55%
rename from girls/src/main/release/AndroidManifest.xml
rename to module_girls/src/main/AndroidManifest.xml
index facd819..48584ac 100644
--- a/girls/src/main/release/AndroidManifest.xml
+++ b/module_girls/src/main/AndroidManifest.xml
@@ -1,10 +1,14 @@
+ package="com.guiying.module.girls">
+
diff --git a/girls/src/main/java/com/guiying/girls/Constants.java b/module_girls/src/main/java/com/guiying/module/girls/Constants.java
similarity index 64%
rename from girls/src/main/java/com/guiying/girls/Constants.java
rename to module_girls/src/main/java/com/guiying/module/girls/Constants.java
index ad755b3..419b643 100644
--- a/girls/src/main/java/com/guiying/girls/Constants.java
+++ b/module_girls/src/main/java/com/guiying/module/girls/Constants.java
@@ -1,4 +1,4 @@
-package com.guiying.girls;
+package com.guiying.module.girls;
/**
* 保存项目中用到的常量
@@ -10,4 +10,7 @@ public interface Constants {
*/
String GAN_HUO_API = "http://gank.io/api/data/";
+ String INTENT_GIRLS = "girls";
+ String INTENT_INDEX = "index";
+
}
diff --git a/module_girls/src/main/java/com/guiying/module/girls/GirlsFragment.java b/module_girls/src/main/java/com/guiying/module/girls/GirlsFragment.java
new file mode 100644
index 0000000..43accad
--- /dev/null
+++ b/module_girls/src/main/java/com/guiying/module/girls/GirlsFragment.java
@@ -0,0 +1,42 @@
+package com.guiying.module.girls;
+
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.guiying.module.common.base.BaseFragment;
+
+
+/**
+ * A simple {@link Fragment} subclass.
+ */
+public class GirlsFragment extends BaseFragment {
+
+ /**
+ * Use this factory method to create a new instance of
+ * this fragment using the provided parameters.
+ *
+ * @return A new instance of fragment GirlsFragment.
+ */
+ public static GirlsFragment newInstance() {
+ return new GirlsFragment();
+ }
+
+
+ public GirlsFragment() {
+ // Required empty public constructor
+ }
+
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ // Inflate the layout for this fragment
+ return inflater.inflate(R.layout.fragment_girls, container, false);
+ }
+
+
+}
diff --git a/module_girls/src/main/java/com/guiying/module/girls/MyDelegate.java b/module_girls/src/main/java/com/guiying/module/girls/MyDelegate.java
new file mode 100644
index 0000000..dc0ecf4
--- /dev/null
+++ b/module_girls/src/main/java/com/guiying/module/girls/MyDelegate.java
@@ -0,0 +1,38 @@
+package com.guiying.module.girls;
+
+import android.support.annotation.Keep;
+
+import com.guiying.module.common.base.IApplicationDelegate;
+import com.guiying.module.common.base.ViewManager;
+
+/**
+ * 类说明
+ *
+ * @author 张华洋 2017/9/20 22:29
+ * @version V2.8.3
+ * @name MyDelegate
+ */
+@Keep
+public class MyDelegate implements IApplicationDelegate {
+
+ @Override
+ public void onCreate() {
+ //主动添加
+ ViewManager.getInstance().addFragment(0, GirlsFragment.newInstance());
+ }
+
+ @Override
+ public void onTerminate() {
+
+ }
+
+ @Override
+ public void onLowMemory() {
+
+ }
+
+ @Override
+ public void onTrimMemory(int level) {
+
+ }
+}
diff --git a/module_girls/src/main/java/com/guiying/module/girls/MyViewDelegate.java b/module_girls/src/main/java/com/guiying/module/girls/MyViewDelegate.java
new file mode 100644
index 0000000..3d4294e
--- /dev/null
+++ b/module_girls/src/main/java/com/guiying/module/girls/MyViewDelegate.java
@@ -0,0 +1,28 @@
+package com.guiying.module.girls;
+
+import android.support.annotation.Keep;
+import android.view.View;
+
+import com.guiying.module.common.base.BaseFragment;
+import com.guiying.module.common.base.IViewDelegate;
+
+/**
+ * 类说明
+ *
+ * @author 张华洋 2018/1/4 22:16
+ * @version V2.8.3
+ * @name MyViewDelegate
+ */
+@Keep
+public class MyViewDelegate implements IViewDelegate {
+
+ @Override
+ public BaseFragment getFragment(String name) {
+ return GirlsFragment.newInstance();
+ }
+
+ @Override
+ public View getView(String name) {
+ return null;
+ }
+}
diff --git a/girls/src/main/java/com/guiying/girls/data/GirlsDataSource.java b/module_girls/src/main/java/com/guiying/module/girls/data/GirlsDataSource.java
similarity index 71%
rename from girls/src/main/java/com/guiying/girls/data/GirlsDataSource.java
rename to module_girls/src/main/java/com/guiying/module/girls/data/GirlsDataSource.java
index c05d2bb..3f2755d 100644
--- a/girls/src/main/java/com/guiying/girls/data/GirlsDataSource.java
+++ b/module_girls/src/main/java/com/guiying/module/girls/data/GirlsDataSource.java
@@ -1,6 +1,6 @@
-package com.guiying.girls.data;
+package com.guiying.module.girls.data;
-import com.guiying.girls.data.parser.GirlsParser;
+import com.guiying.module.girls.data.bean.GirlsParser;
public interface GirlsDataSource {
diff --git a/girls/src/main/java/com/guiying/girls/data/bean/Girls.java b/module_girls/src/main/java/com/guiying/module/girls/data/bean/Girls.java
similarity index 98%
rename from girls/src/main/java/com/guiying/girls/data/bean/Girls.java
rename to module_girls/src/main/java/com/guiying/module/girls/data/bean/Girls.java
index 162b6b5..26573c9 100644
--- a/girls/src/main/java/com/guiying/girls/data/bean/Girls.java
+++ b/module_girls/src/main/java/com/guiying/module/girls/data/bean/Girls.java
@@ -1,4 +1,4 @@
-package com.guiying.girls.data.bean;
+package com.guiying.module.girls.data.bean;
import android.os.Parcel;
import android.os.Parcelable;
diff --git a/girls/src/main/java/com/guiying/girls/data/parser/GirlsParser.java b/module_girls/src/main/java/com/guiying/module/girls/data/bean/GirlsParser.java
similarity index 94%
rename from girls/src/main/java/com/guiying/girls/data/parser/GirlsParser.java
rename to module_girls/src/main/java/com/guiying/module/girls/data/bean/GirlsParser.java
index 0937ef4..d9c4d34 100644
--- a/girls/src/main/java/com/guiying/girls/data/parser/GirlsParser.java
+++ b/module_girls/src/main/java/com/guiying/module/girls/data/bean/GirlsParser.java
@@ -1,6 +1,4 @@
-package com.guiying.girls.data.parser;
-
-import com.guiying.girls.data.bean.Girls;
+package com.guiying.module.girls.data.bean;
import java.util.List;
diff --git a/girls/src/main/java/com/guiying/girls/data/source/RemoteGirlsDataSource.java b/module_girls/src/main/java/com/guiying/module/girls/data/source/RemoteGirlsDataSource.java
similarity index 66%
rename from girls/src/main/java/com/guiying/girls/data/source/RemoteGirlsDataSource.java
rename to module_girls/src/main/java/com/guiying/module/girls/data/source/RemoteGirlsDataSource.java
index 0756f37..457f412 100644
--- a/girls/src/main/java/com/guiying/girls/data/source/RemoteGirlsDataSource.java
+++ b/module_girls/src/main/java/com/guiying/module/girls/data/source/RemoteGirlsDataSource.java
@@ -1,13 +1,13 @@
-package com.guiying.girls.data.source;
+package com.guiying.module.girls.data.source;
-import com.guiying.common.http.HttpClient;
-import com.guiying.common.http.OnResultListener;
-import com.guiying.girls.Constants;
-import com.guiying.girls.data.GirlsDataSource;
-import com.guiying.girls.data.parser.GirlsParser;
+import com.guiying.module.common.http.DataType;
+import com.guiying.module.common.http.HttpClient;
+import com.guiying.module.common.http.OnResultListener;
+import com.guiying.module.girls.Constants;
+import com.guiying.module.girls.data.GirlsDataSource;
+import com.guiying.module.girls.data.bean.GirlsParser;
-import static com.guiying.common.http.HttpClient.OBJECT;
public class RemoteGirlsDataSource implements GirlsDataSource {
@@ -17,7 +17,7 @@ public void getGirls(int size, int page, final LoadGirlsCallback callback) {
HttpClient client = new HttpClient.Builder()
.baseUrl(Constants.GAN_HUO_API)
.url("福利/" + size + "/" + page)
- .bodyType(OBJECT, GirlsParser.class)
+ .bodyType(DataType.JSON_OBJECT, GirlsParser.class)
.build();
client.get(new OnResultListener() {
diff --git a/module_girls/src/main/java/com/guiying/module/girls/girl/GirlActivity.java b/module_girls/src/main/java/com/guiying/module/girls/girl/GirlActivity.java
new file mode 100644
index 0000000..bd1dd78
--- /dev/null
+++ b/module_girls/src/main/java/com/guiying/module/girls/girl/GirlActivity.java
@@ -0,0 +1,57 @@
+package com.guiying.module.girls.girl;
+
+import android.os.Bundle;
+import android.support.v4.view.ViewPager;
+import android.view.WindowManager;
+
+import com.alibaba.android.arouter.facade.annotation.Route;
+import com.guiying.module.common.base.BaseActivity;
+import com.guiying.module.common.widget.HackyViewPager;
+import com.guiying.module.girls.Constants;
+import com.guiying.module.girls.data.bean.Girls;
+
+import java.util.List;
+
+/**
+ *
+ *
+ * @author 张华洋 2017/5/19 20:24
+ * @version V1.1
+ * @name GirlActivity
+ */
+@Route(path = "/girls/detail")
+public class GirlActivity extends BaseActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
+ getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
+ if (getIntent() != null) {
+ List mData = getIntent().getParcelableArrayListExtra(Constants.INTENT_GIRLS);
+ int mCurrentIndex = getIntent().getIntExtra(Constants.INTENT_INDEX, 0);
+ HackyViewPager viewPager = new HackyViewPager(this);
+ setContentView(viewPager);
+ GirlAdapter adapter = new GirlAdapter(this, mData);
+ viewPager.setAdapter(adapter);
+ viewPager.setCurrentItem(mCurrentIndex);
+ viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
+ @Override
+ public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+
+ }
+
+ @Override
+ public void onPageSelected(int position) {
+
+ }
+
+ @Override
+ public void onPageScrollStateChanged(int state) {
+
+ }
+ });
+ }
+ }
+
+}
diff --git a/module_girls/src/main/java/com/guiying/module/girls/girl/GirlAdapter.java b/module_girls/src/main/java/com/guiying/module/girls/girl/GirlAdapter.java
new file mode 100644
index 0000000..dce7361
--- /dev/null
+++ b/module_girls/src/main/java/com/guiying/module/girls/girl/GirlAdapter.java
@@ -0,0 +1,76 @@
+package com.guiying.module.girls.girl;
+
+import android.content.Context;
+import android.support.v4.view.PagerAdapter;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.bumptech.glide.Glide;
+import com.github.chrisbanes.photoview.PhotoView;
+import com.guiying.module.girls.R;
+import com.guiying.module.girls.data.bean.Girls;
+
+import java.util.List;
+
+/**
+ *
+ *
+ * @author 张华洋 2017/5/19 20:31
+ * @version V1.1
+ * @name GirlAdapter
+ */
+public class GirlAdapter extends PagerAdapter {
+
+ private Context mContext;
+ private List mData;
+ private LayoutInflater layoutInflater;
+ private View mCurrentView;
+
+ public GirlAdapter(Context context, List data) {
+ mContext = context;
+ mData = data;
+ layoutInflater = LayoutInflater.from(this.mContext);
+ }
+
+ @Override
+ public int getCount() {
+ if (mData == null) {
+ return 0;
+ }
+ return mData.size();
+ }
+
+ @Override
+ public void setPrimaryItem(ViewGroup container, int position, Object object) {
+ super.setPrimaryItem(container, position, object);
+ mCurrentView = (View) object;
+ }
+
+ @Override
+ public View instantiateItem(ViewGroup container, int position) {
+ final String imageUrl = mData.get(position).getUrl();
+ View view = layoutInflater.inflate(R.layout.item_girl_detail, container, false);
+ PhotoView imageView = (PhotoView) view.findViewById(R.id.girl_image);
+ Glide.with(mContext)
+ .load(imageUrl)
+ .thumbnail(0.2f)
+ .into(imageView);
+ container.addView(view);
+ return view;
+ }
+
+ @Override
+ public void destroyItem(ViewGroup container, int position, Object object) {
+ container.removeView((View) object);
+ }
+
+ @Override
+ public boolean isViewFromObject(View view, Object object) {
+ return view == object;
+ }
+
+ public View getPrimaryItem() {
+ return mCurrentView;
+ }
+}
diff --git a/girls/src/main/java/com/guiying/girls/main/GirlsActivity.java b/module_girls/src/main/java/com/guiying/module/girls/main/GirlsActivity.java
similarity index 70%
rename from girls/src/main/java/com/guiying/girls/main/GirlsActivity.java
rename to module_girls/src/main/java/com/guiying/module/girls/main/GirlsActivity.java
index b0a0851..9a64571 100644
--- a/girls/src/main/java/com/guiying/girls/main/GirlsActivity.java
+++ b/module_girls/src/main/java/com/guiying/module/girls/main/GirlsActivity.java
@@ -1,12 +1,12 @@
-package com.guiying.girls.main;
+package com.guiying.module.girls.main;
import android.os.Bundle;
-import com.github.mzule.activityrouter.annotation.Router;
-import com.guiying.common.base.BaseActionBarActivity;
-import com.guiying.girls.R;
+import com.alibaba.android.arouter.facade.annotation.Route;
+import com.guiying.module.common.base.BaseActionBarActivity;
+import com.guiying.module.girls.R;
-@Router("girls")
+@Route(path = "/girls/list")
public class GirlsActivity extends BaseActionBarActivity {
private GirlsView mView;
diff --git a/girls/src/main/java/com/guiying/girls/main/GirlsAdapter.java b/module_girls/src/main/java/com/guiying/module/girls/main/GirlsAdapter.java
similarity index 93%
rename from girls/src/main/java/com/guiying/girls/main/GirlsAdapter.java
rename to module_girls/src/main/java/com/guiying/module/girls/main/GirlsAdapter.java
index eefbad0..6ee991a 100644
--- a/girls/src/main/java/com/guiying/girls/main/GirlsAdapter.java
+++ b/module_girls/src/main/java/com/guiying/module/girls/main/GirlsAdapter.java
@@ -1,4 +1,4 @@
-package com.guiying.girls.main;
+package com.guiying.module.girls.main;
import android.content.Context;
import android.view.View;
@@ -7,8 +7,8 @@
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
-import com.guiying.girls.R;
-import com.guiying.girls.data.bean.Girls;
+import com.guiying.module.girls.R;
+import com.guiying.module.girls.data.bean.Girls;
import com.jude.easyrecyclerview.adapter.BaseViewHolder;
import com.jude.easyrecyclerview.adapter.RecyclerArrayAdapter;
diff --git a/girls/src/main/java/com/guiying/girls/main/GirlsContract.java b/module_girls/src/main/java/com/guiying/module/girls/main/GirlsContract.java
similarity index 76%
rename from girls/src/main/java/com/guiying/girls/main/GirlsContract.java
rename to module_girls/src/main/java/com/guiying/module/girls/main/GirlsContract.java
index d4cd0d5..fd57180 100644
--- a/girls/src/main/java/com/guiying/girls/main/GirlsContract.java
+++ b/module_girls/src/main/java/com/guiying/module/girls/main/GirlsContract.java
@@ -1,8 +1,8 @@
-package com.guiying.girls.main;
+package com.guiying.module.girls.main;
-import com.guiying.common.base.BasePresenter;
-import com.guiying.common.base.BaseView;
-import com.guiying.girls.data.bean.Girls;
+import com.guiying.module.common.base.BasePresenter;
+import com.guiying.module.common.base.BaseView;
+import com.guiying.module.girls.data.bean.Girls;
import java.util.List;
diff --git a/girls/src/main/java/com/guiying/girls/main/GirlsPresenter.java b/module_girls/src/main/java/com/guiying/module/girls/main/GirlsPresenter.java
similarity index 82%
rename from girls/src/main/java/com/guiying/girls/main/GirlsPresenter.java
rename to module_girls/src/main/java/com/guiying/module/girls/main/GirlsPresenter.java
index 5a75d89..a94fa8b 100644
--- a/girls/src/main/java/com/guiying/girls/main/GirlsPresenter.java
+++ b/module_girls/src/main/java/com/guiying/module/girls/main/GirlsPresenter.java
@@ -1,8 +1,8 @@
-package com.guiying.girls.main;
+package com.guiying.module.girls.main;
-import com.guiying.girls.data.GirlsDataSource;
-import com.guiying.girls.data.parser.GirlsParser;
-import com.guiying.girls.data.source.RemoteGirlsDataSource;
+import com.guiying.module.girls.data.GirlsDataSource;
+import com.guiying.module.girls.data.bean.GirlsParser;
+import com.guiying.module.girls.data.source.RemoteGirlsDataSource;
/**
* 类说明
@@ -46,6 +46,6 @@ public void onDataNotAvailable() {
@Override
public void start() {
- getGirls(10, 1, true);
+ getGirls(20, 1, true);
}
}
diff --git a/girls/src/main/java/com/guiying/girls/main/GirlsView.java b/module_girls/src/main/java/com/guiying/module/girls/main/GirlsView.java
similarity index 75%
rename from girls/src/main/java/com/guiying/girls/main/GirlsView.java
rename to module_girls/src/main/java/com/guiying/module/girls/main/GirlsView.java
index 569b9a7..dc83d90 100644
--- a/girls/src/main/java/com/guiying/girls/main/GirlsView.java
+++ b/module_girls/src/main/java/com/guiying/module/girls/main/GirlsView.java
@@ -1,6 +1,9 @@
-package com.guiying.girls.main;
+package com.guiying.module.girls.main;
import android.content.Context;
+import android.content.Intent;
+import android.support.v4.app.ActivityOptionsCompat;
+import android.support.v4.content.ContextCompat;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.util.AttributeSet;
@@ -8,8 +11,11 @@
import android.view.ViewStub;
import android.widget.FrameLayout;
-import com.guiying.girls.R;
-import com.guiying.girls.data.bean.Girls;
+import com.guiying.module.common.utils.Utils;
+import com.guiying.module.girls.Constants;
+import com.guiying.module.girls.R;
+import com.guiying.module.girls.data.bean.Girls;
+import com.guiying.module.girls.girl.GirlActivity;
import com.jude.easyrecyclerview.EasyRecyclerView;
import com.jude.easyrecyclerview.adapter.BaseViewHolder;
import com.jude.easyrecyclerview.adapter.RecyclerArrayAdapter;
@@ -35,7 +41,7 @@ public class GirlsView extends FrameLayout implements GirlsContract.View, SwipeR
private GirlsAdapter mAdapter;
private ArrayList mData;
private int page = 1;
- private int size = 10;
+ private int size = 20;
public GirlsView(Context context) {
super(context);
@@ -52,26 +58,33 @@ private void initView() {
inflate(getContext(), R.layout.view_girls_content, this);
mNetworkErrorLayout = (ViewStub) findViewById(R.id.network_error_layout);
mGirlsRecyclerView = (EasyRecyclerView) findViewById(R.id.girls_recycler_view);
-
- mData = new ArrayList<>();
StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
mGirlsRecyclerView.setLayoutManager(staggeredGridLayoutManager);
mAdapter = new GirlsAdapter(getContext());
mGirlsRecyclerView.setAdapterWithProgress(mAdapter);
-
+ mGirlsRecyclerView.setRefreshingColor(
+ ContextCompat.getColor(getContext(), R.color.colorPrimary),
+ ContextCompat.getColor(getContext(), android.R.color.holo_blue_light),
+ ContextCompat.getColor(getContext(), android.R.color.holo_green_light)
+ );
mAdapter.setMore(R.layout.layout_load_more, this);
mAdapter.setNoMore(R.layout.layout_load_no_more);
mAdapter.setError(R.layout.layout_load_error);
mAdapter.setOnMyItemClickListener(new GirlsAdapter.OnMyItemClickListener() {
@Override
public void onItemClick(int position, BaseViewHolder holder) {
-
+ Intent intent = new Intent(Utils.getActivity(GirlsView.this), GirlActivity.class);
+ intent.putParcelableArrayListExtra(Constants.INTENT_GIRLS, mData);
+ intent.putExtra(Constants.INTENT_INDEX, position);
+ ActivityOptionsCompat options = ActivityOptionsCompat.makeScaleUpAnimation(holder.itemView, holder.itemView.getWidth() / 2, holder.itemView.getHeight() / 2, 0, 0);
+ Utils.getActivity(GirlsView.this).startActivity(intent, options.toBundle());
}
});
mGirlsRecyclerView.setRefreshListener(this);
+ mData = new ArrayList<>();
mActive = true;
}
diff --git a/girls/src/main/java/debug/GirlsApplication.java b/module_girls/src/main/java/debug/GirlsApplication.java
similarity index 87%
rename from girls/src/main/java/debug/GirlsApplication.java
rename to module_girls/src/main/java/debug/GirlsApplication.java
index b93eb55..052a4e6 100644
--- a/girls/src/main/java/debug/GirlsApplication.java
+++ b/module_girls/src/main/java/debug/GirlsApplication.java
@@ -1,8 +1,8 @@
package debug;
-import com.guiying.common.base.BaseApplication;
-import com.guiying.common.http.HttpClient;
-import com.guiying.common.http.OnResultListener;
+import com.guiying.module.common.base.BaseApplication;
+import com.guiying.module.common.http.HttpClient;
+import com.guiying.module.common.http.OnResultListener;
import com.orhanobut.logger.Logger;
/**
diff --git a/girls/src/main/debug/AndroidManifest.xml b/module_girls/src/main/module/AndroidManifest.xml
similarity index 77%
rename from girls/src/main/debug/AndroidManifest.xml
rename to module_girls/src/main/module/AndroidManifest.xml
index 3c5bc0c..f283bb9 100644
--- a/girls/src/main/debug/AndroidManifest.xml
+++ b/module_girls/src/main/module/AndroidManifest.xml
@@ -1,6 +1,6 @@
+ package="com.guiying.module.girls">
+
\ No newline at end of file
diff --git a/girls/src/main/res/layout/activity_girls.xml b/module_girls/src/main/res/layout/activity_girls.xml
similarity index 88%
rename from girls/src/main/res/layout/activity_girls.xml
rename to module_girls/src/main/res/layout/activity_girls.xml
index 07e6aed..5109cf6 100644
--- a/girls/src/main/res/layout/activity_girls.xml
+++ b/module_girls/src/main/res/layout/activity_girls.xml
@@ -4,7 +4,7 @@
android:id="@+id/activity_girls"
android:layout_width="match_parent"
android:layout_height="match_parent"
- tools:context="com.guiying.girls.main.GirlsActivity">
+ tools:context=".girls.main.GirlsActivity">
+
+
+
+
+
diff --git a/girls/src/main/res/layout/item_girl.xml b/module_girls/src/main/res/layout/item_girl.xml
similarity index 100%
rename from girls/src/main/res/layout/item_girl.xml
rename to module_girls/src/main/res/layout/item_girl.xml
diff --git a/module_girls/src/main/res/layout/item_girl_detail.xml b/module_girls/src/main/res/layout/item_girl_detail.xml
new file mode 100644
index 0000000..5634024
--- /dev/null
+++ b/module_girls/src/main/res/layout/item_girl_detail.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/girls/src/main/res/layout/view_girls_content.xml b/module_girls/src/main/res/layout/view_girls_content.xml
similarity index 100%
rename from girls/src/main/res/layout/view_girls_content.xml
rename to module_girls/src/main/res/layout/view_girls_content.xml
diff --git a/app/src/main/res/values/colors.xml b/module_girls/src/main/res/values/colors.xml
similarity index 100%
rename from app/src/main/res/values/colors.xml
rename to module_girls/src/main/res/values/colors.xml
diff --git a/girls/src/main/res/values/dimens.xml b/module_girls/src/main/res/values/dimens.xml
similarity index 100%
rename from girls/src/main/res/values/dimens.xml
rename to module_girls/src/main/res/values/dimens.xml
diff --git a/girls/src/main/res/values/strings.xml b/module_girls/src/main/res/values/strings.xml
similarity index 61%
rename from girls/src/main/res/values/strings.xml
rename to module_girls/src/main/res/values/strings.xml
index 567ccc0..2b25680 100644
--- a/girls/src/main/res/values/strings.xml
+++ b/module_girls/src/main/res/values/strings.xml
@@ -1,5 +1,5 @@
- Girls
+ Girls组件
Girls
diff --git a/news/.gitignore b/module_main/.gitignore
similarity index 100%
rename from news/.gitignore
rename to module_main/.gitignore
diff --git a/module_main/build.gradle b/module_main/build.gradle
new file mode 100644
index 0000000..a1838bd
--- /dev/null
+++ b/module_main/build.gradle
@@ -0,0 +1,53 @@
+if (isModule.toBoolean()) {
+ apply plugin: 'com.android.application'
+} else {
+ apply plugin: 'com.android.library'
+}
+
+android {
+ compileSdkVersion build_versions.target_sdk
+ defaultConfig {
+ minSdkVersion build_versions.min_sdk
+ targetSdkVersion build_versions.target_sdk
+ versionCode 1
+ versionName "1.0"
+
+ javaCompileOptions {
+ annotationProcessorOptions {
+ arguments = [ moduleName : project.getName() ]
+ }
+ }
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+
+ sourceSets {
+ main {
+ if (isModule.toBoolean()) {
+ manifest.srcFile 'src/main/module/AndroidManifest.xml'
+ } else {
+ manifest.srcFile 'src/main/AndroidManifest.xml'
+ //集成开发模式下排除debug文件夹中的所有Java文件
+ java {
+ exclude 'debug/**'
+ }
+ }
+ }
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ annotationProcessor deps.arouter_compiler
+ implementation project(':lib_common')
+}
diff --git a/module_main/src/main/AndroidManifest.xml b/module_main/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..db12695
--- /dev/null
+++ b/module_main/src/main/AndroidManifest.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/module_main/src/main/java/com/guiying/module/main/BottomNavigationActivity.java b/module_main/src/main/java/com/guiying/module/main/BottomNavigationActivity.java
new file mode 100644
index 0000000..51c27cf
--- /dev/null
+++ b/module_main/src/main/java/com/guiying/module/main/BottomNavigationActivity.java
@@ -0,0 +1,86 @@
+package com.guiying.module.main;
+
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.design.widget.BottomNavigationView;
+import android.view.MenuItem;
+
+import com.guiying.module.common.base.BaseActivity;
+import com.guiying.module.common.base.BaseFragment;
+import com.guiying.module.common.base.ClassUtils;
+import com.guiying.module.common.base.IViewDelegate;
+import com.guiying.module.common.base.ViewManager;
+import com.guiying.module.common.widget.NoScrollViewPager;
+
+import java.util.List;
+
+/**
+ *
+ *
+ * @author 张华洋 2017/9/27 10:23
+ * @version V1.1
+ * @name BottomNavigationActivity
+ */
+public class BottomNavigationActivity extends BaseActivity {
+
+ private NoScrollViewPager mPager;
+ private List mFragments;
+ private FragmentAdapter mAdapter;
+
+ private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
+ = new BottomNavigationView.OnNavigationItemSelectedListener() {
+
+ @Override
+ public boolean onNavigationItemSelected(@NonNull MenuItem item) {
+ int i = item.getItemId();
+ if (i == R.id.navigation_home) {
+ mPager.setCurrentItem(0);
+ return true;
+ } else if (i == R.id.navigation_dashboard) {
+ mPager.setCurrentItem(1);
+ return true;
+ } else if (i == R.id.navigation_notifications) {
+ mPager.setCurrentItem(2);
+ return true;
+ }
+ return false;
+ }
+
+ };
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_bottom_navigation);
+ BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
+ navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
+ initViewPager();
+ }
+
+ private void initViewPager() {
+ mFragments = ViewManager.getInstance().getAllFragment();//这几个Fragment是主动添加到ViewManager中的
+ BaseFragment newsFragment = getNewsFragment();//主动寻找
+ mFragments.add(newsFragment);
+ mPager = (NoScrollViewPager) findViewById(R.id.container_pager);
+ mAdapter = new FragmentAdapter(getSupportFragmentManager(), mFragments);
+ mPager.setPagerEnabled(false);
+ mPager.setAdapter(mAdapter);
+ }
+
+
+ /**
+ * 在News模块中寻找实现的Fragment
+ *
+ * @return Fragment
+ */
+ private BaseFragment getNewsFragment() {
+ BaseFragment newsFragment = null;
+ List viewDelegates = ClassUtils.getObjectsWithInterface(this, IViewDelegate.class, "com.guiying.module.news");
+ if (viewDelegates != null && !viewDelegates.isEmpty()) {
+ newsFragment = viewDelegates.get(0).getFragment("");
+ }
+ return newsFragment;
+ }
+
+}
diff --git a/module_main/src/main/java/com/guiying/module/main/FragmentAdapter.java b/module_main/src/main/java/com/guiying/module/main/FragmentAdapter.java
new file mode 100644
index 0000000..dc5b82b
--- /dev/null
+++ b/module_main/src/main/java/com/guiying/module/main/FragmentAdapter.java
@@ -0,0 +1,40 @@
+package com.guiying.module.main;
+
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentStatePagerAdapter;
+
+import com.guiying.module.common.base.BaseFragment;
+
+import java.util.List;
+
+/**
+ * Fragments适配器
+ *
+ * @author 张华洋 2017/9/27 10:14
+ * @version V1.1
+ * @name ResourcePagerAdapter
+ */
+public class FragmentAdapter extends FragmentStatePagerAdapter {
+ private List mFragments;
+
+ public FragmentAdapter(FragmentManager fm, List mFragments) {
+ super(fm);
+ this.mFragments = mFragments;
+ }
+
+ @Override
+ public Fragment getItem(int position) {
+ return mFragments.get(position);
+ }
+
+ @Override
+ public int getCount() {
+ return mFragments != null ? mFragments.size() : 0;
+ }
+
+ @Override
+ public int getItemPosition(Object object) {
+ return android.support.v4.view.PagerAdapter.POSITION_NONE;
+ }
+}
diff --git a/module_main/src/main/java/com/guiying/module/main/MainActivity.java b/module_main/src/main/java/com/guiying/module/main/MainActivity.java
new file mode 100644
index 0000000..db0fb8b
--- /dev/null
+++ b/module_main/src/main/java/com/guiying/module/main/MainActivity.java
@@ -0,0 +1,62 @@
+package com.guiying.module.main;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.View;
+
+import com.alibaba.android.arouter.launcher.ARouter;
+import com.guiying.module.common.base.BaseActivity;
+import com.guiying.module.common.base.ViewManager;
+import com.guiying.module.common.utils.ToastUtils;
+
+/**
+ * 类说明
+ *
+ * @author 张华洋 2017/7/1 13:13
+ * @version V1.2.0
+ * @name MainActivity
+ */
+public class MainActivity extends BaseActivity implements View.OnClickListener {
+
+ private long mExitTime = 0;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ findViewById(R.id.news_button).setOnClickListener(this);
+ findViewById(R.id.girls_button).setOnClickListener(this);
+ findViewById(R.id.fragment_button).setOnClickListener(this);
+ }
+
+ @Override
+ public void onClick(View view) {
+ if (view.getId() == R.id.news_button) {
+ //跳转到NewsCenterActivity
+ ARouter.getInstance().build("/news/center").navigation();
+ } else if (view.getId() == R.id.girls_button) {
+ //跳转到GirlsActivity
+ ARouter.getInstance().build("/girls/list").navigation();
+ } else if (view.getId() == R.id.fragment_button) {
+ startActivity(new Intent(this, BottomNavigationActivity.class));
+ }
+ }
+
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
+ //两秒之内按返回键就会退出
+ if ((System.currentTimeMillis() - mExitTime) > 2000) {
+ ToastUtils.showShortToast(getString(R.string.app_exit_hint));
+ mExitTime = System.currentTimeMillis();
+ } else {
+ ViewManager.getInstance().exitApp(this);
+ }
+ return true;
+ }
+ return super.onKeyDown(keyCode, event);
+ }
+
+}
diff --git a/app/src/main/java/com/guiying/androidmodulepattern/MyApplication.java b/module_main/src/main/java/debug/MainApplication.java
similarity index 70%
rename from app/src/main/java/com/guiying/androidmodulepattern/MyApplication.java
rename to module_main/src/main/java/debug/MainApplication.java
index a4f3976..24509f5 100644
--- a/app/src/main/java/com/guiying/androidmodulepattern/MyApplication.java
+++ b/module_main/src/main/java/debug/MainApplication.java
@@ -1,21 +1,18 @@
-package com.guiying.androidmodulepattern;
+package debug;
-import com.github.mzule.activityrouter.annotation.Modules;
-import com.guiying.common.base.BaseApplication;
-import com.guiying.common.http.HttpClient;
-import com.guiying.common.http.OnResultListener;
+import com.guiying.module.common.base.BaseApplication;
+import com.guiying.module.common.http.HttpClient;
+import com.guiying.module.common.http.OnResultListener;
import com.orhanobut.logger.Logger;
/**
* 类说明
*
- * @author 张华洋 2017/2/15 20:14
+ * @author 张华洋 2017/2/15 20:09
* @version V1.2.0
- * @name MyApplication
+ * @name GirlsApplication
*/
-@Modules({"app", "girls", "news"})
-public class MyApplication extends BaseApplication {
-
+public class MainApplication extends BaseApplication {
@Override
public void onCreate() {
diff --git a/news/src/main/debug/AndroidManifest.xml b/module_main/src/main/module/AndroidManifest.xml
similarity index 68%
rename from news/src/main/debug/AndroidManifest.xml
rename to module_main/src/main/module/AndroidManifest.xml
index 43b815b..0443b12 100644
--- a/news/src/main/debug/AndroidManifest.xml
+++ b/module_main/src/main/module/AndroidManifest.xml
@@ -1,17 +1,15 @@
+ package="com.guiying.module.main">
-
+
@@ -19,4 +17,5 @@
-
\ No newline at end of file
+
+
diff --git a/module_main/src/main/res/drawable/ic_dashboard_black_24dp.xml b/module_main/src/main/res/drawable/ic_dashboard_black_24dp.xml
new file mode 100644
index 0000000..ae6a446
--- /dev/null
+++ b/module_main/src/main/res/drawable/ic_dashboard_black_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/module_main/src/main/res/drawable/ic_home_black_24dp.xml b/module_main/src/main/res/drawable/ic_home_black_24dp.xml
new file mode 100644
index 0000000..0c36320
--- /dev/null
+++ b/module_main/src/main/res/drawable/ic_home_black_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/module_main/src/main/res/drawable/ic_notifications_black_24dp.xml b/module_main/src/main/res/drawable/ic_notifications_black_24dp.xml
new file mode 100644
index 0000000..0262382
--- /dev/null
+++ b/module_main/src/main/res/drawable/ic_notifications_black_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/module_main/src/main/res/layout/activity_bottom_navigation.xml b/module_main/src/main/res/layout/activity_bottom_navigation.xml
new file mode 100644
index 0000000..060e7be
--- /dev/null
+++ b/module_main/src/main/res/layout/activity_bottom_navigation.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_main.xml b/module_main/src/main/res/layout/activity_main.xml
similarity index 79%
rename from app/src/main/res/layout/activity_main.xml
rename to module_main/src/main/res/layout/activity_main.xml
index 9e0fb9f..c4c16f8 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/module_main/src/main/res/layout/activity_main.xml
@@ -9,7 +9,7 @@
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
- tools:context="com.guiying.androidmodulepattern.MainActivity">
+ tools:context="com.guiying.module.main.MainActivity">
+
+
+
diff --git a/module_main/src/main/res/menu/navigation.xml b/module_main/src/main/res/menu/navigation.xml
new file mode 100644
index 0000000..f4de4f8
--- /dev/null
+++ b/module_main/src/main/res/menu/navigation.xml
@@ -0,0 +1,19 @@
+
+
diff --git a/app/src/main/res/values/dimens.xml b/module_main/src/main/res/values/dimens.xml
similarity index 59%
rename from app/src/main/res/values/dimens.xml
rename to module_main/src/main/res/values/dimens.xml
index 47c8224..8878089 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/module_main/src/main/res/values/dimens.xml
@@ -1,5 +1,8 @@
+
-
+
16dp
16dp
-
+
+
+
\ No newline at end of file
diff --git a/module_main/src/main/res/values/strings.xml b/module_main/src/main/res/values/strings.xml
new file mode 100644
index 0000000..ca0b880
--- /dev/null
+++ b/module_main/src/main/res/values/strings.xml
@@ -0,0 +1,10 @@
+
+ main组件
+
+ 再按一次退出程序
+ Fragment组件化
+ news
+ girls
+ 预留
+
+
diff --git a/module_news/.gitignore b/module_news/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/module_news/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/module_news/build.gradle b/module_news/build.gradle
new file mode 100644
index 0000000..a1838bd
--- /dev/null
+++ b/module_news/build.gradle
@@ -0,0 +1,53 @@
+if (isModule.toBoolean()) {
+ apply plugin: 'com.android.application'
+} else {
+ apply plugin: 'com.android.library'
+}
+
+android {
+ compileSdkVersion build_versions.target_sdk
+ defaultConfig {
+ minSdkVersion build_versions.min_sdk
+ targetSdkVersion build_versions.target_sdk
+ versionCode 1
+ versionName "1.0"
+
+ javaCompileOptions {
+ annotationProcessorOptions {
+ arguments = [ moduleName : project.getName() ]
+ }
+ }
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+
+ sourceSets {
+ main {
+ if (isModule.toBoolean()) {
+ manifest.srcFile 'src/main/module/AndroidManifest.xml'
+ } else {
+ manifest.srcFile 'src/main/AndroidManifest.xml'
+ //集成开发模式下排除debug文件夹中的所有Java文件
+ java {
+ exclude 'debug/**'
+ }
+ }
+ }
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ annotationProcessor deps.arouter_compiler
+ implementation project(':lib_common')
+}
diff --git a/module_news/src/main/AndroidManifest.xml b/module_news/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..14b08f4
--- /dev/null
+++ b/module_news/src/main/AndroidManifest.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
diff --git a/news/src/main/java/com/guiying/news/Constants.java b/module_news/src/main/java/com/guiying/module/news/Constants.java
similarity index 92%
rename from news/src/main/java/com/guiying/news/Constants.java
rename to module_news/src/main/java/com/guiying/module/news/Constants.java
index 2d3cc6f..000de00 100644
--- a/news/src/main/java/com/guiying/news/Constants.java
+++ b/module_news/src/main/java/com/guiying/module/news/Constants.java
@@ -1,4 +1,4 @@
-package com.guiying.news;
+package com.guiying.module.news;
/**
* 保存项目中用到的常量
diff --git a/module_news/src/main/java/com/guiying/module/news/MyDelegate.java b/module_news/src/main/java/com/guiying/module/news/MyDelegate.java
new file mode 100644
index 0000000..98f55a8
--- /dev/null
+++ b/module_news/src/main/java/com/guiying/module/news/MyDelegate.java
@@ -0,0 +1,40 @@
+package com.guiying.module.news;
+
+import android.support.annotation.Keep;
+
+import com.guiying.module.common.base.IApplicationDelegate;
+import com.guiying.module.common.base.ViewManager;
+import com.orhanobut.logger.Logger;
+
+/**
+ * 类说明
+ *
+ * @author 张华洋 2017/9/20 22:29
+ * @version V2.8.3
+ * @name MyDelegate
+ */
+@Keep
+public class MyDelegate implements IApplicationDelegate {
+
+ @Override
+ public void onCreate() {
+ Logger.init("pattern");
+ //主动添加
+ ViewManager.getInstance().addFragment(0, NewsFragment.newInstance());
+ }
+
+ @Override
+ public void onTerminate() {
+
+ }
+
+ @Override
+ public void onLowMemory() {
+
+ }
+
+ @Override
+ public void onTrimMemory(int level) {
+
+ }
+}
diff --git a/module_news/src/main/java/com/guiying/module/news/MyViewDelegate.java b/module_news/src/main/java/com/guiying/module/news/MyViewDelegate.java
new file mode 100644
index 0000000..0620bb5
--- /dev/null
+++ b/module_news/src/main/java/com/guiying/module/news/MyViewDelegate.java
@@ -0,0 +1,28 @@
+package com.guiying.module.news;
+
+import android.support.annotation.Keep;
+import android.view.View;
+
+import com.guiying.module.common.base.BaseFragment;
+import com.guiying.module.common.base.IViewDelegate;
+
+/**
+ * 类说明
+ *
+ * @author 张华洋 2018/1/4 22:16
+ * @version V2.8.3
+ * @name MyViewDelegate
+ */
+@Keep
+public class MyViewDelegate implements IViewDelegate {
+
+ @Override
+ public BaseFragment getFragment(String name) {
+ return NewsFragment.newInstance();
+ }
+
+ @Override
+ public View getView(String name) {
+ return null;
+ }
+}
diff --git a/module_news/src/main/java/com/guiying/module/news/NewsFragment.java b/module_news/src/main/java/com/guiying/module/news/NewsFragment.java
new file mode 100644
index 0000000..93c039a
--- /dev/null
+++ b/module_news/src/main/java/com/guiying/module/news/NewsFragment.java
@@ -0,0 +1,43 @@
+package com.guiying.module.news;
+
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.guiying.module.common.base.BaseFragment;
+
+
+/**
+ * A simple {@link Fragment} subclass.
+ */
+public class NewsFragment extends BaseFragment {
+
+ /**
+ * Use this factory method to create a new instance of
+ * this fragment using the provided parameters.
+ *
+ * @return A new instance of fragment NewsFragment.
+ */
+ public static NewsFragment newInstance() {
+ return new NewsFragment();
+ }
+
+
+
+ public NewsFragment() {
+ // Required empty public constructor
+ }
+
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ // Inflate the layout for this fragment
+ return inflater.inflate(R.layout.fragment_news, container, false);
+ }
+
+
+}
diff --git a/module_news/src/main/java/com/guiying/module/news/data/NewsDataSource.java b/module_news/src/main/java/com/guiying/module/news/data/NewsDataSource.java
new file mode 100644
index 0000000..8990f08
--- /dev/null
+++ b/module_news/src/main/java/com/guiying/module/news/data/NewsDataSource.java
@@ -0,0 +1,34 @@
+package com.guiying.module.news.data;
+
+import com.guiying.module.common.base.InfoCallback;
+import com.guiying.module.news.data.bean.MessageDetail;
+import com.guiying.module.news.data.bean.StoryList;
+
+/**
+ * 类说明
+ *
+ * @author 张华洋 2017/4/20 22:02
+ * @version V1.2.0
+ * @name NewsDataSource
+ */
+public interface NewsDataSource {
+
+
+ /**
+ * 获取当天的新闻列表
+ *
+ * @param date 日期
+ * @param callback 回调
+ */
+ void getNewsList(String date, InfoCallback callback);
+
+ /**
+ * 获取某条新闻详情
+ *
+ * @param id 新闻Id
+ * @param callback 回调
+ */
+ void getNewsDetail(String id, InfoCallback callback);
+
+}
+
diff --git a/module_news/src/main/java/com/guiying/module/news/data/bean/MessageDetail.java b/module_news/src/main/java/com/guiying/module/news/data/bean/MessageDetail.java
new file mode 100644
index 0000000..204bb82
--- /dev/null
+++ b/module_news/src/main/java/com/guiying/module/news/data/bean/MessageDetail.java
@@ -0,0 +1,102 @@
+package com.guiying.module.news.data.bean;
+
+import java.util.List;
+
+public class MessageDetail {
+ private String body;
+ private String image_source;
+ private String title;
+ private String image;
+ private String share_url;
+ private List recommenders;
+ private String ga_prefix;
+ private String type;
+ private String id;
+
+ public String getBody() {
+ return body;
+ }
+
+ public void setBody(String body) {
+ this.body = body;
+ }
+
+ public String getImage_source() {
+ return image_source;
+ }
+
+ public void setImage_source(String image_source) {
+ this.image_source = image_source;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getImage() {
+ return image;
+ }
+
+ public void setImage(String image) {
+ this.image = image;
+ }
+
+ public String getShare_url() {
+ return share_url;
+ }
+
+ public void setShare_url(String share_url) {
+ this.share_url = share_url;
+ }
+
+ public List getRecommenders() {
+ return recommenders;
+ }
+
+ public void setRecommenders(List recommenders) {
+ this.recommenders = recommenders;
+ }
+
+ public String getGa_prefix() {
+ return ga_prefix;
+ }
+
+ public void setGa_prefix(String ga_prefix) {
+ this.ga_prefix = ga_prefix;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ @Override
+ public String toString() {
+ return "MessageDetail{" +
+ "body='" + body + '\'' +
+ ", image_source='" + image_source + '\'' +
+ ", title='" + title + '\'' +
+ ", image='" + image + '\'' +
+ ", share_url='" + share_url + '\'' +
+ ", recommenders=" + recommenders +
+ ", ga_prefix='" + ga_prefix + '\'' +
+ ", type='" + type + '\'' +
+ ", id='" + id + '\'' +
+ '}';
+ }
+}
diff --git a/module_news/src/main/java/com/guiying/module/news/data/bean/Story.java b/module_news/src/main/java/com/guiying/module/news/data/bean/Story.java
new file mode 100644
index 0000000..af488ca
--- /dev/null
+++ b/module_news/src/main/java/com/guiying/module/news/data/bean/Story.java
@@ -0,0 +1,77 @@
+package com.guiying.module.news.data.bean;
+
+/**
+ * 日报新闻实体类
+ */
+public class Story {
+
+ /**
+ * 新闻标题
+ **/
+ private String title;
+ /**
+ * 供 Google Analytics 使用
+ **/
+ private String ga_prefix;
+ /**
+ * 图像地址(官方 API 使用数组形式。目前暂未有使用多张图片的情形出现,曾见无 images 属性的情况,请在使用中注意 )
+ **/
+ private String[] images;
+ /**
+ * 消息是否包含多张图片(仅出现在包含多图的新闻中)
+ **/
+ private String multipic;
+ private String type;
+ /**
+ * url 与 share_url 中最后的数字(应为内容的 id)
+ **/
+ private String id;
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getGa_prefix() {
+ return ga_prefix;
+ }
+
+ public void setGa_prefix(String ga_prefix) {
+ this.ga_prefix = ga_prefix;
+ }
+
+ public String[] getImages() {
+ return images;
+ }
+
+ public void setImages(String[] images) {
+ this.images = images;
+ }
+
+ public String getMultipic() {
+ return multipic;
+ }
+
+ public void setMultipic(String multipic) {
+ this.multipic = multipic;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+}
diff --git a/module_news/src/main/java/com/guiying/module/news/data/bean/StoryList.java b/module_news/src/main/java/com/guiying/module/news/data/bean/StoryList.java
new file mode 100644
index 0000000..58ba7e0
--- /dev/null
+++ b/module_news/src/main/java/com/guiying/module/news/data/bean/StoryList.java
@@ -0,0 +1,32 @@
+package com.guiying.module.news.data.bean;
+
+import java.util.List;
+
+/**
+ * 类说明
+ *
+ * @author 张华洋 2017/4/20 23:04
+ * @version V1.2.0
+ * @name StoryList
+ */
+public class StoryList {
+
+ private String date;
+ private List stories;
+
+ public String getDate() {
+ return date;
+ }
+
+ public void setDate(String date) {
+ this.date = date;
+ }
+
+ public List getStories() {
+ return stories;
+ }
+
+ public void setStories(List stories) {
+ this.stories = stories;
+ }
+}
diff --git a/module_news/src/main/java/com/guiying/module/news/data/source/RemoteNewsDataSource.java b/module_news/src/main/java/com/guiying/module/news/data/source/RemoteNewsDataSource.java
new file mode 100644
index 0000000..05d4d84
--- /dev/null
+++ b/module_news/src/main/java/com/guiying/module/news/data/source/RemoteNewsDataSource.java
@@ -0,0 +1,75 @@
+package com.guiying.module.news.data.source;
+
+import com.guiying.module.common.base.InfoCallback;
+import com.guiying.module.common.http.DataType;
+import com.guiying.module.common.http.HttpClient;
+import com.guiying.module.common.http.OnResultListener;
+import com.guiying.module.news.Constants;
+import com.guiying.module.news.data.NewsDataSource;
+import com.guiying.module.news.data.bean.MessageDetail;
+import com.guiying.module.news.data.bean.StoryList;
+
+/**
+ * 类说明
+ *
+ * @author 张华洋 2017/4/20 23:32
+ * @version V1.2.0
+ * @name RemoteNewsDataSource
+ */
+public class RemoteNewsDataSource implements NewsDataSource {
+
+ @Override
+ public void getNewsList(String date, final InfoCallback callback) {
+ HttpClient client = new HttpClient.Builder()
+ .baseUrl(Constants.ZHIHU_DAILY_BEFORE_MESSAGE)
+ .url(date)
+ .bodyType(DataType.JSON_OBJECT, StoryList.class)
+ .build();
+ client.get(new OnResultListener() {
+
+ @Override
+ public void onSuccess(StoryList result) {
+ callback.onSuccess(result);
+ }
+
+ @Override
+ public void onError(int code, String message) {
+ callback.onError(code, message);
+ }
+
+ @Override
+ public void onFailure(String message) {
+ callback.onError(0, message);
+ }
+ });
+ }
+
+
+ @Override
+ public void getNewsDetail(String id, final InfoCallback callback) {
+ HttpClient client = new HttpClient.Builder()
+ .baseUrl(Constants.ZHIHU_DAILY_BEFORE_MESSAGE_DETAIL)
+ .url(id)
+ .bodyType(DataType.JSON_OBJECT, MessageDetail.class)
+ .build();
+ client.get(new OnResultListener() {
+
+ @Override
+ public void onSuccess(MessageDetail result) {
+ callback.onSuccess(result);
+ }
+
+ @Override
+ public void onError(int code, String message) {
+ callback.onError(code, message);
+ }
+
+ @Override
+ public void onFailure(String message) {
+ callback.onError(0, message);
+ }
+ });
+ }
+
+
+}
diff --git a/module_news/src/main/java/com/guiying/module/news/detail/NewsDetailActivity.java b/module_news/src/main/java/com/guiying/module/news/detail/NewsDetailActivity.java
new file mode 100644
index 0000000..1539ad9
--- /dev/null
+++ b/module_news/src/main/java/com/guiying/module/news/detail/NewsDetailActivity.java
@@ -0,0 +1,27 @@
+package com.guiying.module.news.detail;
+
+import android.os.Bundle;
+
+import com.alibaba.android.arouter.facade.annotation.Route;
+import com.guiying.module.common.base.BaseActivity;
+
+/**
+ * 类说明
+ *
+ * @author 张华洋 2017/7/1 13:13
+ * @version V1.2.0
+ * @name NewsDetailActivity
+ */
+@Route(path = "/news/detail")
+public class NewsDetailActivity extends BaseActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ NewsDetailView detailView = new NewsDetailView(this);
+ setContentView(detailView);
+ String id = getIntent().getStringExtra("id");
+ new NewsDetailPresenter(detailView).getNewsDetail(id);
+ }
+
+}
diff --git a/module_news/src/main/java/com/guiying/module/news/detail/NewsDetailContract.java b/module_news/src/main/java/com/guiying/module/news/detail/NewsDetailContract.java
new file mode 100644
index 0000000..6a21ef5
--- /dev/null
+++ b/module_news/src/main/java/com/guiying/module/news/detail/NewsDetailContract.java
@@ -0,0 +1,35 @@
+package com.guiying.module.news.detail;
+
+import com.guiying.module.common.base.BasePresenter;
+import com.guiying.module.common.base.BaseView;
+import com.guiying.module.news.data.bean.MessageDetail;
+
+/**
+ * 类说明
+ *
+ * @author 张华洋 2017/2/22 20:33
+ * @version V1.2.0
+ * @name NewsContract
+ */
+public interface NewsDetailContract {
+
+ interface View extends BaseView {
+
+ boolean isActive();
+
+ void showNewsDetail(MessageDetail detail);
+
+ }
+
+ interface Presenter extends BasePresenter {
+
+ /**
+ * 获取最新列表
+ *
+ * @param newsId 新闻id
+ */
+ void getNewsDetail(String newsId);
+
+ }
+
+}
diff --git a/module_news/src/main/java/com/guiying/module/news/detail/NewsDetailPresenter.java b/module_news/src/main/java/com/guiying/module/news/detail/NewsDetailPresenter.java
new file mode 100644
index 0000000..f517ae7
--- /dev/null
+++ b/module_news/src/main/java/com/guiying/module/news/detail/NewsDetailPresenter.java
@@ -0,0 +1,49 @@
+package com.guiying.module.news.detail;
+
+import com.guiying.module.common.base.InfoCallback;
+import com.guiying.module.news.data.NewsDataSource;
+import com.guiying.module.news.data.bean.MessageDetail;
+import com.guiying.module.news.data.source.RemoteNewsDataSource;
+
+/**
+ * 类说明
+ *
+ * @author 张华洋 2017/2/22 20:33
+ * @version V1.2.0
+ * @name GirlsPresenter
+ */
+public class NewsDetailPresenter implements NewsDetailContract.Presenter {
+
+ private NewsDetailContract.View mView;
+ private NewsDataSource mDataSource;
+
+ public NewsDetailPresenter(NewsDetailContract.View view) {
+ mView = view;
+ mDataSource = new RemoteNewsDataSource();
+ mView.setPresenter(this);
+ }
+
+ @Override
+ public void start() {
+
+ }
+
+
+ @Override
+ public void getNewsDetail(String newsId) {
+ mDataSource.getNewsDetail(newsId, new InfoCallback() {
+ @Override
+ public void onSuccess(MessageDetail detail) {
+ if (mView.isActive()) {
+ mView.showNewsDetail(detail);
+ }
+ }
+
+ @Override
+ public void onError(int code, String message) {
+
+ }
+ });
+ }
+
+}
diff --git a/module_news/src/main/java/com/guiying/module/news/detail/NewsDetailView.java b/module_news/src/main/java/com/guiying/module/news/detail/NewsDetailView.java
new file mode 100644
index 0000000..6be1e58
--- /dev/null
+++ b/module_news/src/main/java/com/guiying/module/news/detail/NewsDetailView.java
@@ -0,0 +1,129 @@
+package com.guiying.module.news.detail;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.support.design.widget.CollapsingToolbarLayout;
+import android.text.Html;
+import android.text.method.LinkMovementMethod;
+import android.util.AttributeSet;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.request.animation.GlideAnimation;
+import com.bumptech.glide.request.target.SimpleTarget;
+import com.guiying.module.news.R;
+import com.guiying.module.news.data.bean.MessageDetail;
+
+/**
+ * 类说明
+ *
+ * @author 张华洋 2017/7/1 13:18
+ * @version V1.2.0
+ * @name NewsDetailView
+ */
+
+public class NewsDetailView extends FrameLayout implements NewsDetailContract.View {
+
+ private boolean isActive = false;
+ private NewsDetailContract.Presenter mPresenter;
+ private ImageView mToolbarImage;
+ private TextView mToolbarText;
+ private CollapsingToolbarLayout mCollapsingLayout;
+ private TextView mDetailText;
+
+
+ public NewsDetailView(Context context) {
+ super(context);
+ initView();
+ }
+
+ public NewsDetailView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ initView();
+ }
+
+ private void initView() {
+ inflate(getContext(), R.layout.view_news_detail, this);
+ mToolbarImage = (ImageView) findViewById(R.id.toolbar_image);
+ mToolbarText = (TextView) findViewById(R.id.toolbar_text);
+ mCollapsingLayout = (CollapsingToolbarLayout) findViewById(R.id.collapsing_layout);
+ mDetailText = (TextView) findViewById(R.id.news_detail_text);
+
+ isActive = true;
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ isActive = true;
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ isActive = false;
+ }
+
+ @Override
+ public boolean isActive() {
+ return isActive;
+ }
+
+
+ @Override
+ public void setPresenter(NewsDetailContract.Presenter presenter) {
+ mPresenter = presenter;
+ }
+
+ @Override
+ public void showNewsDetail(MessageDetail detail) {
+ mCollapsingLayout.setTitle(detail.getTitle());
+ //设置还没收缩时状态下字体颜色
+ mCollapsingLayout.setExpandedTitleColor(Color.WHITE);
+ //设置收缩后Toolbar上字体的颜色
+ mCollapsingLayout.setCollapsedTitleTextColor(Color.WHITE);
+ mToolbarText.setText(detail.getImage_source());
+ Glide.with(getContext())
+ .load(detail.getImage())
+ .thumbnail(0.2f)
+ .into(mToolbarImage);
+ mDetailText.setMovementMethod(LinkMovementMethod.getInstance());
+ mDetailText.setText(Html.fromHtml(detail.getBody(), new Html.ImageGetter() {
+ @Override
+ public Drawable getDrawable(String source) {
+ final URLDrawable urlDrawable = new URLDrawable();
+ Glide.with(getContext()).load(source).asBitmap().into(new SimpleTarget() {
+
+ @Override
+ public void onResourceReady(Bitmap resource, GlideAnimation super Bitmap> glideAnimation) {
+ urlDrawable.bitmap = resource;
+ urlDrawable.setBounds(0, 0, resource.getWidth(), resource.getHeight());
+ mDetailText.invalidate();
+ // 解决图文重叠
+ mDetailText.setText(mDetailText.getText());
+ }
+ });
+ return urlDrawable;
+ }
+ }, null));
+ }
+
+
+ private class URLDrawable extends BitmapDrawable {
+
+ private Bitmap bitmap;
+
+ @Override
+ public void draw(Canvas canvas) {
+ if (bitmap != null) {
+ canvas.drawBitmap(bitmap, 0, 0, getPaint());
+ }
+ }
+ }
+}
diff --git a/module_news/src/main/java/com/guiying/module/news/main/NewsCenterActivity.java b/module_news/src/main/java/com/guiying/module/news/main/NewsCenterActivity.java
new file mode 100644
index 0000000..af806e2
--- /dev/null
+++ b/module_news/src/main/java/com/guiying/module/news/main/NewsCenterActivity.java
@@ -0,0 +1,78 @@
+package com.guiying.module.news.main;
+
+import android.os.Bundle;
+import android.support.design.widget.TabLayout;
+import android.support.v4.view.ViewPager;
+import android.support.v7.widget.Toolbar;
+
+import com.alibaba.android.arouter.facade.annotation.Route;
+import com.guiying.module.common.base.BaseActivity;
+import com.guiying.module.news.R;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * 类说明
+ *
+ * @author 张华洋 2017/4/20 22:26
+ * @version V1.2.0
+ * @name NewsCenterActivity
+ */
+@Route(path = "/news/center")
+public class NewsCenterActivity extends BaseActivity {
+
+ protected Toolbar mToolBar;
+ protected TabLayout mTabLayout;
+ protected ViewPager mViewPager;
+ private NewsListViewAdapter mListAdapter;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ super.setContentView(R.layout.activity_news);
+ mToolBar = (Toolbar) findViewById(R.id.news_title_bar);
+ mToolBar.setTitle("知乎日报");
+ setupToolBar(mToolBar, false);
+ mTabLayout = (TabLayout) findViewById(R.id.date_tab);
+ mViewPager = (ViewPager) findViewById(R.id.message_pager);
+ mListAdapter = new NewsListViewAdapter(getMessageListViews(), getWeekDate());
+ mViewPager.setAdapter(mListAdapter);
+ //setupWithViewPager必须在ViewPager.setAdapter()之后调用
+ mTabLayout.setupWithViewPager(mViewPager);
+ }
+
+ /**
+ * 获取ViewPager的viewList
+ */
+ private List getMessageListViews() {
+ List viewList = new ArrayList<>();
+ List weekDate = getWeekDate();
+ if (weekDate != null) {
+ for (String tab : weekDate) {
+ viewList.add(new NewsListView(this, tab));
+ }
+ }
+ return viewList;
+ }
+
+
+ /**
+ * 获取过去7天的时期,格式为yymmdd
+ **/
+ public static List getWeekDate() {
+ List dates = new ArrayList<>();
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd", Locale.getDefault());
+ for (int i = 0; i < 7; i++) {
+ Calendar calendar = Calendar.getInstance();
+ calendar.add(Calendar.DAY_OF_YEAR, 1 - i);
+ dates.add(simpleDateFormat.format(calendar.getTime()));
+ }
+ return dates;
+ }
+
+
+}
diff --git a/module_news/src/main/java/com/guiying/module/news/main/NewsListAdapter.java b/module_news/src/main/java/com/guiying/module/news/main/NewsListAdapter.java
new file mode 100644
index 0000000..76e452f
--- /dev/null
+++ b/module_news/src/main/java/com/guiying/module/news/main/NewsListAdapter.java
@@ -0,0 +1,67 @@
+package com.guiying.module.news.main;
+
+import android.content.Context;
+import android.content.Intent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.load.engine.DiskCacheStrategy;
+import com.guiying.module.news.R;
+import com.guiying.module.news.data.bean.Story;
+import com.guiying.module.news.detail.NewsDetailActivity;
+import com.jude.easyrecyclerview.adapter.BaseViewHolder;
+import com.jude.easyrecyclerview.adapter.RecyclerArrayAdapter;
+
+/**
+ * 类说明
+ *
+ * @author 张华洋 2017/4/20 22:26
+ * @version V1.2.0
+ * @name NewsListAdapter
+ */
+public class NewsListAdapter extends RecyclerArrayAdapter {
+
+ public NewsListAdapter(Context context) {
+ super(context);
+ }
+
+ @Override
+ public BaseViewHolder OnCreateViewHolder(ViewGroup parent, int viewType) {
+ return new NewsListHolder(parent);
+ }
+
+ private class NewsListHolder extends BaseViewHolder {
+
+ private TextView mTextView;
+ private ImageView mImageView;
+
+ NewsListHolder(ViewGroup parent) {
+ super(parent, R.layout.item_news_list);
+ mTextView = $(R.id.news_title);
+ mImageView = $(R.id.news_image);
+ }
+
+ @Override
+ public void setData(final Story data) {
+ super.setData(data);
+ mTextView.setText(data.getTitle());
+ Glide.with(getContext())
+ .load(data.getImages()[0])
+ .centerCrop()
+ .crossFade()
+ .diskCacheStrategy(DiskCacheStrategy.SOURCE)
+ .into(mImageView);
+ itemView.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ Intent intent = new Intent(getContext(), NewsDetailActivity.class);
+ intent.putExtra("id", data.getId());
+ getContext().startActivity(intent);
+ }
+ });
+ }
+ }
+}
diff --git a/module_news/src/main/java/com/guiying/module/news/main/NewsListContract.java b/module_news/src/main/java/com/guiying/module/news/main/NewsListContract.java
new file mode 100644
index 0000000..6a7106d
--- /dev/null
+++ b/module_news/src/main/java/com/guiying/module/news/main/NewsListContract.java
@@ -0,0 +1,35 @@
+package com.guiying.module.news.main;
+
+import com.guiying.module.common.base.BasePresenter;
+import com.guiying.module.common.base.BaseView;
+import com.guiying.module.news.data.bean.StoryList;
+
+/**
+ * 类说明
+ *
+ * @author 张华洋 2017/2/22 20:33
+ * @version V1.2.0
+ * @name NewsContract
+ */
+public interface NewsListContract {
+
+ interface View extends BaseView {
+
+ boolean isActive();
+
+ void showNewsList(StoryList info);
+
+ }
+
+ interface Presenter extends BasePresenter {
+
+ /**
+ * 获取最新列表
+ *
+ * @param date
+ */
+ void getNewMessages(int page, int size, String date);
+
+ }
+
+}
diff --git a/module_news/src/main/java/com/guiying/module/news/main/NewsListPresenter.java b/module_news/src/main/java/com/guiying/module/news/main/NewsListPresenter.java
new file mode 100644
index 0000000..8ac69db
--- /dev/null
+++ b/module_news/src/main/java/com/guiying/module/news/main/NewsListPresenter.java
@@ -0,0 +1,47 @@
+package com.guiying.module.news.main;
+
+import com.guiying.module.common.base.InfoCallback;
+import com.guiying.module.news.data.NewsDataSource;
+import com.guiying.module.news.data.bean.StoryList;
+import com.guiying.module.news.data.source.RemoteNewsDataSource;
+
+/**
+ * 类说明
+ *
+ * @author 张华洋 2017/2/22 20:33
+ * @version V1.2.0
+ * @name GirlsPresenter
+ */
+public class NewsListPresenter implements NewsListContract.Presenter {
+
+ private NewsListContract.View mView;
+ private NewsDataSource mDataSource;
+
+ public NewsListPresenter(NewsListContract.View view) {
+ mView = view;
+ mDataSource = new RemoteNewsDataSource();
+ mView.setPresenter(this);
+ }
+
+ @Override
+ public void start() {
+
+ }
+
+ @Override
+ public void getNewMessages(int page, int size, String date) {
+ mDataSource.getNewsList(date, new InfoCallback() {
+ @Override
+ public void onSuccess(StoryList info) {
+ if (mView.isActive()) {
+ mView.showNewsList(info);
+ }
+ }
+
+ @Override
+ public void onError(int code, String message) {
+
+ }
+ });
+ }
+}
diff --git a/module_news/src/main/java/com/guiying/module/news/main/NewsListView.java b/module_news/src/main/java/com/guiying/module/news/main/NewsListView.java
new file mode 100644
index 0000000..254aca0
--- /dev/null
+++ b/module_news/src/main/java/com/guiying/module/news/main/NewsListView.java
@@ -0,0 +1,99 @@
+package com.guiying.module.news.main;
+
+import android.content.Context;
+import android.support.v4.content.ContextCompat;
+import android.support.v4.widget.SwipeRefreshLayout;
+import android.support.v7.widget.LinearLayoutManager;
+import android.util.AttributeSet;
+
+import com.guiying.module.news.R;
+import com.guiying.module.news.data.bean.StoryList;
+import com.jude.easyrecyclerview.EasyRecyclerView;
+import com.jude.easyrecyclerview.adapter.RecyclerArrayAdapter;
+import com.jude.easyrecyclerview.decoration.DividerDecoration;
+
+/**
+ * 类说明
+ *
+ * @author 张华洋 2017/4/20 22:21
+ * @version V1.2.0
+ * @name NewListView
+ */
+public class NewsListView extends EasyRecyclerView implements NewsListContract.View, SwipeRefreshLayout.OnRefreshListener {
+ private NewsListContract.Presenter mPresenter;
+ private String mDate;
+ private NewsListAdapter mAdapter;
+ private boolean isActive = false;
+
+ public NewsListView(Context context, String date) {
+ super(context);
+ mDate = date;
+ initView();
+ }
+
+ public NewsListView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ initView();
+ }
+
+ private void initView() {
+ setRefreshingColor(
+ ContextCompat.getColor(getContext(), R.color.colorPrimary),
+ ContextCompat.getColor(getContext(), android.R.color.holo_blue_light),
+ ContextCompat.getColor(getContext(), android.R.color.holo_green_light)
+ );
+ LinearLayoutManager layoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false);
+ setLayoutManager(layoutManager);
+ DividerDecoration dividerDecoration = new DividerDecoration(getResources().getColor(R.color.gray_e0), 20, 20, 0);
+ dividerDecoration.setDrawLastItem(true);
+ addItemDecoration(dividerDecoration);
+ mAdapter = new NewsListAdapter(getContext());
+ mAdapter.setOnItemClickListener(new RecyclerArrayAdapter.OnItemClickListener() {
+ @Override
+ public void onItemClick(int position) {
+
+ }
+ });
+
+ setAdapterWithProgress(mAdapter);
+ setRefreshListener(this);
+ new NewsListPresenter(this);
+ isActive = true;
+ }
+
+ @Override
+ public void onRefresh() {
+ mPresenter.getNewMessages(1, 20, mDate);
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ isActive = true;
+ mPresenter.getNewMessages(1, 20, mDate);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ isActive = false;
+ }
+
+ @Override
+ public void setPresenter(NewsListContract.Presenter presenter) {
+ mPresenter = presenter;
+ }
+
+ @Override
+ public boolean isActive() {
+ return isActive;
+ }
+
+ @Override
+ public void showNewsList(StoryList info) {
+ if (info != null) {
+ mAdapter.clear();
+ mAdapter.addAll(info.getStories());
+ }
+ }
+}
diff --git a/module_news/src/main/java/com/guiying/module/news/main/NewsListViewAdapter.java b/module_news/src/main/java/com/guiying/module/news/main/NewsListViewAdapter.java
new file mode 100644
index 0000000..4fe1893
--- /dev/null
+++ b/module_news/src/main/java/com/guiying/module/news/main/NewsListViewAdapter.java
@@ -0,0 +1,76 @@
+package com.guiying.module.news.main;
+
+import android.support.v4.view.PagerAdapter;
+import android.view.View;
+import android.view.ViewGroup;
+
+import java.text.DateFormat;
+import java.util.Calendar;
+import java.util.List;
+
+/**
+ * 类说明
+ *
+ * @author 张华洋 2017/4/20 23:41
+ * @version V1.2.0
+ * @name NewsListViewAdapter
+ */
+public class NewsListViewAdapter extends PagerAdapter {
+
+ private final List extends View> mViewList;
+ private final List mTabList;
+ private View mCurrentView;
+
+ public NewsListViewAdapter(List extends View> list, List dates) {
+ mViewList = list;
+ mTabList = dates;
+ }
+
+ @Override
+ public int getCount() {
+ return mViewList == null ? 0 : mViewList.size();
+ }
+
+ @Override
+ public boolean isViewFromObject(View view, Object object) {
+ return view == object;
+ }
+
+ @Override
+ public Object instantiateItem(ViewGroup container, int position) {
+ container.addView((mViewList.get(position)));
+ return mViewList.get(position);
+ }
+
+ @Override
+ public void destroyItem(ViewGroup container, int position, Object object) {
+ container.removeView(mViewList.get(position));
+ }
+
+ @Override
+ public CharSequence getPageTitle(int position) {
+ if (mTabList == null) {
+ return null;
+ }
+ Calendar displayDate = Calendar.getInstance();
+ displayDate.add(Calendar.DAY_OF_YEAR, -position);
+
+ return DateFormat.getDateInstance().format(displayDate.getTime());
+ }
+
+ /**
+ * 获取当前view的方法
+ */
+ View getCurrentView() {
+ return mCurrentView;
+ }
+
+ @Override
+ public void setPrimaryItem(ViewGroup container, int position, Object object) {
+ super.setPrimaryItem(container, position, object);
+ if (mViewList.size() > 0) {
+ mCurrentView = mViewList.get(position);
+ }
+ }
+
+}
diff --git a/module_news/src/main/java/debug/LauncherActivity.java b/module_news/src/main/java/debug/LauncherActivity.java
new file mode 100644
index 0000000..373f765
--- /dev/null
+++ b/module_news/src/main/java/debug/LauncherActivity.java
@@ -0,0 +1,28 @@
+package debug;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+
+import com.guiying.module.news.detail.NewsDetailActivity;
+
+/**
+ * 组件开发模式下,用于传递数据的启动Activity,集成模式下无效
+ *
+ * @author 张华洋
+ * @version V1.2.0
+ * @name LauncherActivity
+ */
+public class LauncherActivity extends AppCompatActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ //在这里传值给需要调试的Activity
+ Intent intent = new Intent(this, NewsDetailActivity.class);
+ intent.putExtra("id", "9500116");
+ startActivity(intent);
+ finish();
+ }
+
+}
diff --git a/news/src/main/java/debug/NewsApplication.java b/module_news/src/main/java/debug/NewsApplication.java
similarity index 62%
rename from news/src/main/java/debug/NewsApplication.java
rename to module_news/src/main/java/debug/NewsApplication.java
index b1ba36d..8bcfdcb 100644
--- a/news/src/main/java/debug/NewsApplication.java
+++ b/module_news/src/main/java/debug/NewsApplication.java
@@ -1,9 +1,11 @@
package debug;
-import com.guiying.common.base.BaseApplication;
-import com.guiying.common.http.HttpClient;
-import com.guiying.common.http.OnResultListener;
-import com.guiying.news.Constants;
+import com.guiying.module.common.base.BaseApplication;
+import com.guiying.module.common.http.DataType;
+import com.guiying.module.common.http.HttpClient;
+import com.guiying.module.common.http.OnResultListener;
+import com.guiying.module.news.Constants;
+import com.guiying.module.news.data.bean.StoryList;
import com.orhanobut.logger.Logger;
/**
@@ -29,13 +31,14 @@ public void onCreate() {
private void login() {
HttpClient client = new HttpClient.Builder()
.baseUrl(Constants.ZHIHU_DAILY_BEFORE_MESSAGE)
- .url("20170225")
+ .url("20170419")
+ .bodyType(DataType.JSON_OBJECT, StoryList.class)
.build();
- client.get(new OnResultListener() {
+ client.get(new OnResultListener() {
@Override
- public void onSuccess(String result) {
- Logger.e(result);
+ public void onSuccess(StoryList result) {
+ Logger.e(result.toString());
}
@Override
diff --git a/module_news/src/main/module/AndroidManifest.xml b/module_news/src/main/module/AndroidManifest.xml
new file mode 100644
index 0000000..d16a659
--- /dev/null
+++ b/module_news/src/main/module/AndroidManifest.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/module_news/src/main/res/layout/activity_news.xml b/module_news/src/main/res/layout/activity_news.xml
new file mode 100644
index 0000000..8508008
--- /dev/null
+++ b/module_news/src/main/res/layout/activity_news.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/module_news/src/main/res/layout/fragment_news.xml b/module_news/src/main/res/layout/fragment_news.xml
new file mode 100644
index 0000000..d0e7792
--- /dev/null
+++ b/module_news/src/main/res/layout/fragment_news.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
diff --git a/module_news/src/main/res/layout/item_news_list.xml b/module_news/src/main/res/layout/item_news_list.xml
new file mode 100644
index 0000000..a559e6e
--- /dev/null
+++ b/module_news/src/main/res/layout/item_news_list.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/module_news/src/main/res/layout/view_news_detail.xml b/module_news/src/main/res/layout/view_news_detail.xml
new file mode 100644
index 0000000..1a8fca3
--- /dev/null
+++ b/module_news/src/main/res/layout/view_news_detail.xml
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/girls/src/main/res/values/colors.xml b/module_news/src/main/res/values/colors.xml
similarity index 100%
rename from girls/src/main/res/values/colors.xml
rename to module_news/src/main/res/values/colors.xml
diff --git a/news/src/main/res/values/dimens.xml b/module_news/src/main/res/values/dimens.xml
similarity index 100%
rename from news/src/main/res/values/dimens.xml
rename to module_news/src/main/res/values/dimens.xml
diff --git a/module_news/src/main/res/values/strings.xml b/module_news/src/main/res/values/strings.xml
new file mode 100644
index 0000000..3ac24fd
--- /dev/null
+++ b/module_news/src/main/res/values/strings.xml
@@ -0,0 +1,9 @@
+
+ News组件
+
+ News
+
+
+ Hello blank fragment
+
+
diff --git a/news/build.gradle b/news/build.gradle
deleted file mode 100644
index 7fd1812..0000000
--- a/news/build.gradle
+++ /dev/null
@@ -1,50 +0,0 @@
-if (isModule.toBoolean()) {
- apply plugin: 'com.android.application'
-} else {
- apply plugin: 'com.android.library'
-}
-
-apply plugin: 'com.neenbedankt.android-apt'
-
-android {
- compileSdkVersion rootProject.ext.compileSdkVersion
- buildToolsVersion rootProject.ext.buildToolsVersion
-
- defaultConfig {
- minSdkVersion rootProject.ext.minSdkVersion
- targetSdkVersion rootProject.ext.targetSdkVersion
- versionCode rootProject.ext.versionCode
- versionName rootProject.ext.versionName
- }
-
- buildTypes {
- release {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- }
- }
-
- sourceSets {
- main {
- if (isModule.toBoolean()) {
- manifest.srcFile 'src/main/debug/AndroidManifest.xml'
- } else {
- manifest.srcFile 'src/main/release/AndroidManifest.xml'
- //release模式下排除debug文件夹中的所有Java文件
- java {
- exclude 'debug/**'
- }
- }
- }
- }
- //设置了resourcePrefix值后,所有的资源名必须以指定的字符串做前缀,否则会报错。
- //但是resourcePrefix这个值只能限定xml里面的资源,并不能限定图片资源,所有图片资源仍然需要手动去修改资源名。
- //resourcePrefix "girls_"
-}
-
-dependencies {
- compile fileTree(dir: 'libs', include: ['*.jar'])
- compile project(':common')
- //router
- apt "com.github.mzule.activityrouter:compiler:$rootProject.aptCompilerVersion"
-}
diff --git a/news/proguard-rules.pro b/news/proguard-rules.pro
deleted file mode 100644
index 1fa287c..0000000
--- a/news/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 D:\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/news/src/main/java/com/guiying/news/News.java b/news/src/main/java/com/guiying/news/News.java
deleted file mode 100644
index a9e21e1..0000000
--- a/news/src/main/java/com/guiying/news/News.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.guiying.news;
-
-import com.github.mzule.activityrouter.annotation.Module;
-
-/**
- * 类说明
- *
- * @author 张华洋 2017/2/15 16:31
- * @version V1.2.0
- * @name news
- */
-
-@Module("news")
-public class News {
-}
diff --git a/news/src/main/java/com/guiying/news/main/NewsActivity.java b/news/src/main/java/com/guiying/news/main/NewsActivity.java
deleted file mode 100644
index 6fc72b1..0000000
--- a/news/src/main/java/com/guiying/news/main/NewsActivity.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package com.guiying.news.main;
-
-import android.os.Bundle;
-import android.view.View;
-import android.widget.Button;
-import android.widget.Toast;
-
-import com.github.mzule.activityrouter.annotation.Router;
-import com.guiying.common.base.BaseActionBarActivity;
-import com.guiying.common.http.HttpClient;
-import com.guiying.common.http.OnResultListener;
-import com.guiying.common.utils.ToastUtils;
-import com.guiying.news.Constants;
-import com.guiying.news.R;
-import com.orhanobut.logger.Logger;
-
-import es.dmoral.toasty.Toasty;
-
-@Router("news")
-public class NewsActivity extends BaseActionBarActivity implements View.OnClickListener {
-
- protected Button mButton;
-
- @Override
- protected int setTitleId() {
- return R.string.news_activity_title;
- }
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- super.setContentView(R.layout.activity_news);
- login();
- initView();
- }
-
-
- /**
- * 在这里模拟登陆,然后拿到sessionId或者Token
- * 这样就能够在组件请求接口了
- */
- private void login() {
- HttpClient client = new HttpClient.Builder()
- .baseUrl(Constants.ZHIHU_DAILY_BEFORE_MESSAGE)
- .url("20170225")
- .build();
- client.get(new OnResultListener() {
-
- @Override
- public void onSuccess(String result) {
- Toasty.info(NewsActivity.this, "Here is some info for you.", Toast.LENGTH_SHORT, true).show();
- }
-
- @Override
- public void onError(int code, String message) {
- Logger.e(message);
- }
-
- @Override
- public void onFailure(String message) {
- Logger.e(message);
- }
- });
- }
-
-
- @Override
- public void onClick(View view) {
- if (view.getId() == R.id.button1) {
- ToastUtils.showShortToast("kannidmfdsfsf ");
- }
- }
-
- private void initView() {
- mButton = (Button) findViewById(R.id.button1);
- mButton.setOnClickListener(NewsActivity.this);
- }
-}
diff --git a/news/src/main/java/com/guiying/news/main/NewsContract.java b/news/src/main/java/com/guiying/news/main/NewsContract.java
deleted file mode 100644
index 8f16780..0000000
--- a/news/src/main/java/com/guiying/news/main/NewsContract.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.guiying.news.main;
-
-import com.guiying.common.base.BasePresenter;
-import com.guiying.common.base.BaseView;
-
-/**
- * 类说明
- *
- * @author 张华洋 2017/2/22 20:33
- * @version V1.2.0
- * @name NewsContract
- */
-public interface NewsContract {
-
- interface View extends BaseView {
-
- }
-
- interface Presenter extends BasePresenter {
-
- }
-
-}
diff --git a/news/src/main/java/com/guiying/news/main/NewsPresenter.java b/news/src/main/java/com/guiying/news/main/NewsPresenter.java
deleted file mode 100644
index 761c2a0..0000000
--- a/news/src/main/java/com/guiying/news/main/NewsPresenter.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.guiying.news.main;
-
-/**
- * 类说明
- *
- * @author 张华洋 2017/2/22 20:33
- * @version V1.2.0
- * @name GirlsPresenter
- */
-public class NewsPresenter {
-}
diff --git a/news/src/main/java/com/guiying/news/main/NewsView.java b/news/src/main/java/com/guiying/news/main/NewsView.java
deleted file mode 100644
index e4954b7..0000000
--- a/news/src/main/java/com/guiying/news/main/NewsView.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.guiying.news.main;
-
-/**
- * 类说明
- *
- * @author 张华洋 2017/2/22 20:33
- * @version V1.2.0
- * @name GirlsView
- */
-
-
-public class NewsView {
-}
diff --git a/news/src/main/release/AndroidManifest.xml b/news/src/main/release/AndroidManifest.xml
deleted file mode 100644
index 2d4f46c..0000000
--- a/news/src/main/release/AndroidManifest.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
diff --git a/news/src/main/res/layout/activity_news.xml b/news/src/main/res/layout/activity_news.xml
deleted file mode 100644
index 86d9029..0000000
--- a/news/src/main/res/layout/activity_news.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/news/src/main/res/values/colors.xml b/news/src/main/res/values/colors.xml
deleted file mode 100644
index d781ec5..0000000
--- a/news/src/main/res/values/colors.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
diff --git a/news/src/main/res/values/strings.xml b/news/src/main/res/values/strings.xml
deleted file mode 100644
index fc802ec..0000000
--- a/news/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
- News
-
- News
-
-
diff --git a/screenshots/Screenshot_1.png b/screenshots/Screenshot_1.png
new file mode 100644
index 0000000..4edf537
Binary files /dev/null and b/screenshots/Screenshot_1.png differ
diff --git a/screenshots/Screenshot_2.png b/screenshots/Screenshot_2.png
new file mode 100644
index 0000000..7fb562d
Binary files /dev/null and b/screenshots/Screenshot_2.png differ
diff --git a/screenshots/Screenshot_3.png b/screenshots/Screenshot_3.png
new file mode 100644
index 0000000..2e652f5
Binary files /dev/null and b/screenshots/Screenshot_3.png differ
diff --git a/screenshots/Screenshot_4.png b/screenshots/Screenshot_4.png
new file mode 100644
index 0000000..3c7b130
Binary files /dev/null and b/screenshots/Screenshot_4.png differ
diff --git a/screenshots/develper.PNG b/screenshots/develper.PNG
new file mode 100644
index 0000000..9d6b8b6
Binary files /dev/null and b/screenshots/develper.PNG differ
diff --git a/settings.gradle b/settings.gradle
index 04f35b4..4e334dd 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,4 +1,6 @@
-include ':app',
- ':girls',
- ':news',
- ':common'
+include ':lib_common',
+ ':module_app',
+ ':module_main',
+ ':module_girls',
+ ':module_news'
+
diff --git a/versions.gradle b/versions.gradle
new file mode 100644
index 0000000..4a8a289
--- /dev/null
+++ b/versions.gradle
@@ -0,0 +1,121 @@
+/**
+ * Shared file between builds so that they can all use the same dependencies and
+ * maven repositories.
+ **/
+ext.deps = [:]
+
+def versions = [:]
+versions.android_gradle_plugin = "3.0.1"
+versions.kotlin = "1.1.51"
+versions.support = "27.0.2"
+versions.multidex = "1.0.2"
+versions.constraint_layout = "1.0.2"
+versions.dagger = "2.11"
+versions.glide = "3.8.0"
+versions.rxjava2 = "2.1.7"
+versions.rx_android = "2.0.1"
+versions.retrofit = "2.3.0"
+versions.event_bus = "3.1.1"
+versions.photo_view = "2.0.0"
+versions.persistent_cookie = "v1.0.1"
+versions.gson = "2.8.2"
+versions.qmui = "1.0.4"
+versions.flow_layout = "1.0.3"
+versions.swipe_recycler = "1.1.3"
+versions.easy_recycler = "4.4.2"
+versions.permission = "1.1.2"
+versions.utils = "1.10.0"
+versions.top_snackbar = "1.1.1"
+versions.litepal = "1.6.1"
+versions.toasty = "1.1.3"
+versions.logger = "1.15"
+versions.material_dialog = "0.9.6.0"
+//Arouter
+versions.arouter_compiler = "1.1.4"
+versions.arouter_api = "1.3.1"
+
+
+
+def deps = [:]
+
+def support = [:]
+support.annotations = "com.android.support:support-annotations:$versions.support"
+support.app_compat = "com.android.support:appcompat-v7:$versions.support"
+support.v13 = "com.android.support:support-v13:$versions.support"
+support.percent = "com.android.support:percent:$versions.support"
+support.recyclerview = "com.android.support:recyclerview-v7:$versions.support"
+support.cardview = "com.android.support:cardview-v7:$versions.support"
+support.design = "com.android.support:design:$versions.support"
+support.v4 = "com.android.support:support-v4:$versions.support"
+support.core_utils = "com.android.support:support-core-utils:$versions.support"
+support.multidex = "com.android.support:multidex:$versions.multidex"
+deps.support = support
+
+
+def retrofit = [:]
+retrofit.runtime = "com.squareup.retrofit2:retrofit:$versions.retrofit"
+retrofit.adapter = "com.squareup.retrofit2:adapter-rxjava2:$versions.retrofi"
+retrofit.gson = "com.squareup.retrofit2:converter-gson:$versions.retrofit"
+deps.retrofit = retrofit
+
+
+def dagger = [:]
+dagger.runtime = "com.google.dagger:dagger:$versions.dagger"
+dagger.android = "com.google.dagger:dagger-android:$versions.dagger"
+dagger.android_support = "com.google.dagger:dagger-android-support:$versions.dagger"
+dagger.compiler = "com.google.dagger:dagger-compiler:$versions.dagger"
+dagger.android_support_compiler = "com.google.dagger:dagger-android-processor:$versions.dagger"
+deps.dagger = dagger
+
+
+def kotlin = [:]
+kotlin.stdlib = "org.jetbrains.kotlin:kotlin-stdlib-jre7:$versions.kotlin"
+kotlin.test = "org.jetbrains.kotlin:kotlin-test-junit:$versions.kotlin"
+kotlin.plugin = "org.jetbrains.kotlin:kotlin-gradle-plugin:$versions.kotlin"
+deps.kotlin = kotlin
+
+//view
+deps.constraint_layout = "com.android.support.constraint:constraint-layout:$versions.constraint_layout"
+deps.qmui = "com.qmuiteam:qmui:$versions.qmui"
+deps.flow_layout = "com.zhy:flowlayout-lib:$versions.flow_layout"
+deps.swipe_recycler = "com.yanzhenjie:recyclerview-swipe:$versions.swipe_recycler"
+deps.easy_recycler = "com.jude:easyrecyclerview:$versions.easy_recycler"
+deps.photo_view = "com.github.chrisbanes:PhotoView:$versions.photo_view"
+deps.material_dialog = "com.afollestad.material-dialogs:core:$versions.material_dialog"
+
+deps.android_gradle_plugin = "com.android.tools.build:gradle:$versions.android_gradle_plugin"
+deps.rxjava2 = "io.reactivex.rxjava2:rxjava:$versions.rxjava2"
+deps.rx_android = "io.reactivex.rxjava2:rxandroid:$versions.rx_android"
+//other
+deps.glide = "com.github.bumptech.glide:glide:$versions.glide"
+deps.event_bus = "org.greenrobot:eventbus:$versions.event_bus"
+deps.persistent_cookie = "com.github.franmontiel:PersistentCookieJar:$versions.persistent_cookie"
+deps.gson = "com.google.code.gson:gson:$versions.gson"
+deps.permission = "com.yanzhenjie:permission:$versions.permission"
+deps.utils = "com.blankj:utilcode:$versions.utils"
+deps.top_snackbar ="com.androidadvance:topsnackbar:$versions.top_snackbar"
+deps.litepal = "org.litepal.android:core:$versions.litepal"
+deps.toasty = "com.github.GrenderG:Toasty:$versions.toasty"
+deps.logger = "com.orhanobut:logger:$versions.logger"
+deps.arouter_api = "com.alibaba:arouter-api:$versions.arouter_api"
+deps.arouter_compiler = "com.alibaba:arouter-compiler:$versions.arouter_compiler"
+
+ext.deps = deps
+
+def build_versions = [:]
+build_versions.min_sdk = 16
+build_versions.target_sdk = 27
+build_versions.build_tools = "27.0.2"
+ext.build_versions = build_versions
+
+
+def addRepos(RepositoryHandler handler) {
+ handler.google()
+ handler.jcenter()
+ handler.mavenCentral()
+ //Add the JitPack repository
+ handler.maven { url "https://jitpack.io" }
+ handler.maven{ url 'http://maven.aliyun.com/nexus/content/groups/public/'}
+}
+
+ext.addRepos = this.&addRepos