[
  {
    "path": ".gitignore",
    "content": "*.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",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"GradleSettings\">\n    <option name=\"linkedExternalProjectsSettings\">\n      <GradleProjectSettings>\n        <option name=\"distributionType\" value=\"DEFAULT_WRAPPED\" />\n        <option name=\"externalProjectPath\" value=\"$PROJECT_DIR$\" />\n        <option name=\"modules\">\n          <set>\n            <option value=\"$PROJECT_DIR$\" />\n            <option value=\"$PROJECT_DIR$/app\" />\n            <option value=\"$PROJECT_DIR$/base\" />\n            <option value=\"$PROJECT_DIR$/module_home\" />\n            <option value=\"$PROJECT_DIR$/module_meizi\" />\n            <option value=\"$PROJECT_DIR$/module_user\" />\n            <option value=\"$PROJECT_DIR$/module_video\" />\n          </set>\n        </option>\n        <option name=\"resolveModulePerSourceSet\" value=\"false\" />\n      </GradleProjectSettings>\n    </option>\n  </component>\n</project>"
  },
  {
    "path": ".idea/markdown-navigator/profiles_settings.xml",
    "content": "<component name=\"MarkdownNavigator.ProfileManager\">\n  <settings default=\"\" pdf-export=\"\" />\n</component>"
  },
  {
    "path": ".idea/markdown-navigator.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"MarkdownProjectSettings\">\n    <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\">\n      <PanelProvider>\n        <provider providerId=\"com.vladsch.idea.multimarkdown.editor.swing.html.panel\" providerName=\"Default - Swing\" />\n      </PanelProvider>\n    </PreviewSettings>\n    <ParserSettings gitHubSyntaxChange=\"false\">\n      <PegdownExtensions>\n        <option name=\"ABBREVIATIONS\" value=\"false\" />\n        <option name=\"ANCHORLINKS\" value=\"true\" />\n        <option name=\"ASIDE\" value=\"false\" />\n        <option name=\"ATXHEADERSPACE\" value=\"true\" />\n        <option name=\"AUTOLINKS\" value=\"true\" />\n        <option name=\"DEFINITIONS\" value=\"false\" />\n        <option name=\"DEFINITION_BREAK_DOUBLE_BLANK_LINE\" value=\"false\" />\n        <option name=\"FENCED_CODE_BLOCKS\" value=\"true\" />\n        <option name=\"FOOTNOTES\" value=\"false\" />\n        <option name=\"HARDWRAPS\" value=\"false\" />\n        <option name=\"HTML_DEEP_PARSER\" value=\"false\" />\n        <option name=\"INSERTED\" value=\"false\" />\n        <option name=\"QUOTES\" value=\"false\" />\n        <option name=\"RELAXEDHRULES\" value=\"true\" />\n        <option name=\"SMARTS\" value=\"false\" />\n        <option name=\"STRIKETHROUGH\" value=\"true\" />\n        <option name=\"SUBSCRIPT\" value=\"false\" />\n        <option name=\"SUPERSCRIPT\" value=\"false\" />\n        <option name=\"SUPPRESS_HTML_BLOCKS\" value=\"false\" />\n        <option name=\"SUPPRESS_INLINE_HTML\" value=\"false\" />\n        <option name=\"TABLES\" value=\"true\" />\n        <option name=\"TASKLISTITEMS\" value=\"true\" />\n        <option name=\"TOC\" value=\"false\" />\n        <option name=\"WIKILINKS\" value=\"true\" />\n      </PegdownExtensions>\n      <ParserOptions>\n        <option name=\"COMMONMARK_LISTS\" value=\"true\" />\n        <option name=\"DUMMY\" value=\"false\" />\n        <option name=\"EMOJI_SHORTCUTS\" value=\"true\" />\n        <option name=\"FLEXMARK_FRONT_MATTER\" value=\"false\" />\n        <option name=\"GFM_LOOSE_BLANK_LINE_AFTER_ITEM_PARA\" value=\"false\" />\n        <option name=\"GFM_TABLE_RENDERING\" value=\"true\" />\n        <option name=\"GITBOOK_URL_ENCODING\" value=\"false\" />\n        <option name=\"GITHUB_EMOJI_URL\" value=\"false\" />\n        <option name=\"GITHUB_LISTS\" value=\"false\" />\n        <option name=\"GITHUB_WIKI_LINKS\" value=\"true\" />\n        <option name=\"JEKYLL_FRONT_MATTER\" value=\"false\" />\n        <option name=\"SIM_TOC_BLANK_LINE_SPACER\" value=\"true\" />\n      </ParserOptions>\n    </ParserSettings>\n    <HtmlSettings headerTopEnabled=\"false\" headerBottomEnabled=\"false\" bodyTopEnabled=\"false\" bodyBottomEnabled=\"false\" embedUrlContent=\"false\" addPageHeader=\"true\">\n      <GeneratorProvider>\n        <provider providerId=\"com.vladsch.idea.multimarkdown.editor.swing.html.generator\" providerName=\"Default Swing HTML Generator\" />\n      </GeneratorProvider>\n      <headerTop />\n      <headerBottom />\n      <bodyTop />\n      <bodyBottom />\n    </HtmlSettings>\n    <CssSettings previewScheme=\"UI_SCHEME\" cssUri=\"\" isCssUriEnabled=\"false\" isCssTextEnabled=\"false\" isDynamicPageWidth=\"true\">\n      <StylesheetProvider>\n        <provider providerId=\"com.vladsch.idea.multimarkdown.editor.swing.html.css\" providerName=\"Default Swing Stylesheet\" />\n      </StylesheetProvider>\n      <ScriptProviders />\n      <cssText />\n    </CssSettings>\n    <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\" />\n    <LinkMapSettings>\n      <textMaps />\n    </LinkMapSettings>\n  </component>\n</project>"
  },
  {
    "path": ".idea/misc.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"NullableNotNullManager\">\n    <option name=\"myDefaultNullable\" value=\"android.support.annotation.Nullable\" />\n    <option name=\"myDefaultNotNull\" value=\"android.support.annotation.NonNull\" />\n    <option name=\"myNullables\">\n      <value>\n        <list size=\"4\">\n          <item index=\"0\" class=\"java.lang.String\" itemvalue=\"org.jetbrains.annotations.Nullable\" />\n          <item index=\"1\" class=\"java.lang.String\" itemvalue=\"javax.annotation.Nullable\" />\n          <item index=\"2\" class=\"java.lang.String\" itemvalue=\"edu.umd.cs.findbugs.annotations.Nullable\" />\n          <item index=\"3\" class=\"java.lang.String\" itemvalue=\"android.support.annotation.Nullable\" />\n        </list>\n      </value>\n    </option>\n    <option name=\"myNotNulls\">\n      <value>\n        <list size=\"4\">\n          <item index=\"0\" class=\"java.lang.String\" itemvalue=\"org.jetbrains.annotations.NotNull\" />\n          <item index=\"1\" class=\"java.lang.String\" itemvalue=\"javax.annotation.Nonnull\" />\n          <item index=\"2\" class=\"java.lang.String\" itemvalue=\"edu.umd.cs.findbugs.annotations.NonNull\" />\n          <item index=\"3\" class=\"java.lang.String\" itemvalue=\"android.support.annotation.NonNull\" />\n        </list>\n      </value>\n    </option>\n  </component>\n  <component name=\"ProjectRootManager\" version=\"2\" languageLevel=\"JDK_1_7\" project-jdk-name=\"1.8\" project-jdk-type=\"JavaSDK\">\n    <output url=\"file://$PROJECT_DIR$/build/classes\" />\n  </component>\n  <component name=\"ProjectType\">\n    <option name=\"id\" value=\"Android\" />\n  </component>\n</project>"
  },
  {
    "path": ".idea/modules.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ProjectModuleManager\">\n    <modules>\n      <module fileurl=\"file://$PROJECT_DIR$/app/app.iml\" filepath=\"$PROJECT_DIR$/app/app.iml\" />\n      <module fileurl=\"file://$PROJECT_DIR$/app/app.iml\" filepath=\"$PROJECT_DIR$/app/app.iml\" />\n      <module fileurl=\"file://$PROJECT_DIR$/base/base.iml\" filepath=\"$PROJECT_DIR$/base/base.iml\" />\n      <module fileurl=\"file://$PROJECT_DIR$/base/base.iml\" filepath=\"$PROJECT_DIR$/base/base.iml\" />\n      <module fileurl=\"file://$PROJECT_DIR$/.idea/clean-project-architecture-check.iml\" filepath=\"$PROJECT_DIR$/.idea/clean-project-architecture-check.iml\" />\n      <module fileurl=\"file://$PROJECT_DIR$/clean-project-architecture_back.iml\" filepath=\"$PROJECT_DIR$/clean-project-architecture_back.iml\" />\n      <module fileurl=\"file://$PROJECT_DIR$/module_home/module_home.iml\" filepath=\"$PROJECT_DIR$/module_home/module_home.iml\" />\n      <module fileurl=\"file://$PROJECT_DIR$/module_home/module_home.iml\" filepath=\"$PROJECT_DIR$/module_home/module_home.iml\" />\n      <module fileurl=\"file://$PROJECT_DIR$/module_meizi/module_meizi.iml\" filepath=\"$PROJECT_DIR$/module_meizi/module_meizi.iml\" />\n      <module fileurl=\"file://$PROJECT_DIR$/module_meizi/module_meizi.iml\" filepath=\"$PROJECT_DIR$/module_meizi/module_meizi.iml\" />\n      <module fileurl=\"file://$PROJECT_DIR$/module_user/module_user.iml\" filepath=\"$PROJECT_DIR$/module_user/module_user.iml\" />\n      <module fileurl=\"file://$PROJECT_DIR$/module_user/module_user.iml\" filepath=\"$PROJECT_DIR$/module_user/module_user.iml\" />\n      <module fileurl=\"file://$PROJECT_DIR$/module_video/module_video.iml\" filepath=\"$PROJECT_DIR$/module_video/module_video.iml\" />\n      <module fileurl=\"file://$PROJECT_DIR$/module_video/module_video.iml\" filepath=\"$PROJECT_DIR$/module_video/module_video.iml\" />\n    </modules>\n  </component>\n</project>"
  },
  {
    "path": ".idea/runConfigurations.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"RunConfigurationProducerService\">\n    <option name=\"ignoredProducers\">\n      <set>\n        <option value=\"org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer\" />\n        <option value=\"org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer\" />\n        <option value=\"org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer\" />\n      </set>\n    </option>\n  </component>\n</project>"
  },
  {
    "path": ".idea/vcs.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"VcsDirectoryMappings\">\n    <mapping directory=\"$PROJECT_DIR$\" vcs=\"Git\" />\n  </component>\n</project>"
  },
  {
    "path": "README.md",
    "content": "\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组件化项目框架,以及主流的项目架构(MVP+RxJava+Retrofit),以后会不断完善.\r\n\r\n\r\n\r\n\r\n- [MVP传送门](https://github.com/ccj659/clean-project-architecture/blob/master/README_MVP.md)\r\n\r\n- [组件化传送门](https://github.com/ccj659/clean-project-architecture/blob/master/README_MODULE.md)\r\n\r\n\r\n\r\n\r\n参考界面:\r\n![](http://i.imgur.com/EnBxczU.gif)"
  },
  {
    "path": "README_MODULE.md",
    "content": "# 客户端组件化探究\n\n**项目地址** [https://github.com/ccj659/clean-project-architecture](https://github.com/ccj659/clean-project-architecture)\n\n\n\n## 1.组件化的产生背景\n\n随着业务的增多,迭代版本的增加,\n\n模块化开发, 业务解耦, 业务独立进行测试,编译,运行,想想都惊喜~\n\n如果不想忍受超长的编译时间,不想忍受类之间的强耦合,受够了满屏的不相干的文件,那么.....\n\n为了你的\"代码洁癖\",还有项目的未来, 组件化, 势在必行.....\n\n\n## 2.普通开发模式的弊端\n\n1、实际业务变化非常快，但是单一工程的业务模块耦合度太高，牵一发而动全身,每次改一个地方都很小心.\n\n2、对工程所做的任何修改都必须要编译整个工程；\n\n3、团队协同开发存在较多的冲突.不得不花费更多的时间去沟通和协调，并且在开发过程中，任何一位成员没办法专注于自己的功能点，影响开发效率；\n\n4、不能灵活的对业务模块进行配置和组装；\n\n\n\n## 3.什么是组件化\n\n\n\t组件化是 编程思想\"高内聚,低耦合\"的一种体现, 是 业务独立化, 粒度最小化,可移植的功能模块.\n\n\n\n1.页面上的每个 独立的 可视/可交互区域视为一个组件;\u000b\n\n2.每个组件对应一个工程目录，组件所需的各种资源都在这个目录下就近维护;\u000b\n\n3.每个组件相对独立，页面只不过是组件的容器，组件自由组合形成功能完整的界面;\u000b\n\n4.当不需要某个组件，或者想要替换组件时，可以整个目录删除/替换。\n\n\n\n\n\n\n\n## 4.组件化会解决 目前项目中哪些问题?\n\n1.急需解决 项目编译时间过长问题!\n\n2.急需团队开发,解决提交代码 牵一发动全身的问题!\n\n3.解决开发效率低下问题.\n\n4.解决项目越来越臃肿,分层不明确,,难以维护问题.\n\n5.减少 学习成本.\n\n\n\n\n## 5.项目如何进行组件化?\n\n\n\n\n\n**在框架中的 项目组件化是这样的~**\n\n![未命名文件 (6).png](http://upload-images.jianshu.io/upload_images/1848340-4011e008d6533cc2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)\n\n\n**反映在代码目录结构上,就是如下所示~**\n\n![image.png](http://upload-images.jianshu.io/upload_images/1848340-1681c9f78b3f90c9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)\n\n\n**根据上述结构图,我对目前的项目做了如下调整.**\n\n1.将项目的业务模块(主页,好价,好文,好物,个人中心,关注),作为独立的application module. 每一位业务的开发人员,只需要管理自己的module即可,避免直接或者间接修改他人代码导致的问题.而且,开发期间,自住选择必要中间件的依赖,自住开发风格(MVP,MVC,etc).\n\n2.将中间组件(通用list_item组件,分享组件,推送组件,内置浏览器组件,通用view组件,以及通用跳转等等),作为library module进行选择性依赖.\n\n3.将底层库(网络请求库,db库,File库,图片库等等),作为一个底层library库,独立进行版本控制,用@aar-v1.0.1 来引用,这样可以防止,他人的随意改动,提高版本切换之间的稳定性.\n\n\n## 6.问题五连\n\n\n#### Q1.如何将工程拆分成有机的整体,组件单独运行？\n\n利用Android studio 自带的gradle 来管理. 我们可以使用grovxy脚本,来对 是否是组件状态进行切换.\n\n![image.png](http://upload-images.jianshu.io/upload_images/1848340-46ab2ef7c01244f3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)\n\n\n####  Q2.如何分别执行独立运行,合并运行的代码?\n当项目是APPlication时候,需要有category为LAUNCHER的入口activity.\n当项目是lib的时候,不能存在入口activity.所以要分别建立两套配置.\n\n还要注意,如果想要保持主题样式通用, 主app下,’theme’'ico','label'等等,在module中都不能存在.\n\n![image.png](http://upload-images.jianshu.io/upload_images/1848340-a531f85dd9d77563.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)\n\n####  Q3.代码都分离了,如何进行带参跳转,相互调用?\n首先,考虑到解耦, 可以把ARouter的所有跳转都进行封装.以后待项目成熟,我会用自己的Router.\n\t另外,module内,可以用传统方式传递和用路由器传递都行.\n![image.png](http://upload-images.jianshu.io/upload_images/1848340-8bf31d3c74218ad9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)\n\n\n\n####  Q4.是啊,分业务是好,但是代码合并后,如果避免存在资源名冲突?\n\n1.第三方依赖的问题,依赖尽量放在base中.这样,gradle会自动去重.\n\n\n2.资源名重复,在编码的时候 添加resourcePrefix \"video\"+\"_\",强制人员添加前缀(但是对drawable不支持,需用户自己增加前缀).\n\n3.将资源统一放在一个module(比如Base中),但是编译会增加时间.(不太复合资源解耦 原则)\n\n####  Q5.代码那么多,把之前的都解耦了,如何避免后期继续耦合?\n\n针对这个问题, 组件之间必须针对接口编程,杜绝面向实现编程.\n另外, 我们在设计一个组件的时候, 要尽量用继承封装多态去解决问题.\n\n\n\n\n## 7.如何实现\n\n\n\n**1.在`gradle.properties` 增加一个变量**\n\n```\n# true代表模块开发,false代表合并到主app.\n#模式切换开关\nisModule=false\n\n```\n\n**2.在每个业务module的`build.gradle`里面添加**\n\n```\n//根据isModule值进行切换 是否为lib或者app\nif (isModule.toBoolean()) {\n    apply plugin: 'com.android.application'\n} else {\n    apply plugin: 'com.android.library'\n}\n```\n\n**3.建立两个`AndroidManifest.xml`,进行切换**\n\n大家都知道,当项目是APPlication时候,需要有category为`LAUNCHER`的入口activity.\n而当项目是lib的时候,不能存在入口activity.所以要分别建立两套`AndroidManifest.xml `,还要注意,如果想要保持主题样式通用, 主app项目下的`theme`,'ico','label'等等,在module中都不能存在.\n进行如下配置.\n![image.png](http://upload-images.jianshu.io/upload_images/1848340-92b4a7213a9ad8d1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)\n\n\n**4.建立两个`AndroidManifest.xml`,进行切换**\n\n```\n    sourceSets {\n        main {\n            if (isModule.toBoolean()) {\n                manifest.srcFile 'src/main/AndroidManifest.xml'\n            } else {\n                manifest.srcFile 'src/main/release/AndroidManifest.xml'\n                java {\n                    //release 时 debug 目录下文件不需要合并到主工程\n                    exclude '**/debug/**'\n                }\n            }\n        }\n    }\n```\n\n**5.业务组件不需要混淆代码.**\n一旦业务组件的代码被混淆，而这时候代码中又出现了bug，将很难根据日志找出导致bug的原因；\n\n\n**6.当ismodule开关为true时,每个module可独立运行.**\n\n![image.png](http://upload-images.jianshu.io/upload_images/1848340-ddb00f60544243a3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)\n\n\n\n## 应用效果\n\n\n![compone1.gif](http://upload-images.jianshu.io/upload_images/1848340-a3af30d73a24fdaa.gif?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)\n\n\n\n\n![compone2.gif](http://upload-images.jianshu.io/upload_images/1848340-06e31929d2927460.gif?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)\n\n\n\n\n#总结\n\n\n## 优点\n\n1.业务module独立,降低业务的学习成本.\n\n2.模块解耦, 代码架构更加清晰，降低项目的维护难度.\n\n3.随着项目的代码增加,单独编译,单独运行,明显减少代码编译时间.\n\n4.适合于团队开发.\n\n\n## 不足\n\n\n1.switch中 case必须是 静态常亮,所以在引用  library中 的 资源(R.id.button) 时, 需要改为if else. 这个还需要找到解决方案...\n\n\n2.模块间 数据交互,比较繁琐\n\n3.路由器模块还不太成熟\n\n4.实际开展过程,抽丝剥茧,过程会很痛苦.\n\n5.还存在潜在问题.\n\n## 后期计划\n\n 1.提高编译速度, 将 依赖 由 整个项目进行编译, 变为依赖 aar包, 减少编译时间.\n\n 2.搭建一个私有的maven仓库，将我们开发好的组件上传到这个私有的maven仓库上，然后内部开发人员就可以像引用三方库那样轻而易举的将组件引入到项目中\n\n3. 完善复合项目的事件路由Router,\n\n\n\n## 参考\n\n [aar的使用](http://blog.csdn.net/zxw136511485/article/details/52777286)\n\n [http://blog.csdn.net/guiying712/article/details/55213884](http://blog.csdn.net/guiying712/article/details/55213884)\n\n [Android彻底组件化demo发布](https://www.jianshu.com/p/59822a7b2fad)"
  },
  {
    "path": "README_MVP.md",
    "content": "\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.添加get请求.\n\n\t2.完成妹子Meterial Design 风格的list界面.\n\n\n参考界面:\n![](http://i.imgur.com/EnBxczU.gif)\n\n-------\n2016/7/23 更新  热修复相关\n\ncsdn: http://blog.csdn.net/ccj659/article/details/52004522\n简书: http://www.jianshu.com/p/2301d40dbb33\n\n[热修复]--源码级分析以及项目实践 谢谢大家指正~\n\n----------\n\n\nandroid架构篇\n===================\nmvp+rxjava+retrofit+eventBus\n===================\n----------\n\n高层不应该知道低层的细节，应该是面向抽象的编程。业务的实现交给实现的接口的类。高层只负责调用。\n\n----------\n首先,要介绍一下一个项目中好架构的好处:好的软件设计必须能够帮助开发者发展和扩充解决方案，保持代码清晰健壮，并且可扩展，易于维护，而不必每件事都重写代码。面对软件存在的问题，必须遵守SOLID原则(面向对象五大原则)，不要过度工程化，尽可能降低框架中模块的依赖性。\n\n----------\n之前的一段时间,学习了一些新的技术,并把自己关注的技术整合了一下,是的,相似的技术有很多,自己择优选择,将它们的思想和技术应用到了自己的搭建的项目框架中.\n限于自己能力水平有限,自己搭建的项目可能还有些不足,欢迎大家指正批评,让自己的想法和设计思想走向正轨.O(∩_∩)O谢谢~\n\n在框架中\n-------------\n *1.**项目整体框架: 利用google-clean-architecture的思想 来负责项目的整体MVP架构.***\n\n - MVP是模型（Model）、视图（View）、主持人（Presenter）的缩写，分别代表项目中3个不同的模块。**我以登录为例子,进行说明.**\n\n![这里写图片描述](http://img.blog.csdn.net/20160712153716629)\n\n  这里每个业务首先要有一个管理接口Contract,在这里面有三个接口来面向接口编程, （Model）,（View）,（Presenter）. 将三个接口放在一起便于管理.\n\n![这里写图片描述](http://img.blog.csdn.net/20160712153741743)\n```java\n   /**\n * 登录关联接口类\n *\n * Created by ccj on 2016/7/7.\n */\npublic interface LoginContract {\n    interface View extends BaseView {\n        void showProgress();\n        void hideProgress();\n        void showError(String error);\n        void navigateToMain();\n        void navigateToRegister();\n    }\n    interface Presenter extends BasePresenter {\n        void login(String username, String password);\n        void onDestroy();\n    }\n    interface Model{\n        void saveUserInfo(User user);\n        void saveLoginState(Boolean isLogin);\n        void saveRememberPass(User user);\n\n    }\n\n}\n```\n - **模型（Model）：实现 implements LoginContract.Model** 负责处理数据的加载或者存储，比如从网络或本地数据库获取数据等；**这里的login 涉及到的业务逻辑比较少请求网络 采用了rxjava +retroft+gsons 相当于 model层. 如果处理的出具多,就采用此model ,就像图片保存显示等等.**\n\n - **视图（View）：采用接口的方式,让activity实现该接口,接口中有关于视图的方法,例如”initVIew()”,”showDialog()”,”hideDialog()”等等, 负责界面数据的展示，与用户进行交互；**\n ```java\n public class LoginActivity extends BaseActivity implements LoginContract.View {\n\n  //省略bufferknife 注解\n    private LoginPresenter presenter;\n    @Override\n    public void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_login);\n        ButterKnife.bind(this);\n        presenter=new LoginPresenter(this);\n        presenter.start();//初始化控制层\n    }\n\n\t//实现于view的方法\n    @Override\n    public void navigateToMain() {\n        Intent intent =new Intent(getBaseContext(),MainActivity.class);\n        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);\n        startActivity(intent);\n    }\n\n ```\n - **主持人（Presenter）：持有 view和model的对象,操作两者的方法.相当于协调者，是模型与视图之间的桥梁，将模型与视图分离开来,对view 和model 进行调度操作。**\n\n```java\n  /**\n * login的presenter层 进行对view 和 model 的控制,\n * Created by ccj on 2016/7/7.\n */\npublic class LoginPresenter implements LoginContract.Presenter {\n\n    private LoginContract.View loginView;\n    public LoginPresenter(LoginContract.View loginView) {\n        this.loginView = loginView;\n    }\n\n    @Override\n    public void login(String username, String password) {\n        loginView.showProgress();\n        Observable<User> userObservable = APIService.userLogin(username, password);\n        userObservable.subscribeOn(Schedulers.io())\n                .observeOn(AndroidSchedulers.mainThread())\n                .subscribe(new Subscriber<User>() {\n                    @Override\n                    public void onCompleted() {\n                        loginView.hideProgress();\n                    }\n\n                    @Override\n                    public void onError(Throwable e) {\n                        TLog.log(e.getMessage().toString());\n                        loginView.hideProgress();\n                        loginView.showError(e.getMessage().toString());\n                    }\n\n                    @Override\n                    public void onNext(User getIpInfoResponse) {\n                        TLog.log(getIpInfoResponse.toString());\n                        loginView.navigateToMain();\n                    }\n                });\n    }\n\n    @Override\n    public void start() {\n\n    }\n\n```\n\n\n***2.网络访问: 采用rxjava+retrofit+gson进行网络访问,并轻松的将json转为对象,结构清晰,使用方便.***\n\n - **在APIService中初始化retrofit**\n\n```java\n /**\n * 调用后台的接口,架构网络层采用Retroft+Rxjava+gson\n * Created by ccj on 2016/7/1.\n *\n */\npublic class APIService {\n\n    private static final String TAG = \"APIService\";\n    public static final String URL_HOST =\"http://123.234.82.23\" ;//服务器端口\n    /**\n     * 基础地址\n     * 初始化 retroft\n     */\n    private static final Retrofit sRetrofit = new Retrofit.Builder()\n            .baseUrl(URL_HOST)\n            .addConverterFactory(GsonConverterFactory.create())\n            .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) // 使用RxJava作为回调适配器\n            .build();\n    private static final RetrofitRequest apiManager = sRetrofit.create(RetrofitRequest.class);\n    /**\n     * 登录,返回,我这边用的是json格式的post,大家可以进行选择\n     * @param city\n     * @return\n     */\n    public static Observable<User> userLogin(String format, String city) {\n        HashMap<String,String> hashMap =new HashMap<>();\n        hashMap.put(\"UserPhone\", format);\n        hashMap.put(\"UserPassWord\", city);\n        TLog.log(hashMap.toString());\n        Observable<User> ss = apiManager.userLogin(hashMap);\n        return  ss;\n    }\n\n    /**********************仿照上面的方法,进行请求数据****************************/\n\n```\n - **用retrofit访问 返回observable的对象**\n\n```java\npublic interface RetrofitRequest {\n\n\n    boolean isTest=true; //是否在测试环境下\n    //发布之前更改\n    String BASE_URL_TEST = \"/flyapptest/\";//测试服务器\n    String BASE_URL_OFFICAL = \"/flyapp/\";//正式服务器\n\n    String BASE_URL = isTest?BASE_URL_TEST:BASE_URL_OFFICAL;//发布服务器\n\n\n    /**\n     * 登录返回(json post)\n     * @param body\n     * @return\n     */\n    @Headers( \"Content-Type: application/json\" )\n    @POST(BASE_URL+\"Login.ashx/\")\n    Observable<User> userLogin(@Body HashMap<String, String> body);\n\n```\n\n***3.异步处理: 采用rxjava响应式框架进行优雅的异步处理,简化代码逻辑,并且很好的解决内存泄漏\t问题.(相关模块在TakePhoto业务中)***\n```java\n  /**\n     * rxjava 进行异步操作 eventBus进行时间传递\n     * @param data\n     */\n    @Override\n    public void savePhoto(final Intent data) {\n        TLog.log(\"savePhoto\", \"data-->\" + data.getData().toString());\n        Log.e(\"Tlog-->\", \"data-->\" + data.getData().toString());\n        saveObservable = Observable.fromCallable(new Callable<String>() {\n            @Override\n            public String call() throws Exception {//通知调用  并返回string\n                return savePic(data);//此方法在io线程中调用 并返回\n            }\n        });\n\n        saveSubscription = saveObservable\n                .subscribeOn(Schedulers.io())//observable在调度中的IO线程中进行调度进行\n                .observeOn(AndroidSchedulers.mainThread())//在主线程中进行观察\n                .subscribe(new Observer<String>() {//订阅观察者\n                    @Override\n                    public void onCompleted() {\n                        Log.e(\"Tlog-->\", \"onCompleted-->\");\n                    }\n                    @Override\n                    public void onError(Throwable e) {\n                        Log.e(\"Tlog-->\", \"Throwable-->\" + e.getMessage().toString());\n                        EventBus.getDefault().post(new EventUtils.ObjectEvent(e.getMessage().toString()));\n                    }\n                    @Override\n                    public void onNext(String s) {//带参数的下一步,在此就是当\n                        Log.e(\"Tlog-->\", \"s-->\" + s);\n                        EventBus.getDefault().post(new EventUtils.ObjectEvent(bitmap));\n\n                    }\n                });\n    }\n```\n\n\n***4.事件订阅: 采用EventBus作为事件总线,进行线程间,组件之间的通信.***\n\n```java\n/**\n * 事件总线 用于组件或线程通信,可替代回调,广播等\n * Created by ccj on 2016/4/14.\n */\npublic class EventUtils {\n\n    /**\n     * object类型(即传统的所有类型,都可以强转进行传递事件)\n     */\n    public static class ObjectEvent{\n        private Object object;\n        public ObjectEvent(Object object) {\n            // TODO Auto-generated constructor stub\n            this.object = object;\n        }\n        public Object getMsg(){\n            return object;\n        }\n    }\n\n}\n```\n\n***5.代码分包: 根据业务区分进行分包,便于对代码进行管理 .***\n\n![这里写图片描述](http://img.blog.csdn.net/20160712153822145)\n\n\n***6. 工具类: TDeviceUtils设备状态的工具类,,SeriliazebleUtils 序列化工具类,SharepreferenceUtils保存工具类,***\n相关请参考代码\n\n***7.app栈管理: 基于baseActivity,很好的释放内存,管理内存.***\n相关请参考代码\n\n---\n#### 待后期完成\n\n***异常捕获(待完善)***\n***测试框架Espresso/JUnit/Mockito/Robolectric (待完善)***\n\n---\n\n\n##总结\n\n1.层次分明，各层级之间都不管对方如何实现，只关注结果；\n2.在视图层(Presentation Layer)使用MVP架构，使原本臃肿的Activity(或Fragment)变得简单，其处理方法都交给了Presenter。\n3.易于做测试，只要基于每个模块单独做好单元测试就能确保整体的稳定性。\n4.易于快速迭代，基于代码的低耦合，只需在业务逻辑上增加接口，然后在相应的层级分别实现即可，丝毫不影响其他功能。\n\n##Blog-link\n[csdn博客,欢迎大家指正,评阅~谢谢O(∩_∩)O谢谢](http://blog.csdn.net/ccj659/article/details/51889713)\n"
  },
  {
    "path": "app/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "app/build.gradle",
    "content": "apply plugin: 'com.android.application'\nrepositories {\n    jcenter()\n}\nandroid {\n\n    compileSdkVersion rootProject.ext.compileSdkVersion\n    buildToolsVersion rootProject.ext.buildToolsVersion\n    defaultConfig {\n        applicationId \"com.efly.flyhelper\"\n        minSdkVersion rootProject.ext.minSdkVersion\n        targetSdkVersion rootProject.ext.targetSdkVersion\n        versionCode rootProject.ext.versionCode\n        versionName rootProject.ext.versionName\n        multiDexEnabled false\n\n        //arouter\n        javaCompileOptions {\n            annotationProcessorOptions {\n                arguments = [moduleName: project.getName()]\n            }\n        }\n    }\n    buildTypes {\n        release {\n            //更改AndroidManifest.xml中预先定义好占位符信息\n            //manifestPlaceholders = [app_icon: \"@drawable/icon\"]\n            // 不显示Log\n            buildConfigField \"boolean\", \"LEO_DEBUG\", \"false\"\n            //是否zip对齐\n            zipAlignEnabled true\n            // 缩减resource文件\n            shrinkResources true\n            //Proguard\n            minifyEnabled true\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n\n        debug {\n            //给applicationId添加后缀“.debug”\n            applicationIdSuffix \".debug\"\n            //manifestPlaceholders = [app_icon: \"@drawable/launch_beta\"]\n            buildConfigField \"boolean\", \"LOG_DEBUG\", \"true\"\n            zipAlignEnabled false\n            shrinkResources false\n            minifyEnabled false\n            debuggable true\n        }\n    }\n\n}\n\n\ndependencies {\n    compile fileTree(include: ['*.jar'], dir: 'libs')\n\n\n    //arouter\n    compile rootProject.ext.arouterApi\n    annotationProcessor rootProject.ext.arouterCompiler\n\n    //butterknife\n    annotationProcessor rootProject.ext.butterknifeCompiler\n\n    if (isModule.toBoolean()) {\n        //当isDebug true，app得依赖基础库，保证app不报错\n        compile project(':base')\n    } else {\n        compile project(':module_home')\n        compile project(':module_user')\n        compile project(':module_video')\n        compile project(':module_meizi')\n\n    }\n\n}\n"
  },
  {
    "path": "app/proguard-rules.pro",
    "content": "\n\n\n-ignorewarnings                     # 忽略警告，避免打包时某些警告出现\n-dontwarn\n-dontskipnonpubliclibraryclasses\n-dontskipnonpubliclibraryclassmembers\n-dontpreverify\n-verbose                            # 混淆时是否记录日志\n#-printmapping topden.map\n-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n   public *;\n}\n\n\n-keep class * extends java.lang.annotation.Annotation { *; }\n-keep class * extends android.app.Application { *; }\n-keep public class * implements java.io.Serializable {*;}\n-keep public class * implements android.os.Parcelable {*;}\n\n\n\n-keepattributes Exceptions,InnerClasses,Signature\n-keepattributes SourceFile,LineNumberTable,EnclosingMethod\n\n\n# keep 泛型\n-keepattributes *Annotation*\n\n-keepclassmembers class * {\n    public <init>(org.json.JSONObject);\n}\n\n-keepclassmembers class **.R$* {\n    public static <fields>;\n}\n\n-keep public class * extends android.app.Fragment\n-keep public class * extends android.app.Activity\n-keep public class * extends android.app.Application\n-keep public class * extends android.app.Service\n-keep public class * extends android.content.BroadcastReceiver\n-keep public class * extends android.content.ContentProvider\n-keep public class * extends android.app.backup.BackupAgentHelper\n-keep public class * extends android.preference.Preference\n-keepattributes *Annotation*\n-keep class android.support.v4.** { *; }\n-keep interface android.support.v4.app.** { *; }\n-keep public class * extends android.support.v4.**\n-keep public class * extends android.support.v13.**\n-keep class android.support.v13.** { *; }\n-keep class android.support.v7.** { *; }\n\n\n\n-dontwarn javax.annotation.**\n-keep class javax.annotation.** { *;}\n\n\n#########-------------------第三方 ----------------------------------#############\n#recoo\n-keep class com.dodola.** {*;}\n-keep class com.lody.legend.** {*;}\n\n#-dontwarn com.dodola.rocoo.** { *; }\n#-keep class com.dodola.rocoo.** { *; }\n\n# ButterKnife\n-keep class butterknife.** { *; }\n-dontwarn butterknife.internal.**\n-keep class **$$ViewBinder { *; }\n-keepclasseswithmembernames class * {\n    @butterknife.* <fields>;\n}\n-keepclasseswithmembernames class * {\n    @butterknife.* <methods>;\n}\n\n# EventBus\n-keepattributes *Annotation*\n-keepclassmembers class ** {\n    @org.greenrobot.eventbus.Subscribe <methods>;\n}\n-keep enum org.greenrobot.eventbus.ThreadMode { *; }\n\n\n\n# RxJava RxAndroid\n-dontwarn sun.misc.**\n-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {\n    long producerIndex;\n    long consumerIndex;\n}\n-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {\n    rx.internal.util.atomic.LinkedQueueNode producerNode;\n}\n-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef {\n    rx.internal.util.atomic.LinkedQueueNode consumerNode;\n}\n\n\n\n\n\n# Retrofit\n-dontwarn retrofit2.**\n-keep class retrofit2.** { *; }\n-keepattributes Signature\n-keepattributes Exceptions\n\n\n\n# OkHttp3\n-dontwarn com.squareup.okhttp3.**\n-keep class com.squareup.okhttp3.** { *;}\n-dontwarn okio.**\n\n\n\n# Gson\n#-keepattributes Signature-keepattributes *Annotation*\n-keep class sun.misc.Unsafe { *; }\n-keep class com.google.gson.stream.** { *; }\n# 使用Gson时需要配置Gson的解析对象及变量都不混淆。不然Gson会找不到变量。\n# 将下面替换成自己的实体类\n-keep class com.efly.flyhelper.bean.** { *; }\n\n\n\n# EventBus\n-keepattributes *Annotation*\n-keepclassmembers class ** {\n    @org.greenrobot.eventbus.Subscribe <methods>;\n}\n-keep enum org.greenrobot.eventbus.ThreadMode { *; }\n\n"
  },
  {
    "path": "app/src/androidTest/java/com/efly/flyhelper/ApplicationTest.java",
    "content": "package com.efly.flyhelper;\n\nimport android.app.Application;\nimport android.test.ApplicationTestCase;\n\n/**\n * <a href=\"http://d.android.com/tools/testing/testing_android.html\">Testing Fundamentals</a>\n */\npublic class ApplicationTest extends ApplicationTestCase<Application> {\n    public ApplicationTest() {\n        super(Application.class);\n    }\n}"
  },
  {
    "path": "app/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.efly.flyhelper\">\n    <!-- 必选 -->\n    <uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\" />\n    <uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\" />\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.READ_PHONE_STATE\" />\n    <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>\n    <uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\"/>\n    <permission android:name=\"android.permission.INTERNET\" />\n\n\n    <application\n        android:name=\".AppApplication\"\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:supportsRtl=\"true\"\n\n        android:theme=\"@style/AppTheme\">\n        <activity android:name=\".MainActivity\"\n            android:theme=\"@style/AppTheme.NoActionBar\"\n            >\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n\n    </application>\n\n</manifest>"
  },
  {
    "path": "app/src/main/java/com/efly/flyhelper/AppApplication.java",
    "content": "package com.efly.flyhelper;\n\nimport com.ccj.base.base.BaseApplication;\n\n/**\n * ARouter 这里必须在 这里初始化, 在 base里面初始化 无效,奇怪\n * Created by chenchangjun on 17/8/10.\n */\n\npublic class AppApplication extends BaseApplication {\n\n\n\n\n    @Override\n    public void onCreate() {\n        super.onCreate();\n\n    }\n\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/efly/flyhelper/MainActivity.java",
    "content": "package com.efly.flyhelper;\n\nimport android.os.Bundle;\nimport android.support.annotation.NonNull;\nimport android.support.annotation.Nullable;\nimport android.support.design.widget.BottomNavigationView;\nimport android.support.v4.app.Fragment;\nimport android.support.v4.view.ViewPager;\nimport android.view.MenuItem;\n\nimport com.alibaba.android.arouter.launcher.ARouter;\nimport com.ccj.base.base.BaseActivity;\nimport com.ccj.base.RouterConstants;\nimport com.efly.flyhelper.adapter.FragmentAdapter;\n\nimport java.util.LinkedList;\nimport java.util.List;\n\n\npublic class MainActivity extends BaseActivity {\n\n    private ViewPager mPager;\n    private List<Fragment> mFragments = new LinkedList<>();\n    private FragmentAdapter mAdapter;\n    private BottomNavigationView navigation;\n\n    private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener\n            = new BottomNavigationView.OnNavigationItemSelectedListener() {\n\n        @Override\n        public boolean onNavigationItemSelected(@NonNull MenuItem item) {\n            int i = item.getItemId();\n            if (i == R.id.navigation_home) {\n                mPager.setCurrentItem(0);\n                return true;\n            } else if (i == R.id.navigation_dashboard) {\n                mPager.setCurrentItem(1);\n                return true;\n            } else if (i == R.id.navigation_notifications) {\n                mPager.setCurrentItem(2);\n                return true;\n            }\n            return false;\n        }\n\n    };\n\n    @Override\n    public void onCreate(@Nullable Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_bottom_navigation);\n        mPager = (ViewPager) findViewById(R.id.container_pager);\n\n        navigation = (BottomNavigationView) findViewById(R.id.navigation);\n        initViewPager();\n        navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);\n    }\n\n    private void initViewPager() {\n\n\n        Fragment home = (Fragment) ARouter.getInstance().build(RouterConstants.HOME_MUDULE_FRAGMENT_HOME_HOME).navigation();\n        Fragment meizi = (Fragment) ARouter.getInstance().build(RouterConstants.MEIZI_MUDULE_FRAGMENT_HOME_MEIZI).navigation();\n        Fragment user = (Fragment) ARouter.getInstance().build(RouterConstants.USER_MUDULE_FRAGMENT_HOME_USER).navigation();\n        mFragments.add(home);\n        mFragments.add(meizi);\n        mFragments.add(user);\n\n        mAdapter = new FragmentAdapter(getSupportFragmentManager(), mFragments);\n        mPager.setAdapter(mAdapter);\n    }\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/efly/flyhelper/adapter/FragmentAdapter.java",
    "content": "package com.efly.flyhelper.adapter;\n\nimport android.support.v4.app.Fragment;\nimport android.support.v4.app.FragmentManager;\nimport android.support.v4.app.FragmentStatePagerAdapter;\n\nimport java.util.List;\n\npublic class FragmentAdapter extends FragmentStatePagerAdapter {\n    private List<Fragment> mFragments;\n\n    public FragmentAdapter(FragmentManager fm, List<Fragment> mFragments) {\n        super(fm);\n        this.mFragments = mFragments;\n    }\n\n    @Override\n    public Fragment getItem(int position) {\n        return mFragments.get(position);\n    }\n\n    @Override\n    public int getCount() {\n        return mFragments != null ? mFragments.size() : 0;\n    }\n\n    @Override\n    public int getItemPosition(Object object) {\n        return android.support.v4.view.PagerAdapter.POSITION_NONE;\n    }\n}\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_dashboard_black_24dp.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportHeight=\"24.0\"\n    android:viewportWidth=\"24.0\">\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M3,13h8L11,3L3,3v10zM3,21h8v-6L3,15v6zM13,21h8L21,11h-8v10zM13,3v6h8L21,3h-8z\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_home_black_24dp.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportHeight=\"24.0\"\n    android:viewportWidth=\"24.0\">\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_notifications_black_24dp.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportHeight=\"24.0\"\n    android:viewportWidth=\"24.0\">\n    <path\n        android:fillColor=\"#FF000000\"\n        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\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/layout/activity_bottom_navigation.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:orientation=\"vertical\"\n    android:background=\"@color/white\"\n    >\n\n    <android.support.v4.view.ViewPager\n        android:id=\"@+id/container_pager\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"0dp\"\n        android:layout_weight=\"1\" />\n\n    <android.support.design.widget.BottomNavigationView\n        android:id=\"@+id/navigation\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"bottom\"\n        android:background=\"?android:attr/windowBackground\"\n        app:menu=\"@menu/menu_bottom_navigation\" />\n\n</LinearLayout>\n"
  },
  {
    "path": "app/src/main/res/menu/menu_bottom_navigation.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <item\n        android:id=\"@+id/navigation_home\"\n        android:icon=\"@drawable/ic_home_black_24dp\"\n        android:title=\"@string/title_home\" />\n\n    <item\n        android:id=\"@+id/navigation_dashboard\"\n        android:icon=\"@drawable/ic_dashboard_black_24dp\"\n        android:title=\"@string/title_dashboard\" />\n\n    <item\n        android:id=\"@+id/navigation_notifications\"\n        android:icon=\"@drawable/ic_notifications_black_24dp\"\n        android:title=\"@string/title_notifications\" />\n\n</menu>\n"
  },
  {
    "path": "app/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">MVP和组件化</string>\n    <string name=\"title_notifications\">我的</string>\n    <string name=\"title_dashboard\">妹子</string>\n    <string name=\"title_home\">首页</string>\n\n\n</resources>\n"
  },
  {
    "path": "app/src/test/java/com/efly/flyhelper/ExampleUnitTest.java",
    "content": "package com.efly.flyhelper;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * To work on unit tests, switch the Test Artifact in the Build Variants view.\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() throws Exception {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "base/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "base/build.gradle",
    "content": "apply plugin: 'com.android.library'\n\nandroid {\n    compileSdkVersion rootProject.ext.compileSdkVersion\n    buildToolsVersion rootProject.ext.buildToolsVersion\n\n    defaultConfig {\n        minSdkVersion rootProject.ext.minSdkVersion\n        targetSdkVersion rootProject.ext.targetSdkVersion\n        versionCode rootProject.ext.versionCode\n        versionName rootProject.ext.versionName\n\n    }\n\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n}\n\nrepositories {\n    flatDir {\n        dirs 'aars'\n    }\n}\n\next{\n    libSupportVersion = '25.3.1'\n}\n\ndependencies {\n    compile fileTree(dir: 'libs', include: ['*.jar'])\n    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {\n        exclude group: 'com.android.support', module: 'support-annotations'\n    })\n\n    compile rootProject.ext.appcompatV7\n    compile rootProject.ext.constraintLayout\n\n\n\n    //butterknife\n    compile rootProject.ext.butterknife\n\n    compile rootProject.ext.arouterApi\n\n    compile rootProject.ext.eventbus\n\n\n\n\n\n    /*view相关*/\n    compile \"com.android.support:design:${libSupportVersion}\"\n    compile \"com.android.support:recyclerview-v7:${libSupportVersion}\"\n    compile \"com.android.support:cardview-v7:${libSupportVersion}\"\n    compile \"com.android.support:support-v4:${libSupportVersion}\"\n\n    /*请求网络框架*/\n    //retrofit\n    compile 'com.squareup.retrofit2:retrofit:2.0.2'\n    compile 'com.squareup.okhttp3:logging-interceptor:3.1.2'\n    compile 'com.squareup.retrofit2:converter-gson:2.0.2'\n    compile 'com.squareup.retrofit2:adapter-rxjava:2.0.2'\n\n    //rxjava\n    compile 'io.reactivex:rxandroid:1.1.0'\n    compile 'io.reactivex:rxjava:1.1.0'\n\n    compile 'com.google.code.gson:gson:2.4'\n\n\n    compile 'com.mcxiaoke.volley:library:1.0.19'\n\n    //图片请求\n    compile 'com.squareup.picasso:picasso:2.5.2'\n\n\n}\n"
  },
  {
    "path": "base/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/chenchangjun/Library/Android/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n-keep public class com.alibaba.android.arouter.routes.**{*;}\n-keep class * implements com.alibaba.android.arouter.facade.template.ISyringe{*;}\n\n# 如果使用了 byType 的方式获取 Service，需添加下面规则，保护接口\n-keep interface * implements com.alibaba.android.arouter.facade.template.IProvider\n\n# 如果使用了 单类注入，即不定义接口实现 IProvider，需添加下面规则，保护实现\n-keep class * implements com.alibaba.android.arouter.facade.template.IProvider"
  },
  {
    "path": "base/src/androidTest/java/com/ccj/base/ExampleInstrumentedTest.java",
    "content": "package com.ccj.base;\n\nimport android.content.Context;\nimport android.support.test.InstrumentationRegistry;\nimport android.support.test.runner.AndroidJUnit4;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.junit.Assert.*;\n\n/**\n * Instrumentation test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() throws Exception {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getTargetContext();\n\n        assertEquals(\"com.ccj.base.test\", appContext.getPackageName());\n    }\n}\n"
  },
  {
    "path": "base/src/main/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n\n    package=\"com.ccj.base\">\n    <!-- 必选 -->\n    <uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\" />\n    <uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\" />\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.READ_PHONE_STATE\" />\n    <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>\n    <uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\"/>\n    <permission android:name=\"android.permission.INTERNET\" />\n\n    <application android:allowBackup=\"true\" android:label=\"@string/app_name\"\n        android:supportsRtl=\"true\">\n\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/AppManager.java",
    "content": "package com.ccj.base;\n\nimport android.app.Activity;\nimport android.app.ActivityManager;\nimport android.content.Context;\n\nimport java.util.Stack;\n\n/**\n * activity堆栈式管理\n *\n */\npublic class AppManager {\n\n    private static Stack<Activity> activityStack;\n    private static AppManager instance;\n\n    private AppManager() {\n    }\n\n\n\n    /**\n     * 单一实例\n     */\n    public static AppManager getAppManager() {\n        if (instance == null) {\n            instance = new AppManager();\n        }\n\n        if (activityStack == null) {\n            activityStack = new Stack<Activity>();\n        }\n\n        return instance;\n    }\n\n    /**\n     * 获取指定的Activity\n     *\n     * @author kymjs\n     */\n    public static Activity getActivity(Class<?> cls) {\n        if (activityStack != null)\n            for (Activity activity : activityStack) {\n                if (activity.getClass().equals(cls)) {\n                    return activity;\n                }\n            }\n        return null;\n    }\n\n    /**\n     * 添加Activity到堆栈\n     */\n    public void addActivity(Activity activity) {\n        activityStack.add(activity);\n    }\n\n    /**\n     * 获取当前Activity（堆栈中最后一个压入的）\n     */\n    public Activity currentActivity() {\n        Activity activity = activityStack.lastElement();\n        return activity;\n    }\n\n    /**\n     * 结束当前Activity（堆栈中最后一个压入的）\n     */\n    public void finishActivity() {\n        Activity activity = activityStack.lastElement();\n        finishActivity(activity);\n    }\n\n    /**\n     * 结束指定的Activity\n     */\n    public void finishActivity(Activity activity) {\n        if (activity != null && activityStack.contains(activity)) {\n            activityStack.remove(activity);\n            activity.finish();\n        }\n    }\n\n    /**\n     * 结束指定的Activity\n     */\n    public void removeActivity(Activity activity) {\n        if (activity != null && activityStack.contains(activity)) {\n            activityStack.remove(activity);\n        }\n    }\n\n    /**\n     * 结束指定类名的Activity\n     */\n    public void finishActivity(Class<?> cls) {\n        for (Activity activity : activityStack) {\n            if (activity.getClass().equals(cls)) {\n                finishActivity(activity);\n                break;\n            }\n        }\n    }\n\n    /**\n     * 结束所有Activity\n     */\n    public void finishAllActivity() {\n        for (int i = 0, size = activityStack.size(); i < size; i++) {\n            if (null != activityStack.get(i)) {\n                finishActivity(activityStack.get(i));\n            }\n        }\n        activityStack.clear();\n    }\n\n    /**\n     * 退出应用程序\n     */\n    public void AppExit(Context context) {\n\n        try {\n            finishAllActivity();\n            // System.exit(0);\n        } catch (Exception e) {\n        }\n\n        // 获取packagemanager的实例\n        try {\n            ActivityManager activityMgr = (ActivityManager) context\n                    .getSystemService(Context.ACTIVITY_SERVICE);\n            activityMgr.killBackgroundProcesses(context.getPackageName());\n            activityStack = null;\n            instance=null;\n            System.exit(0);\n        } catch (Exception e) {\n            System.exit(0);\n        }\n\n    }\n}\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/Constants.java",
    "content": "package com.ccj.base;\n\n/**\n * Created by chenchangjun on 17/8/10.\n */\n\npublic class Constants {\n\n    public static final String START_LOGIN_WITH_PARAMS = \"START_LOGIN_WITH_PARAMS\";\n    public static final int REQUEST_START_LOGIN = 0x00110;\n    public static final int RESULT_FROM_LOGIN = 0x00011;\n\n\n    public static final String PARAMS_RESULT_FROM_LOGIN = \"PARAMS_RESULT_FROM_LOGIN\";\n    public static final String PARAMS_REQUEST_FOR_DETAIL = \"PARAMS_REQUEST_FOR_DETAIL\";\n\n}\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/RouterConstants.java",
    "content": "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     * home module\n     */\n    public static final String HOME_MODULE_NAME=\"/homemodule/\";\n    public static final String HOME_MUDULE_FRAGMENT_HOME_HOME = HOME_MODULE_NAME+\"FRAGMENT_HOME_HOME\";\n\n\n    /**\n     * user module\n     */\n    public static final String USER_MODULE_NAME =\"/loginmodule/\";\n\n    public static final String USER_MUDULE_FRAGMENT_HOME_USER = USER_MODULE_NAME+\"FRAGMENT_HOME_USER\";\n\n\n    public static final String USER_MOUDLE_ACTIVITY = USER_MODULE_NAME +\"LoginActivity\";\n    public static final String USER_SERVICE_IMPL = USER_MODULE_NAME +\"LoginServiceImpl\";\n    public static final String USER_REGISTER_FRAGMENT = USER_MODULE_NAME +\"/RegisterFragment\";\n\n    /**\n     * video module\n     */\n    public static final String VIDEO_MODULE_NAME=\"/videomodule/\";\n    public static final String VIDEO_MUDULE_FRAGMENT_HOME_VIDEO = VIDEO_MODULE_NAME+\"FRAGMENT_HOME_VIDEO\";\n\n    public static final String VIDEO_MUDULE_ACTIVITY = VIDEO_MODULE_NAME+\"TakePhotoActivity\";\n    public static final String VIDEO_SERVICE_IMPL = VIDEO_MODULE_NAME+\"VideoServiceImpl\";\n\n\n\n\n    /**\n     * meizi module\n     */\n    public static final String MEIZI_MODULE_NAME=\"/meizimodule/\";\n    public static final String MEIZI_MUDULE_FRAGMENT_HOME_MEIZI = MEIZI_MODULE_NAME+\"FRAGMENT_HOME_MEIZI\";\n    public static final String MEIZI_MUDULE_ACTIVITY_MEIZI_DETAIL = MEIZI_MODULE_NAME+\"ACTIVITY_MEIZI_DETAIL\";\n\n\n}\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/adapter/CommonRcvAdapter.java",
    "content": "package com.ccj.base.adapter;\n\nimport android.app.Activity;\nimport android.content.Context;\nimport android.support.annotation.NonNull;\nimport android.support.annotation.Nullable;\nimport android.support.v7.widget.RecyclerView;\nimport android.view.LayoutInflater;\nimport android.view.ViewGroup;\n\nimport com.ccj.base.adapter.item.AdapterItem;\nimport com.ccj.base.adapter.util.IAdapter;\nimport com.ccj.base.adapter.util.ItemTypeUtil;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n\n/**\n * @author ccj\n * @date 2017/3/23\n */\npublic abstract class CommonRcvAdapter<T> extends RecyclerView.Adapter<CommonRcvAdapter.RcvAdapterItem> implements IAdapter<T> {\n\n    private List<T> mDataList;\n\n    private Object mType;\n\n    private ItemTypeUtil mUtil;\n\n    private int currentPos;\n\n    public Activity mActivity;\n\n\n    public CommonRcvAdapter(@Nullable List<T> data, Activity mActivity) {\n        if (data == null) {\n            data = new ArrayList<>();\n        }\n        mDataList = data;\n        mUtil = new ItemTypeUtil();\n        this.mActivity = mActivity;\n    }\n\n\n    public T getItem(int position) {\n        if (position < 0 || position > getItemCount() - 1) {\n            return null;\n        }\n        return mDataList.get(position);\n    }\n\n\n    @Override\n    public int getItemCount() {\n        return mDataList == null ? 0 : mDataList.size();\n    }\n\n    @Override\n    public void setData(@NonNull List<T> data) {\n        mDataList = data;\n    }\n\n    @Override\n    public List<T> getData() {\n        return mDataList;\n    }\n\n    @Override\n    public long getItemId(int position) {\n        return position;\n    }\n\n    /**\n     * instead by{@link #getItemType(Object)}\n     * <p>\n     * 通过数据得到obj的类型的type\n     * 然后，通过{@link ItemTypeUtil}来转换位int类型的type\n     */\n    @Deprecated\n    @Override\n    public int getItemViewType(int position) {\n        this.currentPos = position;\n        mType = getItemType(mDataList.get(position));\n        return mUtil.getIntType(mType);\n    }\n\n    @Override\n    public Object getItemType(T t) {\n        return -1; // default\n    }\n\n    @Override\n    public RcvAdapterItem onCreateViewHolder(ViewGroup parent, int viewType) {\n        return new RcvAdapterItem(parent.getContext(), parent, createItem(mType));\n    }\n\n    @Override\n    public void onBindViewHolder(RcvAdapterItem holder, int position) {\n\n        holder.item.handleData(getConvertedData(mDataList.get(position), mType), position);\n\n\n    }\n\n    @NonNull\n    @Override\n    public Object getConvertedData(T data, Object type) {\n        return data;\n    }\n\n    @Override\n    public int getCurrentPosition() {\n        return currentPos;\n    }\n\n    ///////////////////////////////////////////////////////////////////////////\n    // 内部用到的viewHold\n    ///////////////////////////////////////////////////////////////////////////\n\n    public static class RcvAdapterItem extends RecyclerView.ViewHolder {\n\n        protected AdapterItem item;\n\n        boolean isNew = true; // debug中才用到\n\n        RcvAdapterItem(Context context, ViewGroup parent, AdapterItem item) {\n            super(LayoutInflater.from(context).inflate(item.getLayoutResId(), parent, false));\n            this.item = item;\n            this.item.bindViews(itemView);\n            this.item.setViews();\n        }\n\n    }\n\n    ///////////////////////////////////////////////////////////////////////////\n    // For debug\n    ///////////////////////////////////////////////////////////////////////////\n\n    private void debug(RcvAdapterItem holder) {\n        boolean debug = false;\n        if (debug) {\n            holder.itemView.setBackgroundColor(holder.isNew ? 0xffff0000 : 0xff00ff00);\n            holder.isNew = false;\n        }\n    }\n\n}\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/adapter/bean/AdapterBean.java",
    "content": "package com.ccj.base.adapter.bean;\n\nimport java.io.Serializable;\n\n/**\n * 数据bean\n * 为了不同viewItem 分别对应不同的bean,</br>\n * 避免不同item的字段都杂糅的同一个类中的情况,比如{ mobile中的 CommonRowsBean}</br>\n * 根据Holder建立一个新的bean, 自定义的bean要继承AdapterBean,在bean中添置所需字段,供holder调用,比如(mobile中 BrandRcvAdapter中的holder)</br>\n * <p>\n * Created by chenchangjun on 17/12/28.\n */\n\npublic abstract class AdapterBean implements Serializable {\n\n    //唯一标示!\n\n\n    public abstract void setCell_type(int cell_type);\n\n\n    public abstract int getCell_type();\n\n}\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/adapter/bean/AdapterGroupBean.java",
    "content": "package com.ccj.base.adapter.bean;\n\nimport java.io.Serializable;\nimport java.util.List;\n\n/**\n * 类似于 view和 viewgroup 的概念 这里是 viewgroup\n * Created by chenchangjun on 18/1/4.\n */\n\npublic abstract class AdapterGroupBean<T> extends AdapterBean implements Serializable {\n\n\n    //唯一标示!\n\n    public abstract List getList();\n\n    public abstract String getTitle();\n\n    public abstract T getRedirect_data();\n\n\n}\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/adapter/item/AdapterItem.java",
    "content": "package com.ccj.base.adapter.item;\n\nimport android.support.annotation.LayoutRes;\nimport android.view.View;\n\n/**\n * @author ccj\n * @date 2017/3/21\n */\npublic interface AdapterItem<T> {\n\n\n    /**\n     * @return item布局文件的layoutId\n     */\n    @LayoutRes\n    int getLayoutResId();\n\n    /**\n     * 初始化views\n     */\n    void bindViews(final View root);\n\n    /**\n     * 设置view的参数\n     * 设置监听等,只执行一次\n     */\n    void setViews();\n\n    /**\n     * 根据数据来设置item的内部views\n     *\n     * @param t    数据list内部的model\n     * @param position 当前adapter调用item的位置\n     */\n    void handleData(T t, int position);\n\n}  "
  },
  {
    "path": "base/src/main/java/com/ccj/base/adapter/util/IAdapter.java",
    "content": "package com.ccj.base.adapter.util;\n\nimport android.support.annotation.Keep;\nimport android.support.annotation.NonNull;\n\nimport com.ccj.base.adapter.item.AdapterItem;\n\nimport java.util.List;\n\n\n/**\n * @author ccj\n * @date 2017/3/22\n * 通用的adapter必须实现的接口，作为方法名统一的一个规范\n */\npublic interface IAdapter<T> {\n\n    /**\n     * @param data 设置数据源\n     */\n    void setData(@NonNull List<T> data);\n\n    List<T> getData();\n\n    /**\n     * @param t list中的一条数据\n     * @return 强烈建议返回string, int, bool类似的基础对象做type，不要返回data中的某个对象\n     */\n    Object getItemType(T t);\n\n    /**\n     * 当缓存中无法得到所需item时才会调用\n     *\n     * @param type 通过{@link #getItemType(Object)}得到的type\n     * @return 任意类型的 AdapterItem\n     */\n    @Keep\n    @NonNull\n    AdapterItem createItem(Object type);\n\n    /**\n     * 如果放入item的最终数据和list中的每一条数据类型是不同的，可以通过此方法进行转换\n     *\n     * @param data 从原始的list中取得得数据\n     * @param type item的类型\n     * @return 放入adapterItem的最终数据\n     */\n    @Keep\n    @NonNull\n    Object getConvertedData(T data, Object type);\n\n    /**\n     * 通知adapter更新当前页面的所有数据\n     */\n    void notifyDataSetChanged();\n\n    /**\n     * 得到当前要渲染的最后一个item的position\n     */\n    int getCurrentPosition();\n}\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/adapter/util/ItemTypeUtil.java",
    "content": "package com.ccj.base.adapter.util;\n\nimport android.support.annotation.VisibleForTesting;\n\nimport java.util.HashMap;\n\n/**\n * @author ccj\n * @date 2017/3/22\n */\n@VisibleForTesting\n/*package*/ public class ItemTypeUtil {\n\n    private HashMap<Object, Integer> typePool;\n\n    public void setTypePool(HashMap<Object, Integer> typePool) {\n        this.typePool = typePool;\n    }\n\n    /**\n     * @param type item的类型\n     * @return 通过object类型的type来得到int类型的type\n     */\n    public int getIntType(Object type) {\n        if (typePool == null) {\n            typePool = new HashMap<>();\n        }\n        \n        if (!typePool.containsKey(type)) {\n            typePool.put(type, typePool.size());\n        }\n        return typePool.get(type);\n    }\n}\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/api/APIService.java",
    "content": "package com.ccj.base.api;\n\n\nimport retrofit2.Retrofit;\nimport retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;\nimport retrofit2.converter.gson.GsonConverterFactory;\n\n/**\n * 调用后台的接口,架构网络层采用Retroft+Rxjava+gson\n * Created by ccj on 2016/7/1.\n *\n */\npublic class APIService {\n\n    private static final String TAG = \"APIService\";\n\n    //get请求\n    public static final String URL_GANK_IO = \"http://gank.io\";//gank.io 中的妹子API\n\n\n    /**\n     * 基础地址\n     * 初始化 retroft\n     */\n    protected static final Retrofit sRetrofit = new Retrofit.Builder()\n            .baseUrl( URL_GANK_IO )\n            .addConverterFactory(GsonConverterFactory.create())\n            .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) // 使用RxJava作为回调适配器\n            .build();\n\n   // protected static final RetrofitRequest apiManager = sRetrofit.create(RetrofitRequest.class);\n\n\n\n    /**********************仿照上面的方法,进行请求数据****************************/\n\n\n\n\n}\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/api/RetrofitRequest.java",
    "content": "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 isTest=false; //是否在测试环境下\n    //发布之前更改\n    String BASE_URL_TEST = \"/flyapptest/\";//测试服务器\n    String BASE_URL_OFFICAL = \"/flyapp/\";//正式服务器\n\n    String BASE_URL = isTest?BASE_URL_TEST:BASE_URL_OFFICAL;//发布服务器\n\n}\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/api/VolleyUtils.java",
    "content": "package com.ccj.base.api;\n\nimport android.content.Context;\nimport android.text.TextUtils;\n\nimport com.android.volley.Request;\nimport com.android.volley.RequestQueue;\nimport com.android.volley.toolbox.ImageLoader;\nimport com.android.volley.toolbox.Volley;\nimport com.ccj.base.base.BaseApplication;\nimport com.ccj.base.utils.LruBitmapCache;\n\n\n/**\n * volley留做备用\n * Created by ccj on 2016/12/4.\n */\npublic class VolleyUtils {\n\n    public static final String TAG = VolleyUtils.class.getSimpleName();\n    public static final Context context = BaseApplication.getInstance();\n    public static VolleyUtils volleyUtils;\n    private RequestQueue requestQueue;\n    private ImageLoader imageLoader;\n\n    //\tThe best way to maintain volley core objects and request queue is, making them global by creating a singleton class.\n    public static VolleyUtils getInstance() {\n        if (volleyUtils == null) {\n            volleyUtils = new VolleyUtils();\n        }\n        return volleyUtils;\n    }\n\n    //Default constructor\n    private VolleyUtils() {\n        getRequestQueue();\n        getImageLoader();\n    }\n\n    public RequestQueue getRequestQueue() {\n\n        if (requestQueue == null) {\n            requestQueue = Volley.newRequestQueue(context);\n        }\n        return requestQueue;\n    }\n\n    public ImageLoader getImageLoader() {\n        getRequestQueue();\n        if (imageLoader == null) {\n            imageLoader = new ImageLoader(requestQueue, new LruBitmapCache());\n        }\n        return imageLoader;\n    }\n\n    public <T> void addToRequestQueue(Request<T> req, String tag) {\n        //Set default tag if empty\n        req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);\n        getRequestQueue().add(req);\n    }\n\n    public <T> void addToRequestQueue(Request<T> req) {\n        req.setTag(TAG);\n        getRequestQueue().add(req);\n    }\n\n    public void cancelPendingRequests(Object tag) {\n        if (requestQueue != null) {\n            requestQueue.cancelAll(tag);\n        }\n    }\n\n\n\n}\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/base/BaseActivity.java",
    "content": "package com.ccj.base.base;\n\nimport android.app.ProgressDialog;\nimport android.content.Context;\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.support.v4.app.Fragment;\nimport android.support.v4.app.FragmentManager;\nimport android.support.v7.app.AppCompatActivity;\nimport android.support.v7.widget.Toolbar;\nimport android.util.Log;\nimport android.view.View;\n\nimport com.ccj.base.AppManager;\nimport com.ccj.base.R;\n\nimport java.util.List;\n\n\n/**\n * base 来进行 toolbar dialog 初始化,activity栈的添加,删除等\n * Created by ccj on 2016/7/5.\n */\npublic class BaseActivity<T extends BasePresenter>\n        extends AppCompatActivity implements BaseView {\n\n    private static final String TAG = \"BaseActivity\";\n    public T mPresenter;\n    protected ProgressDialog progressDialog;\n    protected Toolbar toolbar;\n    protected Context mContext;\n    private int fragmentIndex = 0;\n\n    @Override\n    public void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        AppManager.getAppManager().addActivity(this);\n        mContext = this;\n        initDialog();\n\n    }\n\n    public void initToolBar() {\n        toolbar = (Toolbar) findViewById(R.id.toolbar);\n        setSupportActionBar(toolbar);\n        toolbar.setBackgroundColor(getResources().getColor(R.color.tool_bar_white));\n        toolbar.setNavigationIcon(R.mipmap.back);\n        toolbar.setNavigationOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View v) {\n                finish();\n            }\n        });\n    }\n\n    public Toolbar getToolbar() {\n        return toolbar;\n    }\n\n    /**\n     * 资源释放\n     */\n    @Override\n    protected void onDestroy() {\n        super.onDestroy();\n        if (mPresenter != null)\n            mPresenter.onDestroy();\n        AppManager.getAppManager().finishActivity(this);\n    }\n\n    private void initDialog() {\n        progressDialog = new ProgressDialog(this);\n        progressDialog.setMessage(getResources().getString(R.string.show_loading_msg));\n    }\n\n    public void showLoading() {\n        progressDialog.show();\n    }\n\n    public void dismissLoading() {\n        progressDialog.dismiss();\n    }\n\n\n    @Override\n    public void initView() {\n\n    }\n\n\n    /**\n     * 解决fragment onActivityResult不调用\n     *\n     * @param requestCode\n     * @param resultCode\n     * @param data\n     */\n    @Override\n    protected void onActivityResult(int requestCode, int resultCode, Intent data) {\n        FragmentManager fm = getSupportFragmentManager();\n        //if (index != 0) {\n        if (fm.getFragments() == null) {\n            Log.w(TAG, \"Activity result fragment fragmentIndex out of range: 0x\"\n                    + Integer.toHexString(requestCode));\n            return;\n        }\n        for (int i = 0; i <fm.getFragments().size() ; i++) {\n            Fragment frag = fm.getFragments().get(i);\n            if (frag == null) {\n                Log.w(TAG, \"Activity result no fragment exists for fragmentIndex: 0x\"\n                        + Integer.toHexString(requestCode));\n            } else {\n                handleResult(frag, requestCode, resultCode, data);\n            }\n        }\n        return;\n        //}\n\n    }\n\n    /**\n     * 递归调用，对所有子Fragement生效\n     *\n     * @param frag\n     * @param requestCode\n     * @param resultCode\n     * @param data\n     */\n    private void handleResult(Fragment frag, int requestCode, int resultCode,\n                              Intent data) {\n        frag.onActivityResult(requestCode, resultCode, data);\n        List<Fragment> frags = frag.getChildFragmentManager().getFragments();\n        if (frags != null) {\n            for (Fragment f : frags) {\n                if (f != null)\n                    handleResult(f, requestCode, resultCode, data);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/base/BaseApplication.java",
    "content": "package com.ccj.base.base;\n\nimport android.app.Application;\nimport android.content.Context;\nimport android.content.res.Resources;\nimport android.view.Gravity;\nimport android.widget.Toast;\n\nimport com.alibaba.android.arouter.launcher.ARouter;\nimport com.ccj.base.utils.SharedPreferenceUtil;\n\n/**\n * 获取上下文,Toast,以及各种初始化\n * Created by Administrator on 2016/7/5.\n */\npublic class BaseApplication extends Application {\n\n    private static String lastToast = \"\";\n    private static long lastToastTime;\n    private static Context context;\n    private static Resources resource;\n    private static BaseApplication baseApplication;\n\n    public static synchronized BaseApplication getInstance() {\n        return baseApplication;\n    }\n\n    @Override\n    protected void attachBaseContext(Context base) {\n        super.attachBaseContext(base);\n\n    }\n\n    @Override\n    public void onCreate() {\n        super.onCreate();\n        initARouter();\n        context = getBaseContext();\n        baseApplication = this;\n        SharedPreferenceUtil.initSharedPreference(getApplicationContext());\n    }\n\n    /**\n     * ARouter 在每个模式下都需要,此时,\n     * 由于每个module的application只有在module模式下才启用,所以可以这样设置-->\n     * 可以将各module都继承BaseApplication\n     */\n    private void initARouter() {\n        //if (BuildConfig.DEBUG) {\n            // 这两行必须写在init之前，否则这些配置在init过程中将无效\n            ARouter.openLog();     // 打印日志\n            ARouter.openDebug();   // 开启调试模式(如果在InstantRun模式下运行，必须开启调试模式！线上版本需要关闭,否则有安全风险)\n            ARouter.printStackTrace(); // 打印日志的时候打印线程堆栈\n       // }\n        ARouter.init(this); // 尽可能早，推荐在Application中初始化\n    }\n\n\n    /**\n     * 防抖动 弹窗\n     *\n     * @param message\n     * @param duration\n     * @param icon\n     * @param gravity\n     */\n    public static void showToast(String message, int duration, int icon,\n                                 int gravity) {\n       Toast.makeText(getContext(),message,duration).show();\n    }\n\n\n\n\n    public static Context getContext() {\n        return context;\n    }\n\n    public static void setContext(Context context) {\n        BaseApplication.context = context;\n    }\n\n    public static Resources getResource() {\n        return resource;\n    }\n\n    public static void setResource(Resources resource) {\n        BaseApplication.resource = resource;\n    }\n\n\n    public static void showShortToast(String message) {\n        showToast(message, Toast.LENGTH_SHORT, 0, Gravity.BOTTOM);\n    }\n\n    public static void showLongToast(String message) {\n        showToast(message, Toast.LENGTH_LONG, 0, Gravity.BOTTOM);\n    }\n\n    public static void showToast(String message) {\n        showToast(message, Toast.LENGTH_LONG, 0, Gravity.BOTTOM);\n    }\n\n}\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/base/BaseBean.java",
    "content": "package com.ccj.base.base;\n\nimport java.io.Serializable;\n\n/**\n * Created by Administrator on 2016/7/6.\n */\npublic class BaseBean implements Serializable {\n\n\n\n}\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/base/BaseFragment.java",
    "content": "package com.ccj.base.base;\n\nimport android.app.Dialog;\nimport android.app.ProgressDialog;\nimport android.content.Context;\nimport android.os.Bundle;\nimport android.support.annotation.Nullable;\nimport android.support.v4.app.Fragment;\nimport android.util.DisplayMetrics;\nimport android.view.LayoutInflater;\n\n\n/**\n * Created by Administrator on 2016/7/5.\n */\npublic abstract class BaseFragment<T extends BasePresenter> extends Fragment implements BaseView {\n    private static final String TAG=\"BaseFragment\";\n    private LayoutInflater mInflater;\n    private Dialog dialog;\n    public T mPresenter;\n    protected float mDensity;\n    protected int mDensityDpi;\n    protected int mWidth;\n    protected int mAvatarSize;\n    private Context mContext;\n\n    @Override\n    public void onCreate(@Nullable Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        getScreen();\n    }\n\n\n    public void showLoading() {\n        if (dialog == null) {\n            dialog = new ProgressDialog(getActivity());\n        }\n        dialog.setTitle(\"正在加载...\");\n        dialog.show();\n    }\n\n    public void dismissLoading() {\n        if (dialog != null) {\n            dialog.dismiss();\n        }\n    }\n\n    private void getScreen() {\n        DisplayMetrics dm = new DisplayMetrics();\n        getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);\n        mDensity = dm.density;\n        mDensityDpi = dm.densityDpi;\n        mWidth = dm.widthPixels;\n        mAvatarSize = (int) (50 * mDensity);\n    }\n\n    /**\n     * 解绑的时候 清除\n     */\n    @Override\n    public void onDetach() {\n        if (mPresenter != null) {\n            mPresenter.onDestroy();\n        }\n\n        super.onDetach();\n    }\n}\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/base/BaseModel.java",
    "content": "package com.ccj.base.base;\n\n/**\n * Created by Administrator on 2016/7/14.\n */\npublic interface BaseModel {\n\n    /**\n     * 默认的开始,在activity中初始化\n     */\n    void start();\n\n    /**\n     * 在activity中的ondestoy 调用 在此方法中将资源至null,\n     * 此处略嫌麻烦,但是如果把presenter层搞成抽象类,在里面添加成员变量和方法体,\n     * 就有点失去了味道,所以还是选择了这种方式代替下列注释的部分.\n     *\n     */\n\n    void onDestroy();\n\n}\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/base/BasePresenter.java",
    "content": "package com.ccj.base.base;\n\n/**\n * Created by Administrator on 2016/7/7.\n */\npublic interface BasePresenter  {\n    /**\n     * 默认的开始,在activity中初始化\n     */\n    void start();\n\n    /**\n     * 在activity中的ondestoy 调用 在此方法中将资源至null,\n     * 此处略嫌麻烦,但是如果把presenter层搞成抽象类,在里面添加成员变量和方法体,\n     * 就有点失去了味道,所以还是选择了这种方式代替下列注释的部分.\n     *\n     */\n    void onDestroy();\n}\n\n/*\npublic abstract class BasePresenter<E, T> {\n    public Context context;\n    public E mModel;\n    public T mView;\n    public Source mSource = new Source();\n\n    public void setVM(T v, E m) {\n        this.mView = v;\n        this.mModel = m;\n        this.onStart();\n    }\n\n    public abstract void onStart();\n\n    public void onDestroy() {\n        mSource.clear();\n    }\n}*/\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/base/BaseView.java",
    "content": "package com.ccj.base.base;\n\n/**\n * Created by Administrator on 2016/7/6.\n */\npublic interface BaseView {\n\n\n    void initView();\n}\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/base/Constants.java",
    "content": "package com.ccj.base.base;\n\n/**\n * 静态常量\n */\npublic class Constants {\n\n    public static final int REQUST_FOR_LOGIN = 0x0001;\n    public static final int RESULT_FOR_LOGIN = 0x0002;\n\n\n    public static final int IMAGES_ACTIVITY_REQUEST_CODE = 300;\n}\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/bean/User.java",
    "content": "package com.ccj.base.bean;\n\nimport com.ccj.base.base.BaseBean;\nimport com.google.gson.Gson;\n\nimport java.io.Serializable;\n\npublic class User extends BaseBean implements Serializable {\n\n    public static final long serialVersionUID = 2233933716943685981L;\n    /**\n     * code : 200\n     * msg : 登录成功\n     * 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}\n     */\n\n    public String code;\n    public String msg;\n    /**\n     * ID : 1\n     * Users_Organization : null\n     * Users_CellPhoneNum : 13800138000\n     * Users_PassWord : 123456\n     * Users_CorpName : 安监站\n     * Users_IDCard : null\n     * Users_Kind : 1\n     * Users_RegisterDate : 2016-06-14T11:20:02\n     * Users_IsDel : false\n     * Users_Guid : null\n     * Users_PersonName : 刘某某\n     * Users_CorpKind : null\n     * Users_AppID : 109\n     * Users_AreaCode : 02\n     * Users_TableName : null\n     * Users_PKCode : null\n     * Users_Alias : 10014AAC2F4FAD043E6BF71E30C34DEC\n     * Users_JobName : 主管\n     * Users_CorpKindName : 施工企业\n     * Users_AreaName : 市南区\n     * Users_Photo : null\n     * Users_OrderBy : null\n     */\n\n    public ResultBean result;\n\n\n    public static User objectFromData(String str) {\n\n        return new Gson().fromJson(str, User.class);\n    }\n\n    public static class ResultBean {\n        public int ID;\n        public Object Users_Organization;\n        public String Users_CellPhoneNum;\n        public String Users_PassWord;\n        public String Users_CorpName;\n        public Object Users_IDCard;\n        public int Users_Kind;\n        public String Users_RegisterDate;\n        public boolean Users_IsDel;\n        public Object Users_Guid;\n        public String Users_PersonName;\n        public Object Users_CorpKind;\n        public int Users_AppID;\n        public String Users_AreaCode;\n        public Object Users_TableName;\n        public Object Users_PKCode;\n        public String Users_Alias;\n        public String Users_JobName;\n        public String Users_CorpKindName;\n        public String Users_AreaName;\n        public Object Users_Photo;\n\n        public Object Users_OrderBy;\n\n        @Override\n        public String toString() {\n            return \"ResultBean{\" +\n                    \"ID=\" + ID +\n                    \", Users_Organization=\" + Users_Organization +\n                    \", Users_CellPhoneNum='\" + Users_CellPhoneNum + '\\'' +\n                    \", Users_PassWord='\" + Users_PassWord + '\\'' +\n                    \", Users_CorpName='\" + Users_CorpName + '\\'' +\n                    \", Users_IDCard=\" + Users_IDCard +\n                    \", Users_Kind=\" + Users_Kind +\n                    \", Users_RegisterDate='\" + Users_RegisterDate + '\\'' +\n                    \", Users_IsDel=\" + Users_IsDel +\n                    \", Users_Guid=\" + Users_Guid +\n                    \", Users_PersonName='\" + Users_PersonName + '\\'' +\n                    \", Users_CorpKind=\" + Users_CorpKind +\n                    \", Users_AppID=\" + Users_AppID +\n                    \", Users_AreaCode='\" + Users_AreaCode + '\\'' +\n                    \", Users_TableName=\" + Users_TableName +\n                    \", Users_PKCode=\" + Users_PKCode +\n                    \", Users_Alias='\" + Users_Alias + '\\'' +\n                    \", Users_JobName='\" + Users_JobName + '\\'' +\n                    \", Users_CorpKindName='\" + Users_CorpKindName + '\\'' +\n                    \", Users_AreaName='\" + Users_AreaName + '\\'' +\n                    \", Users_Photo=\" + Users_Photo +\n                    \", Users_OrderBy=\" + Users_OrderBy +\n                    '}';\n        }\n\n        public static ResultBean objectFromData(String str) {\n\n            return new Gson().fromJson(str, ResultBean.class);\n        }\n    }\n\n\n    @Override\n    public String toString() {\n        return \"User{\" +\n                \"code='\" + code + '\\'' +\n                \", msg='\" + msg + '\\'' +\n                \", result=\" + result +\n                '}';\n    }\n\n\n\n\n}\n\n\n\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/bean/UserDetail.java",
    "content": "package com.ccj.base.bean;\n\n/**\n * Created by Administrator on 2016/8/10.\n */\npublic class UserDetail {\n\n\n\n    public String Users_PersonName;\n\n\n\n    public String Users_CellPhoneNum;\n\n}\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/utils/BitmapUtil.java",
    "content": "package com.ccj.base.utils;\n\nimport android.content.Context;\nimport android.graphics.Bitmap;\nimport android.graphics.BitmapFactory;\nimport android.net.Uri;\nimport android.os.Environment;\nimport android.util.Log;\n\nimport java.io.BufferedOutputStream;\nimport java.io.ByteArrayInputStream;\nimport java.io.ByteArrayOutputStream;\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.text.SimpleDateFormat;\nimport java.util.Date;\n\n/**\n * Created by Administrator on 2016/3/3.\n */\npublic class BitmapUtil {\n    public static final String LOG_TAG = \"HelloCamera\";\n    public static final int MEDIA_TYPE_IMAGE = 1;\n    public static final int MEDIA_TYPE_VIDEO = 2;\n    private static final String TAG = \"BitmapUtil\";\n    private static boolean isRun = true;\n    private static Context context;\n    private int i=0;\n    private static BitmapUtil bitmapUtil;\n    private static File tempFile;\n    private boolean getAllPicIsRun = true;\n    private int pic2=0,pic1=0;\n\n    public BitmapUtil(Context context){\n        BitmapUtil.context =context;\n    }\n\n    /**\n     * Create a file Uri for saving an image or video\n     */\n    public static Uri getOutputMediaFileUri(int type, String name) {\n        return Uri.fromFile(getOutputMediaFile(type, name));\n    }\n\n    /**\n     * Create a File for saving an image or video\n     */\n    public static File getOutputMediaFile(int type, String name) {\n        // To be safe, you should check that the SDCard is mounted\n        // using Environment.getExternalStorageState() before doing this.\n        File mediaStorageDir = null;\n        try {\n            // This location works best if you want the created images to be\n            // shared\n            // between applications and persist after your app has been\n            // uninstalled.\n            mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),\n                    \"MyCamera\");\n        } catch (Exception e) {\n            e.printStackTrace();\n            Log.e(LOG_TAG, \"Error in Creating mediaStorageDir: \" + mediaStorageDir);\n        }\n        // Create the storage directory if it does not exist\n        if (!mediaStorageDir.exists()) {\n            if (!mediaStorageDir.mkdirs()) {\n                // <uses-permission\n                // android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />\n                Log.e(LOG_TAG, \"failed to create directory, check if you have the WRITE_EXTERNAL_STORAGE permission\");\n                return null;\n            }\n        }\n        // Create a media file name\n        String timeStamp = new SimpleDateFormat(\"yyyyMMdd_HHmmss\").format(new Date());\n        File mediaFile = null;\n        if (type == MEDIA_TYPE_IMAGE) {\n            mediaFile = new File(mediaStorageDir.getPath() + File.separator + timeStamp + \".jpg\");\n            Log.d(LOG_TAG,\n                    \"sucessfully create mediafile\");\n        }\n        return mediaFile;\n    }\n\n    public static String getPhotoURL(String name) {\n\n        File mediaStorageDir;\n        mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), \"MyCamera\");\n\n        String fileName = getFile(mediaStorageDir.getPath(), name);//判断文件是否包含文件名\n        String file = mediaStorageDir.getPath() + File.separator + fileName;\n        File file1 = new File(file);\n        if (file1.isDirectory()) {\n            return null;\n        }\n        return file;\n\n    }\n\n    public static String getFile(String dir, String contain) {\n        if (contain==null){\n            return \"\";\n        }\n\n        File file = new File(dir);\n        File[] array = file.listFiles();\n        Log.e(\"listFiles-->\", array.length + \"!\"+contain);\n\n\n        for (int i = 0; i < array.length; i++) {\n            if (array[i].isFile()) {\n                // only take file name\n                Log.e(\"getFile-->\", array[i].getName());\n                if (array[i].getName().contains(contain)) {\n                    return array[i].getName();\n                } else if (array[i].isDirectory()) {\n                    getFile(array[i].getPath(), contain);\n                }\n            }\n        }\n        return \"\";\n\n    }\n\n    public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {\n        final int height = options.outHeight;\n        final int width = options.outWidth;\n        int inSampleSize = 1;\n        if (height > reqHeight || width > reqWidth) {\n            final int heightRatio = Math.round((float) height / (float) reqHeight);\n            final int widthRatio = Math.round((float) width / (float) reqWidth);\n            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;\n        }\n        return inSampleSize;\n    }\n\n\n    public static File transMsgPicFile(File file, Bitmap bitmap) {\n\n         tempFile=BitmapUtil.getOutputMediaFile(MEDIA_TYPE_IMAGE, \"temp\");\n        try {\n            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));\n            bitmap.compress(Bitmap.CompressFormat.JPEG, 60, bos);\n            bos.flush();\n            bos.close();\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n        return tempFile;\n    }\n\n\n    //纯粹的压缩图片\n    public static Bitmap comp(Bitmap image) {\n        if (image==null){\n            return null;\n        }\n        ByteArrayOutputStream baos = new ByteArrayOutputStream();\n        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);\n        if (baos.toByteArray().length / 1024 > 1024) {//判断如果图片大于1M,进行压缩避免在生成图片（BitmapFactory.decodeStream）时溢出\n            baos.reset();//重置baos即清空baos\n            image.compress(Bitmap.CompressFormat.JPEG, 50, baos);//这里压缩50%，把压缩后的数据存放到baos中\n        }\n        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());\n        BitmapFactory.Options newOpts = new BitmapFactory.Options();\n        //开始读入图片，此时把options.inJustDecodeBounds 设回true了\n        newOpts.inJustDecodeBounds = true;\n        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);\n        newOpts.inJustDecodeBounds = false;\n        int w = newOpts.outWidth;\n        int h = newOpts.outHeight;\n        //现在主流手机比较多是800*480分辨率，所以高和宽我们设置为\n        float hh = 800f;//这里设置高度为800f\n        float ww = 480f;//这里设置宽度为480f\n        //缩放比。由于是固定比例缩放，只用高或者宽其中一个数据进行计算即可\n        int be = 1;//be=1表示不缩放\n        if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放\n            be = (int) (newOpts.outWidth / ww);\n        } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放\n            be = (int) (newOpts.outHeight / hh);\n        }\n        if (be <= 0)\n            be = 1;\n        newOpts.inSampleSize = be;//设置缩放比例\n        //重新读入图片，注意此时已经把options.inJustDecodeBounds 设回false了\n        isBm = new ByteArrayInputStream(baos.toByteArray());\n        bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);\n        return compressImage(bitmap);//压缩好比例大小后再进行质量压缩\n    }\n\n\n    //由path 得到压缩后的bitmap\n    private Bitmap getimage(String srcPath) {\n        BitmapFactory.Options newOpts = new BitmapFactory.Options();\n        //开始读入图片，此时把options.inJustDecodeBounds 设回true了\n        newOpts.inJustDecodeBounds = true;\n        Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);//此时返回bm为空\n\n        newOpts.inJustDecodeBounds = false;\n        int w = newOpts.outWidth;\n        int h = newOpts.outHeight;\n        //现在主流手机比较多是800*480分辨率，所以高和宽我们设置为\n        float hh = 800f;//这里设置高度为800f\n        float ww = 480f;//这里设置宽度为480f\n        //缩放比。由于是固定比例缩放，只用高或者宽其中一个数据进行计算即可\n        int be = 1;//be=1表示不缩放\n        if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放\n            be = (int) (newOpts.outWidth / ww);\n        } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放\n            be = (int) (newOpts.outHeight / hh);\n        }\n        if (be <= 0)\n            be = 1;\n        newOpts.inSampleSize = be;//设置缩放比例\n        //重新读入图片，注意此时已经把options.inJustDecodeBounds 设回false了\n        bitmap = BitmapFactory.decodeFile(srcPath, newOpts);\n        return compressImage(bitmap);//压缩好比例大小后再进行质量压缩\n    }\n\n    //质量压缩图片\n    private static Bitmap compressImage(Bitmap image) {\n\n        ByteArrayOutputStream baos = new ByteArrayOutputStream();\n        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中\n        int options = 100;\n        while (baos.toByteArray().length / 1024 > 100 && options>10) {  //循环判断如果压缩后图片是否大于100kb,大于继续压缩\n            baos.reset();//重置baos即清空baos\n            image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%，把压缩后的数据存放到baos中\n            options -= 10;//每次都减少10\n        }\n        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中\n        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片\n        return bitmap;\n    }\n\n}\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/utils/LruBitmapCache.java",
    "content": "package com.ccj.base.utils;\n\nimport android.graphics.Bitmap;\nimport android.support.v4.util.LruCache;\n\nimport com.android.volley.toolbox.ImageLoader;\n\n/**\n * 图片缓存池\n * Created by ccj on 2016/1/6.\n */\npublic class LruBitmapCache implements ImageLoader.ImageCache {\n    private LruCache<String, Bitmap> mCache;\n\n    public LruBitmapCache() {\n        int maxSize = 10 * 1024 * 1024;\n\n        mCache = new LruCache<String, Bitmap>(maxSize) {\n            @Override\n            protected int sizeOf(String key, Bitmap value) {\n                return value.getRowBytes() * value.getHeight();\n            }\n        };\n    }\n\n    @Override\n    public Bitmap getBitmap(String url) {\n        return mCache.get(url);\n    }\n\n    @Override\n    public void putBitmap(String url, Bitmap bitmap) {\n        mCache.put(url, bitmap);\n    }\n\n}\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/utils/SerializableUtil.java",
    "content": "package com.ccj.base.utils;\n\nimport android.util.Base64;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\nimport java.util.List;\n\n/**\n * Created by ccj on 2015/12/7.\n * 将 对象转为 字符串,易于保存 上传等\n *\n */\npublic class SerializableUtil {\n\n    public static String objToStr(Object obj) throws IOException {\n        if (obj == null) {\n            return \"\";\n        }\n        //实例化一个ByteArrayOutputStream对象，用来装载压缩后的字节文件\n        ByteArrayOutputStream baos = new ByteArrayOutputStream();\n        //然后将得到的字符数据装载到ObjectOutputStream\n        ObjectOutputStream oos = new ObjectOutputStream(baos);\n        //writeObject 方法负责写入特定类的对象的状态，以便相应的readObject可以还原它\n        oos.writeObject(obj);\n        //最后，用Base64.encode将字节文件转换成Base64编码，并以String形式保存\n        String listString = new String(Base64.encode(baos.toByteArray(), Base64.DEFAULT));\n        //关闭oos\n        oos.close();\n        return listString;\n\n    }\n\n\n    //将序列化的数据还原成Object\n\n    public static Object strToObj(String str) throws IOException {\n        byte[] mByte = Base64.decode(str.getBytes(), Base64.DEFAULT);\n        ByteArrayInputStream bais = new ByteArrayInputStream(mByte);\n        ObjectInputStream ois = new ObjectInputStream(bais);\n        try {\n\n            return ois.readObject();\n        } catch (ClassNotFoundException e) {\n            e.printStackTrace();\n        }\n        return null;\n    }\n\n    public static <T> String listToString(List<T> list) throws IOException {\n        //实例化一个ByteArrayOutputStream对象，用来装载压缩后的字节文件\n        ByteArrayOutputStream baos = new ByteArrayOutputStream();\n        //然后将得到的字符数据装载到ObjectOutputStream\n        ObjectOutputStream oos = new ObjectOutputStream(baos);\n        //writeObject 方法负责写入特定类的对象的状态，以便相应的readObject可以还原它\n        oos.writeObject(list);\n        //最后，用Base64.encode将字节文件转换成Base64编码，并以String形式保存\n        String listString = new String(Base64.encode(baos.toByteArray(), Base64.DEFAULT));\n        //关闭oos\n        oos.close();\n        return listString;\n    }\n\n\n    public static <T> List<T> stringToList(String str) throws IOException {\n        byte[] mByte = Base64.decode(str.getBytes(), Base64.DEFAULT);\n        ByteArrayInputStream bais = new ByteArrayInputStream(mByte);\n        ObjectInputStream ois = new ObjectInputStream(bais);\n        List<T> stringList = null;\n        try {\n            stringList = (List<T>) ois.readObject();\n        } catch (ClassNotFoundException e) {\n            e.printStackTrace();\n        }\n        return stringList;\n    }\n\n\n}\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/utils/SharedPreferenceUtil.java",
    "content": "package com.ccj.base.utils;\n\nimport android.content.Context;\nimport android.content.SharedPreferences;\nimport android.text.TextUtils;\nimport android.util.Log;\n\nimport com.ccj.base.base.BaseApplication;\nimport com.ccj.base.bean.User;\n\nimport java.io.IOException;\nimport java.io.StreamCorruptedException;\n\n\npublic class SharedPreferenceUtil {\n\n    // 用户名key\n    public final static String KEY_NAME = \"KEY_NAME\";\n    public final static String KEY_AUTO = \"KEY_AUTO\";\n    public final static String KEY_LOGIN = \"KEY_LOGIN\";\n    public final static String KEY_LEVEL = \"KEY_LEVEL\";\n    public final static String KEY_DELIVERY = \"KEY_DELIVERY\";\n    private static SharedPreferenceUtil spUtils;\n    private static User spUser = null;\n    private SharedPreferences sp;\n\n\n    //\n\n    /**\n     *\n     * 初始化，一般在应用启动之后就要初始化\n     *\n     * @param context 此处的context要用application的全局上下文,\n     *                避免static强类型一直持有activity的引用,造成内存泄露\n     */\n    public static synchronized void initSharedPreference(Context context) {\n        if (spUtils == null) {\n            spUtils = new SharedPreferenceUtil(context);\n        }\n    }\n\n\n    /**\n     * 获取唯一的instance\n     *\n     * @return\n     */\n\n    public static synchronized SharedPreferenceUtil getInstance() {\n        if (spUtils == null) {\n            spUtils = new SharedPreferenceUtil(BaseApplication.getInstance());\n        }\n\n        return spUtils;\n    }\n\n    public SharedPreferenceUtil(Context context) {\n        sp = context.getSharedPreferences(\"SharedPreferenceUtil\", Context.MODE_PRIVATE);\n    }\n\n    public SharedPreferences getSharedPref() {\n        return sp;\n    }\n\n    public synchronized void putAutoLogin(Boolean AutoLogin) {\n        SharedPreferences.Editor editor = sp.edit();\n        editor.putBoolean(KEY_AUTO, AutoLogin);\n        editor.commit();\n    }\n\n    public synchronized Boolean getAutoLogin() {\n        Boolean flag = sp.getBoolean(KEY_AUTO, false);\n        Log.i(\"flag\", flag + \"flag\");\n        return flag;\n    }\n\n    public synchronized void setIsLogin(Boolean AutoLogin) {\n        SharedPreferences.Editor editor = sp.edit();\n        editor.putBoolean(KEY_LOGIN, AutoLogin);\n        editor.commit();\n    }\n\n    public synchronized Boolean getIsLogin() {\n        Boolean flag = sp.getBoolean(KEY_LOGIN, false);\n        return flag;\n    }\n\n    public synchronized void putUser(User user) {\n        SharedPreferences.Editor editor = sp.edit();\n        String str = \"\";\n        try {\n            str = SerializableUtil.objToStr(user);\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n        editor.putString(KEY_NAME, str);\n        editor.commit();\n        spUser = user;\n    }\n\n\n    //记录用户名\n    public void setUsername(String username){\n        SharedPreferences.Editor editor = sp.edit();\n        editor.putString(\"pre_username\",username);\n        editor.apply();\n    }\n\n    //读取用户名\n    public String getUsername(){\n        return sp.getString(\"pre_username\",\"\");\n    }\n\n\n    public synchronized User getUser()\n    {\n        String str = sp.getString(SharedPreferenceUtil.KEY_NAME, \"\");\n        if (TextUtils.isEmpty(str)) {\n            return null;\n        }\n        if (spUser == null) {\n            spUser = new User();\n            //获取序列化的数据\n            try {\n                Object obj = SerializableUtil.strToObj(str);\n                if (obj != null) {\n                    spUser = (User) obj;\n                    Log.e(\"USER\", \"getuser\" + spUser.toString());\n                }\n            } catch (StreamCorruptedException e) {\n                e.printStackTrace();\n            } catch (IOException e) {\n                e.printStackTrace();\n            }\n        }\n        return spUser;\n    }\n\n\n    public synchronized void DeleteUser() {\n        SharedPreferences.Editor editor = sp.edit();\n        editor.putString(KEY_NAME, \"\");\n        editor.commit();\n        spUser = null;\n    }\n\n//\n//    public synchronized DeliveryMessage getDeliveryMessage() {\n//        DeliveryMessage deliveryMessage = new DeliveryMessage();\n//        //获取序列化的数据\n//        String str = sp.getString(SharedPreferenceUtil.KEY_DELIVERY, \"\");\n//        if (TextUtils.isEmpty(str)) {\n//            return null;\n//        }\n//        try {\n//            Object obj = SerializableUtil.strToObj(str);\n//            if (obj != null) {\n//                deliveryMessage = (DeliveryMessage) obj;\n//            }\n//        } catch (StreamCorruptedException e) {\n//            e.printStackTrace();\n//        } catch (IOException e) {\n//            e.printStackTrace();\n//        }\n//\n//        return deliveryMessage;\n//\n//    }\n//\n//    public synchronized void putDeliveryMessage(DeliveryMessage deliveryMessage) {\n//        SharedPreferences.Editor editor = sp.edit();\n//        String str = \"\";\n//        try {\n//            str = SerializableUtil.objToStr(deliveryMessage);\n//        } catch (IOException e) {\n//            e.printStackTrace();\n//        }\n//        editor.putString(KEY_DELIVERY, str);\n//        editor.commit();\n//    }\n\n\n}\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/utils/TDeviceUtils.java",
    "content": "package com.ccj.base.utils;\n\nimport android.annotation.TargetApi;\nimport android.app.Activity;\nimport android.app.Dialog;\nimport android.content.ActivityNotFoundException;\nimport android.content.ClipboardManager;\nimport android.content.ComponentName;\nimport android.content.Context;\nimport android.content.Intent;\nimport android.content.pm.PackageInfo;\nimport android.content.pm.PackageManager;\nimport android.content.pm.PackageManager.NameNotFoundException;\nimport android.content.pm.ResolveInfo;\nimport android.graphics.Point;\nimport android.net.ConnectivityManager;\nimport android.net.NetworkInfo;\nimport android.net.Uri;\nimport android.os.Build;\nimport android.os.Environment;\nimport android.os.PowerManager;\nimport android.telephony.TelephonyManager;\nimport android.text.TextUtils;\nimport android.util.DisplayMetrics;\nimport android.util.TypedValue;\nimport android.view.Display;\nimport android.view.View;\nimport android.view.ViewConfiguration;\nimport android.view.WindowManager;\nimport android.view.inputmethod.InputMethodManager;\n\nimport com.ccj.base.R;\nimport com.ccj.base.base.BaseApplication;\n\nimport java.io.File;\nimport java.lang.reflect.Field;\nimport java.text.NumberFormat;\nimport java.util.List;\n\n@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)\npublic class TDeviceUtils {\n\n    // 手机网络类型\n    public static final int NETTYPE_WIFI = 0x01;\n    public static final int NETTYPE_CMWAP = 0x02;\n    public static final int NETTYPE_CMNET = 0x03;\n\n    public static boolean GTE_HC;\n    public static boolean GTE_ICS;\n    public static boolean PRE_HC;\n    private static Boolean _hasBigScreen = null;\n    private static Boolean _hasCamera = null;\n    private static Boolean _isTablet = null;\n    private static Integer _loadFactor = null;\n\n    private static int _pageSize = -1;\n    public static float displayDensity = 0.0F;\n\n    static {\n        GTE_ICS = Build.VERSION.SDK_INT >= 14;\n        GTE_HC = Build.VERSION.SDK_INT >= 11;\n        PRE_HC = Build.VERSION.SDK_INT < 11;\n    }\n\n    public TDeviceUtils() {\n    }\n\n    public static float dpToPixel(float dp) {\n        return dp * (getDisplayMetrics().densityDpi / 160F);\n    }\n\n    public static int getDefaultLoadFactor() {\n        if (_loadFactor == null) {\n            Integer integer = Integer.valueOf(0xf & BaseApplication.getContext()\n                    .getResources().getConfiguration().screenLayout);\n            _loadFactor = integer;\n            _loadFactor = Integer.valueOf(Math.max(integer.intValue(), 1));\n        }\n        return _loadFactor.intValue();\n    }\n\n    public static float getDensity() {\n        if (displayDensity == 0.0)\n            displayDensity = getDisplayMetrics().density;\n        return displayDensity;\n    }\n\n    public static DisplayMetrics getDisplayMetrics() {\n        DisplayMetrics displaymetrics = new DisplayMetrics();\n        ((WindowManager) BaseApplication.getContext().getSystemService(\n                Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(\n                displaymetrics);\n        return displaymetrics;\n    }\n\n    public static float getScreenHeight() {\n        return getDisplayMetrics().heightPixels;\n    }\n\n    public static float getScreenWidth() {\n        return getDisplayMetrics().widthPixels;\n    }\n\n    public static int[] getRealScreenSize(Activity activity) {\n        int[] size = new int[2];\n        int screenWidth = 0, screenHeight = 0;\n        WindowManager w = activity.getWindowManager();\n        Display d = w.getDefaultDisplay();\n        DisplayMetrics metrics = new DisplayMetrics();\n        d.getMetrics(metrics);\n        // since SDK_INT = 1;\n        screenWidth = metrics.widthPixels;\n        screenHeight = metrics.heightPixels;\n        // includes window decorations (statusbar bar/menu bar)\n        if (Build.VERSION.SDK_INT >= 14 && Build.VERSION.SDK_INT < 17)\n            try {\n                screenWidth = (Integer) Display.class.getMethod(\"getRawWidth\")\n                        .invoke(d);\n                screenHeight = (Integer) Display.class\n                        .getMethod(\"getRawHeight\").invoke(d);\n            } catch (Exception ignored) {\n            }\n        // includes window decorations (statusbar bar/menu bar)\n        if (Build.VERSION.SDK_INT >= 17)\n            try {\n                Point realSize = new Point();\n                Display.class.getMethod(\"getRealSize\", Point.class).invoke(d,\n                        realSize);\n                screenWidth = realSize.x;\n                screenHeight = realSize.y;\n            } catch (Exception ignored) {\n            }\n        size[0] = screenWidth;\n        size[1] = screenHeight;\n        return size;\n    }\n\n    public static int getStatusBarHeight() {\n        Class<?> c = null;\n        Object obj = null;\n        Field field = null;\n        int x = 0;\n        try {\n            c = Class.forName(\"com.android.internal.R$dimen\");\n            obj = c.newInstance();\n            field = c.getField(\"status_bar_height\");\n            x = Integer.parseInt(field.get(obj).toString());\n            return BaseApplication.getContext().getResources()\n                    .getDimensionPixelSize(x);\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n        return 0;\n    }\n\n\n\n    public static boolean hasBigScreen() {\n        boolean flag = true;\n        if (_hasBigScreen == null) {\n            boolean flag1;\n            if ((0xf & BaseApplication.getContext().getResources()\n                    .getConfiguration().screenLayout) >= 3)\n                flag1 = flag;\n            else\n                flag1 = false;\n            Boolean boolean1 = Boolean.valueOf(flag1);\n            _hasBigScreen = boolean1;\n            if (!boolean1.booleanValue()) {\n                if (getDensity() <= 1.5F)\n                    flag = false;\n                _hasBigScreen = Boolean.valueOf(flag);\n            }\n        }\n        return _hasBigScreen.booleanValue();\n    }\n\n    public static final boolean hasCamera() {\n        if (_hasCamera == null) {\n            PackageManager pckMgr = BaseApplication.getContext()\n                    .getPackageManager();\n            boolean flag = pckMgr\n                    .hasSystemFeature(\"android.hardware.camera.front\");\n            boolean flag1 = pckMgr.hasSystemFeature(\"android.hardware.camera\");\n            boolean flag2;\n            flag2 = flag || flag1;\n            _hasCamera = Boolean.valueOf(flag2);\n        }\n        return _hasCamera.booleanValue();\n    }\n\n    public static boolean hasHardwareMenuKey(Context getContext) {\n        boolean flag = false;\n        if (PRE_HC)\n            flag = true;\n        else if (GTE_ICS) {\n            flag = ViewConfiguration.get(getContext).hasPermanentMenuKey();\n        } else\n            flag = false;\n        return flag;\n    }\n\n    public static boolean hasInternet() {\n        boolean flag;\n\n        ConnectivityManager manager = (ConnectivityManager) BaseApplication.getContext()\n                .getSystemService(Context.CONNECTIVITY_SERVICE);\n        NetworkInfo activeNetworkInfo = manager.getActiveNetworkInfo();\n        flag = activeNetworkInfo != null;\n        return flag;\n    }\n\n    public static boolean gotoGoogleMarket(Activity activity, String pck) {\n        try {\n            Intent intent = new Intent();\n            intent.setPackage(\"com.android.vending\");\n            intent.setAction(Intent.ACTION_VIEW);\n            intent.setData(Uri.parse(\"market://details?id=\" + pck));\n            activity.startActivity(intent);\n            return true;\n        } catch (Exception e) {\n            e.printStackTrace();\n            return false;\n        }\n    }\n\n    public static boolean isPackageExist(String pckName) {\n        try {\n            PackageInfo pckInfo = BaseApplication.getContext().getPackageManager()\n                    .getPackageInfo(pckName, 0);\n            if (pckInfo != null)\n                return true;\n        } catch (NameNotFoundException e) {\n            TLog.error(e.getMessage());\n        }\n        return false;\n    }\n\n    public static void hideAnimatedView(View view) {\n        if (PRE_HC && view != null)\n            view.setPadding(view.getWidth(), 0, 0, 0);\n    }\n\n    public static void hideSoftKeyboard(View view) {\n        if (view == null)\n            return;\n        ((InputMethodManager) BaseApplication.getContext().getSystemService(\n                Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(\n                view.getWindowToken(), 0);\n    }\n\n    public static boolean isLandscape() {\n        boolean flag;\n        flag = BaseApplication.getContext().getResources().getConfiguration().orientation == 2;\n        return flag;\n    }\n\n    public static boolean isPortrait() {\n        boolean flag = true;\n        if (BaseApplication.getContext().getResources().getConfiguration().orientation != 1)\n            flag = false;\n        return flag;\n    }\n\n    public static boolean isTablet() {\n        if (_isTablet == null) {\n            boolean flag;\n            flag = (0xf & BaseApplication.getContext().getResources()\n                    .getConfiguration().screenLayout) >= 3;\n            _isTablet = Boolean.valueOf(flag);\n        }\n        return _isTablet.booleanValue();\n    }\n\n    public static float pixelsToDp(float f) {\n        return f / (getDisplayMetrics().densityDpi / 160F);\n    }\n\n    public static void showAnimatedView(View view) {\n        if (PRE_HC && view != null)\n            view.setPadding(0, 0, 0, 0);\n    }\n\n    public static void showSoftKeyboard(Dialog dialog) {\n        dialog.getWindow().setSoftInputMode(4);\n    }\n\n    public static void showSoftKeyboard(View view) {\n        ((InputMethodManager) BaseApplication.getContext().getSystemService(\n                Context.INPUT_METHOD_SERVICE)).showSoftInput(view,\n                InputMethodManager.SHOW_FORCED);\n    }\n\n    public static void toogleSoftKeyboard(View view) {\n        ((InputMethodManager) BaseApplication.getContext().getSystemService(\n                Context.INPUT_METHOD_SERVICE)).toggleSoftInput(0,\n                InputMethodManager.HIDE_NOT_ALWAYS);\n    }\n\n    public static boolean isSdcardReady() {\n        return Environment.MEDIA_MOUNTED.equals(Environment\n                .getExternalStorageState());\n    }\n\n    public static String getCurCountryLan() {\n        return BaseApplication.getContext().getResources().getConfiguration().locale\n                .getLanguage()\n                + \"-\"\n                + BaseApplication.getContext().getResources().getConfiguration().locale\n                .getCountry();\n    }\n\n    public static boolean isZhCN() {\n        String lang = BaseApplication.getContext().getResources()\n                .getConfiguration().locale.getCountry();\n        return lang.equalsIgnoreCase(\"CN\");\n    }\n\n    public static String percent(double p1, double p2) {\n        String str;\n        double p3 = p1 / p2;\n        NumberFormat nf = NumberFormat.getPercentInstance();\n        nf.setMinimumFractionDigits(2);\n        str = nf.format(p3);\n        return str;\n    }\n\n    public static String percent2(double p1, double p2) {\n        String str;\n        double p3 = p1 / p2;\n        NumberFormat nf = NumberFormat.getPercentInstance();\n        nf.setMinimumFractionDigits(0);\n        str = nf.format(p3);\n        return str;\n    }\n\n    public static void gotoMarket(Context getContext, String pck) {\n        if (!isHaveMarket(getContext)) {\n            BaseApplication.showToast(\"你手机中没有安装应用市场！\");\n            return;\n        }\n        Intent intent = new Intent();\n        intent.setAction(Intent.ACTION_VIEW);\n        intent.setData(Uri.parse(\"market://details?id=\" + pck));\n        if (intent.resolveActivity(getContext.getPackageManager()) != null) {\n            getContext.startActivity(intent);\n        }\n    }\n\n    public static boolean isHaveMarket(Context getContext) {\n        Intent intent = new Intent();\n        intent.setAction(\"android.intent.action.MAIN\");\n        intent.addCategory(\"android.intent.category.APP_MARKET\");\n        PackageManager pm = getContext.getPackageManager();\n        List<ResolveInfo> infos = pm.queryIntentActivities(intent, 0);\n        return infos.size() > 0;\n    }\n\n    public static void openAppInMarket(Context getContext) {\n        if (getContext != null) {\n            String pckName = getContext.getPackageName();\n            try {\n                gotoMarket(getContext, pckName);\n            } catch (Exception ex) {\n                try {\n                    String otherMarketUri = \"http://market.android.com/details?id=\"\n                            + pckName;\n                    Intent intent = new Intent(Intent.ACTION_VIEW,\n                            Uri.parse(otherMarketUri));\n                    getContext.startActivity(intent);\n                } catch (Exception e) {\n\n                }\n            }\n        }\n    }\n\n    public static void setFullScreen(Activity activity) {\n        WindowManager.LayoutParams params = activity.getWindow()\n                .getAttributes();\n        params.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;\n        activity.getWindow().setAttributes(params);\n        activity.getWindow().addFlags(\n                WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);\n    }\n\n    public static void cancelFullScreen(Activity activity) {\n        WindowManager.LayoutParams params = activity.getWindow()\n                .getAttributes();\n        params.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);\n        activity.getWindow().setAttributes(params);\n        activity.getWindow().clearFlags(\n                WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);\n    }\n\n    public static PackageInfo getPackageInfo(String pckName) {\n        try {\n            return BaseApplication.getContext().getPackageManager()\n                    .getPackageInfo(pckName, 0);\n        } catch (NameNotFoundException e) {\n            TLog.error(e.getMessage());\n        }\n        return null;\n    }\n\n    public static int getVersionCode() {\n        int versionCode = 0;\n        try {\n            versionCode = BaseApplication\n                    .getContext()\n                    .getPackageManager()\n                    .getPackageInfo(BaseApplication.getContext().getPackageName(),\n                            0).versionCode;\n        } catch (NameNotFoundException ex) {\n            versionCode = 0;\n        }\n        return versionCode;\n    }\n\n    public static int getVersionCode(String packageName) {\n        int versionCode = 0;\n        try {\n            versionCode = BaseApplication.getContext().getPackageManager()\n                    .getPackageInfo(packageName, 0).versionCode;\n        } catch (NameNotFoundException ex) {\n            versionCode = 0;\n        }\n        return versionCode;\n    }\n\n    public static String getVersionName() {\n        String name = \"\";\n        try {\n            name = BaseApplication\n                    .getContext()\n                    .getPackageManager()\n                    .getPackageInfo(BaseApplication.getContext().getPackageName(),\n                            0).versionName;\n        } catch (NameNotFoundException ex) {\n            name = \"\";\n        }\n        return name;\n    }\n\n    public static boolean isScreenOn() {\n        PowerManager pm = (PowerManager) BaseApplication.getContext()\n                .getSystemService(Context.POWER_SERVICE);\n        return pm.isScreenOn();\n    }\n\n    public static void installAPK(Context getContext, File file) {\n        if (file == null || !file.exists())\n            return;\n        Intent intent = new Intent();\n        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);\n        intent.setAction(Intent.ACTION_VIEW);\n        intent.setDataAndType(Uri.fromFile(file),\n                \"application/vnd.android.package-archive\");\n        getContext.startActivity(intent);\n    }\n\n    public static Intent getInstallApkIntent(File file) {\n        Intent intent = new Intent();\n        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);\n        intent.setAction(Intent.ACTION_VIEW);\n        intent.setDataAndType(Uri.fromFile(file),\n                \"application/vnd.android.package-archive\");\n        return intent;\n    }\n\n    public static void openDial(Context getContext, String number) {\n        Uri uri = Uri.parse(\"tel:\" + number);\n        Intent it = new Intent(Intent.ACTION_DIAL, uri);\n        getContext.startActivity(it);\n    }\n\n    public static void openSMS(Context getContext, String smsBody, String tel) {\n        Uri uri = Uri.parse(\"smsto:\" + tel);\n        Intent it = new Intent(Intent.ACTION_SENDTO, uri);\n        it.putExtra(\"sms_body\", smsBody);\n        getContext.startActivity(it);\n    }\n\n    public static void openDail(Context getContext) {\n        Intent intent = new Intent(Intent.ACTION_DIAL);\n        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);\n        getContext.startActivity(intent);\n    }\n\n    public static void openSendMsg(Context getContext) {\n        Uri uri = Uri.parse(\"smsto:\");\n        Intent intent = new Intent(Intent.ACTION_SENDTO, uri);\n        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);\n        getContext.startActivity(intent);\n    }\n\n    public static void openCamera(Context getContext) {\n        Intent intent = new Intent(); // 调用照相机\n        intent.setAction(\"android.media.action.STILL_IMAGE_CAMERA\");\n        intent.setFlags(0x34c40000);\n        getContext.startActivity(intent);\n    }\n\n    public static String getIMEI() {\n        TelephonyManager tel = (TelephonyManager) BaseApplication.getContext()\n                .getSystemService(Context.TELEPHONY_SERVICE);\n        return tel.getDeviceId();\n    }\n\n    public static String getPhoneType() {\n        return Build.MODEL;\n    }\n\n    public static void openApp(Context getContext, String packageName) {\n        Intent mainIntent = BaseApplication.getContext().getPackageManager()\n                .getLaunchIntentForPackage(packageName);\n        if (mainIntent == null) {\n            mainIntent = new Intent(packageName);\n        } else {\n            TLog.log(\"Action:\" + mainIntent.getAction());\n        }\n        getContext.startActivity(mainIntent);\n    }\n\n    public static boolean openAppActivity(Context getContext, String packageName,\n                                          String activityName) {\n        Intent intent = new Intent(Intent.ACTION_MAIN);\n        intent.addCategory(Intent.CATEGORY_LAUNCHER);\n        ComponentName cn = new ComponentName(packageName, activityName);\n        intent.setComponent(cn);\n        try {\n            getContext.startActivity(intent);\n            return true;\n        } catch (Exception e) {\n            return false;\n        }\n    }\n\n    public static boolean isWifiOpen() {\n        boolean isWifiConnect = false;\n        ConnectivityManager cm = (ConnectivityManager) BaseApplication\n                .getContext().getSystemService(Context.CONNECTIVITY_SERVICE);\n        // check the networkInfos numbers\n        NetworkInfo[] networkInfos = cm.getAllNetworkInfo();\n        for (int i = 0; i < networkInfos.length; i++) {\n            if (networkInfos[i].getState() == NetworkInfo.State.CONNECTED) {\n                if (networkInfos[i].getType() == ConnectivityManager.TYPE_MOBILE) {\n                    isWifiConnect = false;\n                }\n                if (networkInfos[i].getType() == ConnectivityManager.TYPE_WIFI) {\n                    isWifiConnect = true;\n                }\n            }\n        }\n        return isWifiConnect;\n    }\n\n    public static void uninstallApk(Context getContext, String packageName) {\n        if (isPackageExist(packageName)) {\n            Uri packageURI = Uri.parse(\"package:\" + packageName);\n            Intent uninstallIntent = new Intent(Intent.ACTION_DELETE,\n                    packageURI);\n            getContext.startActivity(uninstallIntent);\n        }\n    }\n\n    @SuppressWarnings(\"deprecation\")\n    public static void copyTextToBoard(String string) {\n        if (TextUtils.isEmpty(string))\n            return;\n        ClipboardManager clip = (ClipboardManager) BaseApplication.getContext()\n                .getSystemService(Context.CLIPBOARD_SERVICE);\n        clip.setText(string);\n        BaseApplication.showToast(\"复制成功\");\n    }\n\n    /**\n     * 发送邮件\n     *\n     * @param getContext\n     * @param subject 主题\n     * @param content 内容\n     * @param emails  邮件地址\n     */\n    public static void sendEmail(Context getContext, String subject,\n                                 String content, String... emails) {\n        try {\n            Intent intent = new Intent(Intent.ACTION_SEND);\n            // 模拟器\n            // intent.setType(\"text/plain\");\n            intent.setType(\"message/rfc822\"); // 真机\n            intent.putExtra(Intent.EXTRA_EMAIL, emails);\n            intent.putExtra(Intent.EXTRA_SUBJECT, subject);\n            intent.putExtra(Intent.EXTRA_TEXT, content);\n            getContext.startActivity(intent);\n        } catch (ActivityNotFoundException e) {\n            e.printStackTrace();\n        }\n    }\n\n    public static int getStatuBarHeight() {\n        Class<?> c = null;\n        Object obj = null;\n        Field field = null;\n        int x = 0, sbar = 38;// 默认为38，貌似大部分是这样的\n        try {\n            c = Class.forName(\"com.android.internal.R$dimen\");\n            obj = c.newInstance();\n            field = c.getField(\"status_bar_height\");\n            x = Integer.parseInt(field.get(obj).toString());\n            sbar = BaseApplication.getContext().getResources()\n                    .getDimensionPixelSize(x);\n\n        } catch (Exception e1) {\n            e1.printStackTrace();\n        }\n        return sbar;\n    }\n\n    public static int getActionBarHeight(Context getContext) {\n        int actionBarHeight = 0;\n        TypedValue tv = new TypedValue();\n        if (getContext.getTheme().resolveAttribute(android.R.attr.actionBarSize,\n                tv, true))\n            actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,\n                    getContext.getResources().getDisplayMetrics());\n\n        if (actionBarHeight == 0\n                && getContext.getTheme().resolveAttribute(R.attr.actionBarSize,\n                tv, true)) {\n            actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,\n                    getContext.getResources().getDisplayMetrics());\n        }\n\n        return actionBarHeight;\n    }\n\n    public static boolean hasStatusBar(Activity activity) {\n        WindowManager.LayoutParams attrs = activity.getWindow().getAttributes();\n        return (attrs.flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) != WindowManager.LayoutParams.FLAG_FULLSCREEN;\n    }\n\n    /**\n     * 调用系统安装了的应用分享\n     *\n     * @param getContext\n     * @param title\n     * @param url\n     */\n    public static void showSystemShareOption(Activity getContext,\n                                             final String title, final String url) {\n        Intent intent = new Intent(Intent.ACTION_SEND);\n        intent.setType(\"text/plain\");\n        intent.putExtra(Intent.EXTRA_SUBJECT, \"分享：\" + title);\n        intent.putExtra(Intent.EXTRA_TEXT, title + \" \" + url);\n        getContext.startActivity(Intent.createChooser(intent, \"选择分享\"));\n    }\n\n    /**\n     * 获取当前网络类型\n     *\n     * @return 0：没有网络 1：WIFI网络 2：WAP网络 3：NET网络\n     */\n    public static int getNetworkType() {\n        int netType = 0;\n        ConnectivityManager connectivityManager = (ConnectivityManager) BaseApplication\n                .getInstance().getSystemService(Context.CONNECTIVITY_SERVICE);\n        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();\n        if (networkInfo == null) {\n            return netType;\n        }\n        int nType = networkInfo.getType();\n        if (nType == ConnectivityManager.TYPE_MOBILE) {\n            String extraInfo = networkInfo.getExtraInfo();\n            if (!TextUtils.isEmpty(extraInfo)) {\n                if (extraInfo.toLowerCase().equals(\"cmnet\")) {\n                    netType = NETTYPE_CMNET;\n                } else {\n                    netType = NETTYPE_CMWAP;\n                }\n            }\n        } else if (nType == ConnectivityManager.TYPE_WIFI) {\n            netType = NETTYPE_WIFI;\n        }\n        return netType;\n    }\n}\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/utils/TLog.java",
    "content": "package com.ccj.base.utils;\n\nimport android.util.Log;\n\npublic class TLog {\n\tpublic static final String LOG_TAG = \"TLog-->\";\n\tpublic static boolean DEBUG = true;//是否处在debug\n\n\tpublic TLog() {\n\t}\n\t\n\tpublic static final void analytics(String log) {\n\t\tif (DEBUG)\n\t\t\tLog.d(LOG_TAG, log);\n\t}\n\n\tpublic static final void error(String log) {\n\t\tif (DEBUG)\n\t\t\tLog.e(LOG_TAG, \"\" + log);\n\t}\n\n\tpublic static final void log(String log) {\n\t\tif (DEBUG)\n\t\t\tLog.e(LOG_TAG, log);\n\t}\n\n\tpublic static final void log(String tag, String log) {\n\t\tif (DEBUG)\n\t\t\tLog.e(tag, log);\n\t}\n\n\tpublic static final void logI(String log) {\n\t\tif (DEBUG)\n\t\t\tLog.i(LOG_TAG, log);\n\t}\n\n\tpublic static final void warn(String log) {\n\t\tif (DEBUG)\n\t\t\tLog.w(LOG_TAG, log);\n\t}\n}\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/utils/ToastUtil.java",
    "content": "package com.ccj.base.utils;\n\nimport com.ccj.base.base.BaseApplication;\n\npublic class ToastUtil {\n\n\n    public static void show( String text) {\n        android.widget.Toast.makeText(BaseApplication.getContext(), text, android.widget.Toast.LENGTH_SHORT).show();\n    }\n\n}\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/utils/eventbus/EventUtils.java",
    "content": "package com.ccj.base.utils.eventbus;\n\n\n/**\n * 事件总线 用于组件或线程通信,可替代回调,广播等\n * Created by ccj on 2016/4/14.\n */\npublic class EventUtils {\n    /**\n     * 传递String类型的event\n     *\n     */\n    public static class StringEvent{\n        private String mMsg;\n        public StringEvent(String msg) {\n            // TODO Auto-generated constructor stub\n            this.mMsg = msg;\n        }\n        public String getMsg(){\n            return mMsg;\n        }\n    }\n\n    public static class intEvent{\n        private int mMsg;\n        public intEvent(int msg) {\n            // TODO Auto-generated constructor stub\n            this.mMsg = msg;\n        }\n        public int getMsg(){\n            return mMsg;\n        }\n    }\n\n    /**\n     * object类型(即传统的所有类型,都可以强转进行传递事件)\n     *\n     */\n\n    public static class ObjectEvent{\n        private Object object;\n        public ObjectEvent(Object object) {\n            // TODO Auto-generated constructor stub\n            this.object = object;\n        }\n        public Object getMsg(){\n            return object;\n        }\n    }\n\n}\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/utils/router/LoginModuleService.java",
    "content": "package com.ccj.base.utils.router;\n\nimport com.alibaba.android.arouter.facade.template.IProvider;\n\n/**\n * 示例:子模块间调用方法\n * Created by chenchangjun on 17/8/14.\n */\n\npublic interface LoginModuleService extends IProvider {\n\n\n     boolean checkLoginState();\n\n}\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/utils/router/RounterInterceptor.java",
    "content": "package com.ccj.base.utils.router;\n\nimport android.content.Context;\n\nimport com.alibaba.android.arouter.facade.Postcard;\nimport com.alibaba.android.arouter.facade.annotation.Interceptor;\nimport com.alibaba.android.arouter.facade.callback.InterceptorCallback;\nimport com.alibaba.android.arouter.facade.template.IInterceptor;\n\n/**\n * // 比较经典的应用就是在跳转过程中处理登陆事件，这样就不需要在目标页重复做登陆检查\n // 拦截器会在跳转之间执行，多个拦截器会按优先级顺序依次执行\n * Created by chenchangjun on 17/8/9.\n */\n\n@Interceptor(priority = 8, name = \"测试用拦截器\")\npublic class RounterInterceptor implements IInterceptor {\n\n\n\n\n    @Override\n    public void process(Postcard postcard, InterceptorCallback callback) {\n\n        callback.onContinue(postcard);  // 处理完成，交还控制权\n        // callback.onInterrupt(new RuntimeException(\"我觉得有点异常\"));      // 觉得有问题，中断路由流程\n\n        // 以上两种至少需要调用其中一种，否则不会继续路由\n    }\n\n    @Override\n    public void init(Context context) {\n        // 拦截器的初始化，会在sdk初始化的时候调用该方法，仅会调用一次\n\n    }\n}\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/utils/router/RounterSerialization.java",
    "content": "package com.ccj.base.utils.router;\n\nimport android.content.Context;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\nimport com.alibaba.android.arouter.facade.service.SerializationService;\n\nimport java.lang.reflect.Type;\n\n/**\n * Created by chenchangjun on 17/8/9.\n */\n@Route(path = \"/router/RounterSerialization\")\npublic class RounterSerialization implements SerializationService {\n\n\n    @Override\n    public <T> T json2Object(String json, Class<T> clazz) {\n        return null;\n    }\n\n    @Override\n    public String object2Json(Object instance) {\n        return null;\n    }\n\n    /**\n     * Parse json to object\n     *\n     * @param input json string\n     * @param clazz object type\n     * @return instance of object\n     */\n    @Override\n    public <T> T parseObject(String input, Type clazz) {\n        return null;\n    }\n\n    @Override\n    public void init(Context context) {\n\n    }\n}\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/utils/router/RouterService.java",
    "content": "package com.ccj.base.utils.router;\n\nimport com.alibaba.android.arouter.facade.template.IProvider;\n\n/**\n * Created by chenchangjun on 17/8/9.\n */\n\npublic interface RouterService extends IProvider {\n\n\n    String start(String name);\n\n}\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/utils/router/RouterUtils.java",
    "content": "package com.ccj.base.utils.router;\n\nimport android.app.Activity;\n\nimport com.alibaba.android.arouter.launcher.ARouter;\n\n//https://github.com/alibaba/ARouter\npublic class RouterUtils {\n\n\n\n    public static void inject(Object obj){\n        ARouter.getInstance().inject(obj);\n\n    }\n\n    /**\n     * 跳转\n     * 得到 跳转对象\n     * @param path\n     * @return\n     */\n    public static Object navigation(String path) {\n        // 构建标准的路由请求\n        return  ARouter.getInstance().build(path).navigation();\n    }\n\n\n\n    public void startActivityForResult(Activity activity,String path,int requestCode,String argKey,Object argValue) {\n        ARouter.getInstance().build(path).\n                withObject(argKey, argValue).\n                navigation(activity, requestCode);\n    }\n\n    public void startActivityForCallback() {\n// 使用两个参数的navigation方法，可以获取单次跳转的结果\n        //ARouter.getInstance().build(\"/test/1\").navigation(this, new NavigationCallback() );\n    }\n\n\n}\n\n\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/view/SuperRecyclerView.java",
    "content": "package com.ccj.base.view;\n\nimport android.content.Context;\nimport android.support.v7.widget.LinearLayoutManager;\nimport android.support.v7.widget.RecyclerView;\nimport android.util.AttributeSet;\n\nimport com.ccj.base.R;\nimport com.ccj.base.utils.ToastUtil;\nimport com.ccj.base.view.list.OnAppBarSkipListener;\nimport com.ccj.base.view.list.OnLoadNextListener;\n\n\npublic class SuperRecyclerView extends RecyclerView {\n\n    private OnLoadNextListener mLoadNextListener;\n    private OnAppBarSkipListener mAppBarSkipListener;\n\n    //是否正在加载\n    private boolean isLoading = false;\n    //是否加载到最后\n    private boolean isEnd = false;\n    //没有更多提示是否已显示过\n    private boolean toastHasShown = false;\n\n    private int mActionBarAutoHideSensivity = 0;\n    private int mActionBarAutoHideMinY = 0;\n    private int mActionBarAutoHideSignal = 0;\n\n    public SuperRecyclerView(Context context) {\n        super(context);\n        init();\n    }\n\n    public SuperRecyclerView(Context context, AttributeSet attrs) {\n        super(context, attrs);\n        init();\n    }\n\n    public SuperRecyclerView(Context context, AttributeSet attrs, int defStyle) {\n        super(context, attrs, defStyle);\n        init();\n    }\n\n    public void setOnAppBarSkipListener(OnAppBarSkipListener listener) {\n        mAppBarSkipListener = listener;\n    }\n\n    private void init() {\n\n        addOnScrollListener(new OnScrollListener() {\n            final static int ITEMS_THRESHOLD = 1;\n            int lastFvi = 0;\n\n            @Override\n            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {\n                super.onScrolled(recyclerView, dx, dy);\n                LinearLayoutManager mLayoutManager = (LinearLayoutManager) getLayoutManager();\n                int firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition();\n                if (lastFvi != firstVisibleItem) {\n                    if (lastFvi > 0) {\n                        onMainContentScrolled(firstVisibleItem <= ITEMS_THRESHOLD ? 0 : Integer.MAX_VALUE,\n                                lastFvi - firstVisibleItem > 0 ? Integer.MIN_VALUE : Integer.MAX_VALUE\n                        );\n                    }\n                    lastFvi = firstVisibleItem;\n                }\n                int totalItemCount = mLayoutManager.getItemCount();\n                if (isEnd) {\n                    if (!toastHasShown) {\n                        //加载到最后，判断是否拉到底部\n                        if (!canScrollVertically(1)) {\n                            if (canScrollVertically(-1)) {//只有内容超过一屏时才触发提示\n                                ToastUtil.show( getResources().getString(R.string.no_more));\n                                toastHasShown = true;\n                            }\n                        }\n                    }\n                } else if (!isLoading && mLoadNextListener != null) {\n                    int lastVisibleItem = mLayoutManager.findLastVisibleItemPosition();\n                    //lastVisibleItem >= totalItemCount - 3 表示剩下2个item自动加载(因为包含Banner)\n                    // dy>0 表示向下滑动\n                    if (totalItemCount > 5 && lastVisibleItem >= totalItemCount - 3 && dy > 0) {\n                        isLoading = true;\n                        mLoadNextListener.onLoadNext();\n                    }\n                }\n                //用于防止首页好价的toolbar 因快速的显示隐藏而抖动\n                if (null != mAppBarSkipListener) {\n                    if (firstVisibleItem > ITEMS_THRESHOLD) {\n                        if (Math.abs(dy) < 15) {\n                            mAppBarSkipListener.isSkip(true);\n                        } else {\n                            mAppBarSkipListener.isSkip(false);\n                        }\n                    } else {\n                        mAppBarSkipListener.isSkip(false);\n                    }\n                }\n            }\n        });\n        initActionBarAutoHide();\n    }\n\n    public void setLoadNextListener(OnLoadNextListener listener) {\n        mLoadNextListener = listener;\n    }\n\n    public void setLoadingState(boolean isLoading) {\n        this.isLoading = isLoading;\n    }\n\n    public boolean getLoadingState() {\n        return isLoading;\n    }\n\n    /**\n     * 设置是否加载到最后\n     *\n     * @param isEnd true:不再触发翻页 false:正常翻页\n     */\n    public void setLoadToEnd(boolean isEnd) {\n        if (!isEnd) {\n            //列表已刷新，重置toastHasShown状态\n            toastHasShown = false;\n        }\n        this.isEnd = isEnd;\n    }\n\n    /**\n     * Initializes the Action Bar auto-hide (aka Quick Recall) effect.\n     */\n    protected void initActionBarAutoHide() {\n        mActionBarAutoHideMinY = getResources().getDimensionPixelSize(\n                R.dimen.action_bar_auto_hide_min_y);\n        mActionBarAutoHideSensivity = getResources().getDimensionPixelSize(\n                R.dimen.action_bar_auto_hide_sensivity);\n    }\n\n    /**\n     * Copied from google io 2014 by Aidi\n     * Indicates that the main content has scrolled (for the purposes of showing/hiding\n     * the action bar for the \"action bar auto hide\" effect). currentY and deltaY may be exact\n     * (if the underlying view supports it) or may be approximate indications:\n     * deltaY may be INT_MAX to mean \"scrolled forward indeterminately\" and INT_MIN to mean\n     * \"scrolled backward indeterminately\".  currentY may be 0 to mean \"somewhere close to the\n     * start of the list\" and INT_MAX to mean \"we don't know, but not at the start of the list\"\n     */\n    public void onMainContentScrolled(int currentY, int deltaY) {\n        if (mLoadNextListener != null) {\n            if (deltaY > mActionBarAutoHideSensivity) {\n                deltaY = mActionBarAutoHideSensivity;\n            } else if (deltaY < -mActionBarAutoHideSensivity) {\n                deltaY = -mActionBarAutoHideSensivity;\n            }\n\n            if (Math.signum(deltaY) * Math.signum(mActionBarAutoHideSignal) < 0) {\n                // deltaY is a motion opposite to the accumulated signal, so reset signal\n                mActionBarAutoHideSignal = deltaY;\n            } else {\n                // add to accumulated signal\n                mActionBarAutoHideSignal += deltaY;\n            }\n            boolean shouldShow = currentY < mActionBarAutoHideMinY ||\n                    (mActionBarAutoHideSignal <= -mActionBarAutoHideSensivity);\n            mLoadNextListener.autoShowOrHideToolbar(shouldShow);\n        }\n    }\n\n}\n"
  },
  {
    "path": "base/src/main/java/com/ccj/base/view/list/OnAppBarSkipListener.java",
    "content": "package com.ccj.base.view.list;\n\n\n/**\n * 控制监听好价 toolbar显示隐藏抖动\n */\npublic interface OnAppBarSkipListener {\n    void isSkip(boolean iskip);\n\n}"
  },
  {
    "path": "base/src/main/java/com/ccj/base/view/list/OnLoadNextListener.java",
    "content": "package com.ccj.base.view.list;\n\n/**\n */\npublic interface OnLoadNextListener {\n    public void onLoadNext();\n    public void autoShowOrHideToolbar(boolean show);\n}\n"
  },
  {
    "path": "base/src/main/res/anim/anim_bottom_in.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<translate xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:fromXDelta=\"0%\"\n    android:toXDelta=\"0%\"\n    android:fromYDelta=\"100%\"\n    android:toYDelta=\"0%\"\n    android:duration=\"500\">\n\n</translate>\n"
  },
  {
    "path": "base/src/main/res/anim/anim_bottom_out.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<translate xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:fromXDelta=\"0%\"\n    android:toXDelta=\"0%\"\n    android:fromYDelta=\"00%\"\n    android:toYDelta=\"100%\"\n    android:duration=\"500\">\n\n</translate>\n"
  },
  {
    "path": "base/src/main/res/anim/dialog_enter.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\" >\n\n    <translate\n        android:duration=\"500\"\n        android:toYDelta=\"0%\"\n        android:fillAfter=\"true\"\n        android:fromYDelta=\"100%p\" />\n\n</set>"
  },
  {
    "path": "base/src/main/res/anim/dialog_exit.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\" >\n\n    <translate\n        android:duration=\"500\"\n        android:fromYDelta=\"0%\"\n        android:fillAfter=\"true\"\n        android:toYDelta=\"100%p\" />\n\n</set>"
  },
  {
    "path": "base/src/main/res/anim/footer_menu_slide_in.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<translate xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:duration=\"120\"\n    android:fromYDelta=\"100%\"\n    android:startOffset=\"120\"\n    android:interpolator=\"@android:anim/accelerate_interpolator\"\n    android:toYDelta=\"0%\" />\n"
  },
  {
    "path": "base/src/main/res/anim/footer_menu_slide_out.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<translate xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:duration=\"120\"\n    android:fromYDelta=\"0%\"\n    android:interpolator=\"@android:anim/accelerate_interpolator\"\n    android:toYDelta=\"100%\" />\n"
  },
  {
    "path": "base/src/main/res/anim/in_from_bottom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:interpolator=\"@android:anim/accelerate_interpolator\" >\n\n    <translate\n        android:duration=\"400\"\n        android:fromYDelta=\"100%p\"\n        android:toYDelta=\"0%p\" />  \n\n</set>"
  },
  {
    "path": "base/src/main/res/anim/in_from_top.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:interpolator=\"@android:anim/accelerate_interpolator\" >\n\n    <translate\n        android:duration=\"400\"\n        android:fromYDelta=\"-100%p\"\n        android:toYDelta=\"0%p\" />  \n\n</set>"
  },
  {
    "path": "base/src/main/res/anim/out_to_bottom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:interpolator=\"@android:anim/accelerate_interpolator\" >\n\n    <translate\n        android:duration=\"400\"\n        android:fromYDelta=\"0%p\"\n        android:toYDelta=\"100%p\" />  \n\n</set>"
  },
  {
    "path": "base/src/main/res/anim/out_to_top.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:interpolator=\"@android:anim/accelerate_interpolator\" >\n\n    <translate\n        android:duration=\"400\"\n        android:fromYDelta=\"0%p\"\n        android:toYDelta=\"-100%p\" />\n\n</set>"
  },
  {
    "path": "base/src/main/res/drawable/bg_toolbar.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layer-list xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item>\n        <shape android:shape=\"rectangle\">\n            <stroke\n                android:width=\"1px\"\n                android:color=\"@color/colordc\"/>\n        </shape>\n    </item>\n    <item\n        android:bottom=\"1px\">\n        <shape android:shape=\"rectangle\">\n            <solid android:color=\"@android:color/white\"/>\n        </shape>\n    </item>\n</layer-list>"
  },
  {
    "path": "base/src/main/res/drawable/btn_ripple.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item android:state_enabled=\"false\">\n        <shape>\n            <corners android:radius=\"2dp\"></corners>\n            <solid android:color=\"@color/app_bg\"></solid>\n        </shape>\n    </item>\n    <item android:state_pressed=\"true\">\n        <shape>\n            <corners android:radius=\"2dp\"></corners>\n            <solid android:color=\"@color/btn_blue_bg_press\"></solid>\n        </shape>\n    </item>\n    <item android:state_pressed=\"false\">\n        <shape>\n            <corners android:radius=\"2dp\"></corners>\n            <solid android:color=\"@color/btn_blue_bg_press\"></solid>\n        </shape>\n    </item>\n</selector>"
  },
  {
    "path": "base/src/main/res/layout/base_layout_tool_bar.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<android.support.v7.widget.Toolbar xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:id=\"@+id/toolbar\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"?attr/actionBarSize\"\n    android:background=\"?attr/colorPrimary\">\n\n    <TextView\n        android:id=\"@+id/toolbar_title\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:layout_gravity=\"center\"\n        android:background=\"?attr/colorPrimary\"\n        android:gravity=\"center\"\n        android:textColor=\"@color/white\"\n        android:textSize=\"20sp\" />\n</android.support.v7.widget.Toolbar>\n"
  },
  {
    "path": "base/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"colorPrimaryDark\">#303F9F</color>\n    <color name=\"colorAccent\">#FF4081</color>\n\n\n    <!-- <color name=\"colorPrimary\">#FF03A9F4</color>\n     <color name=\"colorPrimaryDark\">#ff0171c9</color>\n     <color name=\"colorAccent\">#FF00E5FF</color>-->\n    <color name=\"colorControlNormal\">#FF78909C</color>\n    <color name=\"colorControlActivated\">#FF03A9F4</color>\n    <color name=\"colorSwitchThumbNormal\">#FF78909C</color>\n    <color name=\"primary\">#FF03A9F4</color>\n    <color name=\"primary_dark\">#FF0288D1</color>\n    <color name=\"status_bar_color\">@color/primary_dark</color>\n\n\n    <color name=\"red_dark\">#bc1717</color>\n    <color name=\"red_bg\">#dd4b39</color>\n    <color name=\"window_bg\">@android:color/white</color>\n    <color name=\"btn_blue_bg\">#6699ff</color>\n    <color name=\"btn_blue_bg_press\">#3366cc</color>\n    <color name=\"app_bg\">#f2f2f2</color>\n    <color name=\"touming_bg\">#00000000</color>\n    <color name=\"yellow\">#ffcc00</color>\n\n    <color name=\"white\">@android:color/white</color>\n    <color name=\"black\">@android:color/black</color>\n    <color name=\"blue\" >#2b8cff</color>\n    <color name=\"red\"> #ff3824</color>\n    <color name=\"btn_dark\">#929292</color>\n    <color name=\"menu_bg\">#f8f8f9</color>\n    <color name=\"border_dark\">#c9c9c9</color>\n    <color name=\"shallow_blue\">#70dbdb</color>\n    <color name=\"item_click_bg_color\">#dddddd</color>\n    <color name=\"tans\">#00000000</color>\n\n\n    <color name=\"tool_bar_white\">@android:color/white</color>\n    <color name=\"colordc\">#dcdcdc</color>\n\n</resources>\n"
  },
  {
    "path": "base/src/main/res/values/dimens.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n\n\n    <dimen name=\"activity_horizontal_margin\">16dp</dimen>\n    <dimen name=\"activity_vertical_margin\">16dp</dimen>\n\n\n    <dimen name=\"action_bar_auto_hide_min_y\">100dp</dimen>\n    <dimen name=\"action_bar_auto_hide_sensivity\">48dp</dimen>\n\n\n    <!--margin or padding-->\n    <dimen name=\"space_8\">8.0dip</dimen>\n    <dimen name=\"small_container_padding\">5dp</dimen>\n    <dimen name=\"common_container_padding\">10dp</dimen>\n    <dimen name=\"medium_container_padding\">20dp</dimen>\n    <dimen name=\"large_container_padding\">30dp</dimen>\n    <dimen name=\"min_container_padding\">2dp</dimen>\n    <dimen name=\"large_top_margin\">80dp</dimen>\n    <dimen name=\"common_dark_border\">2dp</dimen>\n    <dimen name=\"small_dark_border\">1dp</dimen>\n\n    <dimen name=\"radius\">5dp</dimen>\n    <dimen name=\"large_radius\">10dp</dimen>\n\n    <dimen name=\"small_text_size\">16sp</dimen>\n    <dimen name=\"common_text_size\">18sp</dimen>\n    <dimen name=\"large_text_size\">22sp</dimen>\n\n    <dimen name=\"msg_pic_width\">400dp</dimen>\n    <dimen name=\"msg_pic_high\">200dp</dimen>\n    <dimen name=\"text_medium_size\">18sp</dimen>\n\n</resources>"
  },
  {
    "path": "base/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">Android组件化</string>\n    <string name=\"no_more\">没有更多了</string>\n\n\n    <!-- Error View -->\n    <string name=\"error_view_click_to_refresh\">点击屏幕,重新加载</string>\n    <string name=\"error_view_no_data\">暂无内容</string>\n    <string name=\"error_view_loading\">加载中…</string>\n    <string name=\"error_view_load_error_click_to_refresh\">内容加载失败\\r\\n点击重新加载</string>\n    <string name=\"error_view_network_error_click_to_refresh\">没有可用的网络</string>\n    <string name=\"tip_network_error\">没有可用的网络</string>\n    <string name=\"show_loading_msg\" >正在加载...</string>\n\n</resources>\n"
  },
  {
    "path": "base/src/main/res/values/styles.xml",
    "content": "<resources>\n\n\n    <style name=\"BaseAppTheme\" parent=\"Theme.AppCompat.Light.NoActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n\n        <!-- colorAccent is used as the default value for colorControlActivated\n          which is used to tint widgets -->\n        <!--<item name=\"android:windowActionBar\">false</item>\n        <item name=\"windowActionBar\">false</item>\n        <item name=\"windowNoTitle\">true</item>-->\n        <item name=\"android:windowBackground\">@android:color/transparent</item>\n\n        <item name=\"android:textColor\">@color/black</item>\n        <item name=\"android:textCursorDrawable\">@null</item>\n        <item name=\"android:editTextColor\">@color/black</item>\n        <item name=\"android:textColorHint\">@color/border_dark</item>\n        <item name=\"android:dialogTheme\">@android:style/Widget.ProgressBar</item>\n    </style>\n    <style name=\"AppTheme.NoActionBar\">\n        <item name=\"windowActionBar\">false</item>\n        <item name=\"windowNoTitle\">true</item>\n    </style>\n\n    <style name=\"AppTheme.AppBarOverlay\" parent=\"ThemeOverlay.AppCompat.Dark.ActionBar\" />\n\n    <style name=\"AppTheme.PopupOverlay\" parent=\"ThemeOverlay.AppCompat.Light\" />\n\n\n\n\n\n    <style name=\"AppTheme.Light\" parent=\"AppTheme\">\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n        <item name=\"colorControlNormal\">@color/colorControlNormal</item>\n        <item name=\"colorControlActivated\">@color/colorPrimary</item>\n        <item name=\"colorSwitchThumbNormal\">@color/colorSwitchThumbNormal</item>\n    </style>\n\n    <style name=\"appStartTheme\" parent=\"AppTheme.NoActionBar\">\n        <item name=\"android:windowBackground\">@mipmap/login_bg</item>\n    </style>\n\n\n\n\n    <!-- 全透明的背景 -->\n    <style name=\"Theme.Transparent\" parent=\"@android:style/Theme\">\n        <item name=\"android:windowBackground\">@android:color/transparent</item>\n        <item name=\"android:windowNoTitle\">true</item>\n        <item name=\"android:windowIsFloating\">true</item>\n        <item name=\"android:windowIsTranslucent\">true</item>\n        <item name=\"android:windowContentOverlay\">@null</item>\n        <item name=\"android:backgroundDimEnabled\">false</item>\n    </style>\n\n\n\n</resources>\n"
  },
  {
    "path": "base/src/test/java/com/ccj/base/ExampleUnitTest.java",
    "content": "package com.ccj.base;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() throws Exception {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n    repositories {\n        jcenter()\n        //butterknife\n        mavenCentral()\n        maven {\n            url 'https://maven.google.com/'\n            name 'Google'\n        }\n    }\n    dependencies {\n        classpath 'com.android.tools.build:gradle:2.3.2'\n\n        //butterknife\n        classpath 'com.jakewharton:butterknife-gradle-plugin:8.4.0'\n    }\n}\n\nallprojects {\n    repositories {\n        jcenter()\n        maven {\n            url 'https://maven.google.com/'\n            name 'Google'\n        }\n    }\n}\n\ntask clean(type: Delete) {\n    delete rootProject.buildDir\n}\n\n\ndef androidSupportVersion = '25.3.1'\ndef butterknifeVersion = '8.4.0'\n\n\n// Define versions in a single place\n//时间：2017.2.13；每次修改版本号都要添加修改时间\next {\n    // Sdk and tools\n    //localBuildToolsVersion是gradle.properties中的数据\n    buildToolsVersion = localBuildToolsVersion\n    compileSdkVersion = 25\n    minSdkVersion = 16\n    targetSdkVersion = 25\n    versionCode = 1\n    versionName = \"1.0\"\n    javaVersion = JavaVersion.VERSION_1_8\n\n    // App dependencies version\n    appcompatV7 = \"com.android.support:appcompat-v7:$androidSupportVersion\"\n    constraintLayout = 'com.android.support.constraint:constraint-layout:1.0.2'\n\n    eventbusVersion = \"3.0.0\"\n\n    //arouter\n    arouterApi = 'com.alibaba:arouter-api:1.3.1'\n    arouterCompiler = 'com.alibaba:arouter-compiler:1.1.4'\n\n    //butterknife\n    butterknife = \"com.jakewharton:butterknife:$butterknifeVersion\"\n    butterknifeCompiler = \"com.jakewharton:butterknife-compiler:$butterknifeVersion\"\n\n    //eventbusVersion\n    eventbus= \"org.greenrobot:eventbus:$eventbusVersion\"\n\n    cookieVersion = \"v1.0.1\"\n    toastyVersion = \"1.1.3\"\n\n\n}"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "content": "#Mon Dec 28 10:00:20 PST 2015\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-3.3-all.zip\n"
  },
  {
    "path": "gradle.properties",
    "content": "## Project-wide Gradle settings.\n#\n# For more details on how to configure your build environment visit\n# http://www.gradle.org/docs/current/userguide/build_environment.html\n#\n# Specifies the JVM arguments used for the daemon process.\n# The setting is particularly useful for tweaking memory settings.\n# Default value: -Xmx10248m -XX:MaxPermSize=256m\n #org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8\n#\n# When configured, Gradle will run in incubating parallel mode.\n# This option should only be used with decoupled projects. More details, visit\n# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects\n# org.gradle.parallel=true\n#Tue Jul 05 10:55:37 CST 2016\n\nlocalBuildToolsVersion=25.0.3\nlocalGradlePluginVersion=2.3.3\n\n\n# true代表模块开发,false代表合并到主app.\nisModule=true"
  },
  {
    "path": "gradlew",
    "content": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn ( ) {\n    echo \"$*\"\n}\n\ndie ( ) {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\nesac\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules\nfunction splitJvmOpts() {\n    JVM_OPTS=(\"$@\")\n}\neval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\nJVM_OPTS[${#JVM_OPTS[*]}]=\"-Dorg.gradle.appname=$APP_BASE_NAME\"\n\nexec \"$JAVACMD\" \"${JVM_OPTS[@]}\" -classpath \"$CLASSPATH\" org.gradle.wrapper.GradleWrapperMain \"$@\"\n"
  },
  {
    "path": "gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif \"%ERRORLEVEL%\" == \"0\" goto init\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto init\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:init\n@rem Get command-line arguments, handling Windowz variants\n\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\nif \"%@eval[2+2]\" == \"4\" goto 4NT_args\n\n:win9xME_args\n@rem Slurp the command line arguments.\nset CMD_LINE_ARGS=\nset _SKIP=2\n\n:win9xME_args_slurp\nif \"x%~1\" == \"x\" goto execute\n\nset CMD_LINE_ARGS=%*\ngoto execute\n\n:4NT_args\n@rem Get arguments from the 4NT Shell from JP Software\nset CMD_LINE_ARGS=%$\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\n\n:end\n@rem End local scope for the variables with windows NT shell\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\nexit /b 1\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "module_home/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "module_home/build.gradle",
    "content": "\nif (isModule.toBoolean()) {\n    apply plugin: 'com.android.application'\n} else {\n    apply plugin: 'com.android.library'\n}\n//butterknife\napply plugin: 'com.jakewharton.butterknife'\n\nandroid {\n    compileSdkVersion rootProject.ext.compileSdkVersion\n    buildToolsVersion rootProject.ext.buildToolsVersion\n\n    defaultConfig {\n\n        if (isModule.toBoolean()) {\n            applicationId \"com.ccj.home\"\n        }\n\n        minSdkVersion rootProject.ext.minSdkVersion\n        targetSdkVersion rootProject.ext.targetSdkVersion\n        versionCode rootProject.ext.versionCode\n        versionName rootProject.ext.versionName\n\n\n        // resourcePrefix \"haojia_\"\n\n\n        //arouter\n        javaCompileOptions {\n            annotationProcessorOptions {\n                arguments = [moduleName: project.getName()]\n            }\n        }\n    }\n\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n    sourceSets {\n        main {\n            if (isModule.toBoolean()) {\n                manifest.srcFile 'src/main/AndroidManifest.xml'\n            } else {\n                manifest.srcFile 'src/main/release/AndroidManifest.xml'\n                java {\n                    exclude 'debug/**'\n                }\n            }\n        }\n    }\n\n}\n\ndependencies {\n    compile fileTree(dir: 'libs', include: ['*.jar'])\n\n\n    //butterknife\n    annotationProcessor rootProject.ext.butterknifeCompiler\n\n    //arouter\n    compile rootProject.ext.arouterApi\n    annotationProcessor rootProject.ext.arouterCompiler\n\n    compile project(':base')\n\n}\n\n\n\n"
  },
  {
    "path": "module_home/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "module_home/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.ccj.home\">\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/AppTheme\">\n        <activity android:name=\".MainActivity\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n    </application>\n\n</manifest>"
  },
  {
    "path": "module_home/src/main/java/com/ccj/home/HomeFragment.java",
    "content": "package com.ccj.home;\n\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.support.annotation.Nullable;\nimport android.support.v4.app.Fragment;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.Button;\nimport android.widget.TextView;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\nimport com.alibaba.android.arouter.launcher.ARouter;\nimport com.ccj.base.Constants;\nimport com.ccj.base.RouterConstants;\nimport com.ccj.base.base.BaseApplication;\n\n/**\n * Created by chenchangjun on 18/1/25.\n */\n@Route(path = RouterConstants.HOME_MUDULE_FRAGMENT_HOME_HOME)\npublic class HomeFragment extends Fragment implements View.OnClickListener {\n\n\n    TextView button;\n    Button button2;\n    Button button3;\n    Button button4;\n    private View view;\n\n    @Nullable\n    @Override\n    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {\n        if (view == null) {\n            view = inflater.inflate(R.layout.home_fragment_haojia_home, null);\n        }\n        return view;\n    }\n\n    @Override\n    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {\n        super.onViewCreated(view, savedInstanceState);\n        button2= (Button) view.findViewById(R.id.button2);\n        button3= (Button) view.findViewById(R.id.button3);\n        button4= (Button) view.findViewById(R.id.button4);\n\n        button2.setOnClickListener(this);\n        button3.setOnClickListener(this);\n        button4.setOnClickListener(this);\n\n    }\n\n\n\n    /**\n     * Called when a view has been clicked.\n     *\n     * @param v The view that was clicked.\n     */\n    @Override\n    public void onClick(View v) {\n        int i = v.getId();\n        if (i == R.id.button2) {\n            navigateToLogin();\n        } else if (i == R.id.button3) {\n            navigateMeiziDetail();\n        } else if (i == R.id.button4) {\n            navigateTakePhoto();\n\n        }\n    }\n\n\n\n\n    private void navigateMeiziDetail() {\n        ARouter.getInstance().build(RouterConstants.MEIZI_MUDULE_ACTIVITY_MEIZI_DETAIL).\n                withString(Constants.PARAMS_REQUEST_FOR_DETAIL, \"http://7xi8d6.com1.z0.glb.clouddn.com/20180129074038_O3ydq4_Screenshot.jpeg\").\n                navigation(getActivity());\n\n    }\n\n\n    private void navigateToLogin() {\n        ARouter.getInstance().build(RouterConstants.USER_MOUDLE_ACTIVITY).\n                withString(Constants.START_LOGIN_WITH_PARAMS, \"I am params from HomeFragment\").\n                navigation(getActivity(), Constants.REQUEST_START_LOGIN);\n    }\n\n    private void navigateTakePhoto() {\n        ARouter.getInstance().\n                build(RouterConstants.VIDEO_MUDULE_ACTIVITY).\n                withString(Constants.START_LOGIN_WITH_PARAMS, \"I am params from HomeFragment\").\n                navigation();\n\n    }\n\n\n    @Override\n    public void onActivityResult(int requestCode, int resultCode, Intent data) {\n        super.onActivityResult(requestCode, resultCode, data);\n        if (requestCode == Constants.REQUEST_START_LOGIN) {\n\n            if (data == null) {\n                return;\n            }\n            String str = data.getStringExtra(Constants.PARAMS_RESULT_FROM_LOGIN);\n\n            if (str == null) {\n                return;\n            }\n\n            button.setText(str);\n            BaseApplication.showToast(str);\n        }\n\n    }\n\n}"
  },
  {
    "path": "module_home/src/main/java/com/ccj/home/MainActivity.java",
    "content": "package com.ccj.home;\n\nimport android.os.Bundle;\nimport android.support.v7.app.AppCompatActivity;\n\npublic class MainActivity extends AppCompatActivity {\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_main);\n    }\n}\n"
  },
  {
    "path": "module_home/src/main/release/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\" package=\"com.ccj.home\">\n\n    <application android:allowBackup=\"true\"\n        android:supportsRtl=\"true\" android:theme=\"@style/AppTheme\">\n        <activity android:name=\"com.smzdm.client.home.MainActivity\"></activity>\n    </application>\n\n</manifest>"
  },
  {
    "path": "module_home/src/main/res/drawable/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillColor=\"#26A69A\"\n        android:pathData=\"M0,0h108v108h-108z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9,0L9,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,0L19,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,0L29,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,0L39,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,0L49,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,0L59,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,0L69,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,0L79,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M89,0L89,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M99,0L99,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,9L108,9\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,19L108,19\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,29L108,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,39L108,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,49L108,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,59L108,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,69L108,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,79L108,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,89L108,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,99L108,99\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,29L89,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,39L89,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,49L89,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,59L89,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,69L89,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,79L89,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,19L29,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,19L39,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,19L49,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,19L59,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,19L69,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,19L79,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n</vector>\n"
  },
  {
    "path": "module_home/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillType=\"evenOdd\"\n        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\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\">\n        <aapt:attr name=\"android:fillColor\">\n            <gradient\n                android:endX=\"78.5885\"\n                android:endY=\"90.9159\"\n                android:startX=\"48.7653\"\n                android:startY=\"61.0927\"\n                android:type=\"linear\">\n                <item\n                    android:color=\"#44000000\"\n                    android:offset=\"0.0\" />\n                <item\n                    android:color=\"#00000000\"\n                    android:offset=\"1.0\" />\n            </gradient>\n        </aapt:attr>\n    </path>\n    <path\n        android:fillColor=\"#FFFFFF\"\n        android:fillType=\"nonZero\"\n        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\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\" />\n</vector>\n"
  },
  {
    "path": "module_home/src/main/res/layout/activity_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.constraint.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    tools:context=\"com.smzdm.client.home.MainActivity\">\n\n    <TextView\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"Module Home Hello World! \"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintLeft_toLeftOf=\"parent\"\n        app:layout_constraintRight_toRightOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"parent\" />\n\n</android.support.constraint.ConstraintLayout>\n"
  },
  {
    "path": "module_home/src/main/res/layout/home_fragment_haojia_home.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n\n    <TextView\n        android:id=\"@+id/button\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_alignParentTop=\"true\"\n        android:layout_centerHorizontal=\"true\"\n        android:layout_gravity=\"center\"\n        android:layout_marginTop=\"32dp\"\n        android:text=\"首页\" />\n\n    <Button\n        android:id=\"@+id/button2\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_below=\"@+id/button\"\n        android:layout_centerHorizontal=\"true\"\n        android:layout_marginTop=\"33dp\"\n        android:text=\"带参-跳转--用户--登录--返回值\" />\n\n    <Button\n        android:id=\"@+id/button3\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_alignLeft=\"@+id/button2\"\n        android:layout_alignStart=\"@+id/button2\"\n        android:layout_below=\"@+id/button2\"\n        android:layout_marginTop=\"29dp\"\n        android:text=\"带参-跳转--妹子--详情\" />\n\n    <Button\n        android:id=\"@+id/button4\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_alignLeft=\"@+id/button3\"\n        android:layout_alignStart=\"@+id/button3\"\n        android:layout_centerVertical=\"true\"\n        android:text=\"跳转--拍照--\" />\n\n</RelativeLayout>"
  },
  {
    "path": "module_home/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "module_home/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "module_home/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"colorPrimaryDark\">#303F9F</color>\n    <color name=\"colorAccent\">#FF4081</color>\n</resources>\n"
  },
  {
    "path": "module_home/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">module_home</string>\n</resources>\n"
  },
  {
    "path": "module_home/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "module_meizi/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "module_meizi/build.gradle",
    "content": "\nif (isModule.toBoolean()) {\n    apply plugin: 'com.android.application'\n} else {\n    apply plugin: 'com.android.library'\n}\n//butterknife\napply plugin: 'com.jakewharton.butterknife'\n\nandroid {\n    compileSdkVersion rootProject.ext.compileSdkVersion\n    buildToolsVersion rootProject.ext.buildToolsVersion\n\n    defaultConfig {\n\n        if (isModule.toBoolean()) {\n            applicationId \"com.ccj.meizi\"\n        }\n\n        minSdkVersion rootProject.ext.minSdkVersion\n        targetSdkVersion rootProject.ext.targetSdkVersion\n        versionCode rootProject.ext.versionCode\n        versionName rootProject.ext.versionName\n\n\n        // resourcePrefix \"user_\"\n\n\n        //arouter\n        javaCompileOptions {\n            annotationProcessorOptions {\n                arguments = [moduleName: project.getName()]\n            }\n        }\n    }\n\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n    sourceSets {\n        main {\n            if (isModule.toBoolean()) {\n                manifest.srcFile 'src/main/AndroidManifest.xml'\n            } else {\n                manifest.srcFile 'src/main/release/AndroidManifest.xml'\n                java {\n                    exclude 'debug/**'\n                }\n            }\n        }\n    }\n\n}\n\ndependencies {\n    compile fileTree(dir: 'libs', include: ['*.jar'])\n\n\n    //butterknife\n    annotationProcessor rootProject.ext.butterknifeCompiler\n\n    //arouter\n    compile rootProject.ext.arouterApi\n    annotationProcessor rootProject.ext.arouterCompiler\n\n    compile project(':base')\n\n}\n\n\n\n"
  },
  {
    "path": "module_meizi/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "module_meizi/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.ccj.meizi\">\n\n    <application\n        android:name=\"com.ccj.base.base.BaseApplication\"\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/AppTheme\">\n        <activity android:name=\".debug.MainActivity\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n\n\n        <activity android:name=\".debug.ContainActivity\" android:theme=\"@style/AppTheme.NoActionBar\"></activity>\n\n        <activity android:name=\".ui.detail.MeiziDetailActivity\"></activity>\n\n    </application>\n\n</manifest>"
  },
  {
    "path": "module_meizi/src/main/java/com/ccj/meizi/adapter/MeiziRcvAdapter.java",
    "content": "package com.ccj.meizi.adapter;\n\nimport android.app.Activity;\nimport android.support.annotation.NonNull;\nimport android.support.annotation.Nullable;\nimport android.util.Log;\n\nimport com.ccj.base.adapter.CommonRcvAdapter;\nimport com.ccj.base.adapter.bean.AdapterBean;\nimport com.ccj.base.adapter.item.AdapterItem;\nimport com.ccj.meizi.holder.MeiziItemHolder;\n\nimport java.util.List;\n\n\npublic class MeiziRcvAdapter extends CommonRcvAdapter<AdapterBean> {\n\n\n    private static final String TAG = \"MeiziRcvAdapter\";\n\n    public MeiziRcvAdapter(@Nullable List data, Activity mActivity) {\n        super(data, mActivity);\n    }\n\n\n    /**\n     * 根据getCell_type得到 VIEW_TYPE\n     *\n     * @param demoModel\n     * @return\n     */\n    @Override\n    public Object getItemType(AdapterBean demoModel) {\n        return demoModel.getCell_type();\n\n    }\n\n    /**\n     * 根据viewType创建Holder\n     *\n     * @param type 通过{@link #getItemType(Object)}得到的type\n     * @return\n     */\n    @NonNull\n    @Override\n    public AdapterItem createItem(Object type) {\n        Log.d(TAG, \"createItem \" + type + \" view\");\n        return new MeiziItemHolder( mActivity);\n\n    }\n}\n"
  },
  {
    "path": "module_meizi/src/main/java/com/ccj/meizi/api/MeiziAPIServiceImp.java",
    "content": "package com.ccj.meizi.api;\n\nimport com.ccj.base.api.APIService;\nimport com.ccj.base.utils.TLog;\nimport com.ccj.meizi.bean.Meizhi;\n\nimport rx.Observable;\n\n/**\n * 继承\n * Created by chenchangjun on 17/8/10.\n */\n\npublic class MeiziAPIServiceImp extends APIService {\n\n\n    protected static final MeiziRetrofitImp apiManager = sRetrofit.create(MeiziRetrofitImp.class);\n\n    /**\n     * @return\n     */\n    public static Observable<Meizhi> getMeiZhi(String date) {\n        Observable<Meizhi> ss = apiManager.getMeiZhi( date);\n        TLog.logI(date);\n        return  ss;\n    }\n\n\n\n    /**\n     * @return\n     */\n    public static Observable<Meizhi> getMeiZhi() {\n        Observable<Meizhi> ss = apiManager.getMeiZhi( );\n        return  ss;\n    }\n}\n"
  },
  {
    "path": "module_meizi/src/main/java/com/ccj/meizi/api/MeiziRetrofitImp.java",
    "content": "package com.ccj.meizi.api;\n\n\nimport com.ccj.meizi.bean.Meizhi;\n\nimport retrofit2.http.GET;\nimport retrofit2.http.Path;\nimport rx.Observable;\n\n/**\n * Created by chenchangjun on 17/8/10.\n */\n\npublic interface MeiziRetrofitImp {\n\n    @GET(\"/api/data/福利/{date}\")\n    Observable<Meizhi> getMeiZhi(@Path(\"date\") String date);\n\n\n\n    @GET(\"/api/random/data/福利/10\")\n    Observable<Meizhi> getMeiZhi();\n}\n"
  },
  {
    "path": "module_meizi/src/main/java/com/ccj/meizi/bean/Meizhi.java",
    "content": "package com.ccj.meizi.bean;\n\nimport com.ccj.base.adapter.bean.AdapterBean;\nimport com.google.gson.Gson;\n\nimport java.util.List;\n\n/**\n * Created by Administrator on 2016/10/31.\n */\n\npublic class Meizhi {\n\n    /**\n     * error : false\n     * 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\":\"代码家\"}]\n     */\n\n    public boolean error;\n    /**\n     * _id : 5816871a421aa91369f959b6\n     * createdAt : 2016-10-31T07:49:46.592Z\n     * desc : 10-31\n     * publishedAt : 2016-10-31T11:43:44.770Z\n     * source : chrome\n     * type : 福利\n     * url : http://ww2.sinaimg.cn/large/610dc034jw1f9b46kpoeoj20ku0kuwhc.jpg\n     * used : true\n     * who : daimajia\n     */\n\n    public List<MeiziItemBean> results;\n\n    public static Meizhi objectFromData(String str) {\n\n        return new Gson().fromJson(str, Meizhi.class);\n    }\n\n    public static class MeiziItemBean extends AdapterBean {\n        public String _id;\n        public String createdAt;\n        public String desc;\n        public String publishedAt;\n        public String source;\n        public String type;\n        public String url;\n        public boolean used;\n        public String who;\n\n        public static MeiziItemBean objectFromData(String str) {\n\n            return new Gson().fromJson(str, MeiziItemBean.class);\n        }\n\n        @Override\n        public String toString() {\n            return \"MeiziItemBean{\" +\n                    \"_id='\" + _id + '\\'' +\n                    \", createdAt='\" + createdAt + '\\'' +\n                    \", desc='\" + desc + '\\'' +\n                    \", publishedAt='\" + publishedAt + '\\'' +\n                    \", source='\" + source + '\\'' +\n                    \", type='\" + type + '\\'' +\n                    \", url='\" + url + '\\'' +\n                    \", used=\" + used +\n                    \", who='\" + who + '\\'' +\n                    '}';\n        }\n\n        @Override\n        public void setCell_type(int cell_type) {\n            \n        }\n\n        @Override\n        public int getCell_type() {\n            return 0;\n        }\n    }\n\n    @Override\n    public String toString() {\n        return \"Meizhi{\" +\n                \"error=\" + error +\n                \", results=\" + results +\n                '}';\n    }\n}\n"
  },
  {
    "path": "module_meizi/src/main/java/com/ccj/meizi/debug/ContainActivity.java",
    "content": "package com.ccj.meizi.debug;\n\nimport android.os.Bundle;\n\nimport com.ccj.base.base.BaseActivity;\nimport com.ccj.meizi.R;\nimport com.ccj.meizi.ui.main.MeiZhiFragment;\n\n/**\n * Created by chenchangjun on 18/1/31.\n */\n\npublic class ContainActivity  extends BaseActivity{\n\n\n    @Override\n    public void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_contain);\n        initFragment();\n    }\n\n\n\n    private void initFragment() {\n        MeiZhiFragment fragment = new MeiZhiFragment();\n        getSupportFragmentManager()\n                .beginTransaction()\n                .replace(R.id.detail_contain, fragment).commitAllowingStateLoss();\n\n    }\n}\n"
  },
  {
    "path": "module_meizi/src/main/java/com/ccj/meizi/debug/MainActivity.java",
    "content": "package com.ccj.meizi.debug;\n\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.support.v7.app.AppCompatActivity;\nimport android.view.View;\n\nimport com.ccj.meizi.R;\n\npublic class MainActivity extends AppCompatActivity {\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_main);\n\n        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View v) {\n                startActivity(new Intent(MainActivity.this,ContainActivity.class));\n            }\n        });\n    }\n\n\n\n\n\n}\n"
  },
  {
    "path": "module_meizi/src/main/java/com/ccj/meizi/holder/MeiziItemHolder.java",
    "content": "package com.ccj.meizi.holder;\n\nimport android.app.Activity;\nimport android.view.View;\nimport android.widget.ImageView;\n\nimport com.alibaba.android.arouter.launcher.ARouter;\nimport com.ccj.base.Constants;\nimport com.ccj.base.RouterConstants;\nimport com.ccj.base.adapter.item.AdapterItem;\nimport com.ccj.meizi.R;\nimport com.ccj.meizi.bean.Meizhi;\nimport com.squareup.picasso.Picasso;\n\n/**\n * 通用brand  card\n */\npublic class MeiziItemHolder implements AdapterItem<Meizhi.MeiziItemBean>, View.OnClickListener {\n\n    private static final String TAG = MeiziItemHolder.class.getSimpleName();\n\n    private Activity mActivity;\n    private Meizhi.MeiziItemBean model;\n\n    private ImageView imageView;\n\n\n    public MeiziItemHolder(Activity mActivity) {\n        this.mActivity = mActivity;\n    }\n\n    @Override\n    public int getLayoutResId() {\n        return R.layout.item_meizi_item;\n    }\n\n    @Override\n    public void bindViews(View root) {\n        imageView = (ImageView) root.findViewById(R.id.imageView);\n        root.setOnClickListener(this);\n    }\n\n    @Override\n    public void setViews() {\n\n    }\n\n    @Override\n    public void onClick(View v) {\n       ARouter.getInstance().\n               build(RouterConstants.MEIZI_MUDULE_ACTIVITY_MEIZI_DETAIL).\n               withString(Constants.PARAMS_REQUEST_FOR_DETAIL,model.url).\n               navigation();\n\n    }\n\n    @Override\n    public void handleData(Meizhi.MeiziItemBean item, int position) {\n        this.model = item;\n\n        Picasso.with(mActivity)\n                .load(item.url)\n                .into(imageView);\n    }\n\n\n}"
  },
  {
    "path": "module_meizi/src/main/java/com/ccj/meizi/ui/detail/MeiziDetailActivity.java",
    "content": "package com.ccj.meizi.ui.detail;\n\nimport android.os.Bundle;\nimport android.widget.ImageView;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\nimport com.ccj.base.Constants;\nimport com.ccj.base.RouterConstants;\nimport com.ccj.base.base.BaseActivity;\nimport com.ccj.meizi.R;\nimport com.squareup.picasso.Picasso;\n\n/**\n * Created by chenchangjun on 18/2/1.\n */\n\n@Route(path = RouterConstants.MEIZI_MUDULE_ACTIVITY_MEIZI_DETAIL)\npublic class MeiziDetailActivity extends BaseActivity {\n\n\n    @Override\n    public void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_meizi_detail);\n        ImageView imageView= (ImageView) findViewById(R.id.image);\n\n\n      String url=  getIntent().getStringExtra(Constants.PARAMS_REQUEST_FOR_DETAIL);\n\n        Picasso.with(this)\n                .load(url+\"\")\n                .into(imageView);\n    }\n\n\n}\n"
  },
  {
    "path": "module_meizi/src/main/java/com/ccj/meizi/ui/main/MeiZhiContract.java",
    "content": "package com.ccj.meizi.ui.main;\n\n\nimport com.ccj.base.base.BasePresenter;\nimport com.ccj.base.base.BaseView;\nimport com.ccj.base.bean.User;\nimport com.ccj.meizi.bean.Meizhi;\n\nimport java.util.ArrayList;\n\n/**\n * Created by Administrator on 2016/11/1.\n */\n\npublic class MeiZhiContract {\n\n    interface View extends BaseView {\n        void showProgress();\n        void hideProgress();\n        void showMeiZhiList(ArrayList<Meizhi.MeiziItemBean> meizhiList);\n        void showError(String error);\n        void navigateToMeiZhiDetail(String url);\n        void setListener();\n\n    }\n\n    interface Presenter extends BasePresenter {\n        void loadMeizhi(int pager);\n        void loadMoreMeizhi(int pager);\n        void  refresh();\n    }\n\n    interface Model{\n        void saveUserInfo(User user);\n        void saveLoginState(Boolean isLogin);\n        void saveRememberPass(User user);\n\n    }\n\n\n}\n"
  },
  {
    "path": "module_meizi/src/main/java/com/ccj/meizi/ui/main/MeiZhiFragment.java",
    "content": "package com.ccj.meizi.ui.main;\n\nimport android.os.Bundle;\nimport android.support.annotation.Nullable;\nimport android.support.v4.widget.SwipeRefreshLayout;\nimport android.support.v7.widget.LinearLayoutManager;\nimport android.support.v7.widget.RecyclerView;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\nimport com.ccj.base.RouterConstants;\nimport com.ccj.base.base.BaseFragment;\nimport com.ccj.base.utils.ToastUtil;\nimport com.ccj.base.view.SuperRecyclerView;\nimport com.ccj.base.view.list.OnLoadNextListener;\nimport com.ccj.meizi.R;\nimport com.ccj.meizi.R2;\nimport com.ccj.meizi.adapter.MeiziRcvAdapter;\nimport com.ccj.meizi.bean.Meizhi;\n\nimport java.util.ArrayList;\n\nimport butterknife.BindView;\nimport butterknife.ButterKnife;\n\n/**\n * Created by Administrator on 2016/11/1.\n */\n@Route(path = RouterConstants.MEIZI_MUDULE_FRAGMENT_HOME_MEIZI)\npublic class MeiZhiFragment extends BaseFragment<MeiZhiContract.Presenter> implements MeiZhiContract.View, SwipeRefreshLayout.OnRefreshListener,\n        OnLoadNextListener {\n\n\n    private static final String TAG = MeiZhiFragment.class.getSimpleName();\n    @BindView(R2.id.srl)\n    SwipeRefreshLayout swipeRefreshLayout;\n    @BindView(R2.id.recycler_view)\n    SuperRecyclerView recyclerView;\n    private View view;\n    private ArrayList<Meizhi.MeiziItemBean> meiZhi = new ArrayList<>();\n    private int page = 0;\n    private MeiZhiPresenter meiZhiPresenter;\n    private RecyclerView.LayoutManager mLayoutManager;\n    private MeiziRcvAdapter adapter;\n\n    @Nullable\n    @Override\n    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {\n        if (view == null) {\n            view = inflater.inflate(R.layout.fragment_meizi, null);\n        }\n        ButterKnife.bind(this, view);\n        return view;\n    }\n\n\n    @Override\n    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {\n        super.onViewCreated(view, savedInstanceState);\n        if (meiZhiPresenter == null) {\n            meiZhiPresenter = new MeiZhiPresenter(this);\n            meiZhiPresenter.start();\n        }\n\n\n    }\n\n\n    @Override\n    public void initView() {\n        swipeRefreshLayout.setColorSchemeResources(android.R.color.holo_orange_light, android.R.color.holo_green_light, android.R.color.holo_blue_bright, android.R.color.holo_purple);\n\n\n        adapter = new MeiziRcvAdapter(meiZhi, getActivity());\n        //mLayoutManager = new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);\n        mLayoutManager = new LinearLayoutManager(getContext());\n        recyclerView.setLayoutManager(mLayoutManager);\n        recyclerView.setAdapter(adapter);\n        recyclerView.setHasFixedSize(true);\n        recyclerView.setNestedScrollingEnabled(false);\n\n\n    }\n\n\n    @Override\n    public void showProgress() {\n        recyclerView.setLoadingState(true);\n\n        swipeRefreshLayout.setRefreshing(true);\n    }\n\n    @Override\n    public void hideProgress() {\n        if (swipeRefreshLayout != null) {\n            swipeRefreshLayout.setRefreshing(false);\n        }\n        recyclerView.setLoadingState(false);\n\n    }\n\n\n    @Override\n    public void showMeiZhiList(ArrayList<Meizhi.MeiziItemBean> newMeizi) {\n        meiZhi.clear();\n        meiZhi.addAll(newMeizi);\n        adapter.notifyDataSetChanged();\n\n    }\n\n    @Override\n    public void showError(String error) {\n        ToastUtil.show(error);\n    }\n\n    @Override\n    public void navigateToMeiZhiDetail(String url) {\n\n\n    }\n\n    @Override\n    public void setListener() {\n        recyclerView.setLoadNextListener(this);\n        swipeRefreshLayout.setOnRefreshListener(this);\n    }\n\n\n    @Override\n    public void onRefresh() {\n        meiZhiPresenter.refresh();\n\n    }\n\n    @Override\n    public void onLoadNext() {\n        meiZhiPresenter.loadMoreMeizhi(--page);\n\n    }\n\n\n    @Override\n    public void autoShowOrHideToolbar(boolean show) {\n\n    }\n}\n"
  },
  {
    "path": "module_meizi/src/main/java/com/ccj/meizi/ui/main/MeiZhiPresenter.java",
    "content": "package com.ccj.meizi.ui.main;\n\nimport com.ccj.base.utils.TLog;\nimport com.ccj.meizi.api.MeiziAPIServiceImp;\nimport com.ccj.meizi.bean.Meizhi;\n\nimport java.util.ArrayList;\n\nimport rx.Observable;\nimport rx.Subscriber;\nimport rx.android.schedulers.AndroidSchedulers;\nimport rx.schedulers.Schedulers;\n\n/**\n * Created by Administrator on 2016/11/1.\n */\n\npublic class MeiZhiPresenter  implements MeiZhiContract.Presenter {\n\n    private MeiZhiContract.View view;\n    private ArrayList<Meizhi.MeiziItemBean> meiZhi;\n\n\n    public MeiZhiPresenter(MeiZhiContract.View view) {\n        this.view = view;\n    }\n\n    @Override\n    public void start() {\n        view.initView();\n        view.setListener();\n        refresh();\n    }\n\n    @Override\n    public void refresh() {\n        loadMeizhi(0);\n    }\n\n    @Override\n    public void loadMoreMeizhi(int pager) {\n        loadMeizhi(pager);\n    }\n\n    @Override\n    public void loadMeizhi(final int page) {\n        view.showProgress();\n\n        if (page>=0&&meiZhi!=null){\n            meiZhi.clear();\n        }\n\n        Observable<Meizhi> userObservable = MeiziAPIServiceImp.getMeiZhi();\n\n\n        userObservable.subscribeOn(Schedulers.io())\n                .observeOn(AndroidSchedulers.mainThread())\n                .subscribe(new Subscriber<Meizhi>() {\n                    @Override\n                    public void onCompleted() {\n                        view.hideProgress();\n                    }\n\n                    @Override\n                    public void onError(Throwable e) {\n                        TLog.log(e.getMessage().toString());\n                        view.hideProgress();\n                    }\n\n                    @Override\n                    public void onNext(Meizhi getIpInfoResponse) {\n                        ArrayList<Meizhi.MeiziItemBean> meiZhiTemp = (ArrayList<Meizhi.MeiziItemBean>) getIpInfoResponse.results;\n\n                        if (getIpInfoResponse.error){\n                            view.showError(\"请求错误\");\n                        }\n\n                        if (page >= 0) {\n                            meiZhi = meiZhiTemp;\n                        } else {\n                            meiZhi.addAll(meiZhiTemp);\n                        }\n                        view.showMeiZhiList(meiZhi);\n                    }\n                });\n    }\n\n    @Override\n    public void onDestroy() {\n\n        view=null;\n    }\n}\n"
  },
  {
    "path": "module_meizi/src/main/java/com/ccj/meizi/utils/DateStringUtils.java",
    "content": "package com.ccj.meizi.utils;\n\nimport java.text.SimpleDateFormat;\nimport java.util.Calendar;\n\n/**\n * Created by Administrator on 2016/11/1.\n */\n\npublic class DateStringUtils {\n    /**\n     * 获得距离今天offset的日期\n     * @param offset\n     * @return\n     */\n    public static String getBeforeStringDate(int offset ){\n        SimpleDateFormat simpleDateFormat=new SimpleDateFormat(\"MM/dd\");\n        Calendar calendar= Calendar.getInstance();\n        calendar.add(Calendar.DATE,offset);\n        return simpleDateFormat.format(calendar.getTime());\n\n    }\n\n\n\n}\n"
  },
  {
    "path": "module_meizi/src/main/release/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\" package=\"com.ccj.meizi\">\n\n    <application android:allowBackup=\"true\"\n        android:supportsRtl=\"true\" >\n        <activity android:name=\".debug.MainActivity\"></activity>\n        <activity android:name=\".debug.ContainActivity\"></activity>\n        <activity android:name=\".ui.detail.MeiziDetailActivity\"></activity>\n    </application>\n\n</manifest>"
  },
  {
    "path": "module_meizi/src/main/res/drawable/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillColor=\"#26A69A\"\n        android:pathData=\"M0,0h108v108h-108z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9,0L9,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,0L19,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,0L29,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,0L39,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,0L49,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,0L59,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,0L69,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,0L79,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M89,0L89,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M99,0L99,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,9L108,9\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,19L108,19\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,29L108,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,39L108,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,49L108,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,59L108,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,69L108,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,79L108,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,89L108,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,99L108,99\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,29L89,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,39L89,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,49L89,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,59L89,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,69L89,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,79L89,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,19L29,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,19L39,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,19L49,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,19L59,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,19L69,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,19L79,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n</vector>\n"
  },
  {
    "path": "module_meizi/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillType=\"evenOdd\"\n        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\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\">\n        <aapt:attr name=\"android:fillColor\">\n            <gradient\n                android:endX=\"78.5885\"\n                android:endY=\"90.9159\"\n                android:startX=\"48.7653\"\n                android:startY=\"61.0927\"\n                android:type=\"linear\">\n                <item\n                    android:color=\"#44000000\"\n                    android:offset=\"0.0\" />\n                <item\n                    android:color=\"#00000000\"\n                    android:offset=\"1.0\" />\n            </gradient>\n        </aapt:attr>\n    </path>\n    <path\n        android:fillColor=\"#FFFFFF\"\n        android:fillType=\"nonZero\"\n        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\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\" />\n</vector>\n"
  },
  {
    "path": "module_meizi/src/main/res/layout/activity_contain.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\">\n\n\n\n\n\n    <RelativeLayout\n        android:id=\"@+id/detail_contain\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"></RelativeLayout>\n\n</LinearLayout>"
  },
  {
    "path": "module_meizi/src/main/res/layout/activity_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\">\n\n\n    <Button\n        android:id=\"@+id/button\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_alignParentLeft=\"true\"\n        android:layout_alignParentStart=\"true\"\n        android:layout_centerVertical=\"true\"\n        android:text=\"跳转到首页fragment测试页\" />\n</RelativeLayout>"
  },
  {
    "path": "module_meizi/src/main/res/layout/activity_meizi_detail.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\" android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n\n\n    <ImageView\n        android:id=\"@+id/image\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\" />\n</LinearLayout>"
  },
  {
    "path": "module_meizi/src/main/res/layout/fragment_meizi.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:orientation=\"vertical\"\n    android:layout_width=\"match_parent\"\n    android:background=\"@color/window_bg\"\n    android:layout_height=\"match_parent\">\n\n\n\n\n    <android.support.v4.widget.SwipeRefreshLayout\n        android:id=\"@+id/srl\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <com.ccj.base.view.SuperRecyclerView\n            android:id=\"@+id/recycler_view\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"/>\n\n    </android.support.v4.widget.SwipeRefreshLayout>\n\n\n</LinearLayout>\n"
  },
  {
    "path": "module_meizi/src/main/res/layout/item_meizi_item.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.v7.widget.CardView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:cardView=\"http://schemas.android.com/apk/res-auto\"\n    android:layout_width=\"wrap_content\"\n    android:layout_height=\"wrap_content\"\n    android:maxHeight=\"140dp\"\n    android:foreground=\"?attr/selectableItemBackground\"\n    android:layout_margin=\"3dp\"\n    cardView:cardCornerRadius=\"2dp\"\n    cardView:cardElevation=\"3dp\"\n    cardView:cardMaxElevation=\"3dp\"\n    cardView:cardPreventCornerOverlap=\"false\">\n    <ImageView\n        xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:id=\"@+id/imageView\"\n        android:scaleType=\"centerCrop\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        />\n\n</android.support.v7.widget.CardView>\n"
  },
  {
    "path": "module_meizi/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "module_meizi/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "module_meizi/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"colorPrimaryDark\">#303F9F</color>\n    <color name=\"colorAccent\">#FF4081</color>\n</resources>\n"
  },
  {
    "path": "module_meizi/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">module_meizi</string>\n</resources>\n"
  },
  {
    "path": "module_meizi/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "module_user/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "module_user/build.gradle",
    "content": "if (isModule.toBoolean()) {\n    apply plugin: 'com.android.application'\n} else {\n    apply plugin: 'com.android.library'\n}\n//butterknife\napply plugin: 'com.jakewharton.butterknife'\n\nandroid {\n    compileSdkVersion rootProject.ext.compileSdkVersion\n    buildToolsVersion rootProject.ext.buildToolsVersion\n\n    defaultConfig {\n\n        if (isModule.toBoolean()) {\n            applicationId \"com.ccj.loginmodule\"\n        }\n\n        minSdkVersion rootProject.ext.minSdkVersion\n        targetSdkVersion rootProject.ext.targetSdkVersion\n        versionCode rootProject.ext.versionCode\n        versionName rootProject.ext.versionName\n\n\n       // resourcePrefix \"user_\"\n\n\n        //arouter\n        javaCompileOptions {\n            annotationProcessorOptions {\n                arguments = [moduleName: project.getName()]\n            }\n        }\n    }\n\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n    sourceSets {\n        main {\n            if (isModule.toBoolean()) {\n                manifest.srcFile 'src/main/AndroidManifest.xml'\n            } else {\n                manifest.srcFile 'src/main/release/AndroidManifest.xml'\n                java {\n                    exclude 'debug/**'\n                }\n            }\n        }\n    }\n\n}\n\ndependencies {\n    compile fileTree(dir: 'libs', include: ['*.jar'])\n\n\n    //butterknife\n    annotationProcessor rootProject.ext.butterknifeCompiler\n\n    //arouter\n    compile rootProject.ext.arouterApi\n    annotationProcessor rootProject.ext.arouterCompiler\n\n    compile project(':base')\n\n}\n\n\n\n"
  },
  {
    "path": "module_user/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/chenchangjun/Library/Android/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "module_user/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\" package=\"com.ccj.login\">\n\n    <application\n\n        android:name=\".debug.LoginApplication\"\n        android:allowBackup=\"true\" android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\" android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\" android:theme=\"@style/AppTheme\">\n        <activity android:name=\".debug.MainActivity\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n\n\n        <activity android:name=\".ui.login.LoginActivity\"></activity>\n        <activity android:name=\".ui.register.RegisterActivity\"></activity>\n    </application>\n\n</manifest>"
  },
  {
    "path": "module_user/src/main/java/com/ccj/login/api/LoginAPIServiceImp.java",
    "content": "package com.ccj.login.api;\n\nimport com.ccj.base.api.APIService;\nimport com.ccj.base.bean.User;\nimport com.ccj.base.utils.TLog;\n\nimport java.util.HashMap;\n\nimport rx.Observable;\n\n/**\n * 继承\n * Created by chenchangjun on 17/8/10.\n */\n\npublic class LoginAPIServiceImp extends APIService {\n\n\n    protected static final LoginRetrofitImp loginApiManager = sRetrofit.create(LoginRetrofitImp.class);\n\n    /**\n     * 登录,返回,我这边用的是json格式的post\n     * @param city\n     * @return\n     */\n    public static Observable<User> userLogin(String format, String city) {\n        HashMap<String,String> hashMap =new HashMap<>();\n        hashMap.put(\"UserPhone\", format);\n        hashMap.put(\"UserPassWord\", city);\n        TLog.log(hashMap.toString());\n        Observable<User> ss = loginApiManager.userLogin(hashMap);\n        return  ss;\n    }\n\n\n\n}\n"
  },
  {
    "path": "module_user/src/main/java/com/ccj/login/api/LoginRetrofitImp.java",
    "content": "package com.ccj.login.api;\n\nimport com.ccj.base.api.RetrofitRequest;\nimport com.ccj.base.bean.User;\n\nimport java.util.HashMap;\n\nimport retrofit2.http.Body;\nimport retrofit2.http.Headers;\nimport retrofit2.http.POST;\nimport rx.Observable;\n\n\n/**\n * Created by chenchangjun on 17/8/10.\n */\n\npublic interface LoginRetrofitImp extends RetrofitRequest {\n\n\n    /**\n     * 登录返回(json post)\n     * @param body\n     * @return\n     */\n    @Headers( \"Content-Type: application/json\" )\n    @POST(BASE_URL+\"Login.ashx/\")\n    Observable<User> userLogin(@Body HashMap<String, String> body);\n\n}\n"
  },
  {
    "path": "module_user/src/main/java/com/ccj/login/debug/LoginApplication.java",
    "content": "package com.ccj.login.debug;\n\nimport com.ccj.base.base.BaseApplication;\n\n/**\n * Created by chenchangjun on 17/8/7.\n */\n\npublic class LoginApplication extends BaseApplication {\n    @Override\n    public void onCreate() {\n        super.onCreate();\n    }\n}\n"
  },
  {
    "path": "module_user/src/main/java/com/ccj/login/debug/MainActivity.java",
    "content": "package com.ccj.login.debug;\n\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.support.v7.app.AppCompatActivity;\nimport android.view.View;\nimport android.widget.TextView;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\nimport com.ccj.login.R;\nimport com.ccj.login.R2;\nimport com.ccj.login.ui.login.LoginActivity;\n\nimport butterknife.BindView;\nimport butterknife.ButterKnife;\n\n// 在支持路由的页面上添加注解(必选)\n// 这里的路径需要注意的是至少需要有两级，/xx/xx\n@Route(path = \"/login/MainActivity\")\npublic class MainActivity extends AppCompatActivity {\n\n    @BindView(R2.id.tv_login_main)\n    TextView tvLoginMain;\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_main);\n        ButterKnife.bind(this);\n\n\n        tvLoginMain.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View v) {\n                jumpToLogin();\n            }\n        });\n    }\n\n    private void jumpToLogin() {\n        Intent intent =new Intent(this, LoginActivity.class);\n        startActivity(intent);\n    }\n\n\n}\n"
  },
  {
    "path": "module_user/src/main/java/com/ccj/login/service/CheckLoginService.java",
    "content": "package com.ccj.login.service;\n\nimport android.content.Context;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\nimport com.ccj.base.utils.router.LoginModuleService;\nimport com.ccj.base.RouterConstants;\n\n/**\n *     * 实现接口,\n * Created by chenchangjun on 17/8/14.\n */\n@Route(path = RouterConstants. USER_SERVICE_IMPL)\npublic class CheckLoginService implements LoginModuleService{\n\n    /**\n     * 实例化服务,面向接口编程\n     * @return\n     */\n    @Override\n    public boolean checkLoginState() {\n        //可自行在loginModule\n        return false;\n    }\n\n    @Override\n    public void init(Context context) {\n\n    }\n}\n"
  },
  {
    "path": "module_user/src/main/java/com/ccj/login/ui/login/LoginActivity.java",
    "content": "package com.ccj.login.ui.login;\n\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.view.View;\nimport android.widget.Button;\nimport android.widget.CheckBox;\nimport android.widget.EditText;\nimport android.widget.ImageView;\nimport android.widget.LinearLayout;\nimport android.widget.TextView;\nimport android.widget.Toast;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\nimport com.ccj.base.Constants;\nimport com.ccj.base.base.BaseActivity;\nimport com.ccj.base.base.BaseApplication;\nimport com.ccj.base.RouterConstants;\nimport com.ccj.login.R;\nimport com.ccj.login.R2;\nimport com.ccj.login.debug.MainActivity;\nimport com.ccj.login.ui.register.RegisterActivity;\n\nimport butterknife.BindView;\nimport butterknife.ButterKnife;\nimport butterknife.OnClick;\n\nimport static com.ccj.base.Constants.PARAMS_RESULT_FROM_LOGIN;\nimport static com.ccj.base.Constants.RESULT_FROM_LOGIN;\n\n/**\n * Created by Administrator on 2016/7/7.\n */\n\n@Route(path = RouterConstants.USER_MOUDLE_ACTIVITY)\npublic class LoginActivity extends BaseActivity<LoginContract.Presenter> implements LoginContract.View {\n\n    @BindView(R2.id.iv_cancel)\n    ImageView ivCancel;\n    @BindView(R2.id.tv_phone)\n    EditText tvPhone;\n    @BindView(R2.id.tv_password)\n    EditText tvPassword;\n    @BindView(R2.id.cb_remember_pass)\n    CheckBox cbRememberPass;\n    @BindView(R2.id.tv_forget_pass)\n    TextView tvForgetPass;\n    @BindView(R2.id.linearLayout)\n    LinearLayout linearLayout;\n    @BindView(R2.id.linearLayout2)\n    LinearLayout linearLayout2;\n    @BindView(R2.id.btn_login)\n    Button btnLogin;\n    @BindView(R2.id.btn_register)\n    Button btnRegister;\n    private String str = \"\";\n\n    @Override\n    public void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_login);\n        str = getIntent().getStringExtra(Constants.START_LOGIN_WITH_PARAMS);\n        ButterKnife.bind(this);\n        mPresenter = new LoginPresenter(this);\n        mPresenter.start();\n    }\n\n\n    @Override\n    public void navigateToMain() {\n        Intent intent = new Intent(getBaseContext(), MainActivity.class);\n        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);\n        startActivity(intent);\n    }\n\n    @Override\n    public void navigateToRegister() {\n        Intent intent = new Intent(getBaseContext(), RegisterActivity.class);\n        startActivity(intent);\n    }\n\n    @OnClick({R2.id.iv_cancel, R2.id.btn_login, R2.id.btn_register})\n    public void onClick(View view) {\n        int i = view.getId();\n        if (i == R.id.iv_cancel) {\n            Intent intent = new Intent();\n            intent.putExtra(PARAMS_RESULT_FROM_LOGIN, \"login sucess\");\n            setResult(RESULT_FROM_LOGIN, intent);\n            finish();\n        } else if (i == R.id.btn_login) {\n            //mPresenter.login(tvPhone.getText().toString(), tvPassword.getText().toString());\n\n        } else if (i == R.id.btn_register) {\n            navigateToRegister();\n        }\n    }\n\n\n    @Override\n    public void showProgress() {\n        progressDialog.show();\n    }\n\n    @Override\n    public void hideProgress() {\n        progressDialog.dismiss();\n    }\n\n    @Override\n    public void showError(String error) {\n        BaseApplication.showShortToast(error);\n\n    }\n\n    @Override\n    public void initView() {\n        Toast.makeText(this, \"登录测试,来自app/MainActivity的参数--\" + str, Toast.LENGTH_SHORT).show();\n\n    }\n}\n"
  },
  {
    "path": "module_user/src/main/java/com/ccj/login/ui/login/LoginContract.java",
    "content": "package com.ccj.login.ui.login;\n\n\nimport com.ccj.base.base.BasePresenter;\nimport com.ccj.base.base.BaseView;\nimport com.ccj.base.bean.User;\n\n/**\n * 登录关联接口类\n *\n * Created by Administrator on 2016/7/7.\n */\npublic interface LoginContract {\n\n\n    interface View extends BaseView {\n        void showProgress();\n        void hideProgress();\n        void showError(String error);\n        void navigateToMain();\n        void navigateToRegister();\n    }\n\n    interface Presenter extends BasePresenter {\n        void login(String username, String password);\n        void onDestroy();\n    }\n\n    interface Model{\n        void saveUserInfo(User user);\n        void saveLoginState(Boolean isLogin);\n        void saveRememberPass(User user);\n\n    }\n\n}\n"
  },
  {
    "path": "module_user/src/main/java/com/ccj/login/ui/login/LoginModel.java",
    "content": "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 *  这里的login 涉及到的业务逻辑比较少\n *  请求网络 采用了rxjava +retroft+gsons\n *  相当于 model层.\n *  如果处理的出具多,就采用此model ,就像图片保存显示等等.\n *\n */\n\n\n\npublic class LoginModel implements LoginContract.Model {\n\n\n    interface SaveFinishListener{\n        void onError(String msg);\n        void onSucess(String msg);\n        void onProgress(String msg);\n    }\n\n    public LoginModel() {\n\n    }\n\n    public void setOnSaveFinishListener(SaveFinishListener onSaveFinishListener){\n\n    }\n\n\n    @Override\n    public void saveUserInfo(User user) {\n\n    }\n\n    @Override\n    public void saveLoginState(Boolean isLogin) {\n\n    }\n\n    @Override\n    public void saveRememberPass(User user) {\n\n    }\n\n\n\n\n}\n"
  },
  {
    "path": "module_user/src/main/java/com/ccj/login/ui/login/LoginPresenter.java",
    "content": "package com.ccj.login.ui.login;\n\n\nimport com.ccj.base.bean.User;\nimport com.ccj.base.utils.TLog;\nimport com.ccj.login.api.LoginAPIServiceImp;\n\nimport rx.Observable;\nimport rx.Subscriber;\nimport rx.android.schedulers.AndroidSchedulers;\nimport rx.schedulers.Schedulers;\n\n/**\n * login的presenter层 进行对view 和 model 的控制,\n * Created by ccj on 2016/7/7.\n */\npublic class LoginPresenter implements LoginContract.Presenter {\n\n    private LoginContract.View loginView;\n    public LoginPresenter(LoginContract.View loginView) {\n        this.loginView = loginView;\n    }\n\n    @Override\n    public void login(String username, String password) {\n        loginView.showProgress();\n        Observable<User> userObservable = LoginAPIServiceImp.userLogin(username, password);\n        userObservable.subscribeOn(Schedulers.io())\n                .observeOn(AndroidSchedulers.mainThread())\n                .subscribe(new Subscriber<User>() {\n                    @Override\n                    public void onCompleted() {\n                        loginView.hideProgress();\n                    }\n\n                    @Override\n                    public void onError(Throwable e) {\n                        TLog.log(e.getMessage().toString());\n                        loginView.hideProgress();\n                        loginView.showError(e.getMessage().toString());\n                    }\n\n                    @Override\n                    public void onNext(User getIpInfoResponse) {\n                        TLog.log(getIpInfoResponse.toString());\n                        loginView.navigateToMain();\n                    }\n                });\n    }\n\n    @Override\n    public void start() {\n        loginView.initView();\n    }\n\n\n    @Override\n    public void onDestroy() {\n        TLog.log(\"-->loginPresenter  onDestroy\");\n    }\n\n\n}\n"
  },
  {
    "path": "module_user/src/main/java/com/ccj/login/ui/register/RegisterActivity.java",
    "content": "package com.ccj.login.ui.register;\n\nimport android.os.Bundle;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\nimport com.ccj.base.base.BaseActivity;\nimport com.ccj.base.utils.eventbus.EventUtils;\nimport com.ccj.base.RouterConstants;\nimport com.ccj.login.R;\n\nimport org.greenrobot.eventbus.EventBus;\n\n/**\n * Created by chenchangjun on 17/8/9.\n */\n@Route(path = RouterConstants.USER_REGISTER_FRAGMENT)\npublic class RegisterActivity extends BaseActivity {\n\n\n    @Override\n    public void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.login_fragment_register);\n        EventBus.getDefault().post(new EventUtils.StringEvent(\"hello, I am  from com.ccj.login.RegisterActivity.btn_event EventBus\"));\n\n    }\n\n\n\n\n}\n"
  },
  {
    "path": "module_user/src/main/java/com/ccj/login/ui/user/UserFragment.java",
    "content": "package com.ccj.login.ui.user;\n\nimport android.support.v4.app.Fragment;\nimport android.os.Bundle;\nimport android.support.annotation.Nullable;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\nimport com.ccj.base.RouterConstants;\nimport com.ccj.login.R;\n\n/**\n * Created by chenchangjun on 18/1/25.\n */\n\n@Route(path = RouterConstants.USER_MUDULE_FRAGMENT_HOME_USER)\npublic class UserFragment extends Fragment {\n\n\n    private View view;\n\n    @Nullable\n    @Override\n    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {\n        if (view == null) {\n            view = inflater.inflate(R.layout.user_fragment_user_home, null);\n        }\n        return view;\n    }\n\n\n}\n"
  },
  {
    "path": "module_user/src/main/release/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\" package=\"com.ccj.login\">\n\n    <application android:allowBackup=\"true\"\n        android:supportsRtl=\"true\" android:theme=\"@style/AppTheme\">\n        <activity android:name=\".debug.MainActivity\"></activity>\n        <activity android:name=\".ui.login.LoginActivity\"></activity>\n        <activity android:name=\".ui.register.RegisterActivity\"></activity>\n    </application>\n\n</manifest>"
  },
  {
    "path": "module_user/src/main/res/layout/activity_login.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:background=\"@mipmap/login_bg\"\n    android:orientation=\"vertical\">\n\n    <ImageView\n        android:id=\"@+id/iv_cancel\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_alignParentEnd=\"true\"\n        android:layout_alignParentRight=\"true\"\n        android:layout_alignParentTop=\"true\"\n        android:padding=\"@dimen/common_container_padding\"\n        />\n\n    <LinearLayout\n        android:id=\"@+id/linearLayout\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerHorizontal=\"true\"\n        android:layout_centerVertical=\"true\"\n        android:layout_margin=\"@dimen/common_container_padding\"\n        android:gravity=\"center\"\n        android:orientation=\"vertical\">\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"@dimen/large_top_margin\" />\n\n        <EditText\n\n            android:id=\"@+id/tv_phone\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center\"\n            android:layout_margin=\"@dimen/common_container_padding\"\n            android:background=\"@color/white\"\n            android:hint=\"手机号\"\n            android:maxLength=\"11\"\n            android:inputType=\"phone\"\n            android:padding=\"@dimen/common_container_padding\" />\n\n        <EditText\n            android:id=\"@+id/tv_password\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center\"\n            android:layout_margin=\"@dimen/common_container_padding\"\n            android:background=\"@color/white\"\n            android:hint=\"密码\"\n            android:maxLength=\"20\"\n            android:inputType=\"textPassword\"\n            android:padding=\"@dimen/common_container_padding\" />\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_margin=\"@dimen/common_container_padding\"\n            android:orientation=\"horizontal\">\n\n\n            <CheckBox\n                android:id=\"@+id/cb_remember_pass\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_weight=\"1\"\n                android:text=\"记住密码\" />\n\n            <TextView\n                android:id=\"@+id/tv_forget_pass\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_weight=\"1\"\n                android:gravity=\"right\"\n                android:visibility=\"gone\"\n                android:text=\"忘记密码\" />\n        </LinearLayout>\n\n\n    </LinearLayout>\n\n\n    <LinearLayout\n        android:orientation=\"horizontal\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_below=\"@+id/linearLayout\"\n        android:layout_centerVertical=\"true\"\n        android:id=\"@+id/linearLayout2\">\n\n    </LinearLayout>\n\n    <Button\n        android:id=\"@+id/btn_login\"\n        android:layout_height=\"wrap_content\"\n        android:layout_width=\"100dp\"\n        android:text=\"登录\"\n        android:textAppearance=\"?android:attr/textAppearanceMedium\"\n\n        android:background=\"@color/white\"\n        android:layout_alignTop=\"@+id/linearLayout2\"\n        android:layout_alignLeft=\"@+id/linearLayout\"\n        android:layout_alignStart=\"@+id/linearLayout\" />\n\n    <Button\n        android:id=\"@+id/btn_register\"\n        android:layout_width=\"100dp\"\n        android:layout_height=\"wrap_content\"\n        android:background=\"@color/white\"\n        android:text=\"注册\"\n        android:textAppearance=\"?android:attr/textAppearanceMedium\"\n\n        android:layout_alignTop=\"@+id/btn_login\"\n        android:layout_alignRight=\"@+id/linearLayout\"\n        android:layout_alignEnd=\"@+id/linearLayout\" />\n\n\n\n</RelativeLayout>"
  },
  {
    "path": "module_user/src/main/res/layout/activity_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.constraint.ConstraintLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\" android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\" tools:context=\"com.ccj.login.debug.MainActivity\">\n\n    <TextView\n        android:id=\"@+id/tv_login_main\"\n        android:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\"\n        android:text=\"login module \\n 点击登录\" app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintLeft_toLeftOf=\"parent\" app:layout_constraintRight_toRightOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"parent\" />\n\n\n</android.support.constraint.ConstraintLayout>\n"
  },
  {
    "path": "module_user/src/main/res/layout/login_fragment_register.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:orientation=\"vertical\"\n    android:gravity=\"center\"\n    android:background=\"@color/white\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <TextView\n        android:layout_gravity=\"center\"\n        android:gravity=\"center\"\n        android:id=\"@+id/login_textview\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"我是注册界面.xml\" />\n</LinearLayout>"
  },
  {
    "path": "module_user/src/main/res/layout/user_fragment_user_home.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <Button\n        android:layout_centerInParent=\"true\"\n        android:id=\"@+id/login_button\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"center\"\n        android:text=\"我的\" />\n</RelativeLayout>"
  },
  {
    "path": "module_user/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"colorPrimaryDark\">#303F9F</color>\n    <color name=\"colorAccent\">#FF4081</color>\n</resources>\n"
  },
  {
    "path": "module_user/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">module_user</string>\n</resources>\n"
  },
  {
    "path": "module_user/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "module_video/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "module_video/build.gradle",
    "content": "if (isModule.toBoolean()) {\n    apply plugin: 'com.android.application'\n} else {\n    apply plugin: 'com.android.library'\n}\n//butterknife\napply plugin: 'com.jakewharton.butterknife'\n\nandroid {\n    compileSdkVersion rootProject.ext.compileSdkVersion\n    buildToolsVersion rootProject.ext.buildToolsVersion\n\n    defaultConfig {\n\n        if (isModule.toBoolean()) {\n            applicationId \"com.ccj.videomodule\"\n        }\n        minSdkVersion rootProject.ext.minSdkVersion\n        targetSdkVersion rootProject.ext.targetSdkVersion\n        versionCode rootProject.ext.versionCode\n        versionName rootProject.ext.versionName\n\n      //  resourcePrefix \"video_\"\n\n        //arouter\n        javaCompileOptions {\n            annotationProcessorOptions {\n                arguments = [moduleName: project.getName()]\n            }\n        }\n    }\n\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n    sourceSets {\n        main {\n            if (isModule.toBoolean()) {\n                manifest.srcFile 'src/main/AndroidManifest.xml'\n            } else {\n                manifest.srcFile 'src/main/release/AndroidManifest.xml'\n                java {\n                    exclude 'debug/**'\n                }\n            }\n        }\n    }\n\n}\n\ndependencies {\n    compile fileTree(dir: 'libs', include: ['*.jar'])\n\n    compile project(':base')\n\n    //butterknife\n    annotationProcessor rootProject.ext.butterknifeCompiler\n\n    //arouter\n    compile rootProject.ext.arouterApi\n    annotationProcessor rootProject.ext.arouterCompiler}\n\n\n\n"
  },
  {
    "path": "module_video/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/chenchangjun/Library/Android/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "module_video/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\" package=\"com.ccj.video\">\n\n    <application\n        android:name=\".debug.VideoApplication\"\n        android:allowBackup=\"true\" android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\" android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\" android:theme=\"@style/AppTheme\">\n        <activity android:name=\".debug.MainActivity\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n\n\n        <activity android:name=\".ui.TakePhotoActivity\"></activity>\n    </application>\n\n</manifest>"
  },
  {
    "path": "module_video/src/main/java/com/ccj/video/VideoFragment.java",
    "content": "package com.ccj.video;\n\nimport android.support.v4.app.Fragment;\nimport android.os.Bundle;\nimport android.support.annotation.Nullable;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\nimport com.ccj.base.RouterConstants;\n\n/**\n * Created by chenchangjun on 18/1/25.\n */\n@Route(path= RouterConstants.VIDEO_MUDULE_FRAGMENT_HOME_VIDEO)\npublic class VideoFragment extends Fragment {\n\n\n    private View view;\n\n    @Nullable\n    @Override\n    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {\n        if (view == null) {\n            view = inflater.inflate(R.layout.video_fragment_video_home, null);\n        }\n        return view;\n    }\n\n\n}\n"
  },
  {
    "path": "module_video/src/main/java/com/ccj/video/debug/MainActivity.java",
    "content": "package com.ccj.video.debug;\n\nimport android.os.Bundle;\nimport android.support.v7.app.AppCompatActivity;\n\nimport com.ccj.video.R;\n\npublic class MainActivity extends AppCompatActivity {\n\n\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_main);\n    }\n}\n"
  },
  {
    "path": "module_video/src/main/java/com/ccj/video/debug/VideoApplication.java",
    "content": "package com.ccj.video.debug;\n\nimport com.ccj.base.base.BaseApplication;\n\n/**\n * 在module模式下,测试的application\n * Created by chenchangjun on 17/8/7.\n */\n\npublic class VideoApplication extends BaseApplication {\n\n    @Override\n    public void onCreate() {\n        super.onCreate();\n    }\n\n}\n"
  },
  {
    "path": "module_video/src/main/java/com/ccj/video/service/VideoServiceImpl.java",
    "content": "package com.ccj.video.service;\n\nimport android.content.Context;\nimport android.util.Log;\n\nimport com.alibaba.android.arouter.facade.annotation.Route;\nimport com.ccj.base.RouterConstants;\nimport com.ccj.base.utils.router.RouterService;\n\n/**\n * Created by chenchangjun on 17/8/9.\n */\n@Route(path = RouterConstants.VIDEO_SERVICE_IMPL)\npublic class VideoServiceImpl implements RouterService {\n\n\n    @Override\n    public void init(Context context) {\n        Log.i(\"VideoServiceImpl\",\"VideoServiceImpl init\");\n    }\n\n    @Override\n    public String start(String name) {\n        return \"VideoServiceImpl started\";\n    }\n\n\n}\n"
  },
  {
    "path": "module_video/src/main/java/com/ccj/video/ui/TakePhotoActivity.java",
    "content": "package com.ccj.video.ui;\n\nimport android.content.Intent;\nimport android.graphics.Bitmap;\nimport android.os.Bundle;\nimport android.provider.MediaStore;\nimport android.util.Log;\nimport android.view.View;\nimport android.widget.Button;\nimport android.widget.ImageView;\nimport android.widget.Toast;\n\nimport com.alibaba.android.arouter.facade.annotation.Autowired;\nimport com.alibaba.android.arouter.facade.annotation.Route;\nimport com.ccj.base.base.BaseActivity;\nimport com.ccj.base.base.Constants;\nimport com.ccj.base.utils.TLog;\nimport com.ccj.base.utils.router.LoginModuleService;\nimport com.ccj.base.RouterConstants;\nimport com.ccj.base.utils.router.RouterUtils;\nimport com.ccj.video.R;\nimport com.ccj.video.R2;\n\nimport butterknife.BindView;\nimport butterknife.ButterKnife;\nimport butterknife.OnClick;\n\n/**\n * Created by Administrator on 2016/7/8.\n */\n@Route(path= RouterConstants.VIDEO_MUDULE_ACTIVITY)\npublic class TakePhotoActivity extends BaseActivity<TakePhotoContract.Presenter> implements TakePhotoContract.View {\n    @BindView(R2.id.imageView)\n    ImageView imageView;\n    @BindView(R2.id.button)\n    Button button;\n\n    @Autowired\n    LoginModuleService loginModuleService;\n\n\n\n    @Override\n    public void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_take_photo);\n        ButterKnife.bind(this);\n        RouterUtils.inject(this);\n\n        mPresenter = new TakePhotoPresenter(this);\n        mPresenter.start();\n    }\n\n\n\n    @OnClick(R2.id.button)\n    public void onClick(View v) {\n        if (v.getId()==R.id.button){\n            takePhoto();\n        }\n    }\n\n\n\n\n    private void takePhoto() {\n        if (loginModuleService.checkLoginState()){ //模拟模块间通信,调用登录服务:如果登录就开始下一步.\n            startTakePhoto();\n        }else {\n            Toast.makeText(this,\"请登录\",Toast.LENGTH_SHORT).show();\n        }\n    }\n\n    private void startTakePhoto() {\n        Intent picture = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);\n        startActivityForResult(picture, Constants.IMAGES_ACTIVITY_REQUEST_CODE);\n    }\n\n\n    @Override\n    protected void onActivityResult(int requestCode, int resultCode, Intent data) {\n        super.onActivityResult(requestCode, resultCode, data);\n        if (Constants.IMAGES_ACTIVITY_REQUEST_CODE == requestCode) {\n            if (resultCode == RESULT_OK) {\n                TLog.log(data.getData().toString());\n                Log.e(\"Tlog\",\"data-->\"+data.getData().toString());\n                mPresenter.savePhoto(data);\n            }\n        }\n\n    }\n\n\n    @Override\n    public void initView() {\n\n    }\n\n    @Override\n    public void showProgress() {\n        progressDialog.show();\n    }\n    //WindowLeaked\n    @Override\n    public void hideProgress() {\n        progressDialog.dismiss();\n    }\n\n    @Override\n    public void showBitmap(Bitmap bitmap) {\n        imageView.setImageBitmap(bitmap);\n    }\n\n\n}\n"
  },
  {
    "path": "module_video/src/main/java/com/ccj/video/ui/TakePhotoContract.java",
    "content": "package com.ccj.video.ui;\n\nimport android.content.Intent;\nimport android.graphics.Bitmap;\n\nimport com.ccj.base.base.BaseModel;\nimport com.ccj.base.base.BasePresenter;\nimport com.ccj.base.base.BaseView;\n\n\n/**\n * 业务联系接口类 面向接口编程 进行解耦 内聚\n * 参照传统的google_mvp\n * Created by ccj on 2016/7/8.\n */\npublic interface TakePhotoContract {\n\n    interface View extends BaseView {\n        void initView();\n        void showProgress();\n        void hideProgress();\n        void showBitmap(Bitmap bitmap);\n\n    }\n    interface Presenter extends BasePresenter {\n        void savePhoto(Intent data);\n    }\n\n    interface Model extends BaseModel {\n        void savePhoto(Intent data);\n    }\n\n\n}\n"
  },
  {
    "path": "module_video/src/main/java/com/ccj/video/ui/TakePhotoModel.java",
    "content": "package com.ccj.video.ui;\n\nimport android.content.Intent;\nimport android.graphics.Bitmap;\nimport android.graphics.BitmapFactory;\nimport android.net.Uri;\nimport android.util.Log;\n\nimport com.ccj.base.base.BaseApplication;\nimport com.ccj.base.utils.BitmapUtil;\nimport com.ccj.base.utils.eventbus.EventUtils;\n\nimport org.greenrobot.eventbus.EventBus;\n\nimport java.io.FileNotFoundException;\nimport java.util.concurrent.Callable;\n\nimport rx.Observable;\nimport rx.Observer;\nimport rx.android.schedulers.AndroidSchedulers;\nimport rx.schedulers.Schedulers;\n\n/**\n * Created by Administrator on 2016/7/8.\n */\npublic class TakePhotoModel implements TakePhotoContract.Model {\n    private Bitmap bitmap = null;\n\n    private Observable<String> saveObservable;\n\n    /**\n     * rxjava 进行异步操作 eventBus进行时间传递\n     *\n     * @param data\n     */\n    @Override\n    public void savePhoto(final Intent data) {\n        saveObservable = Observable.fromCallable(new Callable<String>() {\n            @Override\n            public String call() throws Exception {//通知调用  并返回string\n                return savePic(data);//此方法在io线程中调用 并返回\n            }\n        });\n\n\n        saveObservable.subscribeOn(Schedulers.io())//observable在调度中的IO线程中进行调度进行\n                .observeOn(AndroidSchedulers.mainThread())//在主线程中进行观察\n                .subscribe(new Observer<String>() { //订阅观察者\n                    @Override\n                    public void onCompleted() {\n                    }\n\n                    @Override\n                    public void onError(Throwable e) {\n                        EventBus.getDefault().post(new EventUtils.ObjectEvent(e.getMessage().toString()));\n                    }\n\n                    @Override\n                    public void onNext(String s) {//带参数的下一步,在此就是当\n                        EventBus.getDefault().post(new EventUtils.ObjectEvent(bitmap));\n\n                    }\n                });\n\n\n    }\n\n    private String savePic(Intent data) {\n        if (data == null || data.getData() == null) {\n            return null;\n        }\n        Uri selectedImage = data.getData();\n        try {\n            BitmapFactory.Options opt = new BitmapFactory.Options();\n            opt.inPreferredConfig = Bitmap.Config.RGB_565;\n            opt.inPurgeable = true;\n            opt.inInputShareable = true;\n            Bitmap temp = BitmapFactory\n                    .decodeStream(BaseApplication.getContext().getContentResolver().openInputStream(selectedImage), null, opt);\n\n            bitmap = BitmapUtil.comp(temp);//图片压缩\n            return \"ok\";\n        } catch (FileNotFoundException e) {\n            Log.e(\"cameraBitmap\", \"-----FileNotFoundException---\" + selectedImage.toString());\n\n        } catch (NullPointerException e) {\n            Log.e(\"cameraBitmap\", \"-----NullPointerException---\" + selectedImage.toString());\n        }\n        return null;\n    }\n\n\n    @Override\n    public void start() {\n\n\n    }\n\n    @Override\n    public void onDestroy() {\n        saveObservable=null;\n\n    }\n}\n"
  },
  {
    "path": "module_video/src/main/java/com/ccj/video/ui/TakePhotoPresenter.java",
    "content": "package com.ccj.video.ui;\n\nimport android.content.Intent;\nimport android.graphics.Bitmap;\nimport android.util.Log;\n\nimport com.ccj.base.utils.eventbus.EventUtils;\n\nimport org.greenrobot.eventbus.EventBus;\nimport org.greenrobot.eventbus.Subscribe;\n\n/**\n * Created by ccj on 2016/7/8.\n */\npublic class TakePhotoPresenter implements TakePhotoContract.Presenter {\n\n    private static final String TAG =\"Tlog-->\" ;\n    private TakePhotoContract.View view;\n    private TakePhotoModel takePhotoModel;\n\n    /**\n     * 在activity或fragment中初始化presenter\n     * @param view\n     */\n    public TakePhotoPresenter(TakePhotoContract.View view) {\n        this.view = view;\n        takePhotoModel = new TakePhotoModel();\n        EventBus.getDefault().register(this);\n    }\n\n    /**\n     * 实现保存图片业务的方法\n     * @param data\n     */\n    @Override\n    public void savePhoto(Intent data) {\n        view.showProgress();\n        takePhotoModel.savePhoto(data);\n\n    }\n\n    /**\n     * presenter 初始化\n     */\n    @Override\n    public void start() {\n        view.initView();\n    }\n\n    @Override\n    public void onDestroy() {\n        if (view!=null){\n            view=null;\n        }\n        EventBus.getDefault().unregister(this);\n    }\n\n\n/***********************************下方的订阅也可以放在activity中订阅,注意首先注册订阅****************************************/\n\n\n    /**\n     * 无论发布者在那个线程,在主线程中订阅\n     * @param event\n     */\n    @Subscribe//(threadMode = ThreadMode.MAIN)\n    public void onEvent(EventUtils.ObjectEvent event) {\n        Log.e(TAG, \"onEventMainThread getObjectEvent\" + event.getMsg());\n        Bitmap bitmap=(Bitmap)event.getMsg();\n        view.showBitmap(bitmap);\n        view.hideProgress();\n    }\n\n\n    /**\n     * 和发布者在同一线程订阅\n     * @param event\n     */\n\n   /* public void  onEvent(EventUtils.ObjectEvent event){\n        Log.e(TAG, \"getObjectEvent\" + event.getMsg());\n    }\n*/\n\n\n}\n"
  },
  {
    "path": "module_video/src/main/release/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\" package=\"com.ccj.video\">\n\n    <application android:allowBackup=\"true\"\n        android:supportsRtl=\"true\" >\n        <activity android:name=\".debug.MainActivity\"></activity>\n        <activity android:name=\".ui.TakePhotoActivity\"></activity>\n\n    </application>\n\n</manifest>"
  },
  {
    "path": "module_video/src/main/res/layout/activity_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.constraint.ConstraintLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\" android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\" tools:context=\"com.ccj.video.debug.MainActivity\">\n\n    <TextView android:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\"\n        android:text=\"video mudule Hello World!\" app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintLeft_toLeftOf=\"parent\" app:layout_constraintRight_toRightOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"parent\" />\n\n</android.support.constraint.ConstraintLayout>\n"
  },
  {
    "path": "module_video/src/main/res/layout/activity_take_photo.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:orientation=\"vertical\" android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:background=\"@color/window_bg\"\n    >\n\n    <ImageView\n        android:layout_width=\"400dp\"\n        android:layout_height=\"400dp\"\n        android:id=\"@+id/imageView\"\n        android:scaleType=\"center\"\n        android:layout_gravity=\"center_horizontal\" />\n\n    <Button\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"拍照并保存本地\"\n        android:background=\"@color/border_dark\"\n        android:id=\"@+id/button\"\n        android:layout_gravity=\"center_horizontal\"\n        android:layout_alignParentBottom=\"true\"\n        android:layout_centerHorizontal=\"true\"\n        android:layout_marginBottom=\"43dp\" />\n</RelativeLayout>"
  },
  {
    "path": "module_video/src/main/res/layout/video_fragment_video_home.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.constraint.ConstraintLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <Button\n        android:id=\"@+id/button2\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"video_fragment_video_home\"\n        tools:layout_editor_absoluteX=\"73dp\"\n        tools:layout_editor_absoluteY=\"231dp\" />\n</android.support.constraint.ConstraintLayout>"
  },
  {
    "path": "module_video/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"colorPrimaryDark\">#303F9F</color>\n    <color name=\"colorAccent\">#FF4081</color>\n</resources>\n"
  },
  {
    "path": "module_video/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">module_video</string>\n</resources>\n"
  },
  {
    "path": "module_video/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "settings.gradle",
    "content": "include ':app', ':module_video', ':module_user', ':base', ':module_home', ':module_meizi'\n"
  }
]