master 3b367d5ca83d cached
182 files
234.2 KB
67.1k tokens
452 symbols
1 requests
Download .txt
Showing preview only (295K chars total). Download the full file or copy to clipboard to get everything.
Repository: ccj659/clean-project-architecture
Branch: master
Commit: 3b367d5ca83d
Files: 182
Total size: 234.2 KB

Directory structure:
gitextract_uy9zytuq/

├── .gitignore
├── .idea/
│   ├── gradle.xml
│   ├── markdown-navigator/
│   │   └── profiles_settings.xml
│   ├── markdown-navigator.xml
│   ├── misc.xml
│   ├── modules.xml
│   ├── runConfigurations.xml
│   └── vcs.xml
├── README.md
├── README_MODULE.md
├── README_MVP.md
├── app/
│   ├── .gitignore
│   ├── build.gradle
│   ├── libs/
│   │   └── xUtils-2.6.14.jar
│   ├── proguard-rules.pro
│   └── src/
│       ├── androidTest/
│       │   └── java/
│       │       └── com/
│       │           └── efly/
│       │               └── flyhelper/
│       │                   └── ApplicationTest.java
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── efly/
│       │   │           └── flyhelper/
│       │   │               ├── AppApplication.java
│       │   │               ├── MainActivity.java
│       │   │               └── adapter/
│       │   │                   └── FragmentAdapter.java
│       │   └── res/
│       │       ├── drawable/
│       │       │   ├── ic_dashboard_black_24dp.xml
│       │       │   ├── ic_home_black_24dp.xml
│       │       │   └── ic_notifications_black_24dp.xml
│       │       ├── layout/
│       │       │   └── activity_bottom_navigation.xml
│       │       ├── menu/
│       │       │   └── menu_bottom_navigation.xml
│       │       └── values/
│       │           └── strings.xml
│       └── test/
│           └── java/
│               └── com/
│                   └── efly/
│                       └── flyhelper/
│                           └── ExampleUnitTest.java
├── base/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       ├── androidTest/
│       │   └── java/
│       │       └── com/
│       │           └── ccj/
│       │               └── base/
│       │                   └── ExampleInstrumentedTest.java
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── ccj/
│       │   │           └── base/
│       │   │               ├── AppManager.java
│       │   │               ├── Constants.java
│       │   │               ├── RouterConstants.java
│       │   │               ├── adapter/
│       │   │               │   ├── CommonRcvAdapter.java
│       │   │               │   ├── bean/
│       │   │               │   │   ├── AdapterBean.java
│       │   │               │   │   └── AdapterGroupBean.java
│       │   │               │   ├── item/
│       │   │               │   │   └── AdapterItem.java
│       │   │               │   └── util/
│       │   │               │       ├── IAdapter.java
│       │   │               │       └── ItemTypeUtil.java
│       │   │               ├── api/
│       │   │               │   ├── APIService.java
│       │   │               │   ├── RetrofitRequest.java
│       │   │               │   └── VolleyUtils.java
│       │   │               ├── base/
│       │   │               │   ├── BaseActivity.java
│       │   │               │   ├── BaseApplication.java
│       │   │               │   ├── BaseBean.java
│       │   │               │   ├── BaseFragment.java
│       │   │               │   ├── BaseModel.java
│       │   │               │   ├── BasePresenter.java
│       │   │               │   ├── BaseView.java
│       │   │               │   └── Constants.java
│       │   │               ├── bean/
│       │   │               │   ├── User.java
│       │   │               │   └── UserDetail.java
│       │   │               ├── utils/
│       │   │               │   ├── BitmapUtil.java
│       │   │               │   ├── LruBitmapCache.java
│       │   │               │   ├── SerializableUtil.java
│       │   │               │   ├── SharedPreferenceUtil.java
│       │   │               │   ├── TDeviceUtils.java
│       │   │               │   ├── TLog.java
│       │   │               │   ├── ToastUtil.java
│       │   │               │   ├── eventbus/
│       │   │               │   │   └── EventUtils.java
│       │   │               │   └── router/
│       │   │               │       ├── LoginModuleService.java
│       │   │               │       ├── RounterInterceptor.java
│       │   │               │       ├── RounterSerialization.java
│       │   │               │       ├── RouterService.java
│       │   │               │       └── RouterUtils.java
│       │   │               └── view/
│       │   │                   ├── SuperRecyclerView.java
│       │   │                   └── list/
│       │   │                       ├── OnAppBarSkipListener.java
│       │   │                       └── OnLoadNextListener.java
│       │   └── res/
│       │       ├── anim/
│       │       │   ├── anim_bottom_in.xml
│       │       │   ├── anim_bottom_out.xml
│       │       │   ├── dialog_enter.xml
│       │       │   ├── dialog_exit.xml
│       │       │   ├── footer_menu_slide_in.xml
│       │       │   ├── footer_menu_slide_out.xml
│       │       │   ├── in_from_bottom.xml
│       │       │   ├── in_from_top.xml
│       │       │   ├── out_to_bottom.xml
│       │       │   └── out_to_top.xml
│       │       ├── drawable/
│       │       │   ├── bg_toolbar.xml
│       │       │   └── btn_ripple.xml
│       │       ├── layout/
│       │       │   └── base_layout_tool_bar.xml
│       │       └── values/
│       │           ├── colors.xml
│       │           ├── dimens.xml
│       │           ├── strings.xml
│       │           └── styles.xml
│       └── test/
│           └── java/
│               └── com/
│                   └── ccj/
│                       └── base/
│                           └── ExampleUnitTest.java
├── build.gradle
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── module_home/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── ccj/
│           │           └── home/
│           │               ├── HomeFragment.java
│           │               └── MainActivity.java
│           ├── release/
│           │   └── AndroidManifest.xml
│           └── res/
│               ├── drawable/
│               │   └── ic_launcher_background.xml
│               ├── drawable-v24/
│               │   └── ic_launcher_foreground.xml
│               ├── layout/
│               │   ├── activity_main.xml
│               │   └── home_fragment_haojia_home.xml
│               ├── mipmap-anydpi-v26/
│               │   ├── ic_launcher.xml
│               │   └── ic_launcher_round.xml
│               └── values/
│                   ├── colors.xml
│                   ├── strings.xml
│                   └── styles.xml
├── module_meizi/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── ccj/
│           │           └── meizi/
│           │               ├── adapter/
│           │               │   └── MeiziRcvAdapter.java
│           │               ├── api/
│           │               │   ├── MeiziAPIServiceImp.java
│           │               │   └── MeiziRetrofitImp.java
│           │               ├── bean/
│           │               │   └── Meizhi.java
│           │               ├── debug/
│           │               │   ├── ContainActivity.java
│           │               │   └── MainActivity.java
│           │               ├── holder/
│           │               │   └── MeiziItemHolder.java
│           │               ├── ui/
│           │               │   ├── detail/
│           │               │   │   └── MeiziDetailActivity.java
│           │               │   └── main/
│           │               │       ├── MeiZhiContract.java
│           │               │       ├── MeiZhiFragment.java
│           │               │       └── MeiZhiPresenter.java
│           │               └── utils/
│           │                   └── DateStringUtils.java
│           ├── release/
│           │   └── AndroidManifest.xml
│           └── res/
│               ├── drawable/
│               │   └── ic_launcher_background.xml
│               ├── drawable-v24/
│               │   └── ic_launcher_foreground.xml
│               ├── layout/
│               │   ├── activity_contain.xml
│               │   ├── activity_main.xml
│               │   ├── activity_meizi_detail.xml
│               │   ├── fragment_meizi.xml
│               │   └── item_meizi_item.xml
│               ├── mipmap-anydpi-v26/
│               │   ├── ic_launcher.xml
│               │   └── ic_launcher_round.xml
│               └── values/
│                   ├── colors.xml
│                   ├── strings.xml
│                   └── styles.xml
├── module_user/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── ccj/
│           │           └── login/
│           │               ├── api/
│           │               │   ├── LoginAPIServiceImp.java
│           │               │   └── LoginRetrofitImp.java
│           │               ├── debug/
│           │               │   ├── LoginApplication.java
│           │               │   └── MainActivity.java
│           │               ├── service/
│           │               │   └── CheckLoginService.java
│           │               └── ui/
│           │                   ├── login/
│           │                   │   ├── LoginActivity.java
│           │                   │   ├── LoginContract.java
│           │                   │   ├── LoginModel.java
│           │                   │   └── LoginPresenter.java
│           │                   ├── register/
│           │                   │   └── RegisterActivity.java
│           │                   └── user/
│           │                       └── UserFragment.java
│           ├── release/
│           │   └── AndroidManifest.xml
│           └── res/
│               ├── layout/
│               │   ├── activity_login.xml
│               │   ├── activity_main.xml
│               │   ├── login_fragment_register.xml
│               │   └── user_fragment_user_home.xml
│               └── values/
│                   ├── colors.xml
│                   ├── strings.xml
│                   └── styles.xml
├── module_video/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── ccj/
│           │           └── video/
│           │               ├── VideoFragment.java
│           │               ├── debug/
│           │               │   ├── MainActivity.java
│           │               │   └── VideoApplication.java
│           │               ├── service/
│           │               │   └── VideoServiceImpl.java
│           │               └── ui/
│           │                   ├── TakePhotoActivity.java
│           │                   ├── TakePhotoContract.java
│           │                   ├── TakePhotoModel.java
│           │                   └── TakePhotoPresenter.java
│           ├── release/
│           │   └── AndroidManifest.xml
│           └── res/
│               ├── layout/
│               │   ├── activity_main.xml
│               │   ├── activity_take_photo.xml
│               │   └── video_fragment_video_home.xml
│               └── values/
│                   ├── colors.xml
│                   ├── strings.xml
│                   └── styles.xml
└── settings.gradle

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures


================================================
FILE: .idea/gradle.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="GradleSettings">
    <option name="linkedExternalProjectsSettings">
      <GradleProjectSettings>
        <option name="distributionType" value="DEFAULT_WRAPPED" />
        <option name="externalProjectPath" value="$PROJECT_DIR$" />
        <option name="modules">
          <set>
            <option value="$PROJECT_DIR$" />
            <option value="$PROJECT_DIR$/app" />
            <option value="$PROJECT_DIR$/base" />
            <option value="$PROJECT_DIR$/module_home" />
            <option value="$PROJECT_DIR$/module_meizi" />
            <option value="$PROJECT_DIR$/module_user" />
            <option value="$PROJECT_DIR$/module_video" />
          </set>
        </option>
        <option name="resolveModulePerSourceSet" value="false" />
      </GradleProjectSettings>
    </option>
  </component>
</project>

================================================
FILE: .idea/markdown-navigator/profiles_settings.xml
================================================
<component name="MarkdownNavigator.ProfileManager">
  <settings default="" pdf-export="" />
</component>

================================================
FILE: .idea/markdown-navigator.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="MarkdownProjectSettings">
    <PreviewSettings splitEditorLayout="SPLIT" splitEditorPreview="PREVIEW" useGrayscaleRendering="false" zoomFactor="1.0" maxImageWidth="0" showGitHubPageIfSynced="false" allowBrowsingInPreview="false" synchronizePreviewPosition="true" highlightPreviewType="NONE" highlightFadeOut="5" highlightOnTyping="true" synchronizeSourcePosition="true" verticallyAlignSourceAndPreviewSyncPosition="true" showSearchHighlightsInPreview="false" showSelectionInPreview="true">
      <PanelProvider>
        <provider providerId="com.vladsch.idea.multimarkdown.editor.swing.html.panel" providerName="Default - Swing" />
      </PanelProvider>
    </PreviewSettings>
    <ParserSettings gitHubSyntaxChange="false">
      <PegdownExtensions>
        <option name="ABBREVIATIONS" value="false" />
        <option name="ANCHORLINKS" value="true" />
        <option name="ASIDE" value="false" />
        <option name="ATXHEADERSPACE" value="true" />
        <option name="AUTOLINKS" value="true" />
        <option name="DEFINITIONS" value="false" />
        <option name="DEFINITION_BREAK_DOUBLE_BLANK_LINE" value="false" />
        <option name="FENCED_CODE_BLOCKS" value="true" />
        <option name="FOOTNOTES" value="false" />
        <option name="HARDWRAPS" value="false" />
        <option name="HTML_DEEP_PARSER" value="false" />
        <option name="INSERTED" value="false" />
        <option name="QUOTES" value="false" />
        <option name="RELAXEDHRULES" value="true" />
        <option name="SMARTS" value="false" />
        <option name="STRIKETHROUGH" value="true" />
        <option name="SUBSCRIPT" value="false" />
        <option name="SUPERSCRIPT" value="false" />
        <option name="SUPPRESS_HTML_BLOCKS" value="false" />
        <option name="SUPPRESS_INLINE_HTML" value="false" />
        <option name="TABLES" value="true" />
        <option name="TASKLISTITEMS" value="true" />
        <option name="TOC" value="false" />
        <option name="WIKILINKS" value="true" />
      </PegdownExtensions>
      <ParserOptions>
        <option name="COMMONMARK_LISTS" value="true" />
        <option name="DUMMY" value="false" />
        <option name="EMOJI_SHORTCUTS" value="true" />
        <option name="FLEXMARK_FRONT_MATTER" value="false" />
        <option name="GFM_LOOSE_BLANK_LINE_AFTER_ITEM_PARA" value="false" />
        <option name="GFM_TABLE_RENDERING" value="true" />
        <option name="GITBOOK_URL_ENCODING" value="false" />
        <option name="GITHUB_EMOJI_URL" value="false" />
        <option name="GITHUB_LISTS" value="false" />
        <option name="GITHUB_WIKI_LINKS" value="true" />
        <option name="JEKYLL_FRONT_MATTER" value="false" />
        <option name="SIM_TOC_BLANK_LINE_SPACER" value="true" />
      </ParserOptions>
    </ParserSettings>
    <HtmlSettings headerTopEnabled="false" headerBottomEnabled="false" bodyTopEnabled="false" bodyBottomEnabled="false" embedUrlContent="false" addPageHeader="true">
      <GeneratorProvider>
        <provider providerId="com.vladsch.idea.multimarkdown.editor.swing.html.generator" providerName="Default Swing HTML Generator" />
      </GeneratorProvider>
      <headerTop />
      <headerBottom />
      <bodyTop />
      <bodyBottom />
    </HtmlSettings>
    <CssSettings previewScheme="UI_SCHEME" cssUri="" isCssUriEnabled="false" isCssTextEnabled="false" isDynamicPageWidth="true">
      <StylesheetProvider>
        <provider providerId="com.vladsch.idea.multimarkdown.editor.swing.html.css" providerName="Default Swing Stylesheet" />
      </StylesheetProvider>
      <ScriptProviders />
      <cssText />
    </CssSettings>
    <HtmlExportSettings updateOnSave="false" parentDir="$ProjectFileDir$" targetDir="$ProjectFileDir$" cssDir="" scriptDir="" plainHtml="false" imageDir="" copyLinkedImages="false" imageUniquifyType="0" targetExt="" useTargetExt="false" noCssNoScripts="false" linkToExportedHtml="true" exportOnSettingsChange="true" regenerateOnProjectOpen="false" />
    <LinkMapSettings>
      <textMaps />
    </LinkMapSettings>
  </component>
</project>

================================================
FILE: .idea/misc.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="NullableNotNullManager">
    <option name="myDefaultNullable" value="android.support.annotation.Nullable" />
    <option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
    <option name="myNullables">
      <value>
        <list size="4">
          <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
          <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
          <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
          <item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
        </list>
      </value>
    </option>
    <option name="myNotNulls">
      <value>
        <list size="4">
          <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
          <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
          <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
          <item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
        </list>
      </value>
    </option>
  </component>
  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
    <output url="file://$PROJECT_DIR$/build/classes" />
  </component>
  <component name="ProjectType">
    <option name="id" value="Android" />
  </component>
</project>

================================================
FILE: .idea/modules.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="ProjectModuleManager">
    <modules>
      <module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
      <module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
      <module fileurl="file://$PROJECT_DIR$/base/base.iml" filepath="$PROJECT_DIR$/base/base.iml" />
      <module fileurl="file://$PROJECT_DIR$/base/base.iml" filepath="$PROJECT_DIR$/base/base.iml" />
      <module fileurl="file://$PROJECT_DIR$/.idea/clean-project-architecture-check.iml" filepath="$PROJECT_DIR$/.idea/clean-project-architecture-check.iml" />
      <module fileurl="file://$PROJECT_DIR$/clean-project-architecture_back.iml" filepath="$PROJECT_DIR$/clean-project-architecture_back.iml" />
      <module fileurl="file://$PROJECT_DIR$/module_home/module_home.iml" filepath="$PROJECT_DIR$/module_home/module_home.iml" />
      <module fileurl="file://$PROJECT_DIR$/module_home/module_home.iml" filepath="$PROJECT_DIR$/module_home/module_home.iml" />
      <module fileurl="file://$PROJECT_DIR$/module_meizi/module_meizi.iml" filepath="$PROJECT_DIR$/module_meizi/module_meizi.iml" />
      <module fileurl="file://$PROJECT_DIR$/module_meizi/module_meizi.iml" filepath="$PROJECT_DIR$/module_meizi/module_meizi.iml" />
      <module fileurl="file://$PROJECT_DIR$/module_user/module_user.iml" filepath="$PROJECT_DIR$/module_user/module_user.iml" />
      <module fileurl="file://$PROJECT_DIR$/module_user/module_user.iml" filepath="$PROJECT_DIR$/module_user/module_user.iml" />
      <module fileurl="file://$PROJECT_DIR$/module_video/module_video.iml" filepath="$PROJECT_DIR$/module_video/module_video.iml" />
      <module fileurl="file://$PROJECT_DIR$/module_video/module_video.iml" filepath="$PROJECT_DIR$/module_video/module_video.iml" />
    </modules>
  </component>
</project>

================================================
FILE: .idea/runConfigurations.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="RunConfigurationProducerService">
    <option name="ignoredProducers">
      <set>
        <option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
      </set>
    </option>
  </component>
</project>

================================================
FILE: .idea/vcs.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="VcsDirectoryMappings">
    <mapping directory="$PROJECT_DIR$" vcs="Git" />
  </component>
</project>

================================================
FILE: README.md
================================================





# clean-project-architecture


更新 2018/2/1 组件化重构,修改方式为 主容器app+业务module模式.


----

组件化项目框架,以及主流的项目架构(MVP+RxJava+Retrofit),以后会不断完善.




- [MVP传送门](https://github.com/ccj659/clean-project-architecture/blob/master/README_MVP.md)

- [组件化传送门](https://github.com/ccj659/clean-project-architecture/blob/master/README_MODULE.md)




参考界面:
![](http://i.imgur.com/EnBxczU.gif)

================================================
FILE: README_MODULE.md
================================================
# 客户端组件化探究

**项目地址** [https://github.com/ccj659/clean-project-architecture](https://github.com/ccj659/clean-project-architecture)



## 1.组件化的产生背景

随着业务的增多,迭代版本的增加,

模块化开发, 业务解耦, 业务独立进行测试,编译,运行,想想都惊喜~

如果不想忍受超长的编译时间,不想忍受类之间的强耦合,受够了满屏的不相干的文件,那么.....

为了你的"代码洁癖",还有项目的未来, 组件化, 势在必行.....


## 2.普通开发模式的弊端

1、实际业务变化非常快,但是单一工程的业务模块耦合度太高,牵一发而动全身,每次改一个地方都很小心.

2、对工程所做的任何修改都必须要编译整个工程;

3、团队协同开发存在较多的冲突.不得不花费更多的时间去沟通和协调,并且在开发过程中,任何一位成员没办法专注于自己的功能点,影响开发效率;

4、不能灵活的对业务模块进行配置和组装;



## 3.什么是组件化


	组件化是 编程思想"高内聚,低耦合"的一种体现, 是 业务独立化, 粒度最小化,可移植的功能模块.



1.页面上的每个 独立的 可视/可交互区域视为一个组件;

2.每个组件对应一个工程目录,组件所需的各种资源都在这个目录下就近维护;

3.每个组件相对独立,页面只不过是组件的容器,组件自由组合形成功能完整的界面;

4.当不需要某个组件,或者想要替换组件时,可以整个目录删除/替换。







## 4.组件化会解决 目前项目中哪些问题?

1.急需解决 项目编译时间过长问题!

2.急需团队开发,解决提交代码 牵一发动全身的问题!

3.解决开发效率低下问题.

4.解决项目越来越臃肿,分层不明确,,难以维护问题.

5.减少 学习成本.




## 5.项目如何进行组件化?





**在框架中的 项目组件化是这样的~**

![未命名文件 (6).png](http://upload-images.jianshu.io/upload_images/1848340-4011e008d6533cc2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


**反映在代码目录结构上,就是如下所示~**

![image.png](http://upload-images.jianshu.io/upload_images/1848340-1681c9f78b3f90c9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


**根据上述结构图,我对目前的项目做了如下调整.**

1.将项目的业务模块(主页,好价,好文,好物,个人中心,关注),作为独立的application module. 每一位业务的开发人员,只需要管理自己的module即可,避免直接或者间接修改他人代码导致的问题.而且,开发期间,自住选择必要中间件的依赖,自住开发风格(MVP,MVC,etc).

2.将中间组件(通用list_item组件,分享组件,推送组件,内置浏览器组件,通用view组件,以及通用跳转等等),作为library module进行选择性依赖.

3.将底层库(网络请求库,db库,File库,图片库等等),作为一个底层library库,独立进行版本控制,用@aar-v1.0.1 来引用,这样可以防止,他人的随意改动,提高版本切换之间的稳定性.


## 6.问题五连


#### Q1.如何将工程拆分成有机的整体,组件单独运行?

利用Android studio 自带的gradle 来管理. 我们可以使用grovxy脚本,来对 是否是组件状态进行切换.

![image.png](http://upload-images.jianshu.io/upload_images/1848340-46ab2ef7c01244f3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


####  Q2.如何分别执行独立运行,合并运行的代码?
当项目是APPlication时候,需要有category为LAUNCHER的入口activity.
当项目是lib的时候,不能存在入口activity.所以要分别建立两套配置.

还要注意,如果想要保持主题样式通用, 主app下,’theme’'ico','label'等等,在module中都不能存在.

![image.png](http://upload-images.jianshu.io/upload_images/1848340-a531f85dd9d77563.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

####  Q3.代码都分离了,如何进行带参跳转,相互调用?
首先,考虑到解耦, 可以把ARouter的所有跳转都进行封装.以后待项目成熟,我会用自己的Router.
	另外,module内,可以用传统方式传递和用路由器传递都行.
![image.png](http://upload-images.jianshu.io/upload_images/1848340-8bf31d3c74218ad9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)



####  Q4.是啊,分业务是好,但是代码合并后,如果避免存在资源名冲突?

1.第三方依赖的问题,依赖尽量放在base中.这样,gradle会自动去重.


2.资源名重复,在编码的时候 添加resourcePrefix "video"+"_",强制人员添加前缀(但是对drawable不支持,需用户自己增加前缀).

3.将资源统一放在一个module(比如Base中),但是编译会增加时间.(不太复合资源解耦 原则)

####  Q5.代码那么多,把之前的都解耦了,如何避免后期继续耦合?

针对这个问题, 组件之间必须针对接口编程,杜绝面向实现编程.
另外, 我们在设计一个组件的时候, 要尽量用继承封装多态去解决问题.




## 7.如何实现



**1.在`gradle.properties` 增加一个变量**

```
# true代表模块开发,false代表合并到主app.
#模式切换开关
isModule=false

```

**2.在每个业务module的`build.gradle`里面添加**

```
//根据isModule值进行切换 是否为lib或者app
if (isModule.toBoolean()) {
    apply plugin: 'com.android.application'
} else {
    apply plugin: 'com.android.library'
}
```

**3.建立两个`AndroidManifest.xml`,进行切换**

大家都知道,当项目是APPlication时候,需要有category为`LAUNCHER`的入口activity.
而当项目是lib的时候,不能存在入口activity.所以要分别建立两套`AndroidManifest.xml `,还要注意,如果想要保持主题样式通用, 主app项目下的`theme`,'ico','label'等等,在module中都不能存在.
进行如下配置.
![image.png](http://upload-images.jianshu.io/upload_images/1848340-92b4a7213a9ad8d1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


**4.建立两个`AndroidManifest.xml`,进行切换**

```
    sourceSets {
        main {
            if (isModule.toBoolean()) {
                manifest.srcFile 'src/main/AndroidManifest.xml'
            } else {
                manifest.srcFile 'src/main/release/AndroidManifest.xml'
                java {
                    //release 时 debug 目录下文件不需要合并到主工程
                    exclude '**/debug/**'
                }
            }
        }
    }
```

**5.业务组件不需要混淆代码.**
一旦业务组件的代码被混淆,而这时候代码中又出现了bug,将很难根据日志找出导致bug的原因;


**6.当ismodule开关为true时,每个module可独立运行.**

![image.png](http://upload-images.jianshu.io/upload_images/1848340-ddb00f60544243a3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)



## 应用效果


![compone1.gif](http://upload-images.jianshu.io/upload_images/1848340-a3af30d73a24fdaa.gif?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)




![compone2.gif](http://upload-images.jianshu.io/upload_images/1848340-06e31929d2927460.gif?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)




#总结


## 优点

1.业务module独立,降低业务的学习成本.

2.模块解耦, 代码架构更加清晰,降低项目的维护难度.

3.随着项目的代码增加,单独编译,单独运行,明显减少代码编译时间.

4.适合于团队开发.


## 不足


1.switch中 case必须是 静态常亮,所以在引用  library中 的 资源(R.id.button) 时, 需要改为if else. 这个还需要找到解决方案...


2.模块间 数据交互,比较繁琐

3.路由器模块还不太成熟

4.实际开展过程,抽丝剥茧,过程会很痛苦.

5.还存在潜在问题.

## 后期计划

 1.提高编译速度, 将 依赖 由 整个项目进行编译, 变为依赖 aar包, 减少编译时间.

 2.搭建一个私有的maven仓库,将我们开发好的组件上传到这个私有的maven仓库上,然后内部开发人员就可以像引用三方库那样轻而易举的将组件引入到项目中

3. 完善复合项目的事件路由Router,



## 参考

 [aar的使用](http://blog.csdn.net/zxw136511485/article/details/52777286)

 [http://blog.csdn.net/guiying712/article/details/55213884](http://blog.csdn.net/guiying712/article/details/55213884)

 [Android彻底组件化demo发布](https://www.jianshu.com/p/59822a7b2fad)

================================================
FILE: README_MVP.md
================================================




2018/2/1 更新

	1.完善组件化,宿主构建. 所以,mvp写法请参照`lib_base`和`module_meizi`. ps妹子图又更新了一波,😄



2016/11/1 更新 用gank.io的妹子数据

	1.添加get请求.

	2.完成妹子Meterial Design 风格的list界面.


参考界面:
![](http://i.imgur.com/EnBxczU.gif)

-------
2016/7/23 更新  热修复相关

csdn: http://blog.csdn.net/ccj659/article/details/52004522
简书: http://www.jianshu.com/p/2301d40dbb33

[热修复]--源码级分析以及项目实践 谢谢大家指正~

----------


android架构篇
===================
mvp+rxjava+retrofit+eventBus
===================
----------

高层不应该知道低层的细节,应该是面向抽象的编程。业务的实现交给实现的接口的类。高层只负责调用。

----------
首先,要介绍一下一个项目中好架构的好处:好的软件设计必须能够帮助开发者发展和扩充解决方案,保持代码清晰健壮,并且可扩展,易于维护,而不必每件事都重写代码。面对软件存在的问题,必须遵守SOLID原则(面向对象五大原则),不要过度工程化,尽可能降低框架中模块的依赖性。

----------
之前的一段时间,学习了一些新的技术,并把自己关注的技术整合了一下,是的,相似的技术有很多,自己择优选择,将它们的思想和技术应用到了自己的搭建的项目框架中.
限于自己能力水平有限,自己搭建的项目可能还有些不足,欢迎大家指正批评,让自己的想法和设计思想走向正轨.O(∩_∩)O谢谢~

在框架中
-------------
 *1.**项目整体框架: 利用google-clean-architecture的思想 来负责项目的整体MVP架构.***

 - MVP是模型(Model)、视图(View)、主持人(Presenter)的缩写,分别代表项目中3个不同的模块。**我以登录为例子,进行说明.**

![这里写图片描述](http://img.blog.csdn.net/20160712153716629)

  这里每个业务首先要有一个管理接口Contract,在这里面有三个接口来面向接口编程, (Model),(View),(Presenter). 将三个接口放在一起便于管理.

![这里写图片描述](http://img.blog.csdn.net/20160712153741743)
```java
   /**
 * 登录关联接口类
 *
 * Created by ccj on 2016/7/7.
 */
public interface LoginContract {
    interface View extends BaseView {
        void showProgress();
        void hideProgress();
        void showError(String error);
        void navigateToMain();
        void navigateToRegister();
    }
    interface Presenter extends BasePresenter {
        void login(String username, String password);
        void onDestroy();
    }
    interface Model{
        void saveUserInfo(User user);
        void saveLoginState(Boolean isLogin);
        void saveRememberPass(User user);

    }

}
```
 - **模型(Model):实现 implements LoginContract.Model** 负责处理数据的加载或者存储,比如从网络或本地数据库获取数据等;**这里的login 涉及到的业务逻辑比较少请求网络 采用了rxjava +retroft+gsons 相当于 model层. 如果处理的出具多,就采用此model ,就像图片保存显示等等.**

 - **视图(View):采用接口的方式,让activity实现该接口,接口中有关于视图的方法,例如”initVIew()”,”showDialog()”,”hideDialog()”等等, 负责界面数据的展示,与用户进行交互;**
 ```java
 public class LoginActivity extends BaseActivity implements LoginContract.View {

  //省略bufferknife 注解
    private LoginPresenter presenter;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        ButterKnife.bind(this);
        presenter=new LoginPresenter(this);
        presenter.start();//初始化控制层
    }

	//实现于view的方法
    @Override
    public void navigateToMain() {
        Intent intent =new Intent(getBaseContext(),MainActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        startActivity(intent);
    }

 ```
 - **主持人(Presenter):持有 view和model的对象,操作两者的方法.相当于协调者,是模型与视图之间的桥梁,将模型与视图分离开来,对view 和model 进行调度操作。**

```java
  /**
 * login的presenter层 进行对view 和 model 的控制,
 * Created by ccj on 2016/7/7.
 */
public class LoginPresenter implements LoginContract.Presenter {

    private LoginContract.View loginView;
    public LoginPresenter(LoginContract.View loginView) {
        this.loginView = loginView;
    }

    @Override
    public void login(String username, String password) {
        loginView.showProgress();
        Observable<User> userObservable = APIService.userLogin(username, password);
        userObservable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<User>() {
                    @Override
                    public void onCompleted() {
                        loginView.hideProgress();
                    }

                    @Override
                    public void onError(Throwable e) {
                        TLog.log(e.getMessage().toString());
                        loginView.hideProgress();
                        loginView.showError(e.getMessage().toString());
                    }

                    @Override
                    public void onNext(User getIpInfoResponse) {
                        TLog.log(getIpInfoResponse.toString());
                        loginView.navigateToMain();
                    }
                });
    }

    @Override
    public void start() {

    }

```


***2.网络访问: 采用rxjava+retrofit+gson进行网络访问,并轻松的将json转为对象,结构清晰,使用方便.***

 - **在APIService中初始化retrofit**

```java
 /**
 * 调用后台的接口,架构网络层采用Retroft+Rxjava+gson
 * Created by ccj on 2016/7/1.
 *
 */
public class APIService {

    private static final String TAG = "APIService";
    public static final String URL_HOST ="http://123.234.82.23" ;//服务器端口
    /**
     * 基础地址
     * 初始化 retroft
     */
    private static final Retrofit sRetrofit = new Retrofit.Builder()
            .baseUrl(URL_HOST)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) // 使用RxJava作为回调适配器
            .build();
    private static final RetrofitRequest apiManager = sRetrofit.create(RetrofitRequest.class);
    /**
     * 登录,返回,我这边用的是json格式的post,大家可以进行选择
     * @param city
     * @return
     */
    public static Observable<User> userLogin(String format, String city) {
        HashMap<String,String> hashMap =new HashMap<>();
        hashMap.put("UserPhone", format);
        hashMap.put("UserPassWord", city);
        TLog.log(hashMap.toString());
        Observable<User> ss = apiManager.userLogin(hashMap);
        return  ss;
    }

    /**********************仿照上面的方法,进行请求数据****************************/

```
 - **用retrofit访问 返回observable的对象**

```java
public interface RetrofitRequest {


    boolean isTest=true; //是否在测试环境下
    //发布之前更改
    String BASE_URL_TEST = "/flyapptest/";//测试服务器
    String BASE_URL_OFFICAL = "/flyapp/";//正式服务器

    String BASE_URL = isTest?BASE_URL_TEST:BASE_URL_OFFICAL;//发布服务器


    /**
     * 登录返回(json post)
     * @param body
     * @return
     */
    @Headers( "Content-Type: application/json" )
    @POST(BASE_URL+"Login.ashx/")
    Observable<User> userLogin(@Body HashMap<String, String> body);

```

***3.异步处理: 采用rxjava响应式框架进行优雅的异步处理,简化代码逻辑,并且很好的解决内存泄漏	问题.(相关模块在TakePhoto业务中)***
```java
  /**
     * rxjava 进行异步操作 eventBus进行时间传递
     * @param data
     */
    @Override
    public void savePhoto(final Intent data) {
        TLog.log("savePhoto", "data-->" + data.getData().toString());
        Log.e("Tlog-->", "data-->" + data.getData().toString());
        saveObservable = Observable.fromCallable(new Callable<String>() {
            @Override
            public String call() throws Exception {//通知调用  并返回string
                return savePic(data);//此方法在io线程中调用 并返回
            }
        });

        saveSubscription = saveObservable
                .subscribeOn(Schedulers.io())//observable在调度中的IO线程中进行调度进行
                .observeOn(AndroidSchedulers.mainThread())//在主线程中进行观察
                .subscribe(new Observer<String>() {//订阅观察者
                    @Override
                    public void onCompleted() {
                        Log.e("Tlog-->", "onCompleted-->");
                    }
                    @Override
                    public void onError(Throwable e) {
                        Log.e("Tlog-->", "Throwable-->" + e.getMessage().toString());
                        EventBus.getDefault().post(new EventUtils.ObjectEvent(e.getMessage().toString()));
                    }
                    @Override
                    public void onNext(String s) {//带参数的下一步,在此就是当
                        Log.e("Tlog-->", "s-->" + s);
                        EventBus.getDefault().post(new EventUtils.ObjectEvent(bitmap));

                    }
                });
    }
```


***4.事件订阅: 采用EventBus作为事件总线,进行线程间,组件之间的通信.***

```java
/**
 * 事件总线 用于组件或线程通信,可替代回调,广播等
 * Created by ccj on 2016/4/14.
 */
public class EventUtils {

    /**
     * object类型(即传统的所有类型,都可以强转进行传递事件)
     */
    public static class ObjectEvent{
        private Object object;
        public ObjectEvent(Object object) {
            // TODO Auto-generated constructor stub
            this.object = object;
        }
        public Object getMsg(){
            return object;
        }
    }

}
```

***5.代码分包: 根据业务区分进行分包,便于对代码进行管理 .***

![这里写图片描述](http://img.blog.csdn.net/20160712153822145)


***6. 工具类: TDeviceUtils设备状态的工具类,,SeriliazebleUtils 序列化工具类,SharepreferenceUtils保存工具类,***
相关请参考代码

***7.app栈管理: 基于baseActivity,很好的释放内存,管理内存.***
相关请参考代码

---
#### 待后期完成

***异常捕获(待完善)***
***测试框架Espresso/JUnit/Mockito/Robolectric (待完善)***

---


##总结

1.层次分明,各层级之间都不管对方如何实现,只关注结果;
2.在视图层(Presentation Layer)使用MVP架构,使原本臃肿的Activity(或Fragment)变得简单,其处理方法都交给了Presenter。
3.易于做测试,只要基于每个模块单独做好单元测试就能确保整体的稳定性。
4.易于快速迭代,基于代码的低耦合,只需在业务逻辑上增加接口,然后在相应的层级分别实现即可,丝毫不影响其他功能。

##Blog-link
[csdn博客,欢迎大家指正,评阅~谢谢O(∩_∩)O谢谢](http://blog.csdn.net/ccj659/article/details/51889713)


================================================
FILE: app/.gitignore
================================================
/build


================================================
FILE: app/build.gradle
================================================
apply plugin: 'com.android.application'
repositories {
    jcenter()
}
android {

    compileSdkVersion rootProject.ext.compileSdkVersion
    buildToolsVersion rootProject.ext.buildToolsVersion
    defaultConfig {
        applicationId "com.efly.flyhelper"
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        versionCode rootProject.ext.versionCode
        versionName rootProject.ext.versionName
        multiDexEnabled false

        //arouter
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = [moduleName: project.getName()]
            }
        }
    }
    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'
        }

        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(include: ['*.jar'], dir: 'libs')


    //arouter
    compile rootProject.ext.arouterApi
    annotationProcessor rootProject.ext.arouterCompiler

    //butterknife
    annotationProcessor rootProject.ext.butterknifeCompiler

    if (isModule.toBoolean()) {
        //当isDebug true,app得依赖基础库,保证app不报错
        compile project(':base')
    } else {
        compile project(':module_home')
        compile project(':module_user')
        compile project(':module_video')
        compile project(':module_meizi')

    }

}


================================================
FILE: app/proguard-rules.pro
================================================



-ignorewarnings                     # 忽略警告,避免打包时某些警告出现
-dontwarn
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-dontpreverify
-verbose                            # 混淆时是否记录日志
#-printmapping topden.map
-keepclassmembers class fqcn.of.javascript.interface.for.webview {
   public *;
}


-keep class * extends java.lang.annotation.Annotation { *; }
-keep class * extends android.app.Application { *; }
-keep public class * implements java.io.Serializable {*;}
-keep public class * implements android.os.Parcelable {*;}



-keepattributes Exceptions,InnerClasses,Signature
-keepattributes SourceFile,LineNumberTable,EnclosingMethod


# keep 泛型
-keepattributes *Annotation*

-keepclassmembers class * {
    public <init>(org.json.JSONObject);
}

-keepclassmembers class **.R$* {
    public static <fields>;
}

-keep public class * extends android.app.Fragment
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-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
-keepattributes *Annotation*
-keep class android.support.v4.** { *; }
-keep interface android.support.v4.app.** { *; }
-keep public class * extends android.support.v4.**
-keep public class * extends android.support.v13.**
-keep class android.support.v13.** { *; }
-keep class android.support.v7.** { *; }



-dontwarn javax.annotation.**
-keep class javax.annotation.** { *;}


#########-------------------第三方 ----------------------------------#############
#recoo
-keep class com.dodola.** {*;}
-keep class com.lody.legend.** {*;}

#-dontwarn com.dodola.rocoo.** { *; }
#-keep class com.dodola.rocoo.** { *; }

# ButterKnife
-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-keep class **$$ViewBinder { *; }
-keepclasseswithmembernames class * {
    @butterknife.* <fields>;
}
-keepclasseswithmembernames class * {
    @butterknife.* <methods>;
}

# EventBus
-keepattributes *Annotation*
-keepclassmembers class ** {
    @org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }



# RxJava RxAndroid
-dontwarn sun.misc.**
-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {
    long producerIndex;
    long consumerIndex;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {
    rx.internal.util.atomic.LinkedQueueNode producerNode;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef {
    rx.internal.util.atomic.LinkedQueueNode consumerNode;
}





# Retrofit
-dontwarn retrofit2.**
-keep class retrofit2.** { *; }
-keepattributes Signature
-keepattributes Exceptions



# OkHttp3
-dontwarn com.squareup.okhttp3.**
-keep class com.squareup.okhttp3.** { *;}
-dontwarn okio.**



# Gson
#-keepattributes Signature-keepattributes *Annotation*
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.stream.** { *; }
# 使用Gson时需要配置Gson的解析对象及变量都不混淆。不然Gson会找不到变量。
# 将下面替换成自己的实体类
-keep class com.efly.flyhelper.bean.** { *; }



# EventBus
-keepattributes *Annotation*
-keepclassmembers class ** {
    @org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }



================================================
FILE: app/src/androidTest/java/com/efly/flyhelper/ApplicationTest.java
================================================
package com.efly.flyhelper;

import android.app.Application;
import android.test.ApplicationTestCase;

/**
 * <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
 */
public class ApplicationTest extends ApplicationTestCase<Application> {
    public ApplicationTest() {
        super(Application.class);
    }
}

================================================
FILE: app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.efly.flyhelper">
    <!-- 必选 -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <permission android:name="android.permission.INTERNET" />


    <application
        android:name=".AppApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"

        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity"
            android:theme="@style/AppTheme.NoActionBar"
            >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>

</manifest>

================================================
FILE: app/src/main/java/com/efly/flyhelper/AppApplication.java
================================================
package com.efly.flyhelper;

import com.ccj.base.base.BaseApplication;

/**
 * ARouter 这里必须在 这里初始化, 在 base里面初始化 无效,奇怪
 * Created by chenchangjun on 17/8/10.
 */

public class AppApplication extends BaseApplication {




    @Override
    public void onCreate() {
        super.onCreate();

    }



}


================================================
FILE: app/src/main/java/com/efly/flyhelper/MainActivity.java
================================================
package com.efly.flyhelper;

import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.BottomNavigationView;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.view.MenuItem;

import com.alibaba.android.arouter.launcher.ARouter;
import com.ccj.base.base.BaseActivity;
import com.ccj.base.RouterConstants;
import com.efly.flyhelper.adapter.FragmentAdapter;

import java.util.LinkedList;
import java.util.List;


public class MainActivity extends BaseActivity {

    private ViewPager mPager;
    private List<Fragment> mFragments = new LinkedList<>();
    private FragmentAdapter mAdapter;
    private BottomNavigationView navigation;

    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
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bottom_navigation);
        mPager = (ViewPager) findViewById(R.id.container_pager);

        navigation = (BottomNavigationView) findViewById(R.id.navigation);
        initViewPager();
        navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
    }

    private void initViewPager() {


        Fragment home = (Fragment) ARouter.getInstance().build(RouterConstants.HOME_MUDULE_FRAGMENT_HOME_HOME).navigation();
        Fragment meizi = (Fragment) ARouter.getInstance().build(RouterConstants.MEIZI_MUDULE_FRAGMENT_HOME_MEIZI).navigation();
        Fragment user = (Fragment) ARouter.getInstance().build(RouterConstants.USER_MUDULE_FRAGMENT_HOME_USER).navigation();
        mFragments.add(home);
        mFragments.add(meizi);
        mFragments.add(user);

        mAdapter = new FragmentAdapter(getSupportFragmentManager(), mFragments);
        mPager.setAdapter(mAdapter);
    }


}


================================================
FILE: app/src/main/java/com/efly/flyhelper/adapter/FragmentAdapter.java
================================================
package com.efly.flyhelper.adapter;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;

import java.util.List;

public class FragmentAdapter extends FragmentStatePagerAdapter {
    private List<Fragment> mFragments;

    public FragmentAdapter(FragmentManager fm, List<Fragment> 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;
    }
}


================================================
FILE: app/src/main/res/drawable/ic_dashboard_black_24dp.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportHeight="24.0"
    android:viewportWidth="24.0">
    <path
        android:fillColor="#FF000000"
        android:pathData="M3,13h8L11,3L3,3v10zM3,21h8v-6L3,15v6zM13,21h8L21,11h-8v10zM13,3v6h8L21,3h-8z" />
</vector>


================================================
FILE: app/src/main/res/drawable/ic_home_black_24dp.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportHeight="24.0"
    android:viewportWidth="24.0">
    <path
        android:fillColor="#FF000000"
        android:pathData="M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z" />
</vector>


================================================
FILE: app/src/main/res/drawable/ic_notifications_black_24dp.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportHeight="24.0"
    android:viewportWidth="24.0">
    <path
        android:fillColor="#FF000000"
        android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.89,2 2,2zM18,16v-5c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2z" />
</vector>


================================================
FILE: app/src/main/res/layout/activity_bottom_navigation.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:background="@color/white"
    >

    <android.support.v4.view.ViewPager
        android:id="@+id/container_pager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <android.support.design.widget.BottomNavigationView
        android:id="@+id/navigation"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:background="?android:attr/windowBackground"
        app:menu="@menu/menu_bottom_navigation" />

</LinearLayout>


================================================
FILE: app/src/main/res/menu/menu_bottom_navigation.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/navigation_home"
        android:icon="@drawable/ic_home_black_24dp"
        android:title="@string/title_home" />

    <item
        android:id="@+id/navigation_dashboard"
        android:icon="@drawable/ic_dashboard_black_24dp"
        android:title="@string/title_dashboard" />

    <item
        android:id="@+id/navigation_notifications"
        android:icon="@drawable/ic_notifications_black_24dp"
        android:title="@string/title_notifications" />

</menu>


================================================
FILE: app/src/main/res/values/strings.xml
================================================
<resources>
    <string name="app_name">MVP和组件化</string>
    <string name="title_notifications">我的</string>
    <string name="title_dashboard">妹子</string>
    <string name="title_home">首页</string>


</resources>


================================================
FILE: app/src/test/java/com/efly/flyhelper/ExampleUnitTest.java
================================================
package com.efly.flyhelper;

import org.junit.Test;

import static org.junit.Assert.*;

/**
 * To work on unit tests, switch the Test Artifact in the Build Variants view.
 */
public class ExampleUnitTest {
    @Test
    public void addition_isCorrect() throws Exception {
        assertEquals(4, 2 + 2);
    }
}

================================================
FILE: base/.gitignore
================================================
/build


================================================
FILE: base/build.gradle
================================================
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'
        }
    }
}

repositories {
    flatDir {
        dirs 'aars'
    }
}

ext{
    libSupportVersion = '25.3.1'
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })

    compile rootProject.ext.appcompatV7
    compile rootProject.ext.constraintLayout



    //butterknife
    compile rootProject.ext.butterknife

    compile rootProject.ext.arouterApi

    compile rootProject.ext.eventbus





    /*view相关*/
    compile "com.android.support:design:${libSupportVersion}"
    compile "com.android.support:recyclerview-v7:${libSupportVersion}"
    compile "com.android.support:cardview-v7:${libSupportVersion}"
    compile "com.android.support:support-v4:${libSupportVersion}"

    /*请求网络框架*/
    //retrofit
    compile 'com.squareup.retrofit2:retrofit:2.0.2'
    compile 'com.squareup.okhttp3:logging-interceptor:3.1.2'
    compile 'com.squareup.retrofit2:converter-gson:2.0.2'
    compile 'com.squareup.retrofit2:adapter-rxjava:2.0.2'

    //rxjava
    compile 'io.reactivex:rxandroid:1.1.0'
    compile 'io.reactivex:rxjava:1.1.0'

    compile 'com.google.code.gson:gson:2.4'


    compile 'com.mcxiaoke.volley:library:1.0.19'

    //图片请求
    compile 'com.squareup.picasso:picasso:2.5.2'


}


================================================
FILE: base/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/chenchangjun/Library/Android/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
-keep public class com.alibaba.android.arouter.routes.**{*;}
-keep class * implements com.alibaba.android.arouter.facade.template.ISyringe{*;}

# 如果使用了 byType 的方式获取 Service,需添加下面规则,保护接口
-keep interface * implements com.alibaba.android.arouter.facade.template.IProvider

# 如果使用了 单类注入,即不定义接口实现 IProvider,需添加下面规则,保护实现
-keep class * implements com.alibaba.android.arouter.facade.template.IProvider

================================================
FILE: base/src/androidTest/java/com/ccj/base/ExampleInstrumentedTest.java
================================================
package com.ccj.base;

import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;

import static org.junit.Assert.*;

/**
 * Instrumentation test, which will execute on an Android device.
 *
 * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
 */
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
    @Test
    public void useAppContext() throws Exception {
        // Context of the app under test.
        Context appContext = InstrumentationRegistry.getTargetContext();

        assertEquals("com.ccj.base.test", appContext.getPackageName());
    }
}


================================================
FILE: base/src/main/AndroidManifest.xml
================================================
<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.ccj.base">
    <!-- 必选 -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <permission android:name="android.permission.INTERNET" />

    <application android:allowBackup="true" android:label="@string/app_name"
        android:supportsRtl="true">

    </application>

</manifest>


================================================
FILE: base/src/main/java/com/ccj/base/AppManager.java
================================================
package com.ccj.base;

import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;

import java.util.Stack;

/**
 * activity堆栈式管理
 *
 */
public class AppManager {

    private static Stack<Activity> activityStack;
    private static AppManager instance;

    private AppManager() {
    }



    /**
     * 单一实例
     */
    public static AppManager getAppManager() {
        if (instance == null) {
            instance = new AppManager();
        }

        if (activityStack == null) {
            activityStack = new Stack<Activity>();
        }

        return instance;
    }

    /**
     * 获取指定的Activity
     *
     * @author kymjs
     */
    public static Activity getActivity(Class<?> cls) {
        if (activityStack != null)
            for (Activity activity : activityStack) {
                if (activity.getClass().equals(cls)) {
                    return activity;
                }
            }
        return null;
    }

    /**
     * 添加Activity到堆栈
     */
    public void addActivity(Activity activity) {
        activityStack.add(activity);
    }

    /**
     * 获取当前Activity(堆栈中最后一个压入的)
     */
    public Activity currentActivity() {
        Activity activity = activityStack.lastElement();
        return activity;
    }

    /**
     * 结束当前Activity(堆栈中最后一个压入的)
     */
    public void finishActivity() {
        Activity activity = activityStack.lastElement();
        finishActivity(activity);
    }

    /**
     * 结束指定的Activity
     */
    public void finishActivity(Activity activity) {
        if (activity != null && activityStack.contains(activity)) {
            activityStack.remove(activity);
            activity.finish();
        }
    }

    /**
     * 结束指定的Activity
     */
    public void removeActivity(Activity activity) {
        if (activity != null && activityStack.contains(activity)) {
            activityStack.remove(activity);
        }
    }

    /**
     * 结束指定类名的Activity
     */
    public void finishActivity(Class<?> cls) {
        for (Activity activity : activityStack) {
            if (activity.getClass().equals(cls)) {
                finishActivity(activity);
                break;
            }
        }
    }

    /**
     * 结束所有Activity
     */
    public void finishAllActivity() {
        for (int i = 0, size = activityStack.size(); i < size; i++) {
            if (null != activityStack.get(i)) {
                finishActivity(activityStack.get(i));
            }
        }
        activityStack.clear();
    }

    /**
     * 退出应用程序
     */
    public void AppExit(Context context) {

        try {
            finishAllActivity();
            // System.exit(0);
        } catch (Exception e) {
        }

        // 获取packagemanager的实例
        try {
            ActivityManager activityMgr = (ActivityManager) context
                    .getSystemService(Context.ACTIVITY_SERVICE);
            activityMgr.killBackgroundProcesses(context.getPackageName());
            activityStack = null;
            instance=null;
            System.exit(0);
        } catch (Exception e) {
            System.exit(0);
        }

    }
}


================================================
FILE: base/src/main/java/com/ccj/base/Constants.java
================================================
package com.ccj.base;

/**
 * Created by chenchangjun on 17/8/10.
 */

public class Constants {

    public static final String START_LOGIN_WITH_PARAMS = "START_LOGIN_WITH_PARAMS";
    public static final int REQUEST_START_LOGIN = 0x00110;
    public static final int RESULT_FROM_LOGIN = 0x00011;


    public static final String PARAMS_RESULT_FROM_LOGIN = "PARAMS_RESULT_FROM_LOGIN";
    public static final String PARAMS_REQUEST_FOR_DETAIL = "PARAMS_REQUEST_FOR_DETAIL";

}


================================================
FILE: base/src/main/java/com/ccj/base/RouterConstants.java
================================================
package com.ccj.base;
/**
 * Created by chenchangjun on 17/8/9.
 */


public final class RouterConstants {




    /**
     * home module
     */
    public static final String HOME_MODULE_NAME="/homemodule/";
    public static final String HOME_MUDULE_FRAGMENT_HOME_HOME = HOME_MODULE_NAME+"FRAGMENT_HOME_HOME";


    /**
     * user module
     */
    public static final String USER_MODULE_NAME ="/loginmodule/";

    public static final String USER_MUDULE_FRAGMENT_HOME_USER = USER_MODULE_NAME+"FRAGMENT_HOME_USER";


    public static final String USER_MOUDLE_ACTIVITY = USER_MODULE_NAME +"LoginActivity";
    public static final String USER_SERVICE_IMPL = USER_MODULE_NAME +"LoginServiceImpl";
    public static final String USER_REGISTER_FRAGMENT = USER_MODULE_NAME +"/RegisterFragment";

    /**
     * video module
     */
    public static final String VIDEO_MODULE_NAME="/videomodule/";
    public static final String VIDEO_MUDULE_FRAGMENT_HOME_VIDEO = VIDEO_MODULE_NAME+"FRAGMENT_HOME_VIDEO";

    public static final String VIDEO_MUDULE_ACTIVITY = VIDEO_MODULE_NAME+"TakePhotoActivity";
    public static final String VIDEO_SERVICE_IMPL = VIDEO_MODULE_NAME+"VideoServiceImpl";




    /**
     * meizi module
     */
    public static final String MEIZI_MODULE_NAME="/meizimodule/";
    public static final String MEIZI_MUDULE_FRAGMENT_HOME_MEIZI = MEIZI_MODULE_NAME+"FRAGMENT_HOME_MEIZI";
    public static final String MEIZI_MUDULE_ACTIVITY_MEIZI_DETAIL = MEIZI_MODULE_NAME+"ACTIVITY_MEIZI_DETAIL";


}


================================================
FILE: base/src/main/java/com/ccj/base/adapter/CommonRcvAdapter.java
================================================
package com.ccj.base.adapter;

import android.app.Activity;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.ViewGroup;

import com.ccj.base.adapter.item.AdapterItem;
import com.ccj.base.adapter.util.IAdapter;
import com.ccj.base.adapter.util.ItemTypeUtil;

import java.util.ArrayList;
import java.util.List;


/**
 * @author ccj
 * @date 2017/3/23
 */
public abstract class CommonRcvAdapter<T> extends RecyclerView.Adapter<CommonRcvAdapter.RcvAdapterItem> implements IAdapter<T> {

    private List<T> mDataList;

    private Object mType;

    private ItemTypeUtil mUtil;

    private int currentPos;

    public Activity mActivity;


    public CommonRcvAdapter(@Nullable List<T> data, Activity mActivity) {
        if (data == null) {
            data = new ArrayList<>();
        }
        mDataList = data;
        mUtil = new ItemTypeUtil();
        this.mActivity = mActivity;
    }


    public T getItem(int position) {
        if (position < 0 || position > getItemCount() - 1) {
            return null;
        }
        return mDataList.get(position);
    }


    @Override
    public int getItemCount() {
        return mDataList == null ? 0 : mDataList.size();
    }

    @Override
    public void setData(@NonNull List<T> data) {
        mDataList = data;
    }

    @Override
    public List<T> getData() {
        return mDataList;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    /**
     * instead by{@link #getItemType(Object)}
     * <p>
     * 通过数据得到obj的类型的type
     * 然后,通过{@link ItemTypeUtil}来转换位int类型的type
     */
    @Deprecated
    @Override
    public int getItemViewType(int position) {
        this.currentPos = position;
        mType = getItemType(mDataList.get(position));
        return mUtil.getIntType(mType);
    }

    @Override
    public Object getItemType(T t) {
        return -1; // default
    }

    @Override
    public RcvAdapterItem onCreateViewHolder(ViewGroup parent, int viewType) {
        return new RcvAdapterItem(parent.getContext(), parent, createItem(mType));
    }

    @Override
    public void onBindViewHolder(RcvAdapterItem holder, int position) {

        holder.item.handleData(getConvertedData(mDataList.get(position), mType), position);


    }

    @NonNull
    @Override
    public Object getConvertedData(T data, Object type) {
        return data;
    }

    @Override
    public int getCurrentPosition() {
        return currentPos;
    }

    ///////////////////////////////////////////////////////////////////////////
    // 内部用到的viewHold
    ///////////////////////////////////////////////////////////////////////////

    public static class RcvAdapterItem extends RecyclerView.ViewHolder {

        protected AdapterItem item;

        boolean isNew = true; // debug中才用到

        RcvAdapterItem(Context context, ViewGroup parent, AdapterItem item) {
            super(LayoutInflater.from(context).inflate(item.getLayoutResId(), parent, false));
            this.item = item;
            this.item.bindViews(itemView);
            this.item.setViews();
        }

    }

    ///////////////////////////////////////////////////////////////////////////
    // For debug
    ///////////////////////////////////////////////////////////////////////////

    private void debug(RcvAdapterItem holder) {
        boolean debug = false;
        if (debug) {
            holder.itemView.setBackgroundColor(holder.isNew ? 0xffff0000 : 0xff00ff00);
            holder.isNew = false;
        }
    }

}


================================================
FILE: base/src/main/java/com/ccj/base/adapter/bean/AdapterBean.java
================================================
package com.ccj.base.adapter.bean;

import java.io.Serializable;

/**
 * 数据bean
 * 为了不同viewItem 分别对应不同的bean,</br>
 * 避免不同item的字段都杂糅的同一个类中的情况,比如{ mobile中的 CommonRowsBean}</br>
 * 根据Holder建立一个新的bean, 自定义的bean要继承AdapterBean,在bean中添置所需字段,供holder调用,比如(mobile中 BrandRcvAdapter中的holder)</br>
 * <p>
 * Created by chenchangjun on 17/12/28.
 */

public abstract class AdapterBean implements Serializable {

    //唯一标示!


    public abstract void setCell_type(int cell_type);


    public abstract int getCell_type();

}


================================================
FILE: base/src/main/java/com/ccj/base/adapter/bean/AdapterGroupBean.java
================================================
package com.ccj.base.adapter.bean;

import java.io.Serializable;
import java.util.List;

/**
 * 类似于 view和 viewgroup 的概念 这里是 viewgroup
 * Created by chenchangjun on 18/1/4.
 */

public abstract class AdapterGroupBean<T> extends AdapterBean implements Serializable {


    //唯一标示!

    public abstract List getList();

    public abstract String getTitle();

    public abstract T getRedirect_data();


}


================================================
FILE: base/src/main/java/com/ccj/base/adapter/item/AdapterItem.java
================================================
package com.ccj.base.adapter.item;

import android.support.annotation.LayoutRes;
import android.view.View;

/**
 * @author ccj
 * @date 2017/3/21
 */
public interface AdapterItem<T> {


    /**
     * @return item布局文件的layoutId
     */
    @LayoutRes
    int getLayoutResId();

    /**
     * 初始化views
     */
    void bindViews(final View root);

    /**
     * 设置view的参数
     * 设置监听等,只执行一次
     */
    void setViews();

    /**
     * 根据数据来设置item的内部views
     *
     * @param t    数据list内部的model
     * @param position 当前adapter调用item的位置
     */
    void handleData(T t, int position);

}  

================================================
FILE: base/src/main/java/com/ccj/base/adapter/util/IAdapter.java
================================================
package com.ccj.base.adapter.util;

import android.support.annotation.Keep;
import android.support.annotation.NonNull;

import com.ccj.base.adapter.item.AdapterItem;

import java.util.List;


/**
 * @author ccj
 * @date 2017/3/22
 * 通用的adapter必须实现的接口,作为方法名统一的一个规范
 */
public interface IAdapter<T> {

    /**
     * @param data 设置数据源
     */
    void setData(@NonNull List<T> data);

    List<T> getData();

    /**
     * @param t list中的一条数据
     * @return 强烈建议返回string, int, bool类似的基础对象做type,不要返回data中的某个对象
     */
    Object getItemType(T t);

    /**
     * 当缓存中无法得到所需item时才会调用
     *
     * @param type 通过{@link #getItemType(Object)}得到的type
     * @return 任意类型的 AdapterItem
     */
    @Keep
    @NonNull
    AdapterItem createItem(Object type);

    /**
     * 如果放入item的最终数据和list中的每一条数据类型是不同的,可以通过此方法进行转换
     *
     * @param data 从原始的list中取得得数据
     * @param type item的类型
     * @return 放入adapterItem的最终数据
     */
    @Keep
    @NonNull
    Object getConvertedData(T data, Object type);

    /**
     * 通知adapter更新当前页面的所有数据
     */
    void notifyDataSetChanged();

    /**
     * 得到当前要渲染的最后一个item的position
     */
    int getCurrentPosition();
}


================================================
FILE: base/src/main/java/com/ccj/base/adapter/util/ItemTypeUtil.java
================================================
package com.ccj.base.adapter.util;

import android.support.annotation.VisibleForTesting;

import java.util.HashMap;

/**
 * @author ccj
 * @date 2017/3/22
 */
@VisibleForTesting
/*package*/ public class ItemTypeUtil {

    private HashMap<Object, Integer> typePool;

    public void setTypePool(HashMap<Object, Integer> typePool) {
        this.typePool = typePool;
    }

    /**
     * @param type item的类型
     * @return 通过object类型的type来得到int类型的type
     */
    public int getIntType(Object type) {
        if (typePool == null) {
            typePool = new HashMap<>();
        }
        
        if (!typePool.containsKey(type)) {
            typePool.put(type, typePool.size());
        }
        return typePool.get(type);
    }
}


================================================
FILE: base/src/main/java/com/ccj/base/api/APIService.java
================================================
package com.ccj.base.api;


import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * 调用后台的接口,架构网络层采用Retroft+Rxjava+gson
 * Created by ccj on 2016/7/1.
 *
 */
public class APIService {

    private static final String TAG = "APIService";

    //get请求
    public static final String URL_GANK_IO = "http://gank.io";//gank.io 中的妹子API


    /**
     * 基础地址
     * 初始化 retroft
     */
    protected static final Retrofit sRetrofit = new Retrofit.Builder()
            .baseUrl( URL_GANK_IO )
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) // 使用RxJava作为回调适配器
            .build();

   // protected static final RetrofitRequest apiManager = sRetrofit.create(RetrofitRequest.class);



    /**********************仿照上面的方法,进行请求数据****************************/




}


================================================
FILE: base/src/main/java/com/ccj/base/api/RetrofitRequest.java
================================================
package com.ccj.base.api;


/**
 *
 * Created by ccj on 2016/7/6.
 */
public interface RetrofitRequest {


    boolean isTest=false; //是否在测试环境下
    //发布之前更改
    String BASE_URL_TEST = "/flyapptest/";//测试服务器
    String BASE_URL_OFFICAL = "/flyapp/";//正式服务器

    String BASE_URL = isTest?BASE_URL_TEST:BASE_URL_OFFICAL;//发布服务器

}


================================================
FILE: base/src/main/java/com/ccj/base/api/VolleyUtils.java
================================================
package com.ccj.base.api;

import android.content.Context;
import android.text.TextUtils;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.Volley;
import com.ccj.base.base.BaseApplication;
import com.ccj.base.utils.LruBitmapCache;


/**
 * volley留做备用
 * Created by ccj on 2016/12/4.
 */
public class VolleyUtils {

    public static final String TAG = VolleyUtils.class.getSimpleName();
    public static final Context context = BaseApplication.getInstance();
    public static VolleyUtils volleyUtils;
    private RequestQueue requestQueue;
    private ImageLoader imageLoader;

    //	The best way to maintain volley core objects and request queue is, making them global by creating a singleton class.
    public static VolleyUtils getInstance() {
        if (volleyUtils == null) {
            volleyUtils = new VolleyUtils();
        }
        return volleyUtils;
    }

    //Default constructor
    private VolleyUtils() {
        getRequestQueue();
        getImageLoader();
    }

    public RequestQueue getRequestQueue() {

        if (requestQueue == null) {
            requestQueue = Volley.newRequestQueue(context);
        }
        return requestQueue;
    }

    public ImageLoader getImageLoader() {
        getRequestQueue();
        if (imageLoader == null) {
            imageLoader = new ImageLoader(requestQueue, new LruBitmapCache());
        }
        return imageLoader;
    }

    public <T> void addToRequestQueue(Request<T> req, String tag) {
        //Set default tag if empty
        req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
        getRequestQueue().add(req);
    }

    public <T> void addToRequestQueue(Request<T> req) {
        req.setTag(TAG);
        getRequestQueue().add(req);
    }

    public void cancelPendingRequests(Object tag) {
        if (requestQueue != null) {
            requestQueue.cancelAll(tag);
        }
    }



}


================================================
FILE: base/src/main/java/com/ccj/base/base/BaseActivity.java
================================================
package com.ccj.base.base;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;

import com.ccj.base.AppManager;
import com.ccj.base.R;

import java.util.List;


/**
 * base 来进行 toolbar dialog 初始化,activity栈的添加,删除等
 * Created by ccj on 2016/7/5.
 */
public class BaseActivity<T extends BasePresenter>
        extends AppCompatActivity implements BaseView {

    private static final String TAG = "BaseActivity";
    public T mPresenter;
    protected ProgressDialog progressDialog;
    protected Toolbar toolbar;
    protected Context mContext;
    private int fragmentIndex = 0;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        AppManager.getAppManager().addActivity(this);
        mContext = this;
        initDialog();

    }

    public void initToolBar() {
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        toolbar.setBackgroundColor(getResources().getColor(R.color.tool_bar_white));
        toolbar.setNavigationIcon(R.mipmap.back);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
    }

    public Toolbar getToolbar() {
        return toolbar;
    }

    /**
     * 资源释放
     */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mPresenter != null)
            mPresenter.onDestroy();
        AppManager.getAppManager().finishActivity(this);
    }

    private void initDialog() {
        progressDialog = new ProgressDialog(this);
        progressDialog.setMessage(getResources().getString(R.string.show_loading_msg));
    }

    public void showLoading() {
        progressDialog.show();
    }

    public void dismissLoading() {
        progressDialog.dismiss();
    }


    @Override
    public void initView() {

    }


    /**
     * 解决fragment onActivityResult不调用
     *
     * @param requestCode
     * @param resultCode
     * @param data
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        FragmentManager fm = getSupportFragmentManager();
        //if (index != 0) {
        if (fm.getFragments() == null) {
            Log.w(TAG, "Activity result fragment fragmentIndex out of range: 0x"
                    + Integer.toHexString(requestCode));
            return;
        }
        for (int i = 0; i <fm.getFragments().size() ; i++) {
            Fragment frag = fm.getFragments().get(i);
            if (frag == null) {
                Log.w(TAG, "Activity result no fragment exists for fragmentIndex: 0x"
                        + Integer.toHexString(requestCode));
            } else {
                handleResult(frag, requestCode, resultCode, data);
            }
        }
        return;
        //}

    }

    /**
     * 递归调用,对所有子Fragement生效
     *
     * @param frag
     * @param requestCode
     * @param resultCode
     * @param data
     */
    private void handleResult(Fragment frag, int requestCode, int resultCode,
                              Intent data) {
        frag.onActivityResult(requestCode, resultCode, data);
        List<Fragment> frags = frag.getChildFragmentManager().getFragments();
        if (frags != null) {
            for (Fragment f : frags) {
                if (f != null)
                    handleResult(f, requestCode, resultCode, data);
            }
        }
    }
}


================================================
FILE: base/src/main/java/com/ccj/base/base/BaseApplication.java
================================================
package com.ccj.base.base;

import android.app.Application;
import android.content.Context;
import android.content.res.Resources;
import android.view.Gravity;
import android.widget.Toast;

import com.alibaba.android.arouter.launcher.ARouter;
import com.ccj.base.utils.SharedPreferenceUtil;

/**
 * 获取上下文,Toast,以及各种初始化
 * Created by Administrator on 2016/7/5.
 */
public class BaseApplication extends Application {

    private static String lastToast = "";
    private static long lastToastTime;
    private static Context context;
    private static Resources resource;
    private static BaseApplication baseApplication;

    public static synchronized BaseApplication getInstance() {
        return baseApplication;
    }

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);

    }

    @Override
    public void onCreate() {
        super.onCreate();
        initARouter();
        context = getBaseContext();
        baseApplication = this;
        SharedPreferenceUtil.initSharedPreference(getApplicationContext());
    }

    /**
     * ARouter 在每个模式下都需要,此时,
     * 由于每个module的application只有在module模式下才启用,所以可以这样设置-->
     * 可以将各module都继承BaseApplication
     */
    private void initARouter() {
        //if (BuildConfig.DEBUG) {
            // 这两行必须写在init之前,否则这些配置在init过程中将无效
            ARouter.openLog();     // 打印日志
            ARouter.openDebug();   // 开启调试模式(如果在InstantRun模式下运行,必须开启调试模式!线上版本需要关闭,否则有安全风险)
            ARouter.printStackTrace(); // 打印日志的时候打印线程堆栈
       // }
        ARouter.init(this); // 尽可能早,推荐在Application中初始化
    }


    /**
     * 防抖动 弹窗
     *
     * @param message
     * @param duration
     * @param icon
     * @param gravity
     */
    public static void showToast(String message, int duration, int icon,
                                 int gravity) {
       Toast.makeText(getContext(),message,duration).show();
    }




    public static Context getContext() {
        return context;
    }

    public static void setContext(Context context) {
        BaseApplication.context = context;
    }

    public static Resources getResource() {
        return resource;
    }

    public static void setResource(Resources resource) {
        BaseApplication.resource = resource;
    }


    public static void showShortToast(String message) {
        showToast(message, Toast.LENGTH_SHORT, 0, Gravity.BOTTOM);
    }

    public static void showLongToast(String message) {
        showToast(message, Toast.LENGTH_LONG, 0, Gravity.BOTTOM);
    }

    public static void showToast(String message) {
        showToast(message, Toast.LENGTH_LONG, 0, Gravity.BOTTOM);
    }

}


================================================
FILE: base/src/main/java/com/ccj/base/base/BaseBean.java
================================================
package com.ccj.base.base;

import java.io.Serializable;

/**
 * Created by Administrator on 2016/7/6.
 */
public class BaseBean implements Serializable {



}


================================================
FILE: base/src/main/java/com/ccj/base/base/BaseFragment.java
================================================
package com.ccj.base.base;

import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;


/**
 * Created by Administrator on 2016/7/5.
 */
public abstract class BaseFragment<T extends BasePresenter> extends Fragment implements BaseView {
    private static final String TAG="BaseFragment";
    private LayoutInflater mInflater;
    private Dialog dialog;
    public T mPresenter;
    protected float mDensity;
    protected int mDensityDpi;
    protected int mWidth;
    protected int mAvatarSize;
    private Context mContext;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getScreen();
    }


    public void showLoading() {
        if (dialog == null) {
            dialog = new ProgressDialog(getActivity());
        }
        dialog.setTitle("正在加载...");
        dialog.show();
    }

    public void dismissLoading() {
        if (dialog != null) {
            dialog.dismiss();
        }
    }

    private void getScreen() {
        DisplayMetrics dm = new DisplayMetrics();
        getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
        mDensity = dm.density;
        mDensityDpi = dm.densityDpi;
        mWidth = dm.widthPixels;
        mAvatarSize = (int) (50 * mDensity);
    }

    /**
     * 解绑的时候 清除
     */
    @Override
    public void onDetach() {
        if (mPresenter != null) {
            mPresenter.onDestroy();
        }

        super.onDetach();
    }
}


================================================
FILE: base/src/main/java/com/ccj/base/base/BaseModel.java
================================================
package com.ccj.base.base;

/**
 * Created by Administrator on 2016/7/14.
 */
public interface BaseModel {

    /**
     * 默认的开始,在activity中初始化
     */
    void start();

    /**
     * 在activity中的ondestoy 调用 在此方法中将资源至null,
     * 此处略嫌麻烦,但是如果把presenter层搞成抽象类,在里面添加成员变量和方法体,
     * 就有点失去了味道,所以还是选择了这种方式代替下列注释的部分.
     *
     */

    void onDestroy();

}


================================================
FILE: base/src/main/java/com/ccj/base/base/BasePresenter.java
================================================
package com.ccj.base.base;

/**
 * Created by Administrator on 2016/7/7.
 */
public interface BasePresenter  {
    /**
     * 默认的开始,在activity中初始化
     */
    void start();

    /**
     * 在activity中的ondestoy 调用 在此方法中将资源至null,
     * 此处略嫌麻烦,但是如果把presenter层搞成抽象类,在里面添加成员变量和方法体,
     * 就有点失去了味道,所以还是选择了这种方式代替下列注释的部分.
     *
     */
    void onDestroy();
}

/*
public abstract class BasePresenter<E, T> {
    public Context context;
    public E mModel;
    public T mView;
    public Source mSource = new Source();

    public void setVM(T v, E m) {
        this.mView = v;
        this.mModel = m;
        this.onStart();
    }

    public abstract void onStart();

    public void onDestroy() {
        mSource.clear();
    }
}*/


================================================
FILE: base/src/main/java/com/ccj/base/base/BaseView.java
================================================
package com.ccj.base.base;

/**
 * Created by Administrator on 2016/7/6.
 */
public interface BaseView {


    void initView();
}


================================================
FILE: base/src/main/java/com/ccj/base/base/Constants.java
================================================
package com.ccj.base.base;

/**
 * 静态常量
 */
public class Constants {

    public static final int REQUST_FOR_LOGIN = 0x0001;
    public static final int RESULT_FOR_LOGIN = 0x0002;


    public static final int IMAGES_ACTIVITY_REQUEST_CODE = 300;
}


================================================
FILE: base/src/main/java/com/ccj/base/bean/User.java
================================================
package com.ccj.base.bean;

import com.ccj.base.base.BaseBean;
import com.google.gson.Gson;

import java.io.Serializable;

public class User extends BaseBean implements Serializable {

    public static final long serialVersionUID = 2233933716943685981L;
    /**
     * code : 200
     * msg : 登录成功
     * result : {"ID":1,"Users_Organization":null,"Users_CellPhoneNum":"13800138000","Users_PassWord":"123456","Users_CorpName":"安监站","Users_IDCard":null,"Users_Kind":1,"Users_RegisterDate":"2016-06-14T11:20:02","Users_IsDel":false,"Users_Guid":null,"Users_PersonName":"刘某某","Users_CorpKind":null,"Users_AppID":109,"Users_AreaCode":"02","Users_TableName":null,"Users_PKCode":null,"Users_Alias":"10014AAC2F4FAD043E6BF71E30C34DEC","Users_JobName":"主管","Users_CorpKindName":"施工企业","Users_AreaName":"市南区","Users_Photo":null,"Users_OrderBy":null}
     */

    public String code;
    public String msg;
    /**
     * ID : 1
     * Users_Organization : null
     * Users_CellPhoneNum : 13800138000
     * Users_PassWord : 123456
     * Users_CorpName : 安监站
     * Users_IDCard : null
     * Users_Kind : 1
     * Users_RegisterDate : 2016-06-14T11:20:02
     * Users_IsDel : false
     * Users_Guid : null
     * Users_PersonName : 刘某某
     * Users_CorpKind : null
     * Users_AppID : 109
     * Users_AreaCode : 02
     * Users_TableName : null
     * Users_PKCode : null
     * Users_Alias : 10014AAC2F4FAD043E6BF71E30C34DEC
     * Users_JobName : 主管
     * Users_CorpKindName : 施工企业
     * Users_AreaName : 市南区
     * Users_Photo : null
     * Users_OrderBy : null
     */

    public ResultBean result;


    public static User objectFromData(String str) {

        return new Gson().fromJson(str, User.class);
    }

    public static class ResultBean {
        public int ID;
        public Object Users_Organization;
        public String Users_CellPhoneNum;
        public String Users_PassWord;
        public String Users_CorpName;
        public Object Users_IDCard;
        public int Users_Kind;
        public String Users_RegisterDate;
        public boolean Users_IsDel;
        public Object Users_Guid;
        public String Users_PersonName;
        public Object Users_CorpKind;
        public int Users_AppID;
        public String Users_AreaCode;
        public Object Users_TableName;
        public Object Users_PKCode;
        public String Users_Alias;
        public String Users_JobName;
        public String Users_CorpKindName;
        public String Users_AreaName;
        public Object Users_Photo;

        public Object Users_OrderBy;

        @Override
        public String toString() {
            return "ResultBean{" +
                    "ID=" + ID +
                    ", Users_Organization=" + Users_Organization +
                    ", Users_CellPhoneNum='" + Users_CellPhoneNum + '\'' +
                    ", Users_PassWord='" + Users_PassWord + '\'' +
                    ", Users_CorpName='" + Users_CorpName + '\'' +
                    ", Users_IDCard=" + Users_IDCard +
                    ", Users_Kind=" + Users_Kind +
                    ", Users_RegisterDate='" + Users_RegisterDate + '\'' +
                    ", Users_IsDel=" + Users_IsDel +
                    ", Users_Guid=" + Users_Guid +
                    ", Users_PersonName='" + Users_PersonName + '\'' +
                    ", Users_CorpKind=" + Users_CorpKind +
                    ", Users_AppID=" + Users_AppID +
                    ", Users_AreaCode='" + Users_AreaCode + '\'' +
                    ", Users_TableName=" + Users_TableName +
                    ", Users_PKCode=" + Users_PKCode +
                    ", Users_Alias='" + Users_Alias + '\'' +
                    ", Users_JobName='" + Users_JobName + '\'' +
                    ", Users_CorpKindName='" + Users_CorpKindName + '\'' +
                    ", Users_AreaName='" + Users_AreaName + '\'' +
                    ", Users_Photo=" + Users_Photo +
                    ", Users_OrderBy=" + Users_OrderBy +
                    '}';
        }

        public static ResultBean objectFromData(String str) {

            return new Gson().fromJson(str, ResultBean.class);
        }
    }


    @Override
    public String toString() {
        return "User{" +
                "code='" + code + '\'' +
                ", msg='" + msg + '\'' +
                ", result=" + result +
                '}';
    }




}





================================================
FILE: base/src/main/java/com/ccj/base/bean/UserDetail.java
================================================
package com.ccj.base.bean;

/**
 * Created by Administrator on 2016/8/10.
 */
public class UserDetail {



    public String Users_PersonName;



    public String Users_CellPhoneNum;

}


================================================
FILE: base/src/main/java/com/ccj/base/utils/BitmapUtil.java
================================================
package com.ccj.base.utils;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Environment;
import android.util.Log;

import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Created by Administrator on 2016/3/3.
 */
public class BitmapUtil {
    public static final String LOG_TAG = "HelloCamera";
    public static final int MEDIA_TYPE_IMAGE = 1;
    public static final int MEDIA_TYPE_VIDEO = 2;
    private static final String TAG = "BitmapUtil";
    private static boolean isRun = true;
    private static Context context;
    private int i=0;
    private static BitmapUtil bitmapUtil;
    private static File tempFile;
    private boolean getAllPicIsRun = true;
    private int pic2=0,pic1=0;

    public BitmapUtil(Context context){
        BitmapUtil.context =context;
    }

    /**
     * Create a file Uri for saving an image or video
     */
    public static Uri getOutputMediaFileUri(int type, String name) {
        return Uri.fromFile(getOutputMediaFile(type, name));
    }

    /**
     * Create a File for saving an image or video
     */
    public static File getOutputMediaFile(int type, String name) {
        // To be safe, you should check that the SDCard is mounted
        // using Environment.getExternalStorageState() before doing this.
        File mediaStorageDir = null;
        try {
            // This location works best if you want the created images to be
            // shared
            // between applications and persist after your app has been
            // uninstalled.
            mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
                    "MyCamera");
        } catch (Exception e) {
            e.printStackTrace();
            Log.e(LOG_TAG, "Error in Creating mediaStorageDir: " + mediaStorageDir);
        }
        // Create the storage directory if it does not exist
        if (!mediaStorageDir.exists()) {
            if (!mediaStorageDir.mkdirs()) {
                // <uses-permission
                // android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
                Log.e(LOG_TAG, "failed to create directory, check if you have the WRITE_EXTERNAL_STORAGE permission");
                return null;
            }
        }
        // Create a media file name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        File mediaFile = null;
        if (type == MEDIA_TYPE_IMAGE) {
            mediaFile = new File(mediaStorageDir.getPath() + File.separator + timeStamp + ".jpg");
            Log.d(LOG_TAG,
                    "sucessfully create mediafile");
        }
        return mediaFile;
    }

    public static String getPhotoURL(String name) {

        File mediaStorageDir;
        mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "MyCamera");

        String fileName = getFile(mediaStorageDir.getPath(), name);//判断文件是否包含文件名
        String file = mediaStorageDir.getPath() + File.separator + fileName;
        File file1 = new File(file);
        if (file1.isDirectory()) {
            return null;
        }
        return file;

    }

    public static String getFile(String dir, String contain) {
        if (contain==null){
            return "";
        }

        File file = new File(dir);
        File[] array = file.listFiles();
        Log.e("listFiles-->", array.length + "!"+contain);


        for (int i = 0; i < array.length; i++) {
            if (array[i].isFile()) {
                // only take file name
                Log.e("getFile-->", array[i].getName());
                if (array[i].getName().contains(contain)) {
                    return array[i].getName();
                } else if (array[i].isDirectory()) {
                    getFile(array[i].getPath(), contain);
                }
            }
        }
        return "";

    }

    public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;
        if (height > reqHeight || width > reqWidth) {
            final int heightRatio = Math.round((float) height / (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);
            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
        }
        return inSampleSize;
    }


    public static File transMsgPicFile(File file, Bitmap bitmap) {

         tempFile=BitmapUtil.getOutputMediaFile(MEDIA_TYPE_IMAGE, "temp");
        try {
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
            bitmap.compress(Bitmap.CompressFormat.JPEG, 60, bos);
            bos.flush();
            bos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return tempFile;
    }


    //纯粹的压缩图片
    public static Bitmap comp(Bitmap image) {
        if (image==null){
            return null;
        }
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        if (baos.toByteArray().length / 1024 > 1024) {//判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出
            baos.reset();//重置baos即清空baos
            image.compress(Bitmap.CompressFormat.JPEG, 50, baos);//这里压缩50%,把压缩后的数据存放到baos中
        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        //开始读入图片,此时把options.inJustDecodeBounds 设回true了
        newOpts.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
        newOpts.inJustDecodeBounds = false;
        int w = newOpts.outWidth;
        int h = newOpts.outHeight;
        //现在主流手机比较多是800*480分辨率,所以高和宽我们设置为
        float hh = 800f;//这里设置高度为800f
        float ww = 480f;//这里设置宽度为480f
        //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
        int be = 1;//be=1表示不缩放
        if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放
            be = (int) (newOpts.outWidth / ww);
        } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放
            be = (int) (newOpts.outHeight / hh);
        }
        if (be <= 0)
            be = 1;
        newOpts.inSampleSize = be;//设置缩放比例
        //重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
        isBm = new ByteArrayInputStream(baos.toByteArray());
        bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
        return compressImage(bitmap);//压缩好比例大小后再进行质量压缩
    }


    //由path 得到压缩后的bitmap
    private Bitmap getimage(String srcPath) {
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        //开始读入图片,此时把options.inJustDecodeBounds 设回true了
        newOpts.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);//此时返回bm为空

        newOpts.inJustDecodeBounds = false;
        int w = newOpts.outWidth;
        int h = newOpts.outHeight;
        //现在主流手机比较多是800*480分辨率,所以高和宽我们设置为
        float hh = 800f;//这里设置高度为800f
        float ww = 480f;//这里设置宽度为480f
        //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
        int be = 1;//be=1表示不缩放
        if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放
            be = (int) (newOpts.outWidth / ww);
        } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放
            be = (int) (newOpts.outHeight / hh);
        }
        if (be <= 0)
            be = 1;
        newOpts.inSampleSize = be;//设置缩放比例
        //重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
        bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
        return compressImage(bitmap);//压缩好比例大小后再进行质量压缩
    }

    //质量压缩图片
    private static Bitmap compressImage(Bitmap image) {

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
        int options = 100;
        while (baos.toByteArray().length / 1024 > 100 && options>10) {  //循环判断如果压缩后图片是否大于100kb,大于继续压缩
            baos.reset();//重置baos即清空baos
            image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%,把压缩后的数据存放到baos中
            options -= 10;//每次都减少10
        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片
        return bitmap;
    }

}


================================================
FILE: base/src/main/java/com/ccj/base/utils/LruBitmapCache.java
================================================
package com.ccj.base.utils;

import android.graphics.Bitmap;
import android.support.v4.util.LruCache;

import com.android.volley.toolbox.ImageLoader;

/**
 * 图片缓存池
 * Created by ccj on 2016/1/6.
 */
public class LruBitmapCache implements ImageLoader.ImageCache {
    private LruCache<String, Bitmap> mCache;

    public LruBitmapCache() {
        int maxSize = 10 * 1024 * 1024;

        mCache = new LruCache<String, Bitmap>(maxSize) {
            @Override
            protected int sizeOf(String key, Bitmap value) {
                return value.getRowBytes() * value.getHeight();
            }
        };
    }

    @Override
    public Bitmap getBitmap(String url) {
        return mCache.get(url);
    }

    @Override
    public void putBitmap(String url, Bitmap bitmap) {
        mCache.put(url, bitmap);
    }

}


================================================
FILE: base/src/main/java/com/ccj/base/utils/SerializableUtil.java
================================================
package com.ccj.base.utils;

import android.util.Base64;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.List;

/**
 * Created by ccj on 2015/12/7.
 * 将 对象转为 字符串,易于保存 上传等
 *
 */
public class SerializableUtil {

    public static String objToStr(Object obj) throws IOException {
        if (obj == null) {
            return "";
        }
        //实例化一个ByteArrayOutputStream对象,用来装载压缩后的字节文件
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        //然后将得到的字符数据装载到ObjectOutputStream
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        //writeObject 方法负责写入特定类的对象的状态,以便相应的readObject可以还原它
        oos.writeObject(obj);
        //最后,用Base64.encode将字节文件转换成Base64编码,并以String形式保存
        String listString = new String(Base64.encode(baos.toByteArray(), Base64.DEFAULT));
        //关闭oos
        oos.close();
        return listString;

    }


    //将序列化的数据还原成Object

    public static Object strToObj(String str) throws IOException {
        byte[] mByte = Base64.decode(str.getBytes(), Base64.DEFAULT);
        ByteArrayInputStream bais = new ByteArrayInputStream(mByte);
        ObjectInputStream ois = new ObjectInputStream(bais);
        try {

            return ois.readObject();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static <T> String listToString(List<T> list) throws IOException {
        //实例化一个ByteArrayOutputStream对象,用来装载压缩后的字节文件
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        //然后将得到的字符数据装载到ObjectOutputStream
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        //writeObject 方法负责写入特定类的对象的状态,以便相应的readObject可以还原它
        oos.writeObject(list);
        //最后,用Base64.encode将字节文件转换成Base64编码,并以String形式保存
        String listString = new String(Base64.encode(baos.toByteArray(), Base64.DEFAULT));
        //关闭oos
        oos.close();
        return listString;
    }


    public static <T> List<T> stringToList(String str) throws IOException {
        byte[] mByte = Base64.decode(str.getBytes(), Base64.DEFAULT);
        ByteArrayInputStream bais = new ByteArrayInputStream(mByte);
        ObjectInputStream ois = new ObjectInputStream(bais);
        List<T> stringList = null;
        try {
            stringList = (List<T>) ois.readObject();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return stringList;
    }


}


================================================
FILE: base/src/main/java/com/ccj/base/utils/SharedPreferenceUtil.java
================================================
package com.ccj.base.utils;

import android.content.Context;
import android.content.SharedPreferences;
import android.text.TextUtils;
import android.util.Log;

import com.ccj.base.base.BaseApplication;
import com.ccj.base.bean.User;

import java.io.IOException;
import java.io.StreamCorruptedException;


public class SharedPreferenceUtil {

    // 用户名key
    public final static String KEY_NAME = "KEY_NAME";
    public final static String KEY_AUTO = "KEY_AUTO";
    public final static String KEY_LOGIN = "KEY_LOGIN";
    public final static String KEY_LEVEL = "KEY_LEVEL";
    public final static String KEY_DELIVERY = "KEY_DELIVERY";
    private static SharedPreferenceUtil spUtils;
    private static User spUser = null;
    private SharedPreferences sp;


    //

    /**
     *
     * 初始化,一般在应用启动之后就要初始化
     *
     * @param context 此处的context要用application的全局上下文,
     *                避免static强类型一直持有activity的引用,造成内存泄露
     */
    public static synchronized void initSharedPreference(Context context) {
        if (spUtils == null) {
            spUtils = new SharedPreferenceUtil(context);
        }
    }


    /**
     * 获取唯一的instance
     *
     * @return
     */

    public static synchronized SharedPreferenceUtil getInstance() {
        if (spUtils == null) {
            spUtils = new SharedPreferenceUtil(BaseApplication.getInstance());
        }

        return spUtils;
    }

    public SharedPreferenceUtil(Context context) {
        sp = context.getSharedPreferences("SharedPreferenceUtil", Context.MODE_PRIVATE);
    }

    public SharedPreferences getSharedPref() {
        return sp;
    }

    public synchronized void putAutoLogin(Boolean AutoLogin) {
        SharedPreferences.Editor editor = sp.edit();
        editor.putBoolean(KEY_AUTO, AutoLogin);
        editor.commit();
    }

    public synchronized Boolean getAutoLogin() {
        Boolean flag = sp.getBoolean(KEY_AUTO, false);
        Log.i("flag", flag + "flag");
        return flag;
    }

    public synchronized void setIsLogin(Boolean AutoLogin) {
        SharedPreferences.Editor editor = sp.edit();
        editor.putBoolean(KEY_LOGIN, AutoLogin);
        editor.commit();
    }

    public synchronized Boolean getIsLogin() {
        Boolean flag = sp.getBoolean(KEY_LOGIN, false);
        return flag;
    }

    public synchronized void putUser(User user) {
        SharedPreferences.Editor editor = sp.edit();
        String str = "";
        try {
            str = SerializableUtil.objToStr(user);
        } catch (IOException e) {
            e.printStackTrace();
        }
        editor.putString(KEY_NAME, str);
        editor.commit();
        spUser = user;
    }


    //记录用户名
    public void setUsername(String username){
        SharedPreferences.Editor editor = sp.edit();
        editor.putString("pre_username",username);
        editor.apply();
    }

    //读取用户名
    public String getUsername(){
        return sp.getString("pre_username","");
    }


    public synchronized User getUser()
    {
        String str = sp.getString(SharedPreferenceUtil.KEY_NAME, "");
        if (TextUtils.isEmpty(str)) {
            return null;
        }
        if (spUser == null) {
            spUser = new User();
            //获取序列化的数据
            try {
                Object obj = SerializableUtil.strToObj(str);
                if (obj != null) {
                    spUser = (User) obj;
                    Log.e("USER", "getuser" + spUser.toString());
                }
            } catch (StreamCorruptedException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return spUser;
    }


    public synchronized void DeleteUser() {
        SharedPreferences.Editor editor = sp.edit();
        editor.putString(KEY_NAME, "");
        editor.commit();
        spUser = null;
    }

//
//    public synchronized DeliveryMessage getDeliveryMessage() {
//        DeliveryMessage deliveryMessage = new DeliveryMessage();
//        //获取序列化的数据
//        String str = sp.getString(SharedPreferenceUtil.KEY_DELIVERY, "");
//        if (TextUtils.isEmpty(str)) {
//            return null;
//        }
//        try {
//            Object obj = SerializableUtil.strToObj(str);
//            if (obj != null) {
//                deliveryMessage = (DeliveryMessage) obj;
//            }
//        } catch (StreamCorruptedException e) {
//            e.printStackTrace();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//
//        return deliveryMessage;
//
//    }
//
//    public synchronized void putDeliveryMessage(DeliveryMessage deliveryMessage) {
//        SharedPreferences.Editor editor = sp.edit();
//        String str = "";
//        try {
//            str = SerializableUtil.objToStr(deliveryMessage);
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//        editor.putString(KEY_DELIVERY, str);
//        editor.commit();
//    }


}


================================================
FILE: base/src/main/java/com/ccj/base/utils/TDeviceUtils.java
================================================
package com.ccj.base.utils;

import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Dialog;
import android.content.ActivityNotFoundException;
import android.content.ClipboardManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.graphics.Point;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.PowerManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Display;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;

import com.ccj.base.R;
import com.ccj.base.base.BaseApplication;

import java.io.File;
import java.lang.reflect.Field;
import java.text.NumberFormat;
import java.util.List;

@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
public class TDeviceUtils {

    // 手机网络类型
    public static final int NETTYPE_WIFI = 0x01;
    public static final int NETTYPE_CMWAP = 0x02;
    public static final int NETTYPE_CMNET = 0x03;

    public static boolean GTE_HC;
    public static boolean GTE_ICS;
    public static boolean PRE_HC;
    private static Boolean _hasBigScreen = null;
    private static Boolean _hasCamera = null;
    private static Boolean _isTablet = null;
    private static Integer _loadFactor = null;

    private static int _pageSize = -1;
    public static float displayDensity = 0.0F;

    static {
        GTE_ICS = Build.VERSION.SDK_INT >= 14;
        GTE_HC = Build.VERSION.SDK_INT >= 11;
        PRE_HC = Build.VERSION.SDK_INT < 11;
    }

    public TDeviceUtils() {
    }

    public static float dpToPixel(float dp) {
        return dp * (getDisplayMetrics().densityDpi / 160F);
    }

    public static int getDefaultLoadFactor() {
        if (_loadFactor == null) {
            Integer integer = Integer.valueOf(0xf & BaseApplication.getContext()
                    .getResources().getConfiguration().screenLayout);
            _loadFactor = integer;
            _loadFactor = Integer.valueOf(Math.max(integer.intValue(), 1));
        }
        return _loadFactor.intValue();
    }

    public static float getDensity() {
        if (displayDensity == 0.0)
            displayDensity = getDisplayMetrics().density;
        return displayDensity;
    }

    public static DisplayMetrics getDisplayMetrics() {
        DisplayMetrics displaymetrics = new DisplayMetrics();
        ((WindowManager) BaseApplication.getContext().getSystemService(
                Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(
                displaymetrics);
        return displaymetrics;
    }

    public static float getScreenHeight() {
        return getDisplayMetrics().heightPixels;
    }

    public static float getScreenWidth() {
        return getDisplayMetrics().widthPixels;
    }

    public static int[] getRealScreenSize(Activity activity) {
        int[] size = new int[2];
        int screenWidth = 0, screenHeight = 0;
        WindowManager w = activity.getWindowManager();
        Display d = w.getDefaultDisplay();
        DisplayMetrics metrics = new DisplayMetrics();
        d.getMetrics(metrics);
        // since SDK_INT = 1;
        screenWidth = metrics.widthPixels;
        screenHeight = metrics.heightPixels;
        // includes window decorations (statusbar bar/menu bar)
        if (Build.VERSION.SDK_INT >= 14 && Build.VERSION.SDK_INT < 17)
            try {
                screenWidth = (Integer) Display.class.getMethod("getRawWidth")
                        .invoke(d);
                screenHeight = (Integer) Display.class
                        .getMethod("getRawHeight").invoke(d);
            } catch (Exception ignored) {
            }
        // includes window decorations (statusbar bar/menu bar)
        if (Build.VERSION.SDK_INT >= 17)
            try {
                Point realSize = new Point();
                Display.class.getMethod("getRealSize", Point.class).invoke(d,
                        realSize);
                screenWidth = realSize.x;
                screenHeight = realSize.y;
            } catch (Exception ignored) {
            }
        size[0] = screenWidth;
        size[1] = screenHeight;
        return size;
    }

    public static int getStatusBarHeight() {
        Class<?> c = null;
        Object obj = null;
        Field field = null;
        int x = 0;
        try {
            c = Class.forName("com.android.internal.R$dimen");
            obj = c.newInstance();
            field = c.getField("status_bar_height");
            x = Integer.parseInt(field.get(obj).toString());
            return BaseApplication.getContext().getResources()
                    .getDimensionPixelSize(x);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }



    public static boolean hasBigScreen() {
        boolean flag = true;
        if (_hasBigScreen == null) {
            boolean flag1;
            if ((0xf & BaseApplication.getContext().getResources()
                    .getConfiguration().screenLayout) >= 3)
                flag1 = flag;
            else
                flag1 = false;
            Boolean boolean1 = Boolean.valueOf(flag1);
            _hasBigScreen = boolean1;
            if (!boolean1.booleanValue()) {
                if (getDensity() <= 1.5F)
                    flag = false;
                _hasBigScreen = Boolean.valueOf(flag);
            }
        }
        return _hasBigScreen.booleanValue();
    }

    public static final boolean hasCamera() {
        if (_hasCamera == null) {
            PackageManager pckMgr = BaseApplication.getContext()
                    .getPackageManager();
            boolean flag = pckMgr
                    .hasSystemFeature("android.hardware.camera.front");
            boolean flag1 = pckMgr.hasSystemFeature("android.hardware.camera");
            boolean flag2;
            flag2 = flag || flag1;
            _hasCamera = Boolean.valueOf(flag2);
        }
        return _hasCamera.booleanValue();
    }

    public static boolean hasHardwareMenuKey(Context getContext) {
        boolean flag = false;
        if (PRE_HC)
            flag = true;
        else if (GTE_ICS) {
            flag = ViewConfiguration.get(getContext).hasPermanentMenuKey();
        } else
            flag = false;
        return flag;
    }

    public static boolean hasInternet() {
        boolean flag;

        ConnectivityManager manager = (ConnectivityManager) BaseApplication.getContext()
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = manager.getActiveNetworkInfo();
        flag = activeNetworkInfo != null;
        return flag;
    }

    public static boolean gotoGoogleMarket(Activity activity, String pck) {
        try {
            Intent intent = new Intent();
            intent.setPackage("com.android.vending");
            intent.setAction(Intent.ACTION_VIEW);
            intent.setData(Uri.parse("market://details?id=" + pck));
            activity.startActivity(intent);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public static boolean isPackageExist(String pckName) {
        try {
            PackageInfo pckInfo = BaseApplication.getContext().getPackageManager()
                    .getPackageInfo(pckName, 0);
            if (pckInfo != null)
                return true;
        } catch (NameNotFoundException e) {
            TLog.error(e.getMessage());
        }
        return false;
    }

    public static void hideAnimatedView(View view) {
        if (PRE_HC && view != null)
            view.setPadding(view.getWidth(), 0, 0, 0);
    }

    public static void hideSoftKeyboard(View view) {
        if (view == null)
            return;
        ((InputMethodManager) BaseApplication.getContext().getSystemService(
                Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(
                view.getWindowToken(), 0);
    }

    public static boolean isLandscape() {
        boolean flag;
        flag = BaseApplication.getContext().getResources().getConfiguration().orientation == 2;
        return flag;
    }

    public static boolean isPortrait() {
        boolean flag = true;
        if (BaseApplication.getContext().getResources().getConfiguration().orientation != 1)
            flag = false;
        return flag;
    }

    public static boolean isTablet() {
        if (_isTablet == null) {
            boolean flag;
            flag = (0xf & BaseApplication.getContext().getResources()
                    .getConfiguration().screenLayout) >= 3;
            _isTablet = Boolean.valueOf(flag);
        }
        return _isTablet.booleanValue();
    }

    public static float pixelsToDp(float f) {
        return f / (getDisplayMetrics().densityDpi / 160F);
    }

    public static void showAnimatedView(View view) {
        if (PRE_HC && view != null)
            view.setPadding(0, 0, 0, 0);
    }

    public static void showSoftKeyboard(Dialog dialog) {
        dialog.getWindow().setSoftInputMode(4);
    }

    public static void showSoftKeyboard(View view) {
        ((InputMethodManager) BaseApplication.getContext().getSystemService(
                Context.INPUT_METHOD_SERVICE)).showSoftInput(view,
                InputMethodManager.SHOW_FORCED);
    }

    public static void toogleSoftKeyboard(View view) {
        ((InputMethodManager) BaseApplication.getContext().getSystemService(
                Context.INPUT_METHOD_SERVICE)).toggleSoftInput(0,
                InputMethodManager.HIDE_NOT_ALWAYS);
    }

    public static boolean isSdcardReady() {
        return Environment.MEDIA_MOUNTED.equals(Environment
                .getExternalStorageState());
    }

    public static String getCurCountryLan() {
        return BaseApplication.getContext().getResources().getConfiguration().locale
                .getLanguage()
                + "-"
                + BaseApplication.getContext().getResources().getConfiguration().locale
                .getCountry();
    }

    public static boolean isZhCN() {
        String lang = BaseApplication.getContext().getResources()
                .getConfiguration().locale.getCountry();
        return lang.equalsIgnoreCase("CN");
    }

    public static String percent(double p1, double p2) {
        String str;
        double p3 = p1 / p2;
        NumberFormat nf = NumberFormat.getPercentInstance();
        nf.setMinimumFractionDigits(2);
        str = nf.format(p3);
        return str;
    }

    public static String percent2(double p1, double p2) {
        String str;
        double p3 = p1 / p2;
        NumberFormat nf = NumberFormat.getPercentInstance();
        nf.setMinimumFractionDigits(0);
        str = nf.format(p3);
        return str;
    }

    public static void gotoMarket(Context getContext, String pck) {
        if (!isHaveMarket(getContext)) {
            BaseApplication.showToast("你手机中没有安装应用市场!");
            return;
        }
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_VIEW);
        intent.setData(Uri.parse("market://details?id=" + pck));
        if (intent.resolveActivity(getContext.getPackageManager()) != null) {
            getContext.startActivity(intent);
        }
    }

    public static boolean isHaveMarket(Context getContext) {
        Intent intent = new Intent();
        intent.setAction("android.intent.action.MAIN");
        intent.addCategory("android.intent.category.APP_MARKET");
        PackageManager pm = getContext.getPackageManager();
        List<ResolveInfo> infos = pm.queryIntentActivities(intent, 0);
        return infos.size() > 0;
    }

    public static void openAppInMarket(Context getContext) {
        if (getContext != null) {
            String pckName = getContext.getPackageName();
            try {
                gotoMarket(getContext, pckName);
            } catch (Exception ex) {
                try {
                    String otherMarketUri = "http://market.android.com/details?id="
                            + pckName;
                    Intent intent = new Intent(Intent.ACTION_VIEW,
                            Uri.parse(otherMarketUri));
                    getContext.startActivity(intent);
                } catch (Exception e) {

                }
            }
        }
    }

    public static void setFullScreen(Activity activity) {
        WindowManager.LayoutParams params = activity.getWindow()
                .getAttributes();
        params.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
        activity.getWindow().setAttributes(params);
        activity.getWindow().addFlags(
                WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
    }

    public static void cancelFullScreen(Activity activity) {
        WindowManager.LayoutParams params = activity.getWindow()
                .getAttributes();
        params.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);
        activity.getWindow().setAttributes(params);
        activity.getWindow().clearFlags(
                WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
    }

    public static PackageInfo getPackageInfo(String pckName) {
        try {
            return BaseApplication.getContext().getPackageManager()
                    .getPackageInfo(pckName, 0);
        } catch (NameNotFoundException e) {
            TLog.error(e.getMessage());
        }
        return null;
    }

    public static int getVersionCode() {
        int versionCode = 0;
        try {
            versionCode = BaseApplication
                    .getContext()
                    .getPackageManager()
                    .getPackageInfo(BaseApplication.getContext().getPackageName(),
                            0).versionCode;
        } catch (NameNotFoundException ex) {
            versionCode = 0;
        }
        return versionCode;
    }

    public static int getVersionCode(String packageName) {
        int versionCode = 0;
        try {
            versionCode = BaseApplication.getContext().getPackageManager()
                    .getPackageInfo(packageName, 0).versionCode;
        } catch (NameNotFoundException ex) {
            versionCode = 0;
        }
        return versionCode;
    }

    public static String getVersionName() {
        String name = "";
        try {
            name = BaseApplication
                    .getContext()
                    .getPackageManager()
                    .getPackageInfo(BaseApplication.getContext().getPackageName(),
                            0).versionName;
        } catch (NameNotFoundException ex) {
            name = "";
        }
        return name;
    }

    public static boolean isScreenOn() {
        PowerManager pm = (PowerManager) BaseApplication.getContext()
                .getSystemService(Context.POWER_SERVICE);
        return pm.isScreenOn();
    }

    public static void installAPK(Context getContext, File file) {
        if (file == null || !file.exists())
            return;
        Intent intent = new Intent();
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setAction(Intent.ACTION_VIEW);
        intent.setDataAndType(Uri.fromFile(file),
                "application/vnd.android.package-archive");
        getContext.startActivity(intent);
    }

    public static Intent getInstallApkIntent(File file) {
        Intent intent = new Intent();
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setAction(Intent.ACTION_VIEW);
        intent.setDataAndType(Uri.fromFile(file),
                "application/vnd.android.package-archive");
        return intent;
    }

    public static void openDial(Context getContext, String number) {
        Uri uri = Uri.parse("tel:" + number);
        Intent it = new Intent(Intent.ACTION_DIAL, uri);
        getContext.startActivity(it);
    }

    public static void openSMS(Context getContext, String smsBody, String tel) {
        Uri uri = Uri.parse("smsto:" + tel);
        Intent it = new Intent(Intent.ACTION_SENDTO, uri);
        it.putExtra("sms_body", smsBody);
        getContext.startActivity(it);
    }

    public static void openDail(Context getContext) {
        Intent intent = new Intent(Intent.ACTION_DIAL);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        getContext.startActivity(intent);
    }

    public static void openSendMsg(Context getContext) {
        Uri uri = Uri.parse("smsto:");
        Intent intent = new Intent(Intent.ACTION_SENDTO, uri);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        getContext.startActivity(intent);
    }

    public static void openCamera(Context getContext) {
        Intent intent = new Intent(); // 调用照相机
        intent.setAction("android.media.action.STILL_IMAGE_CAMERA");
        intent.setFlags(0x34c40000);
        getContext.startActivity(intent);
    }

    public static String getIMEI() {
        TelephonyManager tel = (TelephonyManager) BaseApplication.getContext()
                .getSystemService(Context.TELEPHONY_SERVICE);
        return tel.getDeviceId();
    }

    public static String getPhoneType() {
        return Build.MODEL;
    }

    public static void openApp(Context getContext, String packageName) {
        Intent mainIntent = BaseApplication.getContext().getPackageManager()
                .getLaunchIntentForPackage(packageName);
        if (mainIntent == null) {
            mainIntent = new Intent(packageName);
        } else {
            TLog.log("Action:" + mainIntent.getAction());
        }
        getContext.startActivity(mainIntent);
    }

    public static boolean openAppActivity(Context getContext, String packageName,
                                          String activityName) {
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_LAUNCHER);
        ComponentName cn = new ComponentName(packageName, activityName);
        intent.setComponent(cn);
        try {
            getContext.startActivity(intent);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public static boolean isWifiOpen() {
        boolean isWifiConnect = false;
        ConnectivityManager cm = (ConnectivityManager) BaseApplication
                .getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
        // check the networkInfos numbers
        NetworkInfo[] networkInfos = cm.getAllNetworkInfo();
        for (int i = 0; i < networkInfos.length; i++) {
            if (networkInfos[i].getState() == NetworkInfo.State.CONNECTED) {
                if (networkInfos[i].getType() == ConnectivityManager.TYPE_MOBILE) {
                    isWifiConnect = false;
                }
                if (networkInfos[i].getType() == ConnectivityManager.TYPE_WIFI) {
                    isWifiConnect = true;
                }
            }
        }
        return isWifiConnect;
    }

    public static void uninstallApk(Context getContext, String packageName) {
        if (isPackageExist(packageName)) {
            Uri packageURI = Uri.parse("package:" + packageName);
            Intent uninstallIntent = new Intent(Intent.ACTION_DELETE,
                    packageURI);
            getContext.startActivity(uninstallIntent);
        }
    }

    @SuppressWarnings("deprecation")
    public static void copyTextToBoard(String string) {
        if (TextUtils.isEmpty(string))
            return;
        ClipboardManager clip = (ClipboardManager) BaseApplication.getContext()
                .getSystemService(Context.CLIPBOARD_SERVICE);
        clip.setText(string);
        BaseApplication.showToast("复制成功");
    }

    /**
     * 发送邮件
     *
     * @param getContext
     * @param subject 主题
     * @param content 内容
     * @param emails  邮件地址
     */
    public static void sendEmail(Context getContext, String subject,
                                 String content, String... emails) {
        try {
            Intent intent = new Intent(Intent.ACTION_SEND);
            // 模拟器
            // intent.setType("text/plain");
            intent.setType("message/rfc822"); // 真机
            intent.putExtra(Intent.EXTRA_EMAIL, emails);
            intent.putExtra(Intent.EXTRA_SUBJECT, subject);
            intent.putExtra(Intent.EXTRA_TEXT, content);
            getContext.startActivity(intent);
        } catch (ActivityNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static int getStatuBarHeight() {
        Class<?> c = null;
        Object obj = null;
        Field field = null;
        int x = 0, sbar = 38;// 默认为38,貌似大部分是这样的
        try {
            c = Class.forName("com.android.internal.R$dimen");
            obj = c.newInstance();
            field = c.getField("status_bar_height");
            x = Integer.parseInt(field.get(obj).toString());
            sbar = BaseApplication.getContext().getResources()
                    .getDimensionPixelSize(x);

        } catch (Exception e1) {
            e1.printStackTrace();
        }
        return sbar;
    }

    public static int getActionBarHeight(Context getContext) {
        int actionBarHeight = 0;
        TypedValue tv = new TypedValue();
        if (getContext.getTheme().resolveAttribute(android.R.attr.actionBarSize,
                tv, true))
            actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,
                    getContext.getResources().getDisplayMetrics());

        if (actionBarHeight == 0
                && getContext.getTheme().resolveAttribute(R.attr.actionBarSize,
                tv, true)) {
            actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,
                    getContext.getResources().getDisplayMetrics());
        }

        return actionBarHeight;
    }

    public static boolean hasStatusBar(Activity activity) {
        WindowManager.LayoutParams attrs = activity.getWindow().getAttributes();
        return (attrs.flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) != WindowManager.LayoutParams.FLAG_FULLSCREEN;
    }

    /**
     * 调用系统安装了的应用分享
     *
     * @param getContext
     * @param title
     * @param url
     */
    public static void showSystemShareOption(Activity getContext,
                                             final String title, final String url) {
        Intent intent = new Intent(Intent.ACTION_SEND);
        intent.setType("text/plain");
        intent.putExtra(Intent.EXTRA_SUBJECT, "分享:" + title);
        intent.putExtra(Intent.EXTRA_TEXT, title + " " + url);
        getContext.startActivity(Intent.createChooser(intent, "选择分享"));
    }

    /**
     * 获取当前网络类型
     *
     * @return 0:没有网络 1:WIFI网络 2:WAP网络 3:NET网络
     */
    public static int getNetworkType() {
        int netType = 0;
        ConnectivityManager connectivityManager = (ConnectivityManager) BaseApplication
                .getInstance().getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
        if (networkInfo == null) {
            return netType;
        }
        int nType = networkInfo.getType();
        if (nType == ConnectivityManager.TYPE_MOBILE) {
            String extraInfo = networkInfo.getExtraInfo();
            if (!TextUtils.isEmpty(extraInfo)) {
                if (extraInfo.toLowerCase().equals("cmnet")) {
                    netType = NETTYPE_CMNET;
                } else {
                    netType = NETTYPE_CMWAP;
                }
            }
        } else if (nType == ConnectivityManager.TYPE_WIFI) {
            netType = NETTYPE_WIFI;
        }
        return netType;
    }
}


================================================
FILE: base/src/main/java/com/ccj/base/utils/TLog.java
================================================
package com.ccj.base.utils;

import android.util.Log;

public class TLog {
	public static final String LOG_TAG = "TLog-->";
	public static boolean DEBUG = true;//是否处在debug

	public TLog() {
	}
	
	public static final void analytics(String log) {
		if (DEBUG)
			Log.d(LOG_TAG, log);
	}

	public static final void error(String log) {
		if (DEBUG)
			Log.e(LOG_TAG, "" + log);
	}

	public static final void log(String log) {
		if (DEBUG)
			Log.e(LOG_TAG, log);
	}

	public static final void log(String tag, String log) {
		if (DEBUG)
			Log.e(tag, log);
	}

	public static final void logI(String log) {
		if (DEBUG)
			Log.i(LOG_TAG, log);
	}

	public static final void warn(String log) {
		if (DEBUG)
			Log.w(LOG_TAG, log);
	}
}


================================================
FILE: base/src/main/java/com/ccj/base/utils/ToastUtil.java
================================================
package com.ccj.base.utils;

import com.ccj.base.base.BaseApplication;

public class ToastUtil {


    public static void show( String text) {
        android.widget.Toast.makeText(BaseApplication.getContext(), text, android.widget.Toast.LENGTH_SHORT).show();
    }

}


================================================
FILE: base/src/main/java/com/ccj/base/utils/eventbus/EventUtils.java
================================================
package com.ccj.base.utils.eventbus;


/**
 * 事件总线 用于组件或线程通信,可替代回调,广播等
 * Created by ccj on 2016/4/14.
 */
public class EventUtils {
    /**
     * 传递String类型的event
     *
     */
    public static class StringEvent{
        private String mMsg;
        public StringEvent(String msg) {
            // TODO Auto-generated constructor stub
            this.mMsg = msg;
        }
        public String getMsg(){
            return mMsg;
        }
    }

    public static class intEvent{
        private int mMsg;
        public intEvent(int msg) {
            // TODO Auto-generated constructor stub
            this.mMsg = msg;
        }
        public int getMsg(){
            return mMsg;
        }
    }

    /**
     * object类型(即传统的所有类型,都可以强转进行传递事件)
     *
     */

    public static class ObjectEvent{
        private Object object;
        public ObjectEvent(Object object) {
            // TODO Auto-generated constructor stub
            this.object = object;
        }
        public Object getMsg(){
            return object;
        }
    }

}


================================================
FILE: base/src/main/java/com/ccj/base/utils/router/LoginModuleService.java
================================================
package com.ccj.base.utils.router;

import com.alibaba.android.arouter.facade.template.IProvider;

/**
 * 示例:子模块间调用方法
 * Created by chenchangjun on 17/8/14.
 */

public interface LoginModuleService extends IProvider {


     boolean checkLoginState();

}


================================================
FILE: base/src/main/java/com/ccj/base/utils/router/RounterInterceptor.java
================================================
package com.ccj.base.utils.router;

import android.content.Context;

import com.alibaba.android.arouter.facade.Postcard;
import com.alibaba.android.arouter.facade.annotation.Interceptor;
import com.alibaba.android.arouter.facade.callback.InterceptorCallback;
import com.alibaba.android.arouter.facade.template.IInterceptor;

/**
 * // 比较经典的应用就是在跳转过程中处理登陆事件,这样就不需要在目标页重复做登陆检查
 // 拦截器会在跳转之间执行,多个拦截器会按优先级顺序依次执行
 * Created by chenchangjun on 17/8/9.
 */

@Interceptor(priority = 8, name = "测试用拦截器")
public class RounterInterceptor implements IInterceptor {




    @Override
    public void process(Postcard postcard, InterceptorCallback callback) {

        callback.onContinue(postcard);  // 处理完成,交还控制权
        // callback.onInterrupt(new RuntimeException("我觉得有点异常"));      // 觉得有问题,中断路由流程

        // 以上两种至少需要调用其中一种,否则不会继续路由
    }

    @Override
    public void init(Context context) {
        // 拦截器的初始化,会在sdk初始化的时候调用该方法,仅会调用一次

    }
}


================================================
FILE: base/src/main/java/com/ccj/base/utils/router/RounterSerialization.java
================================================
package com.ccj.base.utils.router;

import android.content.Context;

import com.alibaba.android.arouter.facade.annotation.Route;
import com.alibaba.android.arouter.facade.service.SerializationService;

import java.lang.reflect.Type;

/**
 * Created by chenchangjun on 17/8/9.
 */
@Route(path = "/router/RounterSerialization")
public class RounterSerialization implements SerializationService {


    @Override
    public <T> T json2Object(String json, Class<T> clazz) {
        return null;
    }

    @Override
    public String object2Json(Object instance) {
        return null;
    }

    /**
     * Parse json to object
     *
     * @param input json string
     * @param clazz object type
     * @return instance of object
     */
    @Override
    public <T> T parseObject(String input, Type clazz) {
        return null;
    }

    @Override
    public void init(Context context) {

    }
}


================================================
FILE: base/src/main/java/com/ccj/base/utils/router/RouterService.java
================================================
package com.ccj.base.utils.router;

import com.alibaba.android.arouter.facade.template.IProvider;

/**
 * Created by chenchangjun on 17/8/9.
 */

public interface RouterService extends IProvider {


    String start(String name);

}


================================================
FILE: base/src/main/java/com/ccj/base/utils/router/RouterUtils.java
================================================
package com.ccj.base.utils.router;

import android.app.Activity;

import com.alibaba.android.arouter.launcher.ARouter;

//https://github.com/alibaba/ARouter
public class RouterUtils {



    public static void inject(Object obj){
        ARouter.getInstance().inject(obj);

    }

    /**
     * 跳转
     * 得到 跳转对象
     * @param path
     * @return
     */
    public static Object navigation(String path) {
        // 构建标准的路由请求
        return  ARouter.getInstance().build(path).navigation();
    }



    public void startActivityForResult(Activity activity,String path,int requestCode,String argKey,Object argValue) {
        ARouter.getInstance().build(path).
                withObject(argKey, argValue).
                navigation(activity, requestCode);
    }

    public void startActivityForCallback() {
// 使用两个参数的navigation方法,可以获取单次跳转的结果
        //ARouter.getInstance().build("/test/1").navigation(this, new NavigationCallback() );
    }


}




================================================
FILE: base/src/main/java/com/ccj/base/view/SuperRecyclerView.java
================================================
package com.ccj.base.view;

import android.content.Context;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;

import com.ccj.base.R;
import com.ccj.base.utils.ToastUtil;
import com.ccj.base.view.list.OnAppBarSkipListener;
import com.ccj.base.view.list.OnLoadNextListener;


public class SuperRecyclerView extends RecyclerView {

    private OnLoadNextListener mLoadNextListener;
    private OnAppBarSkipListener mAppBarSkipListener;

    //是否正在加载
    private boolean isLoading = false;
    //是否加载到最后
    private boolean isEnd = false;
    //没有更多提示是否已显示过
    private boolean toastHasShown = false;

    private int mActionBarAutoHideSensivity = 0;
    private int mActionBarAutoHideMinY = 0;
    private int mActionBarAutoHideSignal = 0;

    public SuperRecyclerView(Context context) {
        super(context);
        init();
    }

    public SuperRecyclerView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public SuperRecyclerView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    public void setOnAppBarSkipListener(OnAppBarSkipListener listener) {
        mAppBarSkipListener = listener;
    }

    private void init() {

        addOnScrollListener(new OnScrollListener() {
            final static int ITEMS_THRESHOLD = 1;
            int lastFvi = 0;

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                LinearLayoutManager mLayoutManager = (LinearLayoutManager) getLayoutManager();
                int firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition();
                if (lastFvi != firstVisibleItem) {
                    if (lastFvi > 0) {
                        onMainContentScrolled(firstVisibleItem <= ITEMS_THRESHOLD ? 0 : Integer.MAX_VALUE,
                                lastFvi - firstVisibleItem > 0 ? Integer.MIN_VALUE : Integer.MAX_VALUE
                        );
                    }
                    lastFvi = firstVisibleItem;
                }
                int totalItemCount = mLayoutManager.getItemCount();
                if (isEnd) {
                    if (!toastHasShown) {
                        //加载到最后,判断是否拉到底部
                        if (!canScrollVertically(1)) {
                            if (canScrollVertically(-1)) {//只有内容超过一屏时才触发提示
                                ToastUtil.show( getResources().getString(R.string.no_more));
                                toastHasShown = true;
                            }
                        }
                    }
                } else if (!isLoading && mLoadNextListener != null) {
                    int lastVisibleItem = mLayoutManager.findLastVisibleItemPosition();
                    //lastVisibleItem >= totalItemCount - 3 表示剩下2个item自动加载(因为包含Banner)
                    // dy>0 表示向下滑动
                    if (totalItemCount > 5 && lastVisibleItem >= totalItemCount - 3 && dy > 0) {
                        isLoading = true;
                        mLoadNextListener.onLoadNext();
                    }
                }
                //用于防止首页好价的toolbar 因快速的显示隐藏而抖动
                if (null != mAppBarSkipListener) {
                    if (firstVisibleItem > ITEMS_THRESHOLD) {
                        if (Math.abs(dy) < 15) {
                            mAppBarSkipListener.isSkip(true);
                        } else {
                            mAppBarSkipListener.isSkip(false);
                        }
                    } else {
                        mAppBarSkipListener.isSkip(false);
                    }
                }
            }
        });
        initActionBarAutoHide();
    }

    public void setLoadNextListener(OnLoadNextListener listener) {
        mLoadNextListener = listener;
    }

    public void setLoadingState(boolean isLoading) {
        this.isLoading = isLoading;
    }

    public boolean getLoadingState() {
        return isLoading;
    }

    /**
     * 设置是否加载到最后
     *
     * @param isEnd true:不再触发翻页 false:正常翻页
     */
    public void setLoadToEnd(boolean isEnd) {
        if (!isEnd) {
            //列表已刷新,重置toastHasShown状态
            toastHasShown = false;
        }
        this.isEnd = isEnd;
    }

    /**
     * Initializes the Action Bar auto-hide (aka Quick Recall) effect.
     */
    protected void initActionBarAutoHide() {
        mActionBarAutoHideMinY = getResources().getDimensionPixelSize(
                R.dimen.action_bar_auto_hide_min_y);
        mActionBarAutoHideSensivity = getResources().getDimensionPixelSize(
                R.dimen.action_bar_auto_hide_sensivity);
    }

    /**
     * Copied from google io 2014 by Aidi
     * Indicates that the main content has scrolled (for the purposes of showing/hiding
     * the action bar for the "action bar auto hide" effect). currentY and deltaY may be exact
     * (if the underlying view supports it) or may be approximate indications:
     * deltaY may be INT_MAX to mean "scrolled forward indeterminately" and INT_MIN to mean
     * "scrolled backward indeterminately".  currentY may be 0 to mean "somewhere close to the
     * start of the list" and INT_MAX to mean "we don't know, but not at the start of the list"
     */
    public void onMainContentScrolled(int currentY, int deltaY) {
        if (mLoadNextListener != null) {
            if (deltaY > mActionBarAutoHideSensivity) {
                deltaY = mActionBarAutoHideSensivity;
            } else if (deltaY < -mActionBarAutoHideSensivity) {
                deltaY = -mActionBarAutoHideSensivity;
            }

            if (Math.signum(deltaY) * Math.signum(mActionBarAutoHideSignal) < 0) {
                // deltaY is a motion opposite to the accumulated signal, so reset signal
                mActionBarAutoHideSignal = deltaY;
            } else {
                // add to accumulated signal
                mActionBarAutoHideSignal += deltaY;
            }
            boolean shouldShow = currentY < mActionBarAutoHideMinY ||
                    (mActionBarAutoHideSignal <= -mActionBarAutoHideSensivity);
            mLoadNextListener.autoShowOrHideToolbar(shouldShow);
        }
    }

}


================================================
FILE: base/src/main/java/com/ccj/base/view/list/OnAppBarSkipListener.java
================================================
package com.ccj.base.view.list;


/**
 * 控制监听好价 toolbar显示隐藏抖动
 */
public interface OnAppBarSkipListener {
    void isSkip(boolean iskip);

}

================================================
FILE: base/src/main/java/com/ccj/base/view/list/OnLoadNextListener.java
================================================
package com.ccj.base.view.list;

/**
 */
public interface OnLoadNextListener {
    public void onLoadNext();
    public void autoShowOrHideToolbar(boolean show);
}


================================================
FILE: base/src/main/res/anim/anim_bottom_in.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="0%"
    android:toXDelta="0%"
    android:fromYDelta="100%"
    android:toYDelta="0%"
    android:duration="500">

</translate>


================================================
FILE: base/src/main/res/anim/anim_bottom_out.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="0%"
    android:toXDelta="0%"
    android:fromYDelta="00%"
    android:toYDelta="100%"
    android:duration="500">

</translate>


================================================
FILE: base/src/main/res/anim/dialog_enter.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <translate
        android:duration="500"
        android:toYDelta="0%"
        android:fillAfter="true"
        android:fromYDelta="100%p" />

</set>

================================================
FILE: base/src/main/res/anim/dialog_exit.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <translate
        android:duration="500"
        android:fromYDelta="0%"
        android:fillAfter="true"
        android:toYDelta="100%p" />

</set>

================================================
FILE: base/src/main/res/anim/footer_menu_slide_in.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="120"
    android:fromYDelta="100%"
    android:startOffset="120"
    android:interpolator="@android:anim/accelerate_interpolator"
    android:toYDelta="0%" />


================================================
FILE: base/src/main/res/anim/footer_menu_slide_out.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="120"
    android:fromYDelta="0%"
    android:interpolator="@android:anim/accelerate_interpolator"
    android:toYDelta="100%" />


================================================
FILE: base/src/main/res/anim/in_from_bottom.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_interpolator" >

    <translate
        android:duration="400"
        android:fromYDelta="100%p"
        android:toYDelta="0%p" />  

</set>

================================================
FILE: base/src/main/res/anim/in_from_top.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_interpolator" >

    <translate
        android:duration="400"
        android:fromYDelta="-100%p"
        android:toYDelta="0%p" />  

</set>

================================================
FILE: base/src/main/res/anim/out_to_bottom.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_interpolator" >

    <translate
        android:duration="400"
        android:fromYDelta="0%p"
        android:toYDelta="100%p" />  

</set>

================================================
FILE: base/src/main/res/anim/out_to_top.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_interpolator" >

    <translate
        android:duration="400"
        android:fromYDelta="0%p"
        android:toYDelta="-100%p" />

</set>

================================================
FILE: base/src/main/res/drawable/bg_toolbar.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <stroke
                android:width="1px"
                android:color="@color/colordc"/>
        </shape>
    </item>
    <item
        android:bottom="1px">
        <shape android:shape="rectangle">
            <solid android:color="@android:color/white"/>
        </shape>
    </item>
</layer-list>

================================================
FILE: base/src/main/res/drawable/btn_ripple.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="false">
        <shape>
            <corners android:radius="2dp"></corners>
            <solid android:color="@color/app_bg"></solid>
        </shape>
    </item>
    <item android:state_pressed="true">
        <shape>
            <corners android:radius="2dp"></corners>
            <solid android:color="@color/btn_blue_bg_press"></solid>
        </shape>
    </item>
    <item android:state_pressed="false">
        <shape>
            <corners android:radius="2dp"></corners>
            <solid android:color="@color/btn_blue_bg_press"></solid>
        </shape>
    </item>
</selector>

================================================
FILE: base/src/main/res/layout/base_layout_tool_bar.xml
================================================
<?xml version="1.0" encoding="utf-8"?>

<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="?attr/colorPrimary">

    <TextView
        android:id="@+id/toolbar_title"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:background="?attr/colorPrimary"
        android:gravity="center"
        android:textColor="@color/white"
        android:textSize="20sp" />
</android.support.v7.widget.Toolbar>


================================================
FILE: base/src/main/res/values/colors.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>


    <!-- <color name="colorPrimary">#FF03A9F4</color>
     <color name="colorPrimaryDark">#ff0171c9</color>
     <color name="colorAccent">#FF00E5FF</color>-->
    <color name="colorControlNormal">#FF78909C</color>
    <color name="colorControlActivated">#FF03A9F4</color>
    <color name="colorSwitchThumbNormal">#FF78909C</color>
    <color name="primary">#FF03A9F4</color>
    <color name="primary_dark">#FF0288D1</color>
    <color name="status_bar_color">@color/primary_dark</color>


    <color name="red_dark">#bc1717</color>
    <color name="red_bg">#dd4b39</color>
    <color name="window_bg">@android:color/white</color>
    <color name="btn_blue_bg">#6699ff</color>
    <color name="btn_blue_bg_press">#3366cc</color>
    <color name="app_bg">#f2f2f2</color>
    <color name="touming_bg">#00000000</color>
    <color name="yellow">#ffcc00</color>

    <color name="white">@android:color/white</color>
    <color name="black">@android:color/black</color>
    <color name="blue" >#2b8cff</color>
    <color name="red"> #ff3824</color>
    <color name="btn_dark">#929292</color>
    <color name="menu_bg">#f8f8f9</color>
    <color name="border_dark">#c9c9c9</color>
    <color name="shallow_blue">#70dbdb</color>
    <color name="item_click_bg_color">#dddddd</color>
    <color name="tans">#00000000</color>


    <color name="tool_bar_white">@android:color/white</color>
    <color name="colordc">#dcdcdc</color>

</resources>


================================================
FILE: base/src/main/res/values/dimens.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>



    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>


    <dimen name="action_bar_auto_hide_min_y">100dp</dimen>
    <dimen name="action_bar_auto_hide_sensivity">48dp</dimen>


    <!--margin or padding-->
    <dimen name="space_8">8.0dip</dimen>
    <dimen name="small_container_padding">5dp</dimen>
    <dimen name="common_container_padding">10dp</dimen>
    <dimen name="medium_container_padding">20dp</dimen>
    <dimen name="large_container_padding">30dp</dimen>
    <dimen name="min_container_padding">2dp</dimen>
    <dimen name="large_top_margin">80dp</dimen>
    <dimen name="common_dark_border">2dp</dimen>
    <dimen name="small_dark_border">1dp</dimen>

    <dimen name="radius">5dp</dimen>
    <dimen name="large_radius">10dp</dimen>

    <dimen name="small_text_size">16sp</dimen>
    <dimen name="common_text_size">18sp</dimen>
    <dimen name="large_text_size">22sp</dimen>

    <dimen name="msg_pic_width">400dp</dimen>
    <dimen name="msg_pic_high">200dp</dimen>
    <dimen name="text_medium_size">18sp</dimen>

</resources>

================================================
FILE: base/src/main/res/values/strings.xml
================================================
<resources>
    <string name="app_name">Android组件化</string>
    <string name="no_more">没有更多了</string>


    <!-- Error View -->
    <string name="error_view_click_to_refresh">点击屏幕,重新加载</string>
    <string name="error_view_no_data">暂无内容</string>
    <string name="error_view_loading">加载中…</string>
    <string name="error_view_load_error_click_to_refresh">内容加载失败\r\n点击重新加载</string>
    <string name="error_view_network_error_click_to_refresh">没有可用的网络</string>
    <string name="tip_network_error">没有可用的网络</string>
    <string name="show_loading_msg" >正在加载...</string>

</resources>


================================================
FILE: base/src/main/res/values/styles.xml
================================================
<resources>


    <style name="BaseAppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>

        <!-- colorAccent is used as the default value for colorControlActivated
          which is used to tint widgets -->
        <!--<item name="android:windowActionBar">false</item>
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>-->
        <item name="android:windowBackground">@android:color/transparent</item>

        <item name="android:textColor">@color/black</item>
        <item name="android:textCursorDrawable">@null</item>
        <item name="android:editTextColor">@color/black</item>
        <item name="android:textColorHint">@color/border_dark</item>
        <item name="android:dialogTheme">@android:style/Widget.ProgressBar</item>
    </style>
    <style name="AppTheme.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>

    <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />

    <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />





    <style name="AppTheme.Light" parent="AppTheme">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="colorControlNormal">@color/colorControlNormal</item>
        <item name="colorControlActivated">@color/colorPrimary</item>
        <item name="colorSwitchThumbNormal">@color/colorSwitchThumbNormal</item>
    </style>

    <style name="appStartTheme" parent="AppTheme.NoActionBar">
        <item name="android:windowBackground">@mipmap/login_bg</item>
    </style>




    <!-- 全透明的背景 -->
    <style name="Theme.Transparent" parent="@android:style/Theme">
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowIsFloating">true</item>
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:windowContentOverlay">@null</item>
        <item name="android:backgroundDimEnabled">false</item>
    </style>



</resources>


================================================
FILE: base/src/test/java/com/ccj/base/ExampleUnitTest.java
================================================
package com.ccj.base;

import org.junit.Test;

import static org.junit.Assert.*;

/**
 * Example local unit test, which will execute on the development machine (host).
 *
 * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
 */
public class ExampleUnitTest {
    @Test
    public void addition_isCorrect() throws Exception {
        assertEquals(4, 2 + 2);
    }
}

================================================
FILE: build.gradle
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
        //butterknife
        mavenCentral()
        maven {
            url 'https://maven.google.com/'
            name 'Google'
        }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.2'

        //butterknife
        classpath 'com.jakewharton:butterknife-gradle-plugin:8.4.0'
    }
}

allprojects {
    repositories {
        jcenter()
        maven {
            url 'https://maven.google.com/'
            name 'Google'
        }
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}


def androidSupportVersion = '25.3.1'
def butterknifeVersion = '8.4.0'


// Define versions in a single place
//时间:2017.2.13;每次修改版本号都要添加修改时间
ext {
    // Sdk and tools
    //localBuildToolsVersion是gradle.properties中的数据
    buildToolsVersion = localBuildToolsVersion
    compileSdkVersion = 25
    minSdkVersion = 16
    targetSdkVersion = 25
    versionCode = 1
    versionName = "1.0"
    javaVersion = JavaVersion.VERSION_1_8

    // App dependencies version
    appcompatV7 = "com.android.support:appcompat-v7:$androidSupportVersion"
    constraintLayout = 'com.android.support.constraint:constraint-layout:1.0.2'

    eventbusVersion = "3.0.0"

    //arouter
    arouterApi = 'com.alibaba:arouter-api:1.3.1'
    arouterCompiler = 'com.alibaba:arouter-compiler:1.1.4'

    //butterknife
    butterknife = "com.jakewharton:butterknife:$butterknifeVersion"
    butterknifeCompiler = "com.jakewharton:butterknife-compiler:$butterknifeVersion"

    //eventbusVersion
    eventbus= "org.greenrobot:eventbus:$eventbusVersion"

    cookieVersion = "v1.0.1"
    toastyVersion = "1.1.3"


}

================================================
FILE: gradle/wrapper/gradle-wrapper.properties
================================================
#Mon Dec 28 10:00:20 PST 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip


================================================
FILE: gradle.properties
================================================
## Project-wide Gradle settings.
#
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
#
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
 #org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
#
# 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.parallel=true
#Tue Jul 05 10:55:37 CST 2016

localBuildToolsVersion=25.0.3
localGradlePluginVersion=2.3.3


# true代表模块开发,false代表合并到主app.
isModule=true

================================================
FILE: gradlew
================================================
#!/usr/bin/env bash

##############################################################################
##
##  Gradle start up script for UN*X
##
##############################################################################

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""

APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"

warn ( ) {
    echo "$*"
}

die ( ) {
    echo
    echo "$*"
    echo
    exit 1
}

# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
  CYGWIN* )
    cygwin=true
    ;;
  Darwin* )
    darwin=true
    ;;
  MINGW* )
    msys=true
    ;;
esac

# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
    ls=`ls -ld "$PRG"`
    link=`expr "$ls" : '.*-> \(.*\)$'`
    if expr "$link" : '/.*' > /dev/null; then
        PRG="$link"
    else
        PRG=`dirname "$PRG"`"/$link"
    fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null

CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar

# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
        # IBM's JDK on AIX uses strange locations for the executables
        JAVACMD="$JAVA_HOME/jre/sh/java"
    else
        JAVACMD="$JAVA_HOME/bin/java"
    fi
    if [ ! -x "$JAVACMD" ] ; then
        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
    fi
else
    JAVACMD="java"
    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi

# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
    MAX_FD_LIMIT=`ulimit -H -n`
    if [ $? -eq 0 ] ; then
        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
            MAX_FD="$MAX_FD_LIMIT"
        fi
        ulimit -n $MAX_FD
        if [ $? -ne 0 ] ; then
            warn "Could not set maximum file descriptor limit: $MAX_FD"
        fi
    else
        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
    fi
fi

# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi

# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
    JAVACMD=`cygpath --unix "$JAVACMD"`

    # We build the pattern for arguments to be converted via cygpath
    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
    SEP=""
    for dir in $ROOTDIRSRAW ; do
        ROOTDIRS="$ROOTDIRS$SEP$dir"
        SEP="|"
    done
    OURCYGPATTERN="(^($ROOTDIRS))"
    # Add a user-defined pattern to the cygpath arguments
    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
    fi
    # Now convert the arguments - kludge to limit ourselves to /bin/sh
    i=0
    for arg in "$@" ; do
        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option

        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
        else
            eval `echo args$i`="\"$arg\""
        fi
        i=$((i+1))
    done
    case $i in
        (0) set -- ;;
        (1) set -- "$args0" ;;
        (2) set -- "$args0" "$args1" ;;
        (3) set -- "$args0" "$args1" "$args2" ;;
        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
    esac
fi

# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
    JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"

exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"


================================================
FILE: gradlew.bat
================================================
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem  Gradle startup script for Windows
@rem
@rem ##########################################################################

@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=

set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init

echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe

if exist "%JAVA_EXE%" goto init

echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:init
@rem Get command-line arguments, handling Windowz variants

if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args

:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2

:win9xME_args_slurp
if "x%~1" == "x" goto execute

set CMD_LINE_ARGS=%*
goto execute

:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$

:execute
@rem Setup the command line

set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd

:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1

:mainEnd
if "%OS%"=="Windows_NT" endlocal

:omega


================================================
FILE: module_home/.gitignore
================================================
/build


================================================
FILE: module_home/build.gradle
================================================

if (isModule.toBoolean()) {
    apply plugin: 'com.android.application'
} else {
    apply plugin: 'com.android.library'
}
//butterknife
apply plugin: 'com.jakewharton.butterknife'

android {
    compileSdkVersion rootProject.ext.compileSdkVersion
    buildToolsVersion rootProject.ext.buildToolsVersion

    defaultConfig {

        if (isModule.toBoolean()) {
            applicationId "com.ccj.home"
        }

        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        versionCode rootProject.ext.versionCode
        versionName rootProject.ext.versionName


        // resourcePrefix "haojia_"


        //arouter
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = [moduleName: project.getName()]
            }
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    sourceSets {
        main {
            if (isModule.toBoolean()) {
                manifest.srcFile 'src/main/AndroidManifest.xml'
            } else {
                manifest.srcFile 'src/main/release/AndroidManifest.xml'
                java {
                    exclude 'debug/**'
                }
            }
        }
    }

}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])


    //butterknife
    annotationProcessor rootProject.ext.butterknifeCompiler

    //arouter
    compile rootProject.ext.arouterApi
    annotationProcessor rootProject.ext.arouterCompiler

    compile project(':base')

}





================================================
FILE: module_home/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile


================================================
FILE: module_home/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.ccj.home">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

================================================
FILE: module_home/src/main/java/com/ccj/home/HomeFragment.java
================================================
package com.ccj.home;

import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

import com.alibaba.android.arouter.facade.annotation.Route;
import com.alibaba.android.arouter.launcher.ARouter;
import com.ccj.base.Constants;
import com.ccj.base.RouterConstants;
import com.ccj.base.base.BaseApplication;

/**
 * Created by chenchangjun on 18/1/25.
 */
@Route(path = RouterConstants.HOME_MUDULE_FRAGMENT_HOME_HOME)
public class HomeFragment extends Fragment implements View.OnClickListener {


    TextView button;
    Button button2;
    Button button3;
    Button button4;
    private View view;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        if (view == null) {
            view = inflater.inflate(R.layout.home_fragment_haojia_home, null);
        }
        return view;
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        button2= (Button) view.findViewById(R.id.button2);
        button3= (Button) view.findViewById(R.id.button3);
        button4= (Button) view.findViewById(R.id.button4);

        button2.setOnClickListener(this);
        button3.setOnClickListener(this);
        button4.setOnClickListener(this);

    }



    /**
     * Called when a view has been clicked.
     *
     * @param v The view that was clicked.
     */
    @Override
    public void onClick(View v) {
        int i = v.getId();
        if (i == R.id.button2) {
            navigateToLogin();
        } else if (i == R.id.button3) {
            navigateMeiziDetail();
        } else if (i == R.id.button4) {
            navigateTakePhoto();

        }
    }




    private void navigateMeiziDetail() {
        ARouter.getInstance().build(RouterConstants.MEIZI_MUDULE_ACTIVITY_MEIZI_DETAIL).
                withString(Constants.PARAMS_REQUEST_FOR_DETAIL, "http://7xi8d6.com1.z0.glb.clouddn.com/20180129074038_O3ydq4_Screenshot.jpeg").
                navigation(getActivity());

    }


    private void navigateToLogin() {
        ARouter.getInstance().build(RouterConstants.USER_MOUDLE_ACTIVITY).
                withString(Constants.START_LOGIN_WITH_PARAMS, "I am params from HomeFragment").
                navigation(getActivity(), Constants.REQUEST_START_LOGIN);
    }

    private void navigateTakePhoto() {
        ARouter.getInstance().
                build(RouterConstants.VIDEO_MUDULE_ACTIVITY).
                withString(Constants.START_LOGIN_WITH_PARAMS, "I am params from HomeFragment").
                navigation();

    }


    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == Constants.REQUEST_START_LOGIN) {

            if (data == null) {
                return;
            }
            String str = data.getStringExtra(Constants.PARAMS_RESULT_FROM_LOGIN);

            if (str == null) {
                return;
            }

            button.setText(str);
            BaseApplication.showToast(str);
        }

    }

}

================================================
FILE: module_home/src/main/java/com/ccj/home/MainActivity.java
================================================
package com.ccj.home;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}


================================================
FILE: module_home/src/main/release/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.ccj.home">

    <application android:allowBackup="true"
        android:supportsRtl="true" android:theme="@style/AppTheme">
        <activity android:name="com.smzdm.client.home.MainActivity"></activity>
    </application>

</manifest>

================================================
FILE: module_home/src/main/res/drawable/ic_launcher_background.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="108dp"
    android:height="108dp"
    android:viewportHeight="108"
    android:viewportWidth="108">
    <path
        android:fillColor="#26A69A"
        android:pathData="M0,0h108v108h-108z" />
    <path
        android:fillColor="#00000000"
        android:pathData="M9,0L9,108"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M19,0L19,108"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M29,0L29,108"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M39,0L39,108"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M49,0L49,108"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M59,0L59,108"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M69,0L69,108"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M79,0L79,108"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M89,0L89,108"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M99,0L99,108"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,9L108,9"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,19L108,19"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,29L108,29"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,39L108,39"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,49L108,49"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,59L108,59"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,69L108,69"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,79L108,79"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,89L108,89"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,99L108,99"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M19,29L89,29"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M19,39L89,39"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M19,49L89,49"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M19,59L89,59"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M19,69L89,69"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M19,79L89,79"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M29,19L29,89"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M39,19L39,89"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M49,19L49,89"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M59,19L59,89"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M69,19L69,89"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M79,19L79,89"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
</vector>


================================================
FILE: module_home/src/main/res/drawable-v24/ic_launcher_foreground.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:aapt="http://schemas.android.com/aapt"
    android:width="108dp"
    android:height="108dp"
    android:viewportHeight="108"
    android:viewportWidth="108">
    <path
        android:fillType="evenOdd"
        android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
        android:strokeColor="#00000000"
        android:strokeWidth="1">
        <aapt:attr name="android:fillColor">
            <gradient
                android:endX="78.5885"
                android:endY="90.9159"
                android:startX="48.7653"
                android:startY="61.0927"
                android:type="linear">
                <item
                    android:color="#44000000"
                    android:offset="0.0" />
                <item
                    android:color="#00000000"
                    android:offset="1.0" />
            </gradient>
        </aapt:attr>
    </path>
    <path
        android:fillColor="#FFFFFF"
        android:fillType="nonZero"
        android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
        android:strokeColor="#00000000"
        android:strokeWidth="1" />
</vector>


================================================
FILE: module_home/src/main/res/layout/activity_main.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.smzdm.client.home.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Module Home Hello World! "
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>


================================================
FILE: module_home/src/main/res/layout/home_fragment_haojia_home.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <TextView
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_gravity="center"
        android:layout_marginTop="32dp"
        android:text="首页" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/button"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="33dp"
        android:text="带参-跳转--用户--登录--返回值" />

    <Button
        android:id="@+id/button3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/button2"
        android:layout_alignStart="@+id/button2"
        android:layout_below="@+id/button2"
        android:layout_marginTop="29dp"
        android:text="带参-跳转--妹子--详情" />

    <Button
        android:id="@+id/button4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/button3"
        android:layout_alignStart="@+id/button3"
        android:layout_centerVertical="true"
        android:text="跳转--拍照--" />

</RelativeLayout>

================================================
FILE: module_home/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
    <background android:drawable="@drawable/ic_launcher_background" />
    <foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

================================================
FILE: module_home/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
    <background android:drawable="@drawable/ic_launcher_background" />
    <foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

================================================
FILE: module_home/src/main/res/values/colors.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
</resources>


================================================
FILE: module_home/src/main/res/values/strings.xml
================================================
<resources>
    <string name="app_name">module_home</string>
</resources>


================================================
FILE: module_home/src/main/res/values/styles.xml
================================================
<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

</resources>


================================================
FILE: module_meizi/.gitignore
================================================
/build


================================================
FILE: module_meizi/build.gradle
================================================

if (isModule.toBoolean()) {
    apply plugin: 'com.android.application'
} else {
    apply plugin: 'com.android.library'
}
//butterknife
apply plugin: 'com.jakewharton.butterknife'

android {
    compileSdkVersion rootProject.ext.compileSdkVersion
    buildToolsVersion rootProject.ext.buildToolsVersion

    defaultConfig {

        if (isModule.toBoolean()) {
            applicationId "com.ccj.meizi"
        }

        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        versionCode rootProject.ext.versionCode
        versionName rootProject.ext.versionName


        // resourcePrefix "user_"


        //arouter
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = [moduleName: project.getName()]
            }
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    sourceSets {
        main {
            if (isModule.toBoolean()) {
                manifest.srcFile 'src/main/AndroidManifest.xml'
            } else {
                manifest.srcFile 'src/main/release/AndroidManifest.xml'
                java {
                    exclude 'debug/**'
                }
            }
        }
    }

}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])


    //butterknife
    annotationProcessor rootProject.ext.butterknifeCompiler

    //arouter
    compile rootProject.ext.arouterApi
    annotationProcessor rootProject.ext.arouterCompiler

    compile project(':base')

}





================================================
FILE: module_meizi/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile


================================================
FILE: module_meizi/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.ccj.meizi">

    <application
        android:name="com.ccj.base.base.BaseApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".debug.MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>


        <activity android:name=".debug.ContainActivity" android:theme="@style/AppTheme.NoActionBar"></activity>

        <activity android:name=".ui.detail.MeiziDetailActivity"></activity>

    </application>

</manifest>

================================================
FILE: module_meizi/src/main/java/com/ccj/meizi/adapter/MeiziRcvAdapter.java
================================================
package com.ccj.meizi.adapter;

import android.app.Activity;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;

import com.ccj.base.adapter.CommonRcvAdapter;
import com.ccj.base.adapter.bean.AdapterBean;
import com.ccj.base.adapter.item.AdapterItem;
import com.ccj.meizi.holder.MeiziItemHolder;

import java.util.List;


public class MeiziRcvAdapter extends CommonRcvAdapter<AdapterBean> {


    private static final String TAG = "MeiziRcvAdapter";

    public MeiziRcvAdapter(@Nullable List data, Activity mActivity) {
        super(data, mActivity);
    }


    /**
     * 根据getCell_type得到 VIEW_TYPE
     *
     * @param demoModel
     * @return
     */
    @Override
    public Object getItemType(AdapterBean demoModel) {
        return demoModel.getCell_type();

    }

    /**
     * 根据viewType创建Holder
     *
     * @param type 通过{@link #getItemType(Object)}得到的type
     * @return
     */
    @NonNull
    @Override
    public AdapterItem createItem(Object type) {
        Log.d(TAG, "createItem " + type + " view");
        return new MeiziItemHolder( mActivity);

    }
}


================================================
FILE: module_meizi/src/main/java/com/ccj/meizi/api/MeiziAPIServiceImp.java
================================================
package com.ccj.meizi.api;

import com.ccj.base.api.APIService;
import com.ccj.base.utils.TLog;
import com.ccj.meizi.bean.Meizhi;

import rx.Observable;

/**
 * 继承
 * Created by chenchangjun on 17/8/10.
 */

public class MeiziAPIServiceImp extends APIService {


    protected static final MeiziRetrofitImp apiManager = sRetrofit.create(MeiziRetrofitImp.class);

    /**
     * @return
     */
    public static Observable<Meizhi> getMeiZhi(String date) {
        Observable<Meizhi> ss = apiManager.getMeiZhi( date);
        TLog.logI(date);
        return  ss;
    }



    /**
     * @return
     */
    public static Observable<Meizhi> getMeiZhi() {
        Observable<Meizhi> ss = apiManager.getMeiZhi( );
        return  ss;
    }
}


================================================
FILE: module_meizi/src/main/java/com/ccj/meizi/api/MeiziRetrofitImp.java
================================================
package com.ccj.meizi.api;


import com.ccj.meizi.bean.Meizhi;

import retrofit2.http.GET;
import retrofit2.http.Path;
import rx.Observable;

/**
 * Created by chenchangjun on 17/8/10.
 */

public interface MeiziRetrofitImp {

    @GET("/api/data/福利/{date}")
    Observable<Meizhi> getMeiZhi(@Path("date") String date);



    @GET("/api/random/data/福利/10")
    Observable<Meizhi> getMeiZhi();
}


================================================
FILE: module_meizi/src/main/java/com/ccj/meizi/bean/Meizhi.java
================================================
package com.ccj.meizi.bean;

import com.ccj.base.adapter.bean.AdapterBean;
import com.google.gson.Gson;

import java.util.List;

/**
 * Created by Administrator on 2016/10/31.
 */

public class Meizhi {

    /**
     * error : false
     * results : [{"_id":"5816871a421aa91369f959b6","createdAt":"2016-10-31T07:49:46.592Z","desc":"10-31","publishedAt":"2016-10-31T11:43:44.770Z","source":"chrome","type":"福利","url":"http://ww2.sinaimg.cn/large/610dc034jw1f9b46kpoeoj20ku0kuwhc.jpg","used":true,"who":"daimajia"},{"_id":"581218e9421aa90e799ec222","createdAt":"2016-10-27T23:10:33.618Z","desc":"10-28","publishedAt":"2016-10-28T11:29:36.510Z","source":"chrome","type":"福利","url":"http://ww2.sinaimg.cn/large/610dc034jw1f978bh1cerj20u00u0767.jpg","used":true,"who":"daimajia"},{"_id":"5811596a421aa90e6f21b45e","createdAt":"2016-10-27T09:33:30.47Z","desc":"10-27","publishedAt":"2016-10-27T11:41:45.88Z","source":"chrome","type":"福利","url":"http://ww4.sinaimg.cn/large/610dc034gw1f96kp6faayj20u00jywg9.jpg","used":true,"who":"daimajia"},{"_id":"58101f83421aa90e6f21b44b","createdAt":"2016-10-26T11:14:11.143Z","desc":"10-26","publishedAt":"2016-10-26T11:28:10.759Z","source":"chrome","type":"福利","url":"http://ww4.sinaimg.cn/large/610dc034jw1f95hzq3p4rj20u011htbm.jpg","used":true,"who":"daimajia"},{"_id":"580e9c74421aa90e799ec1fa","createdAt":"2016-10-25T07:42:44.254Z","desc":"10-25","publishedAt":"2016-10-25T11:35:01.586Z","source":"chrome","type":"福利","url":"http://ww4.sinaimg.cn/large/610dc034jw1f9469eoojtj20u011hdjy.jpg","used":true,"who":"daimajia"},{"_id":"580c1794421aa90e6f21b431","createdAt":"2016-10-23T09:51:16.503Z","desc":"10-24","publishedAt":"2016-10-24T11:25:22.197Z","source":"chrome","type":"福利","url":"http://ww2.sinaimg.cn/large/610dc034jw1f91ypzqaivj20u00k0jui.jpg","used":true,"who":"daimajia"},{"_id":"5809639e421aa90e799ec1de","createdAt":"2016-10-21T08:38:54.539Z","desc":"10-21","publishedAt":"2016-10-21T11:42:18.625Z","source":"chrome","type":"福利","url":"http://ww1.sinaimg.cn/large/610dc034jw1f8zlenaornj20u011idhv.jpg","used":true,"who":"daimajia"},{"_id":"58078baf421aa91369f9594c","createdAt":"2016-10-19T23:05:19.787Z","desc":"10-20","publishedAt":"2016-10-20T11:39:59.546Z","source":"chrome","type":"福利","url":"http://ww4.sinaimg.cn/large/610dc034jw1f8xz7ip2u5j20u011h78h.jpg","used":true,"who":"daimajia"},{"_id":"5806eb37421aa90e799ec1c4","createdAt":"2016-10-19T11:40:39.218Z","desc":"10-19","publishedAt":"2016-10-19T11:47:24.946Z","source":"chrome","type":"福利","url":"http://ww1.sinaimg.cn/large/610dc034jw1f8xff48zauj20u00x5jws.jpg","used":true,"who":"daimajia"},{"_id":"5805612d421aa90e799ec1ac","createdAt":"2016-10-18T07:39:25.756Z","desc":"10-18","publishedAt":"2016-10-18T11:50:35.205Z","source":"chrome","type":"福利","url":"http://ww3.sinaimg.cn/large/610dc034jw1f8w2tr9bgzj20ku0mjdi8.jpg","used":true,"who":"代码家"}]
     */

    public boolean error;
    /**
     * _id : 5816871a421aa91369f959b6
     * createdAt : 2016-10-31T07:49:46.592Z
     * desc : 10-31
     * publishedAt : 2016-10-31T11:43:44.770Z
     * source : chrome
     * type : 福利
     * url : http://ww2.sinaimg.cn/large/610dc034jw1f9b46kpoeoj20ku0kuwhc.jpg
     * used : true
     * who : daimajia
     */

    public List<MeiziItemBean> results;

    public static Meizhi objectFromData(String str) {

        return new Gson().fromJson(str, Meizhi.class);
    }

    public static class MeiziItemBean extends AdapterBean {
        public String _id;
        public String createdAt;
        public String desc;
        public String publishedAt;
        public String source;
        public String type;
        public String url;
        public boolean used;
        public String who;

        public static MeiziItemBean objectFromData(String str) {

            return new Gson().fromJson(str, MeiziItemBean.class);
        }

        @Override
        public String toString() {
            return "MeiziItemBean{" +
                    "_id='" + _id + '\'' +
                    ", createdAt='" + createdAt + '\'' +
                    ", desc='" + desc + '\'' +
                    ", publishedAt='" + publishedAt + '\'' +
                    ", source='" + source + '\'' +
                    ", type='" + type + '\'' +
                    ", url='" + url + '\'' +
                    ", used=" + used +
                    ", who='" + who + '\'' +
                    '}';
        }

        @Override
        public void setCell_type(int cell_type) {
            
        }

        @Override
        public int getCell_type() {
            return 0;
        }
    }

    @Override
    public String toString() {
        return "Meizhi{" +
                "error=" + error +
                ", results=" + results +
                '}';
    }
}


================================================
FILE: module_meizi/src/main/java/com/ccj/meizi/debug/ContainActivity.java
================================================
package com.ccj.meizi.debug;

import android.os.Bundle;

import com.ccj.base.base.BaseActivity;
import com.ccj.meizi.R;
import com.ccj.meizi.ui.main.MeiZhiFragment;

/**
 * Created by chenchangjun on 18/1/31.
 */

public class ContainActivity  extends BaseActivity{


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_contain);
        initFragment();
    }



    private void initFragment() {
        MeiZhiFragment fragment = new MeiZhiFragment();
        getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.detail_contain, fragment).commitAllowingStateLoss();

    }
}


================================================
FILE: module_meizi/src/main/java/com/ccj/meizi/debug/MainActivity.java
================================================
package com.ccj.meizi.debug;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

import com.ccj.meizi.R;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(MainActivity.this,ContainActivity.class));
            }
        });
    }





}


================================================
FILE: module_meizi/src/main/java/com/ccj/meizi/holder/MeiziItemHolder.java
================================================
package com.ccj.meizi.holder;

import android.app.Activity;
import android.view.View;
import android.widget.ImageView;

import com.alibaba.android.arouter.launcher.ARouter;
import com.ccj.base.Constants;
import com.ccj.base.RouterConstants;
import com.ccj.base.adapter.item.AdapterItem;
import com.ccj.meizi.R;
import com.ccj.meizi.bean.Meizhi;
import com.squareup.picasso.Picasso;

/**
 * 通用brand  card
 */
public class MeiziItemHolder implements AdapterItem<Meizhi.MeiziItemBean>, View.OnClickListener {

    private static final String TAG = MeiziItemHolder.class.getSimpleName();

    private Activity mActivity;
    private Meizhi.MeiziItemBean model;

    private ImageView imageView;


    public MeiziItemHolder(Activity mActivity) {
        this.mActivity = mActivity;
    }

    @Override
    public int getLayoutResId() {
        return R.layout.item_meizi_item;
    }

    @Override
    public void bindViews(View root) {
        imageView = (ImageView) root.findViewById(R.id.imageView);
        root.setOnClickListener(this);
    }

    @Override
    public void setViews() {

    }

    @Override
    public void onClick(View v) {
       ARouter.getInstance().
               build(RouterConstants.MEIZI_MUDULE_ACTIVITY_MEIZI_DETAIL).
               withString(Constants.PARAMS_REQUEST_FOR_DETAIL,model.url).
               navigation();

    }

    @Override
    public void handleData(Meizhi.MeiziItemBean item, int position) {
        this.model = item;

        Picasso.with(mActivity)
                .load(item.url)
                .into(imageView);
    }


}

================================================
FILE: module_meizi/src/main/java/com/ccj/meizi/ui/detail/MeiziDetailActivity.java
================================================
package com.ccj.meizi.ui.detail;

import android.os.Bundle;
import android.widget.ImageView;

import com.alibaba.android.arouter.facade.annotation.Route;
import com.ccj.base.Constants;
import com.ccj.base.RouterConstants;
import com.ccj.base.base.BaseActivity;
import com.ccj.meizi.R;
import com.squareup.picasso.Picasso;

/**
 * Created by chenchangjun on 18/2/1.
 */

@Route(path = RouterConstants.MEIZI_MUDULE_ACTIVITY_MEIZI_DETAIL)
public class MeiziDetailActivity extends BaseActivity {


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_meizi_detail);
        ImageView imageView= (ImageView) findViewById(R.id.image);


      String url=  getIntent().getStringExtra(Constants.PARAMS_REQUEST_FOR_DETAIL);

        Picasso.with(this)
                .load(url+"")
                .into(imageView);
    }


}


================================================
FILE: module_meizi/src/main/java/com/ccj/meizi/ui/main/MeiZhiContract.java
================================================
package com.ccj.meizi.ui.main;


import com.ccj.base.base.BasePresenter;
import com.ccj.base.base.BaseView;
import com.ccj.base.bean.User;
import com.ccj.meizi.bean.Meizhi;

import java.util.ArrayList;

/**
 * Created by Administrator on 2016/11/1.
 */

public class MeiZhiContract {

    interface View extends BaseView {
        void showProgress();
        void hideProgress();
        void showMeiZhiList(ArrayList<Meizhi.MeiziItemBean> meizhiList);
        void showError(String error);
        void navigateToMeiZhiDetail(String url);
        void setListener();

    }

    interface Presenter extends BasePresenter {
        void loadMeizhi(int pager);
        void loadMoreMeizhi(int pager);
        void  refresh();
    }

    interface Model{
        void saveUserInfo(User user);
        void saveLoginState(Boolean isLogin);
        void saveRememberPass(User user);

    }


}


================================================
FILE: module_meizi/src/main/java/com/ccj/meizi/ui/main/MeiZhiFragment.java
================================================
package com.ccj.meizi.ui.main;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.alibaba.android.arouter.facade.annotation.Route;
import com.ccj.base.RouterConstants;
import com.ccj.base.
Download .txt
gitextract_uy9zytuq/

├── .gitignore
├── .idea/
│   ├── gradle.xml
│   ├── markdown-navigator/
│   │   └── profiles_settings.xml
│   ├── markdown-navigator.xml
│   ├── misc.xml
│   ├── modules.xml
│   ├── runConfigurations.xml
│   └── vcs.xml
├── README.md
├── README_MODULE.md
├── README_MVP.md
├── app/
│   ├── .gitignore
│   ├── build.gradle
│   ├── libs/
│   │   └── xUtils-2.6.14.jar
│   ├── proguard-rules.pro
│   └── src/
│       ├── androidTest/
│       │   └── java/
│       │       └── com/
│       │           └── efly/
│       │               └── flyhelper/
│       │                   └── ApplicationTest.java
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── efly/
│       │   │           └── flyhelper/
│       │   │               ├── AppApplication.java
│       │   │               ├── MainActivity.java
│       │   │               └── adapter/
│       │   │                   └── FragmentAdapter.java
│       │   └── res/
│       │       ├── drawable/
│       │       │   ├── ic_dashboard_black_24dp.xml
│       │       │   ├── ic_home_black_24dp.xml
│       │       │   └── ic_notifications_black_24dp.xml
│       │       ├── layout/
│       │       │   └── activity_bottom_navigation.xml
│       │       ├── menu/
│       │       │   └── menu_bottom_navigation.xml
│       │       └── values/
│       │           └── strings.xml
│       └── test/
│           └── java/
│               └── com/
│                   └── efly/
│                       └── flyhelper/
│                           └── ExampleUnitTest.java
├── base/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       ├── androidTest/
│       │   └── java/
│       │       └── com/
│       │           └── ccj/
│       │               └── base/
│       │                   └── ExampleInstrumentedTest.java
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── ccj/
│       │   │           └── base/
│       │   │               ├── AppManager.java
│       │   │               ├── Constants.java
│       │   │               ├── RouterConstants.java
│       │   │               ├── adapter/
│       │   │               │   ├── CommonRcvAdapter.java
│       │   │               │   ├── bean/
│       │   │               │   │   ├── AdapterBean.java
│       │   │               │   │   └── AdapterGroupBean.java
│       │   │               │   ├── item/
│       │   │               │   │   └── AdapterItem.java
│       │   │               │   └── util/
│       │   │               │       ├── IAdapter.java
│       │   │               │       └── ItemTypeUtil.java
│       │   │               ├── api/
│       │   │               │   ├── APIService.java
│       │   │               │   ├── RetrofitRequest.java
│       │   │               │   └── VolleyUtils.java
│       │   │               ├── base/
│       │   │               │   ├── BaseActivity.java
│       │   │               │   ├── BaseApplication.java
│       │   │               │   ├── BaseBean.java
│       │   │               │   ├── BaseFragment.java
│       │   │               │   ├── BaseModel.java
│       │   │               │   ├── BasePresenter.java
│       │   │               │   ├── BaseView.java
│       │   │               │   └── Constants.java
│       │   │               ├── bean/
│       │   │               │   ├── User.java
│       │   │               │   └── UserDetail.java
│       │   │               ├── utils/
│       │   │               │   ├── BitmapUtil.java
│       │   │               │   ├── LruBitmapCache.java
│       │   │               │   ├── SerializableUtil.java
│       │   │               │   ├── SharedPreferenceUtil.java
│       │   │               │   ├── TDeviceUtils.java
│       │   │               │   ├── TLog.java
│       │   │               │   ├── ToastUtil.java
│       │   │               │   ├── eventbus/
│       │   │               │   │   └── EventUtils.java
│       │   │               │   └── router/
│       │   │               │       ├── LoginModuleService.java
│       │   │               │       ├── RounterInterceptor.java
│       │   │               │       ├── RounterSerialization.java
│       │   │               │       ├── RouterService.java
│       │   │               │       └── RouterUtils.java
│       │   │               └── view/
│       │   │                   ├── SuperRecyclerView.java
│       │   │                   └── list/
│       │   │                       ├── OnAppBarSkipListener.java
│       │   │                       └── OnLoadNextListener.java
│       │   └── res/
│       │       ├── anim/
│       │       │   ├── anim_bottom_in.xml
│       │       │   ├── anim_bottom_out.xml
│       │       │   ├── dialog_enter.xml
│       │       │   ├── dialog_exit.xml
│       │       │   ├── footer_menu_slide_in.xml
│       │       │   ├── footer_menu_slide_out.xml
│       │       │   ├── in_from_bottom.xml
│       │       │   ├── in_from_top.xml
│       │       │   ├── out_to_bottom.xml
│       │       │   └── out_to_top.xml
│       │       ├── drawable/
│       │       │   ├── bg_toolbar.xml
│       │       │   └── btn_ripple.xml
│       │       ├── layout/
│       │       │   └── base_layout_tool_bar.xml
│       │       └── values/
│       │           ├── colors.xml
│       │           ├── dimens.xml
│       │           ├── strings.xml
│       │           └── styles.xml
│       └── test/
│           └── java/
│               └── com/
│                   └── ccj/
│                       └── base/
│                           └── ExampleUnitTest.java
├── build.gradle
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── module_home/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── ccj/
│           │           └── home/
│           │               ├── HomeFragment.java
│           │               └── MainActivity.java
│           ├── release/
│           │   └── AndroidManifest.xml
│           └── res/
│               ├── drawable/
│               │   └── ic_launcher_background.xml
│               ├── drawable-v24/
│               │   └── ic_launcher_foreground.xml
│               ├── layout/
│               │   ├── activity_main.xml
│               │   └── home_fragment_haojia_home.xml
│               ├── mipmap-anydpi-v26/
│               │   ├── ic_launcher.xml
│               │   └── ic_launcher_round.xml
│               └── values/
│                   ├── colors.xml
│                   ├── strings.xml
│                   └── styles.xml
├── module_meizi/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── ccj/
│           │           └── meizi/
│           │               ├── adapter/
│           │               │   └── MeiziRcvAdapter.java
│           │               ├── api/
│           │               │   ├── MeiziAPIServiceImp.java
│           │               │   └── MeiziRetrofitImp.java
│           │               ├── bean/
│           │               │   └── Meizhi.java
│           │               ├── debug/
│           │               │   ├── ContainActivity.java
│           │               │   └── MainActivity.java
│           │               ├── holder/
│           │               │   └── MeiziItemHolder.java
│           │               ├── ui/
│           │               │   ├── detail/
│           │               │   │   └── MeiziDetailActivity.java
│           │               │   └── main/
│           │               │       ├── MeiZhiContract.java
│           │               │       ├── MeiZhiFragment.java
│           │               │       └── MeiZhiPresenter.java
│           │               └── utils/
│           │                   └── DateStringUtils.java
│           ├── release/
│           │   └── AndroidManifest.xml
│           └── res/
│               ├── drawable/
│               │   └── ic_launcher_background.xml
│               ├── drawable-v24/
│               │   └── ic_launcher_foreground.xml
│               ├── layout/
│               │   ├── activity_contain.xml
│               │   ├── activity_main.xml
│               │   ├── activity_meizi_detail.xml
│               │   ├── fragment_meizi.xml
│               │   └── item_meizi_item.xml
│               ├── mipmap-anydpi-v26/
│               │   ├── ic_launcher.xml
│               │   └── ic_launcher_round.xml
│               └── values/
│                   ├── colors.xml
│                   ├── strings.xml
│                   └── styles.xml
├── module_user/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── ccj/
│           │           └── login/
│           │               ├── api/
│           │               │   ├── LoginAPIServiceImp.java
│           │               │   └── LoginRetrofitImp.java
│           │               ├── debug/
│           │               │   ├── LoginApplication.java
│           │               │   └── MainActivity.java
│           │               ├── service/
│           │               │   └── CheckLoginService.java
│           │               └── ui/
│           │                   ├── login/
│           │                   │   ├── LoginActivity.java
│           │                   │   ├── LoginContract.java
│           │                   │   ├── LoginModel.java
│           │                   │   └── LoginPresenter.java
│           │                   ├── register/
│           │                   │   └── RegisterActivity.java
│           │                   └── user/
│           │                       └── UserFragment.java
│           ├── release/
│           │   └── AndroidManifest.xml
│           └── res/
│               ├── layout/
│               │   ├── activity_login.xml
│               │   ├── activity_main.xml
│               │   ├── login_fragment_register.xml
│               │   └── user_fragment_user_home.xml
│               └── values/
│                   ├── colors.xml
│                   ├── strings.xml
│                   └── styles.xml
├── module_video/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── ccj/
│           │           └── video/
│           │               ├── VideoFragment.java
│           │               ├── debug/
│           │               │   ├── MainActivity.java
│           │               │   └── VideoApplication.java
│           │               ├── service/
│           │               │   └── VideoServiceImpl.java
│           │               └── ui/
│           │                   ├── TakePhotoActivity.java
│           │                   ├── TakePhotoContract.java
│           │                   ├── TakePhotoModel.java
│           │                   └── TakePhotoPresenter.java
│           ├── release/
│           │   └── AndroidManifest.xml
│           └── res/
│               ├── layout/
│               │   ├── activity_main.xml
│               │   ├── activity_take_photo.xml
│               │   └── video_fragment_video_home.xml
│               └── values/
│                   ├── colors.xml
│                   ├── strings.xml
│                   └── styles.xml
└── settings.gradle
Download .txt
SYMBOL INDEX (452 symbols across 78 files)

FILE: app/src/androidTest/java/com/efly/flyhelper/ApplicationTest.java
  class ApplicationTest (line 9) | public class ApplicationTest extends ApplicationTestCase<Application> {
    method ApplicationTest (line 10) | public ApplicationTest() {

FILE: app/src/main/java/com/efly/flyhelper/AppApplication.java
  class AppApplication (line 10) | public class AppApplication extends BaseApplication {
    method onCreate (line 15) | @Override

FILE: app/src/main/java/com/efly/flyhelper/MainActivity.java
  class MainActivity (line 20) | public class MainActivity extends BaseActivity {
    method onNavigationItemSelected (line 30) | @Override
    method onCreate (line 48) | @Override
    method initViewPager (line 59) | private void initViewPager() {

FILE: app/src/main/java/com/efly/flyhelper/adapter/FragmentAdapter.java
  class FragmentAdapter (line 9) | public class FragmentAdapter extends FragmentStatePagerAdapter {
    method FragmentAdapter (line 12) | public FragmentAdapter(FragmentManager fm, List<Fragment> mFragments) {
    method getItem (line 17) | @Override
    method getCount (line 22) | @Override
    method getItemPosition (line 27) | @Override

FILE: app/src/test/java/com/efly/flyhelper/ExampleUnitTest.java
  class ExampleUnitTest (line 10) | public class ExampleUnitTest {
    method addition_isCorrect (line 11) | @Test

FILE: base/src/androidTest/java/com/ccj/base/ExampleInstrumentedTest.java
  class ExampleInstrumentedTest (line 17) | @RunWith(AndroidJUnit4.class)
    method useAppContext (line 19) | @Test

FILE: base/src/main/java/com/ccj/base/AppManager.java
  class AppManager (line 13) | public class AppManager {
    method AppManager (line 18) | private AppManager() {
    method getAppManager (line 26) | public static AppManager getAppManager() {
    method getActivity (line 43) | public static Activity getActivity(Class<?> cls) {
    method addActivity (line 56) | public void addActivity(Activity activity) {
    method currentActivity (line 63) | public Activity currentActivity() {
    method finishActivity (line 71) | public void finishActivity() {
    method finishActivity (line 79) | public void finishActivity(Activity activity) {
    method removeActivity (line 89) | public void removeActivity(Activity activity) {
    method finishActivity (line 98) | public void finishActivity(Class<?> cls) {
    method finishAllActivity (line 110) | public void finishAllActivity() {
    method AppExit (line 122) | public void AppExit(Context context) {

FILE: base/src/main/java/com/ccj/base/Constants.java
  class Constants (line 7) | public class Constants {

FILE: base/src/main/java/com/ccj/base/RouterConstants.java
  class RouterConstants (line 7) | public final class RouterConstants {

FILE: base/src/main/java/com/ccj/base/adapter/CommonRcvAdapter.java
  class CommonRcvAdapter (line 23) | public abstract class CommonRcvAdapter<T> extends RecyclerView.Adapter<C...
    method CommonRcvAdapter (line 36) | public CommonRcvAdapter(@Nullable List<T> data, Activity mActivity) {
    method getItem (line 46) | public T getItem(int position) {
    method getItemCount (line 54) | @Override
    method setData (line 59) | @Override
    method getData (line 64) | @Override
    method getItemId (line 69) | @Override
    method getItemViewType (line 80) | @Deprecated
    method getItemType (line 88) | @Override
    method onCreateViewHolder (line 93) | @Override
    method onBindViewHolder (line 98) | @Override
    method getConvertedData (line 106) | @NonNull
    method getCurrentPosition (line 112) | @Override
    class RcvAdapterItem (line 121) | public static class RcvAdapterItem extends RecyclerView.ViewHolder {
      method RcvAdapterItem (line 127) | RcvAdapterItem(Context context, ViewGroup parent, AdapterItem item) {
    method debug (line 140) | private void debug(RcvAdapterItem holder) {

FILE: base/src/main/java/com/ccj/base/adapter/bean/AdapterBean.java
  class AdapterBean (line 14) | public abstract class AdapterBean implements Serializable {
    method setCell_type (line 19) | public abstract void setCell_type(int cell_type);
    method getCell_type (line 22) | public abstract int getCell_type();

FILE: base/src/main/java/com/ccj/base/adapter/bean/AdapterGroupBean.java
  class AdapterGroupBean (line 11) | public abstract class AdapterGroupBean<T> extends AdapterBean implements...
    method getList (line 16) | public abstract List getList();
    method getTitle (line 18) | public abstract String getTitle();
    method getRedirect_data (line 20) | public abstract T getRedirect_data();

FILE: base/src/main/java/com/ccj/base/adapter/item/AdapterItem.java
  type AdapterItem (line 10) | public interface AdapterItem<T> {
    method getLayoutResId (line 16) | @LayoutRes
    method bindViews (line 22) | void bindViews(final View root);
    method setViews (line 28) | void setViews();
    method handleData (line 36) | void handleData(T t, int position);

FILE: base/src/main/java/com/ccj/base/adapter/util/IAdapter.java
  type IAdapter (line 16) | public interface IAdapter<T> {
    method setData (line 21) | void setData(@NonNull List<T> data);
    method getData (line 23) | List<T> getData();
    method getItemType (line 29) | Object getItemType(T t);
    method createItem (line 37) | @Keep
    method getConvertedData (line 48) | @Keep
    method notifyDataSetChanged (line 55) | void notifyDataSetChanged();
    method getCurrentPosition (line 60) | int getCurrentPosition();

FILE: base/src/main/java/com/ccj/base/adapter/util/ItemTypeUtil.java
  class ItemTypeUtil (line 11) | @VisibleForTesting
    method setTypePool (line 16) | public void setTypePool(HashMap<Object, Integer> typePool) {
    method getIntType (line 24) | public int getIntType(Object type) {

FILE: base/src/main/java/com/ccj/base/api/APIService.java
  class APIService (line 13) | public class APIService {

FILE: base/src/main/java/com/ccj/base/api/RetrofitRequest.java
  type RetrofitRequest (line 8) | public interface RetrofitRequest {

FILE: base/src/main/java/com/ccj/base/api/VolleyUtils.java
  class VolleyUtils (line 18) | public class VolleyUtils {
    method getInstance (line 27) | public static VolleyUtils getInstance() {
    method VolleyUtils (line 35) | private VolleyUtils() {
    method getRequestQueue (line 40) | public RequestQueue getRequestQueue() {
    method getImageLoader (line 48) | public ImageLoader getImageLoader() {
    method addToRequestQueue (line 56) | public <T> void addToRequestQueue(Request<T> req, String tag) {
    method addToRequestQueue (line 62) | public <T> void addToRequestQueue(Request<T> req) {
    method cancelPendingRequests (line 67) | public void cancelPendingRequests(Object tag) {

FILE: base/src/main/java/com/ccj/base/base/BaseActivity.java
  class BaseActivity (line 24) | public class BaseActivity<T extends BasePresenter>
    method onCreate (line 34) | @Override
    method initToolBar (line 43) | public void initToolBar() {
    method getToolbar (line 56) | public Toolbar getToolbar() {
    method onDestroy (line 63) | @Override
    method initDialog (line 71) | private void initDialog() {
    method showLoading (line 76) | public void showLoading() {
    method dismissLoading (line 80) | public void dismissLoading() {
    method initView (line 85) | @Override
    method onActivityResult (line 98) | @Override
    method handleResult (line 129) | private void handleResult(Fragment frag, int requestCode, int resultCode,

FILE: base/src/main/java/com/ccj/base/base/BaseApplication.java
  class BaseApplication (line 16) | public class BaseApplication extends Application {
    method getInstance (line 24) | public static synchronized BaseApplication getInstance() {
    method attachBaseContext (line 28) | @Override
    method onCreate (line 34) | @Override
    method initARouter (line 48) | private void initARouter() {
    method showToast (line 67) | public static void showToast(String message, int duration, int icon,
    method getContext (line 75) | public static Context getContext() {
    method setContext (line 79) | public static void setContext(Context context) {
    method getResource (line 83) | public static Resources getResource() {
    method setResource (line 87) | public static void setResource(Resources resource) {
    method showShortToast (line 92) | public static void showShortToast(String message) {
    method showLongToast (line 96) | public static void showLongToast(String message) {
    method showToast (line 100) | public static void showToast(String message) {

FILE: base/src/main/java/com/ccj/base/base/BaseBean.java
  class BaseBean (line 8) | public class BaseBean implements Serializable {

FILE: base/src/main/java/com/ccj/base/base/BaseFragment.java
  class BaseFragment (line 16) | public abstract class BaseFragment<T extends BasePresenter> extends Frag...
    method onCreate (line 27) | @Override
    method showLoading (line 34) | public void showLoading() {
    method dismissLoading (line 42) | public void dismissLoading() {
    method getScreen (line 48) | private void getScreen() {
    method onDetach (line 60) | @Override

FILE: base/src/main/java/com/ccj/base/base/BaseModel.java
  type BaseModel (line 6) | public interface BaseModel {
    method start (line 11) | void start();
    method onDestroy (line 20) | void onDestroy();

FILE: base/src/main/java/com/ccj/base/base/BasePresenter.java
  type BasePresenter (line 6) | public interface BasePresenter  {
    method start (line 10) | void start();
    method onDestroy (line 18) | void onDestroy();

FILE: base/src/main/java/com/ccj/base/base/BaseView.java
  type BaseView (line 6) | public interface BaseView {
    method initView (line 9) | void initView();

FILE: base/src/main/java/com/ccj/base/base/Constants.java
  class Constants (line 6) | public class Constants {

FILE: base/src/main/java/com/ccj/base/bean/User.java
  class User (line 8) | public class User extends BaseBean implements Serializable {
    method objectFromData (line 47) | public static User objectFromData(String str) {
    class ResultBean (line 52) | public static class ResultBean {
      method toString (line 77) | @Override
      method objectFromData (line 105) | public static ResultBean objectFromData(String str) {
    method toString (line 112) | @Override

FILE: base/src/main/java/com/ccj/base/bean/UserDetail.java
  class UserDetail (line 6) | public class UserDetail {

FILE: base/src/main/java/com/ccj/base/utils/BitmapUtil.java
  class BitmapUtil (line 22) | public class BitmapUtil {
    method BitmapUtil (line 35) | public BitmapUtil(Context context){
    method getOutputMediaFileUri (line 42) | public static Uri getOutputMediaFileUri(int type, String name) {
    method getOutputMediaFile (line 49) | public static File getOutputMediaFile(int type, String name) {
    method getPhotoURL (line 84) | public static String getPhotoURL(String name) {
    method getFile (line 99) | public static String getFile(String dir, String contain) {
    method calculateInSampleSize (line 124) | public static int calculateInSampleSize(BitmapFactory.Options options,...
    method transMsgPicFile (line 137) | public static File transMsgPicFile(File file, Bitmap bitmap) {
    method comp (line 153) | public static Bitmap comp(Bitmap image) {
    method getimage (line 192) | private Bitmap getimage(String srcPath) {
    method compressImage (line 220) | private static Bitmap compressImage(Bitmap image) {

FILE: base/src/main/java/com/ccj/base/utils/LruBitmapCache.java
  class LruBitmapCache (line 12) | public class LruBitmapCache implements ImageLoader.ImageCache {
    method LruBitmapCache (line 15) | public LruBitmapCache() {
    method getBitmap (line 26) | @Override
    method putBitmap (line 31) | @Override

FILE: base/src/main/java/com/ccj/base/utils/SerializableUtil.java
  class SerializableUtil (line 17) | public class SerializableUtil {
    method objToStr (line 19) | public static String objToStr(Object obj) throws IOException {
    method strToObj (line 40) | public static Object strToObj(String str) throws IOException {
    method listToString (line 53) | public static <T> String listToString(List<T> list) throws IOException {
    method stringToList (line 68) | public static <T> List<T> stringToList(String str) throws IOException {

FILE: base/src/main/java/com/ccj/base/utils/SharedPreferenceUtil.java
  class SharedPreferenceUtil (line 15) | public class SharedPreferenceUtil {
    method initSharedPreference (line 37) | public static synchronized void initSharedPreference(Context context) {
    method getInstance (line 50) | public static synchronized SharedPreferenceUtil getInstance() {
    method SharedPreferenceUtil (line 58) | public SharedPreferenceUtil(Context context) {
    method getSharedPref (line 62) | public SharedPreferences getSharedPref() {
    method putAutoLogin (line 66) | public synchronized void putAutoLogin(Boolean AutoLogin) {
    method getAutoLogin (line 72) | public synchronized Boolean getAutoLogin() {
    method setIsLogin (line 78) | public synchronized void setIsLogin(Boolean AutoLogin) {
    method getIsLogin (line 84) | public synchronized Boolean getIsLogin() {
    method putUser (line 89) | public synchronized void putUser(User user) {
    method setUsername (line 104) | public void setUsername(String username){
    method getUsername (line 111) | public String getUsername(){
    method getUser (line 116) | public synchronized User getUser()
    method DeleteUser (line 141) | public synchronized void DeleteUser() {

FILE: base/src/main/java/com/ccj/base/utils/TDeviceUtils.java
  class TDeviceUtils (line 40) | @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    method TDeviceUtils (line 65) | public TDeviceUtils() {
    method dpToPixel (line 68) | public static float dpToPixel(float dp) {
    method getDefaultLoadFactor (line 72) | public static int getDefaultLoadFactor() {
    method getDensity (line 82) | public static float getDensity() {
    method getDisplayMetrics (line 88) | public static DisplayMetrics getDisplayMetrics() {
    method getScreenHeight (line 96) | public static float getScreenHeight() {
    method getScreenWidth (line 100) | public static float getScreenWidth() {
    method getRealScreenSize (line 104) | public static int[] getRealScreenSize(Activity activity) {
    method getStatusBarHeight (line 138) | public static int getStatusBarHeight() {
    method hasBigScreen (line 158) | public static boolean hasBigScreen() {
    method hasCamera (line 178) | public static final boolean hasCamera() {
    method hasHardwareMenuKey (line 192) | public static boolean hasHardwareMenuKey(Context getContext) {
    method hasInternet (line 203) | public static boolean hasInternet() {
    method gotoGoogleMarket (line 213) | public static boolean gotoGoogleMarket(Activity activity, String pck) {
    method isPackageExist (line 227) | public static boolean isPackageExist(String pckName) {
    method hideAnimatedView (line 239) | public static void hideAnimatedView(View view) {
    method hideSoftKeyboard (line 244) | public static void hideSoftKeyboard(View view) {
    method isLandscape (line 252) | public static boolean isLandscape() {
    method isPortrait (line 258) | public static boolean isPortrait() {
    method isTablet (line 265) | public static boolean isTablet() {
    method pixelsToDp (line 275) | public static float pixelsToDp(float f) {
    method showAnimatedView (line 279) | public static void showAnimatedView(View view) {
    method showSoftKeyboard (line 284) | public static void showSoftKeyboard(Dialog dialog) {
    method showSoftKeyboard (line 288) | public static void showSoftKeyboard(View view) {
    method toogleSoftKeyboard (line 294) | public static void toogleSoftKeyboard(View view) {
    method isSdcardReady (line 300) | public static boolean isSdcardReady() {
    method getCurCountryLan (line 305) | public static String getCurCountryLan() {
    method isZhCN (line 313) | public static boolean isZhCN() {
    method percent (line 319) | public static String percent(double p1, double p2) {
    method percent2 (line 328) | public static String percent2(double p1, double p2) {
    method gotoMarket (line 337) | public static void gotoMarket(Context getContext, String pck) {
    method isHaveMarket (line 350) | public static boolean isHaveMarket(Context getContext) {
    method openAppInMarket (line 359) | public static void openAppInMarket(Context getContext) {
    method setFullScreen (line 378) | public static void setFullScreen(Activity activity) {
    method cancelFullScreen (line 387) | public static void cancelFullScreen(Activity activity) {
    method getPackageInfo (line 396) | public static PackageInfo getPackageInfo(String pckName) {
    method getVersionCode (line 406) | public static int getVersionCode() {
    method getVersionCode (line 420) | public static int getVersionCode(String packageName) {
    method getVersionName (line 431) | public static String getVersionName() {
    method isScreenOn (line 445) | public static boolean isScreenOn() {
    method installAPK (line 451) | public static void installAPK(Context getContext, File file) {
    method getInstallApkIntent (line 462) | public static Intent getInstallApkIntent(File file) {
    method openDial (line 471) | public static void openDial(Context getContext, String number) {
    method openSMS (line 477) | public static void openSMS(Context getContext, String smsBody, String ...
    method openDail (line 484) | public static void openDail(Context getContext) {
    method openSendMsg (line 490) | public static void openSendMsg(Context getContext) {
    method openCamera (line 497) | public static void openCamera(Context getContext) {
    method getIMEI (line 504) | public static String getIMEI() {
    method getPhoneType (line 510) | public static String getPhoneType() {
    method openApp (line 514) | public static void openApp(Context getContext, String packageName) {
    method openAppActivity (line 525) | public static boolean openAppActivity(Context getContext, String packa...
    method isWifiOpen (line 539) | public static boolean isWifiOpen() {
    method uninstallApk (line 558) | public static void uninstallApk(Context getContext, String packageName) {
    method copyTextToBoard (line 567) | @SuppressWarnings("deprecation")
    method sendEmail (line 585) | public static void sendEmail(Context getContext, String subject,
    method getStatuBarHeight (line 601) | public static int getStatuBarHeight() {
    method getActionBarHeight (line 620) | public static int getActionBarHeight(Context getContext) {
    method hasStatusBar (line 638) | public static boolean hasStatusBar(Activity activity) {
    method showSystemShareOption (line 650) | public static void showSystemShareOption(Activity getContext,
    method getNetworkType (line 664) | public static int getNetworkType() {

FILE: base/src/main/java/com/ccj/base/utils/TLog.java
  class TLog (line 5) | public class TLog {
    method TLog (line 9) | public TLog() {
    method analytics (line 12) | public static final void analytics(String log) {
    method error (line 17) | public static final void error(String log) {
    method log (line 22) | public static final void log(String log) {
    method log (line 27) | public static final void log(String tag, String log) {
    method logI (line 32) | public static final void logI(String log) {
    method warn (line 37) | public static final void warn(String log) {

FILE: base/src/main/java/com/ccj/base/utils/ToastUtil.java
  class ToastUtil (line 5) | public class ToastUtil {
    method show (line 8) | public static void show( String text) {

FILE: base/src/main/java/com/ccj/base/utils/eventbus/EventUtils.java
  class EventUtils (line 8) | public class EventUtils {
    class StringEvent (line 13) | public static class StringEvent{
      method StringEvent (line 15) | public StringEvent(String msg) {
      method getMsg (line 19) | public String getMsg(){
    class intEvent (line 24) | public static class intEvent{
      method intEvent (line 26) | public intEvent(int msg) {
      method getMsg (line 30) | public int getMsg(){
    class ObjectEvent (line 40) | public static class ObjectEvent{
      method ObjectEvent (line 42) | public ObjectEvent(Object object) {
      method getMsg (line 46) | public Object getMsg(){

FILE: base/src/main/java/com/ccj/base/utils/router/LoginModuleService.java
  type LoginModuleService (line 10) | public interface LoginModuleService extends IProvider {
    method checkLoginState (line 13) | boolean checkLoginState();

FILE: base/src/main/java/com/ccj/base/utils/router/RounterInterceptor.java
  class RounterInterceptor (line 16) | @Interceptor(priority = 8, name = "测试用拦截器")
    method process (line 22) | @Override
    method init (line 31) | @Override

FILE: base/src/main/java/com/ccj/base/utils/router/RounterSerialization.java
  class RounterSerialization (line 13) | @Route(path = "/router/RounterSerialization")
    method json2Object (line 17) | @Override
    method object2Json (line 22) | @Override
    method parseObject (line 34) | @Override
    method init (line 39) | @Override

FILE: base/src/main/java/com/ccj/base/utils/router/RouterService.java
  type RouterService (line 9) | public interface RouterService extends IProvider {
    method start (line 12) | String start(String name);

FILE: base/src/main/java/com/ccj/base/utils/router/RouterUtils.java
  class RouterUtils (line 8) | public class RouterUtils {
    method inject (line 12) | public static void inject(Object obj){
    method navigation (line 23) | public static Object navigation(String path) {
    method startActivityForResult (line 30) | public void startActivityForResult(Activity activity,String path,int r...
    method startActivityForCallback (line 36) | public void startActivityForCallback() {

FILE: base/src/main/java/com/ccj/base/view/SuperRecyclerView.java
  class SuperRecyclerView (line 14) | public class SuperRecyclerView extends RecyclerView {
    method SuperRecyclerView (line 30) | public SuperRecyclerView(Context context) {
    method SuperRecyclerView (line 35) | public SuperRecyclerView(Context context, AttributeSet attrs) {
    method SuperRecyclerView (line 40) | public SuperRecyclerView(Context context, AttributeSet attrs, int defS...
    method setOnAppBarSkipListener (line 45) | public void setOnAppBarSkipListener(OnAppBarSkipListener listener) {
    method init (line 49) | private void init() {
    method setLoadNextListener (line 105) | public void setLoadNextListener(OnLoadNextListener listener) {
    method setLoadingState (line 109) | public void setLoadingState(boolean isLoading) {
    method getLoadingState (line 113) | public boolean getLoadingState() {
    method setLoadToEnd (line 122) | public void setLoadToEnd(boolean isEnd) {
    method initActionBarAutoHide (line 133) | protected void initActionBarAutoHide() {
    method onMainContentScrolled (line 149) | public void onMainContentScrolled(int currentY, int deltaY) {

FILE: base/src/main/java/com/ccj/base/view/list/OnAppBarSkipListener.java
  type OnAppBarSkipListener (line 7) | public interface OnAppBarSkipListener {
    method isSkip (line 8) | void isSkip(boolean iskip);

FILE: base/src/main/java/com/ccj/base/view/list/OnLoadNextListener.java
  type OnLoadNextListener (line 5) | public interface OnLoadNextListener {
    method onLoadNext (line 6) | public void onLoadNext();
    method autoShowOrHideToolbar (line 7) | public void autoShowOrHideToolbar(boolean show);

FILE: base/src/test/java/com/ccj/base/ExampleUnitTest.java
  class ExampleUnitTest (line 12) | public class ExampleUnitTest {
    method addition_isCorrect (line 13) | @Test

FILE: module_home/src/main/java/com/ccj/home/HomeFragment.java
  class HomeFragment (line 22) | @Route(path = RouterConstants.HOME_MUDULE_FRAGMENT_HOME_HOME)
    method onCreateView (line 32) | @Nullable
    method onViewCreated (line 41) | @Override
    method onClick (line 61) | @Override
    method navigateMeiziDetail (line 77) | private void navigateMeiziDetail() {
    method navigateToLogin (line 85) | private void navigateToLogin() {
    method navigateTakePhoto (line 91) | private void navigateTakePhoto() {
    method onActivityResult (line 100) | @Override

FILE: module_home/src/main/java/com/ccj/home/MainActivity.java
  class MainActivity (line 6) | public class MainActivity extends AppCompatActivity {
    method onCreate (line 8) | @Override

FILE: module_meizi/src/main/java/com/ccj/meizi/adapter/MeiziRcvAdapter.java
  class MeiziRcvAdapter (line 16) | public class MeiziRcvAdapter extends CommonRcvAdapter<AdapterBean> {
    method MeiziRcvAdapter (line 21) | public MeiziRcvAdapter(@Nullable List data, Activity mActivity) {
    method getItemType (line 32) | @Override
    method createItem (line 44) | @NonNull

FILE: module_meizi/src/main/java/com/ccj/meizi/api/MeiziAPIServiceImp.java
  class MeiziAPIServiceImp (line 14) | public class MeiziAPIServiceImp extends APIService {
    method getMeiZhi (line 22) | public static Observable<Meizhi> getMeiZhi(String date) {
    method getMeiZhi (line 33) | public static Observable<Meizhi> getMeiZhi() {

FILE: module_meizi/src/main/java/com/ccj/meizi/api/MeiziRetrofitImp.java
  type MeiziRetrofitImp (line 14) | public interface MeiziRetrofitImp {
    method getMeiZhi (line 16) | @GET("/api/data/福利/{date}")
    method getMeiZhi (line 21) | @GET("/api/random/data/福利/10")

FILE: module_meizi/src/main/java/com/ccj/meizi/bean/Meizhi.java
  class Meizhi (line 12) | public class Meizhi {
    method objectFromData (line 34) | public static Meizhi objectFromData(String str) {
    class MeiziItemBean (line 39) | public static class MeiziItemBean extends AdapterBean {
      method objectFromData (line 50) | public static MeiziItemBean objectFromData(String str) {
      method toString (line 55) | @Override
      method setCell_type (line 70) | @Override
      method getCell_type (line 75) | @Override
    method toString (line 81) | @Override

FILE: module_meizi/src/main/java/com/ccj/meizi/debug/ContainActivity.java
  class ContainActivity (line 13) | public class ContainActivity  extends BaseActivity{
    method onCreate (line 16) | @Override
    method initFragment (line 25) | private void initFragment() {

FILE: module_meizi/src/main/java/com/ccj/meizi/debug/MainActivity.java
  class MainActivity (line 10) | public class MainActivity extends AppCompatActivity {
    method onCreate (line 12) | @Override

FILE: module_meizi/src/main/java/com/ccj/meizi/holder/MeiziItemHolder.java
  class MeiziItemHolder (line 18) | public class MeiziItemHolder implements AdapterItem<Meizhi.MeiziItemBean...
    method MeiziItemHolder (line 28) | public MeiziItemHolder(Activity mActivity) {
    method getLayoutResId (line 32) | @Override
    method bindViews (line 37) | @Override
    method setViews (line 43) | @Override
    method onClick (line 48) | @Override
    method handleData (line 57) | @Override

FILE: module_meizi/src/main/java/com/ccj/meizi/ui/detail/MeiziDetailActivity.java
  class MeiziDetailActivity (line 17) | @Route(path = RouterConstants.MEIZI_MUDULE_ACTIVITY_MEIZI_DETAIL)
    method onCreate (line 21) | @Override

FILE: module_meizi/src/main/java/com/ccj/meizi/ui/main/MeiZhiContract.java
  class MeiZhiContract (line 15) | public class MeiZhiContract {
    type View (line 17) | interface View extends BaseView {
      method showProgress (line 18) | void showProgress();
      method hideProgress (line 19) | void hideProgress();
      method showMeiZhiList (line 20) | void showMeiZhiList(ArrayList<Meizhi.MeiziItemBean> meizhiList);
      method showError (line 21) | void showError(String error);
      method navigateToMeiZhiDetail (line 22) | void navigateToMeiZhiDetail(String url);
      method setListener (line 23) | void setListener();
    type Presenter (line 27) | interface Presenter extends BasePresenter {
      method loadMeizhi (line 28) | void loadMeizhi(int pager);
      method loadMoreMeizhi (line 29) | void loadMoreMeizhi(int pager);
      method refresh (line 30) | void  refresh();
    type Model (line 33) | interface Model{
      method saveUserInfo (line 34) | void saveUserInfo(User user);
      method saveLoginState (line 35) | void saveLoginState(Boolean isLogin);
      method saveRememberPass (line 36) | void saveRememberPass(User user);

FILE: module_meizi/src/main/java/com/ccj/meizi/ui/main/MeiZhiFragment.java
  class MeiZhiFragment (line 31) | @Route(path = RouterConstants.MEIZI_MUDULE_FRAGMENT_HOME_MEIZI)
    method onCreateView (line 48) | @Nullable
    method onViewCreated (line 59) | @Override
    method initView (line 71) | @Override
    method showProgress (line 88) | @Override
    method hideProgress (line 95) | @Override
    method showMeiZhiList (line 105) | @Override
    method showError (line 113) | @Override
    method navigateToMeiZhiDetail (line 118) | @Override
    method setListener (line 124) | @Override
    method onRefresh (line 131) | @Override
    method onLoadNext (line 137) | @Override
    method autoShowOrHideToolbar (line 144) | @Override

FILE: module_meizi/src/main/java/com/ccj/meizi/ui/main/MeiZhiPresenter.java
  class MeiZhiPresenter (line 18) | public class MeiZhiPresenter  implements MeiZhiContract.Presenter {
    method MeiZhiPresenter (line 24) | public MeiZhiPresenter(MeiZhiContract.View view) {
    method start (line 28) | @Override
    method refresh (line 35) | @Override
    method loadMoreMeizhi (line 40) | @Override
    method loadMeizhi (line 45) | @Override
    method onDestroy (line 88) | @Override

FILE: module_meizi/src/main/java/com/ccj/meizi/utils/DateStringUtils.java
  class DateStringUtils (line 10) | public class DateStringUtils {
    method getBeforeStringDate (line 16) | public static String getBeforeStringDate(int offset ){

FILE: module_user/src/main/java/com/ccj/login/api/LoginAPIServiceImp.java
  class LoginAPIServiceImp (line 16) | public class LoginAPIServiceImp extends APIService {
    method userLogin (line 26) | public static Observable<User> userLogin(String format, String city) {

FILE: module_user/src/main/java/com/ccj/login/api/LoginRetrofitImp.java
  type LoginRetrofitImp (line 18) | public interface LoginRetrofitImp extends RetrofitRequest {
    method userLogin (line 26) | @Headers( "Content-Type: application/json" )

FILE: module_user/src/main/java/com/ccj/login/debug/LoginApplication.java
  class LoginApplication (line 9) | public class LoginApplication extends BaseApplication {
    method onCreate (line 10) | @Override

FILE: module_user/src/main/java/com/ccj/login/debug/MainActivity.java
  class MainActivity (line 19) | @Route(path = "/login/MainActivity")
    method onCreate (line 25) | @Override
    method jumpToLogin (line 40) | private void jumpToLogin() {

FILE: module_user/src/main/java/com/ccj/login/service/CheckLoginService.java
  class CheckLoginService (line 13) | @Route(path = RouterConstants. USER_SERVICE_IMPL)
    method checkLoginState (line 20) | @Override
    method init (line 26) | @Override

FILE: module_user/src/main/java/com/ccj/login/ui/login/LoginActivity.java
  class LoginActivity (line 35) | @Route(path = RouterConstants.USER_MOUDLE_ACTIVITY)
    method onCreate (line 58) | @Override
    method navigateToMain (line 69) | @Override
    method navigateToRegister (line 76) | @Override
    method onClick (line 82) | @OnClick({R2.id.iv_cancel, R2.id.btn_login, R2.id.btn_register})
    method showProgress (line 99) | @Override
    method hideProgress (line 104) | @Override
    method showError (line 109) | @Override
    method initView (line 115) | @Override

FILE: module_user/src/main/java/com/ccj/login/ui/login/LoginContract.java
  type LoginContract (line 13) | public interface LoginContract {
    type View (line 16) | interface View extends BaseView {
      method showProgress (line 17) | void showProgress();
      method hideProgress (line 18) | void hideProgress();
      method showError (line 19) | void showError(String error);
      method navigateToMain (line 20) | void navigateToMain();
      method navigateToRegister (line 21) | void navigateToRegister();
    type Presenter (line 24) | interface Presenter extends BasePresenter {
      method login (line 25) | void login(String username, String password);
      method onDestroy (line 26) | void onDestroy();
    type Model (line 29) | interface Model{
      method saveUserInfo (line 30) | void saveUserInfo(User user);
      method saveLoginState (line 31) | void saveLoginState(Boolean isLogin);
      method saveRememberPass (line 32) | void saveRememberPass(User user);

FILE: module_user/src/main/java/com/ccj/login/ui/login/LoginModel.java
  class LoginModel (line 17) | public class LoginModel implements LoginContract.Model {
    type SaveFinishListener (line 20) | interface SaveFinishListener{
      method onError (line 21) | void onError(String msg);
      method onSucess (line 22) | void onSucess(String msg);
      method onProgress (line 23) | void onProgress(String msg);
    method LoginModel (line 26) | public LoginModel() {
    method setOnSaveFinishListener (line 30) | public void setOnSaveFinishListener(SaveFinishListener onSaveFinishLis...
    method saveUserInfo (line 35) | @Override
    method saveLoginState (line 40) | @Override
    method saveRememberPass (line 45) | @Override

FILE: module_user/src/main/java/com/ccj/login/ui/login/LoginPresenter.java
  class LoginPresenter (line 17) | public class LoginPresenter implements LoginContract.Presenter {
    method LoginPresenter (line 20) | public LoginPresenter(LoginContract.View loginView) {
    method login (line 24) | @Override
    method start (line 51) | @Override
    method onDestroy (line 57) | @Override

FILE: module_user/src/main/java/com/ccj/login/ui/register/RegisterActivity.java
  class RegisterActivity (line 16) | @Route(path = RouterConstants.USER_REGISTER_FRAGMENT)
    method onCreate (line 20) | @Override

FILE: module_user/src/main/java/com/ccj/login/ui/user/UserFragment.java
  class UserFragment (line 18) | @Route(path = RouterConstants.USER_MUDULE_FRAGMENT_HOME_USER)
    method onCreateView (line 24) | @Nullable

FILE: module_video/src/main/java/com/ccj/video/VideoFragment.java
  class VideoFragment (line 16) | @Route(path= RouterConstants.VIDEO_MUDULE_FRAGMENT_HOME_VIDEO)
    method onCreateView (line 22) | @Nullable

FILE: module_video/src/main/java/com/ccj/video/debug/MainActivity.java
  class MainActivity (line 8) | public class MainActivity extends AppCompatActivity {
    method onCreate (line 12) | @Override

FILE: module_video/src/main/java/com/ccj/video/debug/VideoApplication.java
  class VideoApplication (line 10) | public class VideoApplication extends BaseApplication {
    method onCreate (line 12) | @Override

FILE: module_video/src/main/java/com/ccj/video/service/VideoServiceImpl.java
  class VideoServiceImpl (line 13) | @Route(path = RouterConstants.VIDEO_SERVICE_IMPL)
    method init (line 17) | @Override
    method start (line 22) | @Override

FILE: module_video/src/main/java/com/ccj/video/ui/TakePhotoActivity.java
  class TakePhotoActivity (line 31) | @Route(path= RouterConstants.VIDEO_MUDULE_ACTIVITY)
    method onCreate (line 43) | @Override
    method onClick (line 56) | @OnClick(R2.id.button)
    method takePhoto (line 66) | private void takePhoto() {
    method startTakePhoto (line 74) | private void startTakePhoto() {
    method onActivityResult (line 80) | @Override
    method initView (line 94) | @Override
    method showProgress (line 99) | @Override
    method hideProgress (line 104) | @Override
    method showBitmap (line 109) | @Override

FILE: module_video/src/main/java/com/ccj/video/ui/TakePhotoContract.java
  type TakePhotoContract (line 16) | public interface TakePhotoContract {
    type View (line 18) | interface View extends BaseView {
      method initView (line 19) | void initView();
      method showProgress (line 20) | void showProgress();
      method hideProgress (line 21) | void hideProgress();
      method showBitmap (line 22) | void showBitmap(Bitmap bitmap);
    type Presenter (line 25) | interface Presenter extends BasePresenter {
      method savePhoto (line 26) | void savePhoto(Intent data);
    type Model (line 29) | interface Model extends BaseModel {
      method savePhoto (line 30) | void savePhoto(Intent data);

FILE: module_video/src/main/java/com/ccj/video/ui/TakePhotoModel.java
  class TakePhotoModel (line 26) | public class TakePhotoModel implements TakePhotoContract.Model {
    method savePhoto (line 36) | @Override
    method savePic (line 68) | private String savePic(Intent data) {
    method start (line 93) | @Override
    method onDestroy (line 99) | @Override

FILE: module_video/src/main/java/com/ccj/video/ui/TakePhotoPresenter.java
  class TakePhotoPresenter (line 15) | public class TakePhotoPresenter implements TakePhotoContract.Presenter {
    method TakePhotoPresenter (line 25) | public TakePhotoPresenter(TakePhotoContract.View view) {
    method savePhoto (line 35) | @Override
    method start (line 45) | @Override
    method onDestroy (line 50) | @Override
    method onEvent (line 66) | @Subscribe//(threadMode = ThreadMode.MAIN)
Condensed preview — 182 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (278K chars).
[
  {
    "path": ".gitignore",
    "chars": 97,
    "preview": "*.iml\n.gradle\n/local.properties\n/.idea/workspace.xml\n/.idea/libraries\n.DS_Store\n/build\n/captures\n"
  },
  {
    "path": ".idea/gradle.xml",
    "chars": 906,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"GradleSettings\">\n    <option name=\"linke"
  },
  {
    "path": ".idea/markdown-navigator/profiles_settings.xml",
    "chars": 104,
    "preview": "<component name=\"MarkdownNavigator.ProfileManager\">\n  <settings default=\"\" pdf-export=\"\" />\n</component>"
  },
  {
    "path": ".idea/markdown-navigator.xml",
    "chars": 4167,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"MarkdownProjectSettings\">\n    <PreviewSe"
  },
  {
    "path": ".idea/misc.xml",
    "chars": 1611,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"NullableNotNullManager\">\n    <option nam"
  },
  {
    "path": ".idea/modules.xml",
    "chars": 1905,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ProjectModuleManager\">\n    <modules>\n   "
  },
  {
    "path": ".idea/runConfigurations.xml",
    "chars": 564,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"RunConfigurationProducerService\">\n    <o"
  },
  {
    "path": ".idea/vcs.xml",
    "chars": 180,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"VcsDirectoryMappings\">\n    <mapping dire"
  },
  {
    "path": "README.md",
    "chars": 396,
    "preview": "\r\n\r\n\r\n\r\n\r\n# clean-project-architecture\r\n\r\n\r\n更新 2018/2/1 组件化重构,修改方式为 主容器app+业务module模式.\r\n\r\n\r\n----\r\n\r\n组件化项目框架,以及主流的项目架构(MV"
  },
  {
    "path": "README_MODULE.md",
    "chars": 5073,
    "preview": "# 客户端组件化探究\n\n**项目地址** [https://github.com/ccj659/clean-project-architecture](https://github.com/ccj659/clean-project-arch"
  },
  {
    "path": "README_MVP.md",
    "chars": 8815,
    "preview": "\n\n\n\n2018/2/1 更新\n\n\t1.完善组件化,宿主构建. 所以,mvp写法请参照`lib_base`和`module_meizi`. ps妹子图又更新了一波,😄\n\n\n\n2016/11/1 更新 用gank.io的妹子数据\n\n\t1.添加"
  },
  {
    "path": "app/.gitignore",
    "chars": 7,
    "preview": "/build\n"
  },
  {
    "path": "app/build.gradle",
    "chars": 2112,
    "preview": "apply plugin: 'com.android.application'\nrepositories {\n    jcenter()\n}\nandroid {\n\n    compileSdkVersion rootProject.ext."
  },
  {
    "path": "app/proguard-rules.pro",
    "chars": 3429,
    "preview": "\n\n\n-ignorewarnings                     # 忽略警告,避免打包时某些警告出现\n-dontwarn\n-dontskipnonpubliclibraryclasses\n-dontskipnonpublicl"
  },
  {
    "path": "app/src/androidTest/java/com/efly/flyhelper/ApplicationTest.java",
    "chars": 349,
    "preview": "package com.efly.flyhelper;\n\nimport android.app.Application;\nimport android.test.ApplicationTestCase;\n\n/**\n * <a href=\"h"
  },
  {
    "path": "app/src/main/AndroidManifest.xml",
    "chars": 1303,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package="
  },
  {
    "path": "app/src/main/java/com/efly/flyhelper/AppApplication.java",
    "chars": 301,
    "preview": "package com.efly.flyhelper;\n\nimport com.ccj.base.base.BaseApplication;\n\n/**\n * ARouter 这里必须在 这里初始化, 在 base里面初始化 无效,奇怪\n *"
  },
  {
    "path": "app/src/main/java/com/efly/flyhelper/MainActivity.java",
    "chars": 2597,
    "preview": "package com.efly.flyhelper;\n\nimport android.os.Bundle;\nimport android.support.annotation.NonNull;\nimport android.support"
  },
  {
    "path": "app/src/main/java/com/efly/flyhelper/adapter/FragmentAdapter.java",
    "chars": 802,
    "preview": "package com.efly.flyhelper.adapter;\n\nimport android.support.v4.app.Fragment;\nimport android.support.v4.app.FragmentManag"
  },
  {
    "path": "app/src/main/res/drawable/ic_dashboard_black_24dp.xml",
    "chars": 352,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/ic_home_black_24dp.xml",
    "chars": 310,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/ic_notifications_black_24dp.xml",
    "chars": 464,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n  "
  },
  {
    "path": "app/src/main/res/layout/activity_bottom_navigation.xml",
    "chars": 929,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmln"
  },
  {
    "path": "app/src/main/res/menu/menu_bottom_navigation.xml",
    "chars": 609,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <item\n    "
  },
  {
    "path": "app/src/main/res/values/strings.xml",
    "chars": 212,
    "preview": "<resources>\n    <string name=\"app_name\">MVP和组件化</string>\n    <string name=\"title_notifications\">我的</string>\n    <string "
  },
  {
    "path": "app/src/test/java/com/efly/flyhelper/ExampleUnitTest.java",
    "chars": 311,
    "preview": "package com.efly.flyhelper;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * To work on unit tests, sw"
  },
  {
    "path": "base/.gitignore",
    "chars": 7,
    "preview": "/build\n"
  },
  {
    "path": "base/build.gradle",
    "chars": 1937,
    "preview": "apply plugin: 'com.android.library'\n\nandroid {\n    compileSdkVersion rootProject.ext.compileSdkVersion\n    buildToolsVer"
  },
  {
    "path": "base/proguard-rules.pro",
    "chars": 1334,
    "preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /U"
  },
  {
    "path": "base/src/androidTest/java/com/ccj/base/ExampleInstrumentedTest.java",
    "chars": 733,
    "preview": "package com.ccj.base;\n\nimport android.content.Context;\nimport android.support.test.InstrumentationRegistry;\nimport andro"
  },
  {
    "path": "base/src/main/AndroidManifest.xml",
    "chars": 779,
    "preview": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n\n    package=\"com.ccj.base\">\n    <!-- 必选 -->\n    <u"
  },
  {
    "path": "base/src/main/java/com/ccj/base/AppManager.java",
    "chars": 3141,
    "preview": "package com.ccj.base;\n\nimport android.app.Activity;\nimport android.app.ActivityManager;\nimport android.content.Context;\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/Constants.java",
    "chars": 476,
    "preview": "package com.ccj.base;\n\n/**\n * Created by chenchangjun on 17/8/10.\n */\n\npublic class Constants {\n\n    public static final"
  },
  {
    "path": "base/src/main/java/com/ccj/base/RouterConstants.java",
    "chars": 1518,
    "preview": "package com.ccj.base;\n/**\n * Created by chenchangjun on 17/8/9.\n */\n\n\npublic final class RouterConstants {\n\n\n\n\n    /**\n "
  },
  {
    "path": "base/src/main/java/com/ccj/base/adapter/CommonRcvAdapter.java",
    "chars": 3690,
    "preview": "package com.ccj.base.adapter;\n\nimport android.app.Activity;\nimport android.content.Context;\nimport android.support.annot"
  },
  {
    "path": "base/src/main/java/com/ccj/base/adapter/bean/AdapterBean.java",
    "chars": 511,
    "preview": "package com.ccj.base.adapter.bean;\n\nimport java.io.Serializable;\n\n/**\n * 数据bean\n * 为了不同viewItem 分别对应不同的bean,</br>\n * 避免不"
  },
  {
    "path": "base/src/main/java/com/ccj/base/adapter/bean/AdapterGroupBean.java",
    "chars": 403,
    "preview": "package com.ccj.base.adapter.bean;\n\nimport java.io.Serializable;\nimport java.util.List;\n\n/**\n * 类似于 view和 viewgroup 的概念 "
  },
  {
    "path": "base/src/main/java/com/ccj/base/adapter/item/AdapterItem.java",
    "chars": 591,
    "preview": "package com.ccj.base.adapter.item;\n\nimport android.support.annotation.LayoutRes;\nimport android.view.View;\n\n/**\n * @auth"
  },
  {
    "path": "base/src/main/java/com/ccj/base/adapter/util/IAdapter.java",
    "chars": 1153,
    "preview": "package com.ccj.base.adapter.util;\n\nimport android.support.annotation.Keep;\nimport android.support.annotation.NonNull;\n\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/adapter/util/ItemTypeUtil.java",
    "chars": 737,
    "preview": "package com.ccj.base.adapter.util;\n\nimport android.support.annotation.VisibleForTesting;\n\nimport java.util.HashMap;\n\n/**"
  },
  {
    "path": "base/src/main/java/com/ccj/base/api/APIService.java",
    "chars": 931,
    "preview": "package com.ccj.base.api;\n\n\nimport retrofit2.Retrofit;\nimport retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;\nimport "
  },
  {
    "path": "base/src/main/java/com/ccj/base/api/RetrofitRequest.java",
    "chars": 328,
    "preview": "package com.ccj.base.api;\n\n\n/**\n *\n * Created by ccj on 2016/7/6.\n */\npublic interface RetrofitRequest {\n\n\n    boolean i"
  },
  {
    "path": "base/src/main/java/com/ccj/base/api/VolleyUtils.java",
    "chars": 1988,
    "preview": "package com.ccj.base.api;\n\nimport android.content.Context;\nimport android.text.TextUtils;\n\nimport com.android.volley.Req"
  },
  {
    "path": "base/src/main/java/com/ccj/base/base/BaseActivity.java",
    "chars": 3804,
    "preview": "package com.ccj.base.base;\n\nimport android.app.ProgressDialog;\nimport android.content.Context;\nimport android.content.In"
  },
  {
    "path": "base/src/main/java/com/ccj/base/base/BaseApplication.java",
    "chars": 2661,
    "preview": "package com.ccj.base.base;\n\nimport android.app.Application;\nimport android.content.Context;\nimport android.content.res.R"
  },
  {
    "path": "base/src/main/java/com/ccj/base/base/BaseBean.java",
    "chars": 160,
    "preview": "package com.ccj.base.base;\n\nimport java.io.Serializable;\n\n/**\n * Created by Administrator on 2016/7/6.\n */\npublic class "
  },
  {
    "path": "base/src/main/java/com/ccj/base/base/BaseFragment.java",
    "chars": 1703,
    "preview": "package com.ccj.base.base;\n\nimport android.app.Dialog;\nimport android.app.ProgressDialog;\nimport android.content.Context"
  },
  {
    "path": "base/src/main/java/com/ccj/base/base/BaseModel.java",
    "chars": 352,
    "preview": "package com.ccj.base.base;\n\n/**\n * Created by Administrator on 2016/7/14.\n */\npublic interface BaseModel {\n\n    /**\n    "
  },
  {
    "path": "base/src/main/java/com/ccj/base/base/BasePresenter.java",
    "chars": 729,
    "preview": "package com.ccj.base.base;\n\n/**\n * Created by Administrator on 2016/7/7.\n */\npublic interface BasePresenter  {\n    /**\n "
  },
  {
    "path": "base/src/main/java/com/ccj/base/base/BaseView.java",
    "chars": 130,
    "preview": "package com.ccj.base.base;\n\n/**\n * Created by Administrator on 2016/7/6.\n */\npublic interface BaseView {\n\n\n    void init"
  },
  {
    "path": "base/src/main/java/com/ccj/base/base/Constants.java",
    "chars": 248,
    "preview": "package com.ccj.base.base;\n\n/**\n * 静态常量\n */\npublic class Constants {\n\n    public static final int REQUST_FOR_LOGIN = 0x0"
  },
  {
    "path": "base/src/main/java/com/ccj/base/bean/User.java",
    "chars": 4398,
    "preview": "package com.ccj.base.bean;\n\nimport com.ccj.base.base.BaseBean;\nimport com.google.gson.Gson;\n\nimport java.io.Serializable"
  },
  {
    "path": "base/src/main/java/com/ccj/base/bean/UserDetail.java",
    "chars": 187,
    "preview": "package com.ccj.base.bean;\n\n/**\n * Created by Administrator on 2016/8/10.\n */\npublic class UserDetail {\n\n\n\n    public St"
  },
  {
    "path": "base/src/main/java/com/ccj/base/utils/BitmapUtil.java",
    "chars": 8839,
    "preview": "package com.ccj.base.utils;\n\nimport android.content.Context;\nimport android.graphics.Bitmap;\nimport android.graphics.Bit"
  },
  {
    "path": "base/src/main/java/com/ccj/base/utils/LruBitmapCache.java",
    "chars": 822,
    "preview": "package com.ccj.base.utils;\n\nimport android.graphics.Bitmap;\nimport android.support.v4.util.LruCache;\n\nimport com.androi"
  },
  {
    "path": "base/src/main/java/com/ccj/base/utils/SerializableUtil.java",
    "chars": 2585,
    "preview": "package com.ccj.base.utils;\n\nimport android.util.Base64;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.ByteArrayO"
  },
  {
    "path": "base/src/main/java/com/ccj/base/utils/SharedPreferenceUtil.java",
    "chars": 5021,
    "preview": "package com.ccj.base.utils;\n\nimport android.content.Context;\nimport android.content.SharedPreferences;\nimport android.te"
  },
  {
    "path": "base/src/main/java/com/ccj/base/utils/TDeviceUtils.java",
    "chars": 24129,
    "preview": "package com.ccj.base.utils;\n\nimport android.annotation.TargetApi;\nimport android.app.Activity;\nimport android.app.Dialog"
  },
  {
    "path": "base/src/main/java/com/ccj/base/utils/TLog.java",
    "chars": 729,
    "preview": "package com.ccj.base.utils;\n\nimport android.util.Log;\n\npublic class TLog {\n\tpublic static final String LOG_TAG = \"TLog--"
  },
  {
    "path": "base/src/main/java/com/ccj/base/utils/ToastUtil.java",
    "chars": 269,
    "preview": "package com.ccj.base.utils;\n\nimport com.ccj.base.base.BaseApplication;\n\npublic class ToastUtil {\n\n\n    public static voi"
  },
  {
    "path": "base/src/main/java/com/ccj/base/utils/eventbus/EventUtils.java",
    "chars": 1057,
    "preview": "package com.ccj.base.utils.eventbus;\n\n\n/**\n * 事件总线 用于组件或线程通信,可替代回调,广播等\n * Created by ccj on 2016/4/14.\n */\npublic class "
  },
  {
    "path": "base/src/main/java/com/ccj/base/utils/router/LoginModuleService.java",
    "chars": 255,
    "preview": "package com.ccj.base.utils.router;\n\nimport com.alibaba.android.arouter.facade.template.IProvider;\n\n/**\n * 示例:子模块间调用方法\n *"
  },
  {
    "path": "base/src/main/java/com/ccj/base/utils/router/RounterInterceptor.java",
    "chars": 937,
    "preview": "package com.ccj.base.utils.router;\n\nimport android.content.Context;\n\nimport com.alibaba.android.arouter.facade.Postcard;"
  },
  {
    "path": "base/src/main/java/com/ccj/base/utils/router/RounterSerialization.java",
    "chars": 900,
    "preview": "package com.ccj.base.utils.router;\n\nimport android.content.Context;\n\nimport com.alibaba.android.arouter.facade.annotatio"
  },
  {
    "path": "base/src/main/java/com/ccj/base/utils/router/RouterService.java",
    "chars": 233,
    "preview": "package com.ccj.base.utils.router;\n\nimport com.alibaba.android.arouter.facade.template.IProvider;\n\n/**\n * Created by che"
  },
  {
    "path": "base/src/main/java/com/ccj/base/utils/router/RouterUtils.java",
    "chars": 952,
    "preview": "package com.ccj.base.utils.router;\n\nimport android.app.Activity;\n\nimport com.alibaba.android.arouter.launcher.ARouter;\n\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/view/SuperRecyclerView.java",
    "chars": 6347,
    "preview": "package com.ccj.base.view;\n\nimport android.content.Context;\nimport android.support.v7.widget.LinearLayoutManager;\nimport"
  },
  {
    "path": "base/src/main/java/com/ccj/base/view/list/OnAppBarSkipListener.java",
    "chars": 140,
    "preview": "package com.ccj.base.view.list;\n\n\n/**\n * 控制监听好价 toolbar显示隐藏抖动\n */\npublic interface OnAppBarSkipListener {\n    void isSki"
  },
  {
    "path": "base/src/main/java/com/ccj/base/view/list/OnLoadNextListener.java",
    "chars": 164,
    "preview": "package com.ccj.base.view.list;\n\n/**\n */\npublic interface OnLoadNextListener {\n    public void onLoadNext();\n    public "
  },
  {
    "path": "base/src/main/res/anim/anim_bottom_in.xml",
    "chars": 261,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<translate xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android"
  },
  {
    "path": "base/src/main/res/anim/anim_bottom_out.xml",
    "chars": 262,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<translate xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android"
  },
  {
    "path": "base/src/main/res/anim/dialog_enter.xml",
    "chars": 260,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\" >\n\n    <translate"
  },
  {
    "path": "base/src/main/res/anim/dialog_exit.xml",
    "chars": 260,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\" >\n\n    <translate"
  },
  {
    "path": "base/src/main/res/anim/footer_menu_slide_in.xml",
    "chars": 290,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<translate xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android"
  },
  {
    "path": "base/src/main/res/anim/footer_menu_slide_out.xml",
    "chars": 260,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<translate xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android"
  },
  {
    "path": "base/src/main/res/anim/in_from_bottom.xml",
    "chars": 295,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:inter"
  },
  {
    "path": "base/src/main/res/anim/in_from_top.xml",
    "chars": 296,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:inter"
  },
  {
    "path": "base/src/main/res/anim/out_to_bottom.xml",
    "chars": 295,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:inter"
  },
  {
    "path": "base/src/main/res/anim/out_to_top.xml",
    "chars": 294,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:inter"
  },
  {
    "path": "base/src/main/res/drawable/bg_toolbar.xml",
    "chars": 480,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layer-list xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item"
  },
  {
    "path": "base/src/main/res/drawable/btn_ripple.xml",
    "chars": 732,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item a"
  },
  {
    "path": "base/src/main/res/layout/base_layout_tool_bar.xml",
    "chars": 726,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<android.support.v7.widget.Toolbar xmlns:android=\"http://schemas.android.com/apk"
  },
  {
    "path": "base/src/main/res/values/colors.xml",
    "chars": 1634,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"color"
  },
  {
    "path": "base/src/main/res/values/dimens.xml",
    "chars": 1159,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n\n\n    <dimen name=\"activity_horizontal_margin\">16dp</dimen>\n    <dim"
  },
  {
    "path": "base/src/main/res/values/strings.xml",
    "chars": 582,
    "preview": "<resources>\n    <string name=\"app_name\">Android组件化</string>\n    <string name=\"no_more\">没有更多了</string>\n\n\n    <!-- Error V"
  },
  {
    "path": "base/src/main/res/values/styles.xml",
    "chars": 2848,
    "preview": "<resources>\n\n\n    <style name=\"BaseAppTheme\" parent=\"Theme.AppCompat.Light.NoActionBar\">\n        <!-- Customize your the"
  },
  {
    "path": "base/src/test/java/com/ccj/base/ExampleUnitTest.java",
    "chars": 390,
    "preview": "package com.ccj.base;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit test, which "
  },
  {
    "path": "build.gradle",
    "chars": 1777,
    "preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n    r"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "chars": 230,
    "preview": "#Mon Dec 28 10:00:20 PST 2015\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_"
  },
  {
    "path": "gradle.properties",
    "chars": 860,
    "preview": "## Project-wide Gradle settings.\n#\n# For more details on how to configure your build environment visit\n# http://www.grad"
  },
  {
    "path": "gradlew",
    "chars": 4971,
    "preview": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start "
  },
  {
    "path": "gradlew.bat",
    "chars": 2314,
    "preview": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem "
  },
  {
    "path": "module_home/.gitignore",
    "chars": 7,
    "preview": "/build\n"
  },
  {
    "path": "module_home/build.gradle",
    "chars": 1656,
    "preview": "\nif (isModule.toBoolean()) {\n    apply plugin: 'com.android.application'\n} else {\n    apply plugin: 'com.android.library"
  },
  {
    "path": "module_home/proguard-rules.pro",
    "chars": 751,
    "preview": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguar"
  },
  {
    "path": "module_home/src/main/AndroidManifest.xml",
    "chars": 706,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package="
  },
  {
    "path": "module_home/src/main/java/com/ccj/home/HomeFragment.java",
    "chars": 3425,
    "preview": "package com.ccj.home;\n\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.support.annotation.Nullab"
  },
  {
    "path": "module_home/src/main/java/com/ccj/home/MainActivity.java",
    "chars": 325,
    "preview": "package com.ccj.home;\n\nimport android.os.Bundle;\nimport android.support.v7.app.AppCompatActivity;\n\npublic class MainActi"
  },
  {
    "path": "module_home/src/main/release/AndroidManifest.xml",
    "chars": 356,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\" package=\"com"
  },
  {
    "path": "module_home/src/main/res/drawable/ic_launcher_background.xml",
    "chars": 5606,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:wi"
  },
  {
    "path": "module_home/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "chars": 1880,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    "
  },
  {
    "path": "module_home/src/main/res/layout/activity_main.xml",
    "chars": 803,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.constraint.ConstraintLayout xmlns:android=\"http://schemas.androi"
  },
  {
    "path": "module_home/src/main/res/layout/home_fragment_haojia_home.xml",
    "chars": 1589,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  "
  },
  {
    "path": "module_home/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "chars": 272,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <b"
  },
  {
    "path": "module_home/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "chars": 272,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <b"
  },
  {
    "path": "module_home/src/main/res/values/colors.xml",
    "chars": 208,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"color"
  },
  {
    "path": "module_home/src/main/res/values/strings.xml",
    "chars": 74,
    "preview": "<resources>\n    <string name=\"app_name\">module_home</string>\n</resources>\n"
  },
  {
    "path": "module_home/src/main/res/values/styles.xml",
    "chars": 383,
    "preview": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar"
  },
  {
    "path": "module_meizi/.gitignore",
    "chars": 7,
    "preview": "/build\n"
  },
  {
    "path": "module_meizi/build.gradle",
    "chars": 1655,
    "preview": "\nif (isModule.toBoolean()) {\n    apply plugin: 'com.android.application'\n} else {\n    apply plugin: 'com.android.library"
  },
  {
    "path": "module_meizi/proguard-rules.pro",
    "chars": 751,
    "preview": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguar"
  },
  {
    "path": "module_meizi/src/main/AndroidManifest.xml",
    "chars": 962,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package="
  },
  {
    "path": "module_meizi/src/main/java/com/ccj/meizi/adapter/MeiziRcvAdapter.java",
    "chars": 1142,
    "preview": "package com.ccj.meizi.adapter;\n\nimport android.app.Activity;\nimport android.support.annotation.NonNull;\nimport android.s"
  },
  {
    "path": "module_meizi/src/main/java/com/ccj/meizi/api/MeiziAPIServiceImp.java",
    "chars": 738,
    "preview": "package com.ccj.meizi.api;\n\nimport com.ccj.base.api.APIService;\nimport com.ccj.base.utils.TLog;\nimport com.ccj.meizi.bea"
  },
  {
    "path": "module_meizi/src/main/java/com/ccj/meizi/api/MeiziRetrofitImp.java",
    "chars": 396,
    "preview": "package com.ccj.meizi.api;\n\n\nimport com.ccj.meizi.bean.Meizhi;\n\nimport retrofit2.http.GET;\nimport retrofit2.http.Path;\ni"
  },
  {
    "path": "module_meizi/src/main/java/com/ccj/meizi/bean/Meizhi.java",
    "chars": 4774,
    "preview": "package com.ccj.meizi.bean;\n\nimport com.ccj.base.adapter.bean.AdapterBean;\nimport com.google.gson.Gson;\n\nimport java.uti"
  },
  {
    "path": "module_meizi/src/main/java/com/ccj/meizi/debug/ContainActivity.java",
    "chars": 718,
    "preview": "package com.ccj.meizi.debug;\n\nimport android.os.Bundle;\n\nimport com.ccj.base.base.BaseActivity;\nimport com.ccj.meizi.R;\n"
  },
  {
    "path": "module_meizi/src/main/java/com/ccj/meizi/debug/MainActivity.java",
    "chars": 676,
    "preview": "package com.ccj.meizi.debug;\n\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.support.v7.app.App"
  },
  {
    "path": "module_meizi/src/main/java/com/ccj/meizi/holder/MeiziItemHolder.java",
    "chars": 1580,
    "preview": "package com.ccj.meizi.holder;\n\nimport android.app.Activity;\nimport android.view.View;\nimport android.widget.ImageView;\n\n"
  },
  {
    "path": "module_meizi/src/main/java/com/ccj/meizi/ui/detail/MeiziDetailActivity.java",
    "chars": 917,
    "preview": "package com.ccj.meizi.ui.detail;\n\nimport android.os.Bundle;\nimport android.widget.ImageView;\n\nimport com.alibaba.android"
  },
  {
    "path": "module_meizi/src/main/java/com/ccj/meizi/ui/main/MeiZhiContract.java",
    "chars": 891,
    "preview": "package com.ccj.meizi.ui.main;\n\n\nimport com.ccj.base.base.BasePresenter;\nimport com.ccj.base.base.BaseView;\nimport com.c"
  },
  {
    "path": "module_meizi/src/main/java/com/ccj/meizi/ui/main/MeiZhiFragment.java",
    "chars": 4028,
    "preview": "package com.ccj.meizi.ui.main;\n\nimport android.os.Bundle;\nimport android.support.annotation.Nullable;\nimport android.sup"
  },
  {
    "path": "module_meizi/src/main/java/com/ccj/meizi/ui/main/MeiZhiPresenter.java",
    "chars": 2388,
    "preview": "package com.ccj.meizi.ui.main;\n\nimport com.ccj.base.utils.TLog;\nimport com.ccj.meizi.api.MeiziAPIServiceImp;\nimport com."
  },
  {
    "path": "module_meizi/src/main/java/com/ccj/meizi/utils/DateStringUtils.java",
    "chars": 549,
    "preview": "package com.ccj.meizi.utils;\n\nimport java.text.SimpleDateFormat;\nimport java.util.Calendar;\n\n/**\n * Created by Administr"
  },
  {
    "path": "module_meizi/src/main/release/AndroidManifest.xml",
    "chars": 455,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\" package=\"com"
  },
  {
    "path": "module_meizi/src/main/res/drawable/ic_launcher_background.xml",
    "chars": 5606,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:wi"
  },
  {
    "path": "module_meizi/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "chars": 1880,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    "
  },
  {
    "path": "module_meizi/src/main/res/layout/activity_contain.xml",
    "chars": 418,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    andr"
  },
  {
    "path": "module_meizi/src/main/res/layout/activity_main.xml",
    "chars": 565,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    an"
  },
  {
    "path": "module_meizi/src/main/res/layout/activity_meizi_detail.xml",
    "chars": 351,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\" andr"
  },
  {
    "path": "module_meizi/src/main/res/layout/fragment_meizi.xml",
    "chars": 761,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmln"
  },
  {
    "path": "module_meizi/src/main/res/layout/item_meizi_item.xml",
    "chars": 842,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.v7.widget.CardView xmlns:android=\"http://schemas.android.com/apk"
  },
  {
    "path": "module_meizi/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "chars": 272,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <b"
  },
  {
    "path": "module_meizi/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "chars": 272,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <b"
  },
  {
    "path": "module_meizi/src/main/res/values/colors.xml",
    "chars": 208,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"color"
  },
  {
    "path": "module_meizi/src/main/res/values/strings.xml",
    "chars": 75,
    "preview": "<resources>\n    <string name=\"app_name\">module_meizi</string>\n</resources>\n"
  },
  {
    "path": "module_meizi/src/main/res/values/styles.xml",
    "chars": 383,
    "preview": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar"
  },
  {
    "path": "module_user/.gitignore",
    "chars": 7,
    "preview": "/build\n"
  },
  {
    "path": "module_user/build.gradle",
    "chars": 1659,
    "preview": "if (isModule.toBoolean()) {\n    apply plugin: 'com.android.application'\n} else {\n    apply plugin: 'com.android.library'"
  },
  {
    "path": "module_user/proguard-rules.pro",
    "chars": 941,
    "preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /U"
  },
  {
    "path": "module_user/src/main/AndroidManifest.xml",
    "chars": 879,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\" package=\"com"
  },
  {
    "path": "module_user/src/main/java/com/ccj/login/api/LoginAPIServiceImp.java",
    "chars": 825,
    "preview": "package com.ccj.login.api;\n\nimport com.ccj.base.api.APIService;\nimport com.ccj.base.bean.User;\nimport com.ccj.base.utils"
  },
  {
    "path": "module_user/src/main/java/com/ccj/login/api/LoginRetrofitImp.java",
    "chars": 576,
    "preview": "package com.ccj.login.api;\n\nimport com.ccj.base.api.RetrofitRequest;\nimport com.ccj.base.bean.User;\n\nimport java.util.Ha"
  },
  {
    "path": "module_user/src/main/java/com/ccj/login/debug/LoginApplication.java",
    "chars": 253,
    "preview": "package com.ccj.login.debug;\n\nimport com.ccj.base.base.BaseApplication;\n\n/**\n * Created by chenchangjun on 17/8/7.\n */\n\n"
  },
  {
    "path": "module_user/src/main/java/com/ccj/login/debug/MainActivity.java",
    "chars": 1145,
    "preview": "package com.ccj.login.debug;\n\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.support.v7.app.App"
  },
  {
    "path": "module_user/src/main/java/com/ccj/login/service/CheckLoginService.java",
    "chars": 613,
    "preview": "package com.ccj.login.service;\n\nimport android.content.Context;\n\nimport com.alibaba.android.arouter.facade.annotation.Ro"
  },
  {
    "path": "module_user/src/main/java/com/ccj/login/ui/login/LoginActivity.java",
    "chars": 3472,
    "preview": "package com.ccj.login.ui.login;\n\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.view.View;\nimpo"
  },
  {
    "path": "module_user/src/main/java/com/ccj/login/ui/login/LoginContract.java",
    "chars": 738,
    "preview": "package com.ccj.login.ui.login;\n\n\nimport com.ccj.base.base.BasePresenter;\nimport com.ccj.base.base.BaseView;\nimport com."
  },
  {
    "path": "module_user/src/main/java/com/ccj/login/ui/login/LoginModel.java",
    "chars": 772,
    "preview": "package com.ccj.login.ui.login;\n\n\nimport com.ccj.base.bean.User;\n\n/**\n * Created by Administrator on 2016/7/8.\n *  这里的lo"
  },
  {
    "path": "module_user/src/main/java/com/ccj/login/ui/login/LoginPresenter.java",
    "chars": 1803,
    "preview": "package com.ccj.login.ui.login;\n\n\nimport com.ccj.base.bean.User;\nimport com.ccj.base.utils.TLog;\nimport com.ccj.login.ap"
  },
  {
    "path": "module_user/src/main/java/com/ccj/login/ui/register/RegisterActivity.java",
    "chars": 786,
    "preview": "package com.ccj.login.ui.register;\n\nimport android.os.Bundle;\n\nimport com.alibaba.android.arouter.facade.annotation.Rout"
  },
  {
    "path": "module_user/src/main/java/com/ccj/login/ui/user/UserFragment.java",
    "chars": 827,
    "preview": "package com.ccj.login.ui.user;\n\nimport android.support.v4.app.Fragment;\nimport android.os.Bundle;\nimport android.support"
  },
  {
    "path": "module_user/src/main/release/AndroidManifest.xml",
    "chars": 486,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\" package=\"com"
  },
  {
    "path": "module_user/src/main/res/layout/activity_login.xml",
    "chars": 4167,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    an"
  },
  {
    "path": "module_user/src/main/res/layout/activity_main.xml",
    "chars": 809,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.constraint.ConstraintLayout\n    xmlns:android=\"http://schemas.an"
  },
  {
    "path": "module_user/src/main/res/layout/login_fragment_register.xml",
    "chars": 566,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    andr"
  },
  {
    "path": "module_user/src/main/res/layout/user_fragment_user_home.xml",
    "chars": 523,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  "
  },
  {
    "path": "module_user/src/main/res/values/colors.xml",
    "chars": 208,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"color"
  },
  {
    "path": "module_user/src/main/res/values/strings.xml",
    "chars": 74,
    "preview": "<resources>\n    <string name=\"app_name\">module_user</string>\n</resources>\n"
  },
  {
    "path": "module_user/src/main/res/values/styles.xml",
    "chars": 383,
    "preview": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar"
  },
  {
    "path": "module_video/.gitignore",
    "chars": 7,
    "preview": "/build\n"
  },
  {
    "path": "module_video/build.gradle",
    "chars": 1654,
    "preview": "if (isModule.toBoolean()) {\n    apply plugin: 'com.android.application'\n} else {\n    apply plugin: 'com.android.library'"
  },
  {
    "path": "module_video/proguard-rules.pro",
    "chars": 941,
    "preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /U"
  },
  {
    "path": "module_video/src/main/AndroidManifest.xml",
    "chars": 801,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\" package=\"com"
  },
  {
    "path": "module_video/src/main/java/com/ccj/video/VideoFragment.java",
    "chars": 798,
    "preview": "package com.ccj.video;\n\nimport android.support.v4.app.Fragment;\nimport android.os.Bundle;\nimport android.support.annotat"
  },
  {
    "path": "module_video/src/main/java/com/ccj/video/debug/MainActivity.java",
    "chars": 359,
    "preview": "package com.ccj.video.debug;\n\nimport android.os.Bundle;\nimport android.support.v7.app.AppCompatActivity;\n\nimport com.ccj"
  },
  {
    "path": "module_video/src/main/java/com/ccj/video/debug/VideoApplication.java",
    "chars": 284,
    "preview": "package com.ccj.video.debug;\n\nimport com.ccj.base.base.BaseApplication;\n\n/**\n * 在module模式下,测试的application\n * Created by "
  },
  {
    "path": "module_video/src/main/java/com/ccj/video/service/VideoServiceImpl.java",
    "chars": 617,
    "preview": "package com.ccj.video.service;\n\nimport android.content.Context;\nimport android.util.Log;\n\nimport com.alibaba.android.aro"
  },
  {
    "path": "module_video/src/main/java/com/ccj/video/ui/TakePhotoActivity.java",
    "chars": 2940,
    "preview": "package com.ccj.video.ui;\n\nimport android.content.Intent;\nimport android.graphics.Bitmap;\nimport android.os.Bundle;\nimpo"
  },
  {
    "path": "module_video/src/main/java/com/ccj/video/ui/TakePhotoContract.java",
    "chars": 673,
    "preview": "package com.ccj.video.ui;\n\nimport android.content.Intent;\nimport android.graphics.Bitmap;\n\nimport com.ccj.base.base.Base"
  },
  {
    "path": "module_video/src/main/java/com/ccj/video/ui/TakePhotoModel.java",
    "chars": 2981,
    "preview": "package com.ccj.video.ui;\n\nimport android.content.Intent;\nimport android.graphics.Bitmap;\nimport android.graphics.Bitmap"
  },
  {
    "path": "module_video/src/main/java/com/ccj/video/ui/TakePhotoPresenter.java",
    "chars": 1855,
    "preview": "package com.ccj.video.ui;\n\nimport android.content.Intent;\nimport android.graphics.Bitmap;\nimport android.util.Log;\n\nimpo"
  },
  {
    "path": "module_video/src/main/release/AndroidManifest.xml",
    "chars": 379,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\" package=\"com"
  },
  {
    "path": "module_video/src/main/res/layout/activity_main.xml",
    "chars": 765,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.constraint.ConstraintLayout\n    xmlns:android=\"http://schemas.an"
  },
  {
    "path": "module_video/src/main/res/layout/activity_take_photo.xml",
    "chars": 913,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    an"
  },
  {
    "path": "module_video/src/main/res/layout/video_fragment_video_home.xml",
    "chars": 605,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.constraint.ConstraintLayout\n    xmlns:android=\"http://schemas.an"
  },
  {
    "path": "module_video/src/main/res/values/colors.xml",
    "chars": 208,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"color"
  },
  {
    "path": "module_video/src/main/res/values/strings.xml",
    "chars": 75,
    "preview": "<resources>\n    <string name=\"app_name\">module_video</string>\n</resources>\n"
  },
  {
    "path": "module_video/src/main/res/values/styles.xml",
    "chars": 383,
    "preview": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar"
  },
  {
    "path": "settings.gradle",
    "chars": 90,
    "preview": "include ':app', ':module_video', ':module_user', ':base', ':module_home', ':module_meizi'\n"
  }
]

// ... and 2 more files (download for full content)

About this extraction

This page contains the full source code of the ccj659/clean-project-architecture GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 182 files (234.2 KB), approximately 67.1k tokens, and a symbol index with 452 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!