Showing preview only (489K chars total). Download the full file or copy to clipboard to get everything.
Repository: malonecoder/Awesome-Kotlin-WanAndroid
Branch: master
Commit: 2bf7cfa3624f
Files: 192
Total size: 419.2 KB
Directory structure:
gitextract_0t5_wqvy/
├── .gitignore
├── .idea/
│ ├── codeStyles/
│ │ ├── Project.xml
│ │ └── codeStyleConfig.xml
│ ├── compiler.xml
│ ├── encodings.xml
│ ├── gradle.xml
│ ├── inspectionProfiles/
│ │ └── Project_Default.xml
│ ├── misc.xml
│ ├── runConfigurations.xml
│ └── vcs.xml
├── README.md
├── app/
│ ├── .gitignore
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src/
│ ├── androidTest/
│ │ └── java/
│ │ └── com/
│ │ └── lxm/
│ │ └── wanandroid/
│ │ └── ExampleInstrumentedTest.kt
│ ├── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── lxm/
│ │ │ └── wanandroid/
│ │ │ ├── MainActivity.kt
│ │ │ ├── repository/
│ │ │ │ ├── model/
│ │ │ │ │ ├── ArticleResponse.kt
│ │ │ │ │ ├── Banner.kt
│ │ │ │ │ ├── HttpResponse.kt
│ │ │ │ │ ├── Listing.kt
│ │ │ │ │ ├── LoginBean.kt
│ │ │ │ │ ├── Navigation.kt
│ │ │ │ │ ├── Resource.kt
│ │ │ │ │ ├── TreeBean.kt
│ │ │ │ │ └── WelfareResponse.kt
│ │ │ │ └── remote/
│ │ │ │ ├── LoginResposity.kt
│ │ │ │ └── httpClient/
│ │ │ │ ├── API.kt
│ │ │ │ └── RetrofitClient.kt
│ │ │ ├── ui/
│ │ │ │ ├── ArticleFragment.kt
│ │ │ │ ├── CollectActivity.kt
│ │ │ │ ├── LoginActivity.kt
│ │ │ │ ├── NavigationFragment.kt
│ │ │ │ ├── ProjectFragment.kt
│ │ │ │ ├── TagArticleActivity.kt
│ │ │ │ ├── TreeFragment.kt
│ │ │ │ ├── ViewBigImageActivity.kt
│ │ │ │ ├── WelfareFragment.kt
│ │ │ │ ├── adapter/
│ │ │ │ │ ├── ArticleAdapter.kt
│ │ │ │ │ ├── NaviAdapter.kt
│ │ │ │ │ ├── TreeAdapter.kt
│ │ │ │ │ └── WelfareAdapter.kt
│ │ │ │ └── base/
│ │ │ │ ├── BaseRecyclerAdapter.kt
│ │ │ │ ├── BaseRecyclerViewHoder.kt
│ │ │ │ ├── OnItemClickListener.kt
│ │ │ │ └── OnItemLongClickListener.kt
│ │ │ ├── utils/
│ │ │ │ ├── CookieUtils.kt
│ │ │ │ ├── GlideUtil.kt
│ │ │ │ └── webview/
│ │ │ │ ├── WebViewActivity.java
│ │ │ │ └── config/
│ │ │ │ ├── FullscreenHolder.java
│ │ │ │ ├── IWebPageView.java
│ │ │ │ ├── ImageClickInterface.java
│ │ │ │ ├── MyWebChromeClient.java
│ │ │ │ └── MyWebViewClient.java
│ │ │ └── viewmodel/
│ │ │ ├── ArticleViewModel.kt
│ │ │ ├── CategoryViewModel.kt
│ │ │ ├── CollectViewModel.kt
│ │ │ ├── LoginViewModel.kt
│ │ │ ├── NaviViewModelView.kt
│ │ │ ├── ProjectViewModel.kt
│ │ │ ├── TreeViewModel.kt
│ │ │ └── WelfareModelView.kt
│ │ └── res/
│ │ ├── drawable/
│ │ │ ├── ic_launcher_background.xml
│ │ │ ├── process_bg.xml
│ │ │ ├── selector_bg_tree_tag.xml
│ │ │ └── selector_collect_check.xml
│ │ ├── drawable-v24/
│ │ │ └── ic_launcher_foreground.xml
│ │ ├── layout/
│ │ │ ├── activity_collection.xml
│ │ │ ├── activity_login.xml
│ │ │ ├── activity_main.xml
│ │ │ ├── activity_show_image.xml
│ │ │ ├── activity_web_view.xml
│ │ │ ├── article_banner.xml
│ │ │ ├── article_fragment.xml
│ │ │ ├── category_activity.xml
│ │ │ ├── drawer_header_layout.xml
│ │ │ ├── item_article.xml
│ │ │ ├── item_banner.xml
│ │ │ ├── item_image_view_pager.xml
│ │ │ ├── item_tree.xml
│ │ │ ├── item_tree_tag.xml
│ │ │ ├── item_view.xml
│ │ │ ├── item_view_welfare.xml
│ │ │ ├── main_content.xml
│ │ │ └── tree_fragment.xml
│ │ ├── menu/
│ │ │ ├── main.xml
│ │ │ ├── navigation.xml
│ │ │ └── webview_menu.xml
│ │ ├── mipmap-anydpi-v26/
│ │ │ ├── ic_launcher.xml
│ │ │ └── ic_launcher_round.xml
│ │ └── values/
│ │ ├── attrs_circle_view.xml
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test/
│ └── java/
│ └── com/
│ └── lxm/
│ └── wanandroid/
│ └── ExampleUnitTest.kt
├── build.gradle
├── gradle/
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── module_library/
│ ├── .gitignore
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src/
│ ├── androidTest/
│ │ └── java/
│ │ └── com/
│ │ └── lxm/
│ │ └── module_library/
│ │ └── ExampleInstrumentedTest.java
│ ├── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── lxm/
│ │ │ └── module_library/
│ │ │ ├── anim/
│ │ │ │ ├── AnimManager.kt
│ │ │ │ ├── AnimUtils.kt
│ │ │ │ └── ToolbarAnimManager.kt
│ │ │ ├── base/
│ │ │ │ ├── BaseActivity.kt
│ │ │ │ ├── BaseFragment.kt
│ │ │ │ ├── BaseViewModel.kt
│ │ │ │ └── NoViewModel.java
│ │ │ ├── global/
│ │ │ │ ├── AppManager.java
│ │ │ │ └── GlobalApplication.java
│ │ │ ├── helper/
│ │ │ │ ├── RetrofitCreateHelper.java
│ │ │ │ ├── RxHelper.java
│ │ │ │ └── okhttp/
│ │ │ │ ├── TrustManager.java
│ │ │ │ ├── cache/
│ │ │ │ │ ├── CacheInterceptor.java
│ │ │ │ │ └── HttpCache.java
│ │ │ │ └── cookies/
│ │ │ │ ├── CookieManger.java
│ │ │ │ ├── OkHttpCookies.java
│ │ │ │ └── PersistentCookieStore.java
│ │ │ ├── materialLogin/
│ │ │ │ ├── DefaultLoginView.java
│ │ │ │ ├── DefaultRegisterView.java
│ │ │ │ ├── MaterialLoginView.java
│ │ │ │ └── RegisterView.java
│ │ │ ├── statusbar/
│ │ │ │ ├── StatusBarUtil.java
│ │ │ │ └── StatusBarView.java
│ │ │ ├── utils/
│ │ │ │ ├── AppUtils.kt
│ │ │ │ ├── BaseTools.java
│ │ │ │ ├── BitmapUtils.kt
│ │ │ │ ├── CheckNetwork.java
│ │ │ │ ├── ClassUtil.kt
│ │ │ │ ├── DateUtils.kt
│ │ │ │ ├── DialogUtils.kt
│ │ │ │ ├── DisplayUtils.kt
│ │ │ │ ├── FileUtils.kt
│ │ │ │ ├── HtmlUtils.kt
│ │ │ │ ├── HttpUtils.kt
│ │ │ │ ├── ImageUtils.kt
│ │ │ │ ├── JsonUtils.kt
│ │ │ │ ├── MD5Utils.kt
│ │ │ │ ├── MyDividerItemDecoration.java
│ │ │ │ ├── NetworkConnectionUtils.kt
│ │ │ │ ├── PreferencesUtil.kt
│ │ │ │ ├── RefreshHelper.kt
│ │ │ │ ├── ResourcesUtils.kt
│ │ │ │ ├── ScreenAdapterUtils.kt
│ │ │ │ ├── ScreenUtils.kt
│ │ │ │ ├── SnackbarUtils.kt
│ │ │ │ ├── StatusBarUtils.kt
│ │ │ │ ├── StringUtils.kt
│ │ │ │ ├── TimestampUtils.kt
│ │ │ │ ├── ToastUtil.java
│ │ │ │ ├── ToastUtils.kt
│ │ │ │ ├── UnicodeUtils.kt
│ │ │ │ └── WifiAutoConnectManager.kt
│ │ │ └── xrecycleview/
│ │ │ ├── BaseRefreshHeader.java
│ │ │ ├── LoadingMoreFooter.java
│ │ │ ├── WrapAdapter.java
│ │ │ ├── XRecyclerView.java
│ │ │ └── YunRefreshHeader.java
│ │ └── res/
│ │ ├── drawable/
│ │ │ ├── app_loading_anim.xml
│ │ │ ├── common_progress_cirle.xml
│ │ │ ├── header_loading_anim.xml
│ │ │ ├── ic_add.xml
│ │ │ ├── ic_clear.xml
│ │ │ ├── login_back.xml
│ │ │ └── shape_line.xml
│ │ ├── layout/
│ │ │ ├── activity_base.xml
│ │ │ ├── custom_login_view.xml
│ │ │ ├── custom_register_view.xml
│ │ │ ├── default_login_view.xml
│ │ │ ├── default_register_view.xml
│ │ │ ├── fragment_base.xml
│ │ │ ├── layout_loading_error.xml
│ │ │ ├── layout_loading_view.xml
│ │ │ ├── login_layout.xml
│ │ │ ├── login_view.xml
│ │ │ ├── refresh_footer.xml
│ │ │ ├── refresh_header.xml
│ │ │ └── register_layout.xml
│ │ ├── values/
│ │ │ ├── attrs.xml
│ │ │ ├── colors.xml
│ │ │ ├── dimen.xml
│ │ │ ├── drawables.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ └── values-w600dp/
│ │ └── dimen.xml
│ └── test/
│ └── java/
│ └── com/
│ └── lxm/
│ └── module_library/
│ └── ExampleUnitTest.java
└── settings.gradle
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
================================================
FILE: .idea/codeStyles/Project.xml
================================================
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<JetCodeStyleSettings>
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings>
<codeStyleSettings language="XML">
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:android</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:id</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>style</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>ANDROID_ATTRIBUTE_ORDER</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
<codeStyleSettings language="kotlin">
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</codeStyleSettings>
</code_scheme>
</component>
================================================
FILE: .idea/codeStyles/codeStyleConfig.xml
================================================
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>
================================================
FILE: .idea/compiler.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<wildcardResourcePatterns>
<entry name="!?*.java" />
<entry name="!?*.form" />
<entry name="!?*.class" />
<entry name="!?*.groovy" />
<entry name="!?*.scala" />
<entry name="!?*.flex" />
<entry name="!?*.kt" />
<entry name="!?*.clj" />
</wildcardResourcePatterns>
</component>
</project>
================================================
FILE: .idea/encodings.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with NO BOM">
<file url="PROJECT" charset="UTF-8" />
</component>
</project>
================================================
FILE: .idea/gradle.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
<option value="$PROJECT_DIR$/module_library" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>
================================================
FILE: .idea/inspectionProfiles/Project_Default.xml
================================================
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="JavaDoc" enabled="true" level="WARNING" enabled_by_default="true">
<option name="TOP_LEVEL_CLASS_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="INNER_CLASS_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="METHOD_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="@return@param@throws or @exception" />
</value>
</option>
<option name="FIELD_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="IGNORE_DEPRECATED" value="false" />
<option name="IGNORE_JAVADOC_PERIOD" value="true" />
<option name="IGNORE_DUPLICATED_THROWS" value="false" />
<option name="IGNORE_POINT_TO_ITSELF" value="false" />
<option name="myAdditionalJavadocTags" value="date" />
</inspection_tool>
</profile>
</component>
================================================
FILE: .idea/misc.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CMakeSettings">
<configurations>
<configuration PROFILE_NAME="Debug" CONFIG_NAME="Debug" />
</configurations>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>
================================================
FILE: .idea/runConfigurations.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>
================================================
FILE: .idea/vcs.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
================================================
FILE: README.md
================================================
# Awesome-Kotlin-WanAndroid
## 简介
项目主要用来入门`kotlin`语言和google推荐的`MVVM`架构,使用了一些`Jetpack`组件来配合MVVM使用,采用了很多流行的开源库,`Okhttp`,`Retrofit`,`Rxjava`,`Glide`,`Livedatabus`等,代码逻辑简单易懂,仅适用入门
## 项目功能列表截图
<img src="https://raw.githubusercontent.com/malonecoder/Awesome-Kotlin-WanAndroid/master/screenshots/%E7%9B%AE%E5%BD%95.webp" width=280 height=500 /><img src="https://raw.githubusercontent.com/malonecoder/Awesome-Kotlin-WanAndroid/master/screenshots/%E4%B8%BB%E9%A1%B5%E4%BE%A7%E6%BB%91%E8%8F%9C%E5%8D%95.webp" width=280 height=500 />
<img src="https://raw.githubusercontent.com/malonecoder/Awesome-Kotlin-WanAndroid/master/screenshots/%E6%B3%A8%E5%86%8C.webp" width=280 height=500 />
<img src="https://raw.githubusercontent.com/malonecoder/Awesome-Kotlin-WanAndroid/master/screenshots/%E7%9F%A5%E8%AF%86%E4%BD%93%E7%B3%BB.webp" width=280 height=500 />
<img src="https://raw.githubusercontent.com/malonecoder/Awesome-Kotlin-WanAndroid/master/screenshots/%E7%A6%8F%E5%88%A9.webp" width=280 height=500 />
<img src="https://raw.githubusercontent.com/malonecoder/Awesome-Kotlin-WanAndroid/master/screenshots/%E5%AF%BC%E8%88%AA.webp" width=280 height=500 />
<img src="https://raw.githubusercontent.com/malonecoder/Awesome-Kotlin-WanAndroid/master/screenshots/%E9%A6%96%E9%A1%B5.webp" width=280 height=500 />
<img src="https://raw.githubusercontent.com/malonecoder/Awesome-Kotlin-WanAndroid/master/screenshots/%E6%94%B6%E8%97%8F.webp" width=280 height=500 />
## 功能TODO List
- [x] 首页
- [x] 知识体系
- [x] 导航
- [x] 项目
- [x] 福利
- [x] 登录/登出
- [x] 我的收藏
- [ ] 欢迎页
- [ ] 热门搜索
- [ ] 待办清单功能
- [ ] 网络层切换协程
- [ ] 代码整体优化
## 使用的开源库
* [Retrofit](https://github.com/square/retrofit)
* [Okhttp](https://github.com/square/okhttp)
* [Rxjava](https://github.com/ReactiveX/RxJava)
* [Glide](https://github.com/bumptech/glide)
* [LiveDataBus](https://github.com/JeremyLiao/LiveEventBus)
* [glide-transformations](https://github.com/wasabeef/glide-transformations)
* [toastcompat](https://github.com/PureWriter/ToastCompat)
* [circleimageview](https://github.com/hdodenhof/CircleImageView)
* [PhotoView](https://github.com/chrisbanes/PhotoView)
* [flowlayout](https://github.com/hongyangAndroid/FlowLayout)
* [MZBannerView](https://github.com/pinguo-zhouwei/MZBannerView)
* [MaterialLogin](https://github.com/shem8/MaterialLogin)
* [AgentWeb](https://github.com/Justson/AgentWeb)
## 非常感谢
* [CloudReader](https://github.com/youlookwhat/CloudReader)
* [WanAndroid Open API](https://www.wanandroid.com/blog/show/2)
* [Gan Open API](https://gank.io/)
* [界面参考](https://flutterchina.club/app/gm.html)
* [ICON素材](https://www.iconfont.cn/)
================================================
FILE: app/.gitignore
================================================
/build
================================================
FILE: app/build.gradle
================================================
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.lxm.wanandroid"
minSdkVersion 21
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
}
dataBinding {
enabled = true
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.android.support:design:28.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation project(':module_library')
implementation 'com.google.android.gms:play-services-plus:15.0.1'
implementation 'com.flyco.tablayout:FlycoTabLayout_Lib:2.1.2@aar'
implementation 'android.arch.lifecycle:extensions:1.1.1'
implementation 'com.android.support:design:28.0.0-rc01'
implementation 'com.just.agentweb:agentweb:4.0.2'
// Navigation
def nav_version = "1.0.0-alpha06"
implementation "android.arch.navigation:navigation-fragment:$nav_version"
implementation "android.arch.navigation:navigation-ui:$nav_version"
androidTestImplementation "android.arch.navigation:navigation-testing:$nav_version"
implementation "org.jetbrains.kotlin:kotlin-reflect:1.2.60"
//Room
def room_version = "1.1.1"
implementation "android.arch.persistence.room:runtime:$room_version"
kapt "android.arch.persistence.room:compiler:$room_version"
implementation "android.arch.persistence.room:rxjava2:$room_version"
implementation "android.arch.persistence.room:guava:$room_version"
testImplementation "android.arch.persistence.room:testing:$room_version"
//首页banner
implementation 'com.github.pinguo-zhouwei:MZBannerView:v2.0.2'
//体系flowlayout
implementation 'com.hyman:flowlayout-lib:1.1.2'
//大图查看
implementation 'com.github.chrisbanes:PhotoView:1.2'
//圆形头像
implementation 'de.hdodenhof:circleimageview:3.0.0'
//livedataBus
implementation 'com.jeremyliao:live-event-bus:1.4.4'
}
================================================
FILE: app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
================================================
FILE: app/src/androidTest/java/com/lxm/wanandroid/ExampleInstrumentedTest.kt
================================================
package com.lxm.wanandroid
import android.support.test.InstrumentationRegistry
import android.support.test.runner.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getTargetContext()
assertEquals("com.lxm.wanandroid", appContext.packageName)
}
}
================================================
FILE: app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.lxm.wanandroid">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:usesCleartextTraffic="true"
android:name="com.lxm.module_library.global.GlobalApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:configChanges="orientation|screenSize"
android:hardwareAccelerated="true"
android:launchMode="singleTask"
android:screenOrientation="portrait"
android:name=".utils.webview.WebViewActivity"></activity>
<activity android:name=".ui.TagArticleActivity"></activity>
<activity android:name=".ui.ViewBigImageActivity"></activity>
<activity android:name=".ui.LoginActivity"></activity>
<activity android:name=".ui.CollectActivity"></activity>
</application>
</manifest>
================================================
FILE: app/src/main/java/com/lxm/wanandroid/MainActivity.kt
================================================
package com.lxm.wanandroid
import android.arch.lifecycle.Observer
import android.arch.lifecycle.ViewModel
import android.arch.lifecycle.ViewModelProvider
import android.arch.lifecycle.ViewModelProviders
import android.content.Intent
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v4.app.FragmentManager
import android.support.v4.app.FragmentPagerAdapter
import android.support.v7.app.AppCompatActivity
import android.view.Gravity
import android.view.KeyEvent
import android.view.Menu
import android.view.MenuItem
import android.widget.TextView
import com.jeremyliao.liveeventbus.LiveEventBus
import com.lxm.module_library.helper.okhttp.cookies.CookieManger
import com.lxm.module_library.statusbar.StatusBarUtil
import com.lxm.module_library.utils.PreferencesUtil
import com.lxm.module_library.utils.ToastUtils
import com.lxm.wanandroid.repository.remote.LoginRepository
import com.lxm.wanandroid.ui.*
import com.lxm.wanandroid.viewmodel.LoginViewModel
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.main_content.*
const val PHOTO_URL = "https://cdn.duitang.com/uploads/blog/201404/22/20140422142715_8GtUk.thumb.600_0.jpeg"
class MainActivity : AppCompatActivity() {
private val mTitles by lazy {
mutableListOf("主页", "知识体系", "导航", "项目", "福利")
}
private val mFragments: MutableList<Fragment> by lazy {
mutableListOf<Fragment>()
}
private val mAdapter: MyPagerAdapter by lazy {
MyPagerAdapter(supportFragmentManager)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
StatusBarUtil.setColor(this, resources.getColor(R.color.colorTheme), 0)
setSupportActionBar(toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(false)
iv_photo.setOnClickListener {
drawerLayout.openDrawer(Gravity.START)
}
var loginViewModel = ViewModelProviders.of(this@MainActivity, object : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return LoginViewModel(LoginRepository()) as T
}
})[LoginViewModel::class.java]
var textView = navigationView.getHeaderView(0).findViewById<TextView>(R.id.tvUserName)
textView.text = "萧兮易水寒"
val menuItem = navigationView.menu.findItem(R.id.accout) as MenuItem
var isLogin: Boolean by PreferencesUtil<Boolean>("login", false)
if (isLogin) {
menuItem.title = "注销"
menuItem.setIcon(R.drawable.ic_logout_menu)
} else {
menuItem.title = "登陆"
menuItem.setIcon(R.drawable.ic_login_menu)
}
LiveEventBus.get()
.with(LoginActivity.LOGIN_SUCCESS, String::class.java)
.observe(this@MainActivity, Observer {
menuItem.title = "注销"
menuItem.setIcon(R.drawable.ic_logout_menu)
})
navigationView.setNavigationItemSelectedListener {
when (it.itemId) {
R.id.colletion -> {
if (isLogin) {
val intent = Intent(this@MainActivity, CollectActivity::class.java)
startActivity(intent)
} else {
val intent = Intent(this@MainActivity, LoginActivity::class.java)
startActivity(intent)
}
}
R.id.about -> {
}
R.id.accout -> {
if (isLogin) {
loginViewModel.logout()
loginViewModel.logoutStatus.observe(this@MainActivity, Observer {
if (it?.errorCode == 0) {
//退出成功 清空cookie
isLogin = false
CookieManger.clearAllCookies()
menuItem.title = "登陆"
menuItem.setIcon(R.drawable.ic_login_menu)
ToastUtils.showToast("注销成功")
}
})
} else {
val intent = Intent(this@MainActivity, LoginActivity::class.java)
startActivity(intent)
}
}
else -> {
}
}
drawerLayout.closeDrawer(Gravity.START)
true
}
mFragments.run {
add(ArticleFragment.getInstance())
add(TreeFragment.getInstance())
add(NavigationFragment.getInstance())
add(ProjectFragment.getInstance())
add(WelfareFragment.getInstance())
}
mAdapter.setFragments(mFragments)
mAdapter.setTitles(mTitles)
view_pager.adapter = mAdapter
view_pager.offscreenPageLimit = 5
tablayout.setViewPager(view_pager)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.main, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.action_search -> {
true
}
else -> super.onOptionsItemSelected(item)
}
}
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (drawerLayout.isDrawerOpen(Gravity.START)) {
drawerLayout.closeDrawer(Gravity.START)
return true
}
}
return super.onKeyDown(keyCode, event)
}
}
class MyPagerAdapter(fragmentManager: FragmentManager) : FragmentPagerAdapter(fragmentManager) {
var fragmentList: MutableList<Fragment> = mutableListOf()
var titleList: MutableList<String> = mutableListOf()
override fun getCount(): Int {
return fragmentList.size
}
override fun getItem(p0: Int): Fragment {
return fragmentList[p0]
}
override fun getPageTitle(position: Int): CharSequence? {
return titleList[position]
}
fun setFragments(fragment: MutableList<Fragment>) {
fragmentList = fragment;
}
fun setTitles(mTitles: MutableList<String>) {
titleList = mTitles
}
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/repository/model/ArticleResponse.kt
================================================
package com.lxm.wanandroid.repository.model
/**
* curPage : 1
* datas : [{"apkLink":"","author":"红橙Darren","chapterId":245,"chapterName":"集合相关","collect":false,"courseId":13,"desc":"","envelopePic":"","fresh":false,"id":3326,"link":"https://www.jianshu.com/p/9edd74769f21","niceDate":"2018-08-27","origin":"","projectLink":"","publishTime":1535372956000,"superChapterId":245,"superChapterName":"Java深入","tags":[],"title":"数据结构算法 - 栈和队列","type":0,"userId":-1,"visible":1,"zan":0}]
* offset : 0
* over : false
* pageCount : 80
* size : 20
* total : 1596
*/
data class ArticleResponseBody<T>(var curPage: Int = 0,
var offset: Int = 0,
var isOver: Boolean = false,
var pageCount: Int = 0,
var size: Int = 0,
var total: Int = 0,
var datas: List<T>? = null)
/**
* apkLink :
* author : 红橙Darren
* chapterId : 245
* chapterName : 集合相关
* collect : false
* courseId : 13
* desc :
* envelopePic :
* fresh : false
* id : 3326
* link : https://www.jianshu.com/p/9edd74769f21
* niceDate : 2018-08-27
* origin :
* projectLink :
* publishTime : 1535372956000
* superChapterId : 245
* superChapterName : Java深入
* tags : []
* title : 数据结构算法 - 栈和队列
* type : 0
* userId : -1
* visible : 1
* zan : 0
*/
data class ArticleBean(var apkLink: String? = null,
var author: String? = null,
var chapterId: Int = 0,
var chapterName: String? = null,
var collect: Boolean = false,
var courseId: Int = 0,
var desc: String? = null,
var envelopePic: String? = null,
var fresh: Boolean = false,
var id: Int = 0,
var link: String? = null,
var niceDate: String? = null,
var origin: String? = null,
var originId: Int? = null,
var projectLink: String? = null,
var publishTime: Long = 0,
var superChapterId: Int = 0,
var superChapterName: String? = null,
var title: String? = null,
var type: Int = 0,
var userId: Int = 0,
var visible: Int = 0,
var zan: Int = 0,
var tags: List<Project>? = null)
data class Project(var name:String?,var url:String?)
================================================
FILE: app/src/main/java/com/lxm/wanandroid/repository/model/Banner.kt
================================================
package com.lxm.wanandroid.repository.model
data class Banner(
val desc: String,
val id: Int,
val imagePath: String,
val isVisible: Int,
val order: Int,
val title: String,
val type: Int,
val url: String
)
================================================
FILE: app/src/main/java/com/lxm/wanandroid/repository/model/HttpResponse.kt
================================================
package com.lxm.wanandroid.repository.model
/**
* data : {"curPage":1,"datas":[{"apkLink":"","author":"红橙Darren","chapterId":245,"chapterName":"集合相关","collect":false,"courseId":13,"desc":"","envelopePic":"","fresh":false,"id":3326,"link":"https://www.jianshu.com/p/9edd74769f21","niceDate":"2018-08-27","origin":"","projectLink":"","publishTime":1535372956000,"superChapterId":245,"superChapterName":"Java深入","tags":[],"title":"数据结构算法 - 栈和队列","type":0,"userId":-1,"visible":1,"zan":0}],"offset":0,"over":false,"pageCount":80,"size":20,"total":1596}
* errorCode : 0
* errorMsg :
*/
data class HttpResponse<T>(
var data: T? = null,
var errorCode: Int = 0,
var errorMsg: String? = null
)
================================================
FILE: app/src/main/java/com/lxm/wanandroid/repository/model/Listing.kt
================================================
package com.lxm.wanandroid.repository.model
import android.arch.lifecycle.MutableLiveData
data class Listing<T>(
val pagedList: MutableLiveData<T>,
val loadStatus: MutableLiveData<Resource<String>>
)
================================================
FILE: app/src/main/java/com/lxm/wanandroid/repository/model/LoginBean.kt
================================================
package com.lxm.wanandroid.repository.model
data class LoginBean(
val admin: Boolean,
val chapterTops: List<Any>,
val collectIds: List<Int>,
val email: String,
val icon: String,
val id: Int,
val nickname: String,
val password: String,
val token: String,
val type: Int,
val username: String
)
================================================
FILE: app/src/main/java/com/lxm/wanandroid/repository/model/Navigation.kt
================================================
package com.lxm.wanandroid.repository.model
data class Navigation(
val articles: List<ArticleBean>,
val cid: Int,
val name: String
)
================================================
FILE: app/src/main/java/com/lxm/wanandroid/repository/model/Resource.kt
================================================
package com.lxm.wanandroid.repository.model
/**
* Created by juan on 2018/05/23.
*/
data class Resource<out T>(val status: Status, val data: T?, val message: String?) {
companion object {
fun <T> loading(msg: String? = null, data: T? = null): Resource<T> {
return Resource(Status.LOADING, data, msg)
}
fun <T> success(data: T? = null): Resource<T> {
return Resource(Status.SUCCESS, data, null)
}
fun <T> error(msg: String? = null, data: T? = null): Resource<T> {
return Resource(Status.ERROR, data, msg)
}
}
}
enum class Status {
SUCCESS,
ERROR,
LOADING
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/repository/model/TreeBean.kt
================================================
package com.lxm.wanandroid.repository.model
import java.io.Serializable
data class TreeBean(
val children: List<TreeBean>,
val courseId: Int,
val id: Int,
val name: String,
val order: Int,
val parentChapterId: Int,
val userControlSetTop: Boolean,
val visible: Int
):Serializable
================================================
FILE: app/src/main/java/com/lxm/wanandroid/repository/model/WelfareResponse.kt
================================================
package com.lxm.wanandroid.repository.model
data class WelfareResponse(
val error: Boolean,
val results: List<Welfare>
)
data class Welfare(
val _id: String,
val createdAt: String,
val desc: String,
val publishedAt: String,
val source: String,
val type: String,
val url: String,
val used: Boolean,
val who: String
)
================================================
FILE: app/src/main/java/com/lxm/wanandroid/repository/remote/LoginResposity.kt
================================================
package com.lxm.wanandroid.repository.remote
import android.arch.lifecycle.MutableLiveData
import com.lxm.module_library.helper.RxHelper
import com.lxm.wanandroid.repository.model.HttpResponse
import com.lxm.wanandroid.repository.model.LoginBean
import com.lxm.wanandroid.repository.remote.httpClient.RetrofitClient
import io.reactivex.functions.Consumer
class LoginRepository {
val login = MutableLiveData<HttpResponse<LoginBean>>()
val register = MutableLiveData<HttpResponse<LoginBean>>()
val logout = MutableLiveData<HttpResponse<Any>>()
fun login(account: String, password: String) {
RetrofitClient.getInstance(RetrofitClient.WAN_BASE_URL).login(account, password)
.compose(RxHelper.rxSchedulerHelper())
.subscribe(Consumer {
login.value = it
}, Consumer {
login.value = HttpResponse(null, 500, it.message!!)
})
}
fun register(account: String, password: String, rPassword: String) {
RetrofitClient.getInstance(RetrofitClient.WAN_BASE_URL).register(account, password, rPassword)
.compose(RxHelper.rxSchedulerHelper())
.subscribe(Consumer {
register.value = it
}, Consumer {
register.value = HttpResponse(null, 500, it.message!!)
})
}
fun logout() {
RetrofitClient.getInstance(RetrofitClient.WAN_BASE_URL).logout()
.compose(RxHelper.rxSchedulerHelper())
.subscribe(Consumer {
logout.value = it
}, Consumer {
logout.value = HttpResponse(null, 500, it.message!!)
})
}
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/repository/remote/httpClient/API.kt
================================================
package com.lxm.wanandroid.repository.remote.httpClient
import com.lxm.wanandroid.repository.model.*
import io.reactivex.Observable
import retrofit2.http.*
interface API{
/*
*
* 获取首页新闻列表
*
* */
@GET("/article/list/{page}/json")
fun getArticleList(@Path(value = "page")page:Int):Observable<HttpResponse<ArticleResponseBody<ArticleBean>>>
/*
*
* 获取首页Banner
*
* */
@GET("/banner/json")
fun getHomeBanner():Observable<HttpResponse<List<Banner>>>
/*
*
* 获取知识体系
*
* */
@GET("/tree/json")
fun getTrees():Observable<HttpResponse<List<TreeBean>>>
/*
*
* 获取知识体系目录
* /article/list/0/json?cid=60
* */
@GET("/article/list/{page}/json")
fun getCategory(@Path(value = "page")page:Int,@Query(value = "cid")cid:Int):Observable<HttpResponse<ArticleResponseBody<ArticleBean>>>
/*
*
* 获取知识体系目录
* /navi/json
* */
@GET("/navi/json")
fun getNavigation():Observable<HttpResponse<List<Navigation>>>
/*
*
* 获取Gan福利
* /navi/json
* */
@GET("/api/data/{type}/{page_size}/{page}")
fun getWelfare(@Path("type") id: String, @Path("page_size") page_size: Int,@Path("page") page: Int): Observable<WelfareResponse>
/*
*
* 获取项目列表
*
* */
@GET("/article/listproject/{page}/json")
fun getProjectList(@Path(value = "page")page:Int):Observable<HttpResponse<ArticleResponseBody<ArticleBean>>>
/**
* 登录
*/
@FormUrlEncoded
@POST("/user/login")
fun login(@Field(value = "username")username: String, @Field(value = "password")password: String): Observable<HttpResponse<LoginBean>>
/**
* 注销
* https://www.wanandroid.com/user/logout/json
*/
@GET("/user/logout/json")
fun logout():Observable<HttpResponse<Any>>
/**
* 注册
*/
@FormUrlEncoded
@POST("/user/register")
fun register(@Field(value = "username")account: String, @Field(value = "password")password: String, @Field(value = "repassword")rPassword: String): Observable<HttpResponse<LoginBean>>
/**
* 我的收藏列表
* lg/collect/list/0/json
*/
@GET("/lg/collect/list/{page}/json")
fun getCollectList(@Path(value = "page")page:Int):Observable<HttpResponse<ArticleResponseBody<ArticleBean>>>
/**
* 收藏
* https://www.wanandroid.com/lg/collect/1165/json
*/
@POST("/lg/collect/{id}/json")
fun collect(@Path(value = "id")id:Int):Observable<HttpResponse<Any>>
/**
* 取消收藏
* https://www.wanandroid.com/lg/uncollect_originId/2333/json
*/
@POST("/lg/uncollect_originId/{id}/json")
fun unCollect(@Path(value = "id")id:Int):Observable<HttpResponse<Any>>
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/repository/remote/httpClient/RetrofitClient.kt
================================================
package com.lxm.wanandroid.repository.remote.httpClient
import com.lxm.module_library.helper.RetrofitCreateHelper
object RetrofitClient {
const val WAN_BASE_URL = "https://www.wanandroid.com"
const val GAN_BASE_URL = "https://gank.io"
private var api: API? = null
fun getInstance(type: String): API {
api = RetrofitCreateHelper.createApi(API::class.java, type)
return api!!
}
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/ui/ArticleFragment.kt
================================================
package com.lxm.wanandroid.ui
import android.arch.lifecycle.Observer
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.widget.ImageView
import com.lxm.module_library.base.BaseFragment
import com.lxm.module_library.utils.RefreshHelper
import com.lxm.module_library.xrecycleview.XRecyclerView
import com.lxm.wanandroid.R
import com.lxm.wanandroid.repository.model.ArticleBean
import com.lxm.wanandroid.repository.model.Banner
import com.lxm.wanandroid.repository.model.Status
import com.lxm.wanandroid.ui.adapter.ArticleAdapter
import com.lxm.wanandroid.ui.base.OnItemClickListener
import com.lxm.wanandroid.utils.GlideUtil
import com.lxm.wanandroid.utils.webview.WebViewActivity
import com.lxm.wanandroid.viewmodel.ArticleViewModel
import com.zhouwei.mzbanner.holder.MZViewHolder
import kotlinx.android.synthetic.main.article_banner.*
import kotlinx.android.synthetic.main.article_fragment.*
class ArticleFragment : BaseFragment<ArticleViewModel>() {
private lateinit var headerView: View
private var bannerList : List<Banner>? = null
private val mAdapter: ArticleAdapter by lazy {
ArticleAdapter()
}
override fun getLayoutID(): Int {
return R.layout.article_fragment
}
companion object {
fun getInstance(): ArticleFragment {
return ArticleFragment()
}
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
showContentView()
initView()
}
private fun initView() {
swipeLayout.setOnRefreshListener {
viewModel.mPage = 0
loadData()
}
swipeLayout.isRefreshing = true
RefreshHelper.init(recyclerView, false)
headerView = layoutInflater.inflate(R.layout.article_banner, null)
recyclerView.addHeaderView(headerView)
recyclerView.adapter = mAdapter
recyclerView.setLoadingListener(object : XRecyclerView.LoadingListener {
override fun onLoadMore() {
viewModel.mPage = viewModel.mPage + 1;
getHomeList()
}
override fun onRefresh() {
}
})
viewModel.loadStatus.observe(this, Observer {
when (it?.status) {
Status.ERROR -> showError()
Status.SUCCESS -> showContentView()
}
})
viewModel.pagedList.observe(this, Observer {
swipeLayout.isRefreshing = false
if (it == null) {
return@Observer
}
if(viewModel.mPage ==0){
mAdapter.setData(it.data?.datas!!)
return@Observer
}
mAdapter.addDataAll(it.data?.datas!!)
if(it?.data?.datas?.size!! < it?.data?.size!!){
recyclerView.noMoreLoading()
}else{
recyclerView.refreshComplete()
}
})
mAdapter.setOnItemClickListener(object : OnItemClickListener<ArticleBean> {
override fun onClick(t: ArticleBean, position: Int) {
WebViewActivity.loadUrl(activity, t.link, t.title)
}
})
}
private fun getBanners() {
viewModel.getBanners().observe(this@ArticleFragment, Observer {
bannerList = it?.data
banner.setBannerPageClickListener { view, i ->
WebViewActivity.loadUrl(activity, it?.data?.get(i)?.url,null)
}
banner.setPages(
it?.data as List<Nothing>?
) {
BannerViewHolder()
}
banner.start()
})
}
class BannerViewHolder : MZViewHolder<Banner> {
private var mImageView: ImageView? = null
override fun createView(context: Context): View {
val view = LayoutInflater.from(context).inflate(R.layout.item_banner, null)
mImageView = view.findViewById(R.id.banner_image) as ImageView
return view
}
override fun onBind(context: Context, position: Int, data: Banner?) {
data?.let {
GlideUtil.displayCircleCorner(mImageView!!, it.imagePath)
}
}
}
override fun onRetry() {
loadData()
}
override fun loadData() {
getHomeList()
getBanners()
}
private fun getHomeList() {
this.viewModel.getHomeList()
}
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/ui/CollectActivity.kt
================================================
package com.lxm.wanandroid.ui
import android.arch.lifecycle.Observer
import android.os.Bundle
import com.lxm.module_library.base.BaseActivity
import com.lxm.module_library.utils.RefreshHelper
import com.lxm.module_library.xrecycleview.XRecyclerView
import com.lxm.wanandroid.R
import com.lxm.wanandroid.repository.model.ArticleBean
import com.lxm.wanandroid.repository.model.Status
import com.lxm.wanandroid.ui.adapter.ArticleAdapter
import com.lxm.wanandroid.ui.base.OnItemClickListener
import com.lxm.wanandroid.utils.webview.WebViewActivity
import com.lxm.wanandroid.viewmodel.CollectViewModel
import kotlinx.android.synthetic.main.article_fragment.*
class CollectActivity : BaseActivity<CollectViewModel>() {
private val mAdapter: ArticleAdapter by lazy {
ArticleAdapter()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.article_fragment)
setTitle("我的收藏")
initView()
getCollection()
}
private fun initView() {
swipeLayout.setOnRefreshListener {
swipeLayout.isRefreshing = true
viewModel.mPage = 0
getCollection()
}
RefreshHelper.init(recyclerView, false)
mAdapter.isCollectionList = true
recyclerView.adapter = mAdapter
recyclerView.setLoadingListener(object : XRecyclerView.LoadingListener {
override fun onLoadMore() {
viewModel.mPage = viewModel.mPage + 1;
getCollection()
}
override fun onRefresh() {
}
})
showLoading()
viewModel.loadStatus.observe(this, Observer {
when (it?.status) {
// Status.ERROR -> showError()
Status.SUCCESS -> showContentView()
}
})
this.viewModel.collectionList.observe(this, Observer {
swipeLayout.isRefreshing = false
if (it == null) {
return@Observer
}
if(viewModel.mPage ==0){
mAdapter.setData(it.data?.datas!!)
return@Observer
}
mAdapter.addDataAll(it.data?.datas!!)
if(it?.data?.datas?.size!! < it?.data?.size!!){
recyclerView.noMoreLoading()
}else{
recyclerView.refreshComplete()
}
})
mAdapter.setOnItemClickListener(object : OnItemClickListener<ArticleBean> {
override fun onClick(t: ArticleBean, position: Int) {
WebViewActivity.loadUrl(this@CollectActivity, t.link, t.title)
}
})
}
private fun getCollection() {
viewModel.getCollect()
}
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/ui/LoginActivity.kt
================================================
package com.lxm.wanandroid.ui
import android.arch.lifecycle.Observer
import android.arch.lifecycle.ViewModel
import android.arch.lifecycle.ViewModelProvider
import android.arch.lifecycle.ViewModelProviders
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.text.TextUtils
import android.view.View
import android.widget.Toast
import com.jeremyliao.liveeventbus.LiveEventBus
import com.lxm.module_library.materialLogin.DefaultLoginView
import com.lxm.module_library.materialLogin.DefaultRegisterView
import com.lxm.module_library.materialLogin.MaterialLoginView
import com.lxm.module_library.statusbar.StatusBarUtil
import com.lxm.module_library.utils.PreferencesUtil
import com.lxm.module_library.utils.ToastUtils
import com.lxm.wanandroid.R
import com.lxm.wanandroid.repository.remote.LoginRepository
import com.lxm.wanandroid.viewmodel.LoginViewModel
import kotlinx.android.synthetic.main.main_content.*
class LoginActivity : AppCompatActivity() {
companion object{
const val LOGIN_SUCCESS = "loginSuccess"
}
private lateinit var model: LoginViewModel
private lateinit var login: MaterialLoginView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
initToolbar()
initView()
initData()
}
private fun initData() {
model = ViewModelProviders.of(this@LoginActivity, object : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return LoginViewModel(LoginRepository()) as T
}
})[LoginViewModel::class.java]
model.apply {
loginStatus.observe(this@LoginActivity, Observer {
if (it?.errorCode == 0) {
//存储账号和cookie等信息
ToastUtils.showToast("登录成功", Toast.LENGTH_LONG)
var isLogin: Boolean by PreferencesUtil<Boolean>("login", false)
var userName: String by PreferencesUtil<String>("userName", "Android")
var nikeName: String by PreferencesUtil<String>("nikeName", "易水寒")
isLogin = true
userName = it.data?.username!!
nikeName = it.data?.nickname!!
LiveEventBus.get()
.with(LOGIN_SUCCESS)
.post("登录成功")
finish()
} else {
ToastUtils.showToast(it?.errorMsg!!, Toast.LENGTH_LONG)
}
})
registerStauts.observe(this@LoginActivity, Observer {
if (it?.errorCode == 0) {
login.animateLogin()
ToastUtils.showToast("注册成功,请登录", Toast.LENGTH_LONG)
} else {
ToastUtils.showToast(it?.errorMsg!!, Toast.LENGTH_LONG)
}
})
}
}
private fun initView() {
login = findViewById<View>(R.id.login) as MaterialLoginView
(login.loginView as DefaultLoginView).setListener { loginUser, loginPass ->
if (!TextUtils.isEmpty(loginUser.editText?.text) && !TextUtils.isEmpty(loginPass.editText?.text)) {
model.login(loginUser.editText?.text.toString(), loginPass.editText?.text.toString())
} else {
ToastUtils.showToast("用户名和密码不能为空", Toast.LENGTH_SHORT)
}
}
(login.registerView as DefaultRegisterView).setListener { registerUser, registerPass, registerPassRep ->
if (!TextUtils.isEmpty(registerUser.editText?.text) && !TextUtils.isEmpty(registerPass.editText?.text) &&
!TextUtils.isEmpty( registerPassRep.editText?.text)) {
model.register(
registerUser.editText?.text.toString(),
registerPass.editText?.text.toString(),
registerPassRep.editText?.text.toString()
)
} else {
ToastUtils.showToast("用户名和密码不能为空", Toast.LENGTH_SHORT)
}
}
}
private fun initToolbar() {
StatusBarUtil.setColor(this, resources.getColor(R.color.colorTheme), 0)
toolbar.setNavigationOnClickListener {
finish()
}
}
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/ui/NavigationFragment.kt
================================================
package com.lxm.wanandroid.ui
import android.arch.lifecycle.Observer
import android.os.Bundle
import android.support.v7.widget.LinearLayoutManager
import android.view.View
import com.lxm.module_library.base.BaseFragment
import com.lxm.module_library.xrecycleview.XRecyclerView
import com.lxm.wanandroid.R
import com.lxm.wanandroid.repository.model.ArticleBean
import com.lxm.wanandroid.repository.model.Status
import com.lxm.wanandroid.ui.adapter.NaviAdapter
import com.lxm.wanandroid.utils.webview.WebViewActivity
import com.lxm.wanandroid.viewmodel.NaviViewModelView
import com.zhy.view.flowlayout.FlowLayout
import kotlinx.android.synthetic.main.article_fragment.*
class NavigationFragment : BaseFragment<NaviViewModelView>() {
private val mAdapter: NaviAdapter by lazy {
NaviAdapter(itemClickListener)
}
private val itemClickListener: NaviAdapter.OnItemNavigationClickListener = object :
NaviAdapter.OnItemNavigationClickListener {
override fun itemClick(view: View, position: Int, parent: FlowLayout, articles: List<ArticleBean>) {
var article = articles[position]
WebViewActivity.loadUrl(activity, article.link, article.title)
}
}
override fun getLayoutID(): Int {
return R.layout.tree_fragment
}
companion object {
fun getInstance(): NavigationFragment {
return NavigationFragment()
}
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
showContentView()
initView()
}
private fun initView() {
swipeLayout.setOnRefreshListener {
loadData()
}
swipeLayout.isRefreshing = true
val layoutManager = LinearLayoutManager(activity)
recyclerView.layoutManager = layoutManager
recyclerView.setPullRefreshEnabled(false)
recyclerView.setLoadingMoreEnabled(false)
recyclerView.clearHeader()
recyclerView.adapter = mAdapter
recyclerView.setLoadingListener(object : XRecyclerView.LoadingListener {
override fun onLoadMore() {
getTreeList()
}
override fun onRefresh() {
}
})
viewModel.loadStatus.observe(this, Observer {
when (it?.status) {
Status.ERROR -> showError()
}
})
}
override fun onRetry() {
loadData()
}
override fun loadData() {
getTreeList()
}
private fun getTreeList() {
this.viewModel.getVavigations().observe(this@NavigationFragment, Observer {
swipeLayout.isRefreshing = false
recyclerView.refreshComplete()
it?.let { list -> mAdapter.setData(it) }
mAdapter.notifyDataSetChanged()
})
}
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/ui/ProjectFragment.kt
================================================
package com.lxm.wanandroid.ui
import android.arch.lifecycle.Observer
import android.os.Bundle
import com.lxm.module_library.base.BaseFragment
import com.lxm.module_library.utils.RefreshHelper
import com.lxm.module_library.xrecycleview.XRecyclerView
import com.lxm.wanandroid.R
import com.lxm.wanandroid.repository.model.ArticleBean
import com.lxm.wanandroid.repository.model.Banner
import com.lxm.wanandroid.repository.model.Status
import com.lxm.wanandroid.ui.adapter.ArticleAdapter
import com.lxm.wanandroid.ui.base.OnItemClickListener
import com.lxm.wanandroid.utils.webview.WebViewActivity
import com.lxm.wanandroid.viewmodel.ArticleViewModel
import com.lxm.wanandroid.viewmodel.ProjectViewModel
import kotlinx.android.synthetic.main.article_fragment.*
class ProjectFragment : BaseFragment<ProjectViewModel>() {
private val mAdapter: ArticleAdapter by lazy {
ArticleAdapter()
}
override fun getLayoutID(): Int {
return R.layout.article_fragment
}
companion object {
fun getInstance(): ProjectFragment {
return ProjectFragment()
}
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
showContentView()
initView()
}
private fun initView() {
swipeLayout.setOnRefreshListener {
viewModel.mPage = 0
loadData()
}
swipeLayout.isRefreshing = true
RefreshHelper.init(recyclerView, false)
recyclerView.adapter = mAdapter
recyclerView.setLoadingListener(object : XRecyclerView.LoadingListener {
override fun onLoadMore() {
viewModel.mPage = viewModel.mPage + 1;
getProjectList()
}
override fun onRefresh() {
}
})
viewModel.loadStatus.observe(this, Observer {
when (it?.status) {
Status.ERROR -> showError()
Status.SUCCESS -> showContentView()
}
})
this.viewModel.pagedList.observe(this, Observer {
swipeLayout.isRefreshing = false
if (it == null) {
return@Observer
}
if(viewModel.mPage ==0){
mAdapter.setData(it.data?.datas!!)
return@Observer
}
mAdapter.addDataAll(it.data?.datas!!)
if(it?.data?.datas?.size!! < it?.data?.size!!){
recyclerView.noMoreLoading()
}else{
recyclerView.refreshComplete()
}
})
mAdapter.setOnItemClickListener(object : OnItemClickListener<ArticleBean> {
override fun onClick(t: ArticleBean, position: Int) {
WebViewActivity.loadUrl(activity, t.link, t.title)
}
})
}
override fun onRetry() {
loadData()
}
override fun loadData() {
getProjectList()
}
private fun getProjectList() {
this.viewModel.getProjects()
}
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/ui/TagArticleActivity.kt
================================================
package com.lxm.wanandroid.ui
import android.arch.lifecycle.Observer
import android.os.Bundle
import com.lxm.module_library.base.BaseActivity
import com.lxm.module_library.utils.RefreshHelper
import com.lxm.module_library.xrecycleview.XRecyclerView
import com.lxm.wanandroid.R
import com.lxm.wanandroid.repository.model.ArticleBean
import com.lxm.wanandroid.repository.model.Status
import com.lxm.wanandroid.repository.model.TreeBean
import com.lxm.wanandroid.ui.adapter.ArticleAdapter
import com.lxm.wanandroid.ui.base.OnItemClickListener
import com.lxm.wanandroid.utils.webview.WebViewActivity
import com.lxm.wanandroid.viewmodel.CategoryViewModel
import kotlinx.android.synthetic.main.article_fragment.*
class TagArticleActivity: BaseActivity<CategoryViewModel>() {
lateinit var treeBean: TreeBean
private val mAdapter: ArticleAdapter by lazy {
ArticleAdapter()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.category_activity)
initView()
treeBean = intent.getSerializableExtra("TagBean") as TreeBean
setTitle(treeBean.name)
getCategory(treeBean.id)
}
private fun initView() {
swipeLayout.setOnRefreshListener {
swipeLayout.isRefreshing = true
viewModel.mPage = 0
getCategory(treeBean.id)
}
RefreshHelper.init(recyclerView, false)
recyclerView.adapter = mAdapter
recyclerView.setLoadingListener(object : XRecyclerView.LoadingListener {
override fun onLoadMore() {
viewModel.mPage = viewModel.mPage + 1;
getCategory(treeBean.id)
}
override fun onRefresh() {
}
})
showLoading()
viewModel.loadStatus.observe(this, Observer {
when (it?.status) {
// Status.ERROR -> showError()
Status.SUCCESS -> showContentView()
}
})
this.viewModel.pagedList.observe(this, Observer {
swipeLayout.isRefreshing = false
if (it == null) {
return@Observer
}
if(viewModel.mPage ==0){
mAdapter.setData(it.data?.datas!!)
return@Observer
}
mAdapter.addDataAll(it.data?.datas!!)
if(it?.data?.datas?.size!! < it?.data?.size!!){
recyclerView.noMoreLoading()
}else{
recyclerView.refreshComplete()
}
})
mAdapter.setOnItemClickListener(object : OnItemClickListener<ArticleBean> {
override fun onClick(t: ArticleBean, position: Int) {
WebViewActivity.loadUrl(this@TagArticleActivity, t.link, t.title)
}
})
}
private fun getCategory(id: Int) {
viewModel.getCategory(id)
}
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/ui/TreeFragment.kt
================================================
package com.lxm.wanandroid.ui
import android.arch.lifecycle.Observer
import android.content.Intent
import android.os.Bundle
import android.support.v7.widget.LinearLayoutManager
import android.view.View
import com.lxm.module_library.base.BaseFragment
import com.lxm.module_library.xrecycleview.XRecyclerView
import com.lxm.wanandroid.R
import com.lxm.wanandroid.repository.model.Status
import com.lxm.wanandroid.repository.model.TreeBean
import com.lxm.wanandroid.ui.adapter.TreeAdapter
import com.lxm.wanandroid.viewmodel.TreeViewModel
import com.zhy.view.flowlayout.FlowLayout
import kotlinx.android.synthetic.main.article_fragment.*
class TreeFragment : BaseFragment<TreeViewModel>() {
private val mAdapter: TreeAdapter by lazy {
TreeAdapter(itemClickListener)
}
private val itemClickListener: TreeAdapter.OnItemNavigationClickListener = object :
TreeAdapter.OnItemNavigationClickListener {
override fun itemClick(view: View, position: Int, parent: FlowLayout, children: List<TreeBean>) {
val intent = Intent(parent.context, TagArticleActivity::class.java)
intent.putExtra("TagBean", children[position])
parent.context.startActivity(intent)
}
}
override fun getLayoutID(): Int {
return R.layout.tree_fragment
}
companion object {
fun getInstance(): TreeFragment {
return TreeFragment()
}
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
showContentView()
initView()
}
private fun initView() {
swipeLayout.setOnRefreshListener {
loadData()
}
swipeLayout.isRefreshing = true
val layoutManager = LinearLayoutManager(activity)
recyclerView.layoutManager = layoutManager
recyclerView.setPullRefreshEnabled(false)
recyclerView.setLoadingMoreEnabled(false)
recyclerView.clearHeader()
recyclerView.adapter = mAdapter
recyclerView.setLoadingListener(object : XRecyclerView.LoadingListener {
override fun onLoadMore() {
getTreeList()
}
override fun onRefresh() {
}
})
viewModel.loadStatus.observe(this, Observer {
when (it?.status) {
Status.ERROR -> showError()
}
})
}
override fun onRetry() {
loadData()
}
override fun loadData() {
getTreeList()
}
private fun getTreeList() {
this.viewModel.getTrees().observe(this@TreeFragment, Observer {
swipeLayout.isRefreshing = false
recyclerView.refreshComplete()
it?.let { list -> mAdapter.setData(list) }
mAdapter.notifyDataSetChanged()
})
}
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/ui/ViewBigImageActivity.kt
================================================
package com.lxm.wanandroid.ui
import android.content.Context
import android.content.Intent
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.support.v4.app.FragmentActivity
import android.support.v4.view.PagerAdapter
import android.support.v4.view.ViewPager.OnPageChangeListener
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.ProgressBar
import com.bumptech.glide.Glide
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.Target
import com.lxm.wanandroid.R
import kotlinx.android.synthetic.main.activity_show_image.*
import uk.co.senab.photoview.PhotoView
import uk.co.senab.photoview.PhotoViewAttacher
import java.util.ArrayList
class ViewBigImageActivity : FragmentActivity(), OnPageChangeListener, PhotoViewAttacher.OnPhotoTapListener {
override fun onPhotoTap(p0: View?, p1: Float, p2: Float) {
finish()
}
/**
* 图片集合
*/
private var imageList: MutableList<String>? = null
/**
* 接收穿过来当前选择的图片的position
*/
internal var position: Int = 0
/**
* 当前页数
*/
private var page: Int = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_show_image)
getIntentData()
}
private fun getIntentData() {
val bundle = intent.extras
if (bundle != null) {
position = bundle.getInt("code")
imageList = bundle.getStringArrayList("imageList")
}
val adapter = ViewPagerAdapter()
viewpager?.adapter = adapter
viewpager?.currentItem = position
page = position
viewpager?.addOnPageChangeListener(this)
viewpager?.isEnabled = false
viewpager_text?.text = (position + 1).toString() + " / " + imageList!!.size
}
/**
* ViewPager的适配器
*/
private inner class ViewPagerAdapter internal constructor() : PagerAdapter() {
private val inflater: LayoutInflater = layoutInflater
override fun instantiateItem(container: ViewGroup, position: Int): Any {
val view = inflater.inflate(R.layout.item_image_view_pager, container, false)
val zoomImageView = view.findViewById<PhotoView>(R.id.zoom_image_view)
val progressBar = view.findViewById<ProgressBar>(R.id.loading)
// 保存网络图片的路径
val adapterImageEntity = getItem(position) as String
val imageUrl: String
imageUrl = adapterImageEntity
progressBar.visibility = View.VISIBLE
progressBar.isClickable = false
Glide.with(this@ViewBigImageActivity).load(imageUrl)
.transition(DrawableTransitionOptions.withCrossFade(700))
.listener(object : RequestListener<Drawable> {
override fun onLoadFailed(
e: GlideException?,
model: Any,
target: Target<Drawable>,
isFirstResource: Boolean
): Boolean {
return false
}
override fun onResourceReady(
resource: Drawable,
model: Any,
target: Target<Drawable>,
dataSource: DataSource,
isFirstResource: Boolean
): Boolean {
progressBar.visibility = View.GONE
/**这里应该是加载成功后图片的高,最大为屏幕的高 */
val height = resource.intrinsicHeight
val wHeight = windowManager.defaultDisplay.height
if (height < wHeight) {
zoomImageView.scaleType = ImageView.ScaleType.FIT_CENTER
} else {
zoomImageView.scaleType = ImageView.ScaleType.CENTER_CROP
}
return false
}
}).into(zoomImageView)
zoomImageView.setOnPhotoTapListener(this@ViewBigImageActivity)
container.addView(view, 0)
return view
}
override fun getCount(): Int {
return if (imageList == null || imageList?.size == 0) {
0
} else imageList!!.size
}
override fun isViewFromObject(arg0: View, arg1: Any): Boolean {
return arg0 === arg1
}
override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
val view = `object` as View
container.removeView(view)
}
private fun getItem(position: Int): Any {
return imageList!![position]
}
}
/**
* 下面是对Viewpager的监听
*/
override fun onPageScrollStateChanged(arg0: Int) {}
override fun onPageScrolled(arg0: Int, arg1: Float, arg2: Int) {}
/**
* 本方法主要监听viewpager滑动的时候的操作
* 每当页数发生改变时重新设定一遍当前的页数和总页数
*/
override fun onPageSelected(arg0: Int) {
viewpager_text?.text = (arg0 + 1).toString() + " / " + imageList!!.size
page = arg0
}
override fun onDestroy() {
imageList?.clear()
super.onDestroy()
}
companion object {
/**
* @param position 大图的话是第几张图片 从0开始
* @param imageList 图片集合
*/
fun startImageList(
context: Context,
position: Int,
imageList: ArrayList<String>
) {
val bundle = Bundle()
bundle.putInt("code", position)
bundle.putStringArrayList("imageList", imageList)
val intent = Intent(context, ViewBigImageActivity::class.java)
intent.putExtras(bundle)
context.startActivity(intent)
}
}
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/ui/WelfareFragment.kt
================================================
package com.lxm.wanandroid.ui
import android.arch.lifecycle.Observer
import android.os.Bundle
import android.support.v7.widget.StaggeredGridLayoutManager
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.RelativeLayout
import com.lxm.module_library.base.BaseFragment
import com.lxm.module_library.xrecycleview.XRecyclerView
import com.lxm.wanandroid.R
import com.lxm.wanandroid.repository.model.Status
import com.lxm.wanandroid.repository.model.Welfare
import com.lxm.wanandroid.ui.adapter.WelfareAdapter
import com.lxm.wanandroid.ui.base.OnItemClickListener
import com.lxm.wanandroid.viewmodel.WelfareModelView
import kotlinx.android.synthetic.main.article_fragment.*
class WelfareFragment : BaseFragment<WelfareModelView>() {
var imageList: ArrayList<String> = ArrayList()
override fun getLayoutID() = R.layout.article_fragment
private val mAdapter: WelfareAdapter by lazy {
WelfareAdapter()
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val ll = inflater.inflate(com.lxm.module_library.R.layout.fragment_base, null)
contentView = LayoutInflater.from(activity).inflate(R.layout.article_fragment, null, false)
val params =
RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
contentView.layoutParams = params
val mContainer = ll.findViewById<RelativeLayout>(com.lxm.module_library.R.id.container)
mContainer.addView(contentView)
return ll
}
companion object {
fun getInstance(): WelfareFragment {
return WelfareFragment()
}
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
showContentView()
initView()
}
private fun initView() {
swipeLayout.setOnRefreshListener {
viewModel.mPage = 1
loadData()
}
swipeLayout.isRefreshing = true
recyclerView.layoutManager = StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)
recyclerView.setPullRefreshEnabled(false)
recyclerView.clearHeader()
recyclerView.adapter = mAdapter
recyclerView.setLoadingListener(object : XRecyclerView.LoadingListener {
override fun onLoadMore() {
viewModel.mPage = viewModel.mPage+1
getWelfare()
}
override fun onRefresh() {
}
})
viewModel.loadStatus.observe(this, Observer {
when (it?.status) {
Status.ERROR -> showError()
}
})
mAdapter.setOnItemClickListener(object : OnItemClickListener<Welfare> {
override fun onClick(t: Welfare, position: Int) {
activity?.let { ViewBigImageActivity.startImageList(it, position, imageList) }
}
})
}
override fun onRetry() {
loadData()
}
override fun loadData() {
getWelfare()
}
private fun getWelfare() {
this.viewModel.getWelfare().observe(this@WelfareFragment, Observer {
if (viewModel.mPage == 1) {
mAdapter.setData(it?.results)
imageList.clear()
for (item in it?.results!!) {
imageList.add(item.url)
}
} else {
mAdapter.addDataAll(it?.results!!)
for (item in it?.results!!) {
imageList.add(item.url)
}
}
swipeLayout.isRefreshing = false
recyclerView.refreshComplete()
mAdapter.notifyDataSetChanged()
})
}
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/ui/adapter/ArticleAdapter.kt
================================================
package com.lxm.wanandroid.ui.adapter
import android.content.Intent
import android.graphics.Paint
import android.view.View
import android.widget.CheckBox
import android.widget.ImageView
import android.widget.TextView
import com.lxm.module_library.utils.PreferencesUtil
import com.lxm.module_library.utils.ToastUtils
import com.lxm.wanandroid.R
import com.lxm.wanandroid.repository.model.ArticleBean
import com.lxm.wanandroid.repository.model.HttpResponse
import com.lxm.wanandroid.repository.remote.httpClient.RetrofitClient
import com.lxm.wanandroid.ui.LoginActivity
import com.lxm.wanandroid.ui.base.BaseRecyclerAdapter
import com.lxm.wanandroid.ui.base.BaseRecyclerViewHolder
import com.lxm.wanandroid.utils.webview.WebViewActivity
import com.lxm.wanandroid.viewmodel.CollectViewModel
class ArticleAdapter : BaseRecyclerAdapter<ArticleBean>() {
var isCollectionList: Boolean = false
private var collectionViewModel: CollectViewModel = CollectViewModel()
override fun getItemLayout(): Int {
return R.layout.item_view
}
override fun onBindViewHoder(holder: BaseRecyclerViewHolder, position: Int) {
var articleBean: ArticleBean = mutableList?.get(position)
with(holder){
setValue(R.id.tv_title, articleBean.title)
setValue(R.id.tv_time, articleBean.niceDate)
setValue(R.id.tv_author, articleBean.author)
setValue(R.id.iv_image, articleBean.envelopePic)
}
var tagTextView = holder.getView(R.id.tv_tag_name) as TextView
tagTextView.text = articleBean.chapterName
if (articleBean.tags != null && articleBean.tags?.size!! > 0) {
tagTextView.paint.flags = Paint.UNDERLINE_TEXT_FLAG; //下划线
tagTextView.paint.isAntiAlias = true;//抗锯齿
tagTextView.setOnClickListener {
WebViewActivity.loadUrl(
tagTextView.context,
RetrofitClient.WAN_BASE_URL + articleBean.tags?.get(0)?.url,
articleBean.chapterName
)
}
}
val isNewImageView: ImageView = holder.getView(R.id.iv_new) as ImageView
if (articleBean.fresh) {
isNewImageView.visibility = View.VISIBLE
} else {
isNewImageView.visibility = View.GONE
}
val isCollectImage: CheckBox = holder.getView(R.id.iv_collect) as CheckBox
isCollectImage.isChecked = articleBean.collect
if(isCollectionList){
isCollectImage.isChecked = true
articleBean.id = articleBean.originId!!
}
isCollectImage.setOnClickListener {
var isLogin: Boolean by PreferencesUtil<Boolean>("login", false)
if(isLogin){
if (isCollectImage.isChecked) {
collectionViewModel.collect(articleBean.id, object : CollectionObserver<HttpResponse<Any>> {
override fun onChanged(t: HttpResponse<Any>?) {
if (t?.errorCode == 0) {
ToastUtils.showToast("收藏成功")
} else {
ToastUtils.showToast("收藏失败")
}
}
})
} else {
collectionViewModel.unCollect(articleBean.id, object : CollectionObserver<HttpResponse<Any>> {
override fun onChanged(t: HttpResponse<Any>?) {
if (t?.errorCode == 0) {
ToastUtils.showToast("取消收藏成功")
} else {
ToastUtils.showToast("取消收藏失败")
}
}
})
}
}else{
val intent = Intent(context, LoginActivity::class.java)
context.startActivity(intent)
}
}
}
interface CollectionObserver<T> {
fun onChanged(t: T?)
}
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/ui/adapter/NaviAdapter.kt
================================================
package com.lxm.wanandroid.ui.adapter
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import com.lxm.wanandroid.R
import com.lxm.wanandroid.repository.model.ArticleBean
import com.lxm.wanandroid.repository.model.Navigation
import com.lxm.wanandroid.repository.model.TreeBean
import com.lxm.wanandroid.ui.base.BaseRecyclerAdapter
import com.lxm.wanandroid.ui.base.BaseRecyclerViewHolder
import com.zhy.view.flowlayout.FlowLayout
import com.zhy.view.flowlayout.TagAdapter
import com.zhy.view.flowlayout.TagFlowLayout
import java.util.*
class NaviAdapter(var itemClickListener: OnItemNavigationClickListener) : BaseRecyclerAdapter<Navigation>() {
override fun getItemLayout(): Int {
return R.layout.item_tree
}
override fun onBindViewHoder(holder: BaseRecyclerViewHolder, position: Int) {
val navigation = mutableList[position]
val viewHolder: ViewHolder = holder as ViewHolder
viewHolder.titleView?.text = navigation.name
showTag(navigation, viewHolder.flowLayout)
}
private fun showTag(
navigation: Navigation,
flowLayout: TagFlowLayout?
) {
flowLayout?.adapter = object : TagAdapter<ArticleBean>(navigation.articles) {
override fun getView(
parent: FlowLayout,
position: Int,
articleBean: ArticleBean
): View {
val textView = View.inflate(parent.context, R.layout.item_tree_tag, null) as TextView
textView.text = articleBean.title
// textView.textColors = Color.rgb(Random().nextInt(255), Random().nextInt(255), Random().nextInt(255))
return textView
}
}
flowLayout?.setOnTagClickListener { view, position, parent ->
itemClickListener?.itemClick(view, position, parent,navigation.articles)
true
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseRecyclerViewHolder {
val item = LayoutInflater.from(parent.context).inflate(R.layout.item_tree, parent, false)
return ViewHolder(item)
}
class ViewHolder(itemView: View) : BaseRecyclerViewHolder(itemView) {
var titleView: TextView? = null
var flowLayout: TagFlowLayout? = null
init {
titleView = itemView.findViewById<TextView>(R.id.tv_tree_title)
flowLayout = itemView.findViewById<TagFlowLayout>(R.id.fl_tree)
}
companion object
}
private fun getBackGround(): Drawable {
val drawable = GradientDrawable()
drawable.cornerRadius = 16f
drawable.setColor(Color.rgb(Random().nextInt(255), Random().nextInt(255), Random().nextInt(255)))
return drawable
}
interface OnItemNavigationClickListener {
/**
*单击事件
*/
fun itemClick(view: View, position: Int, parent: FlowLayout, articles: List<ArticleBean>)
}
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/ui/adapter/TreeAdapter.kt
================================================
package com.lxm.wanandroid.ui.adapter
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import com.lxm.wanandroid.R
import com.lxm.wanandroid.repository.model.TreeBean
import com.lxm.wanandroid.ui.base.BaseRecyclerAdapter
import com.lxm.wanandroid.ui.base.BaseRecyclerViewHolder
import com.zhy.view.flowlayout.FlowLayout
import com.zhy.view.flowlayout.TagAdapter
import com.zhy.view.flowlayout.TagFlowLayout
import java.util.*
class TreeAdapter(var itemClickListener: OnItemNavigationClickListener) : BaseRecyclerAdapter<TreeBean>() {
override fun getItemLayout(): Int {
return R.layout.item_tree
}
override fun onBindViewHoder(holder: BaseRecyclerViewHolder, position: Int) {
val treeBean = mutableList[position]
val viewHolder: ViewHolder = holder as ViewHolder
viewHolder.titleView?.text = treeBean.name
showTag(treeBean, viewHolder.flowLayout)
}
private fun showTag(
treeBean: TreeBean,
flowLayout: TagFlowLayout?
) {
flowLayout?.adapter = object : TagAdapter<TreeBean>(treeBean.children) {
override fun getView(
parent: FlowLayout,
position: Int,
o: TreeBean
): View {
val textView = View.inflate(parent.context, R.layout.item_tree_tag, null) as TextView
textView.text = o.name
textView.setBackgroundDrawable(getBackGround())
return textView
}
}
flowLayout?.setOnTagClickListener { view, position, parent ->
itemClickListener?.itemClick(view, position, parent,treeBean.children)
true
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseRecyclerViewHolder {
val item = LayoutInflater.from(parent.context).inflate(R.layout.item_tree, parent, false)
return ViewHolder(item)
}
class ViewHolder(itemView: View) : BaseRecyclerViewHolder(itemView) {
var titleView: TextView? = null
var flowLayout: TagFlowLayout? = null
init {
titleView = itemView.findViewById<TextView>(R.id.tv_tree_title)
flowLayout = itemView.findViewById<TagFlowLayout>(R.id.fl_tree)
}
companion object
}
private fun getBackGround(): Drawable {
val drawable = GradientDrawable()
drawable.cornerRadius = 16f
drawable.setColor(Color.rgb(Random().nextInt(255), Random().nextInt(255), Random().nextInt(255)))
return drawable
}
interface OnItemNavigationClickListener {
/**
*单击事件
*/
fun itemClick(view: View, position: Int, parent: FlowLayout, children: List<TreeBean>)
}
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/ui/adapter/WelfareAdapter.kt
================================================
package com.lxm.wanandroid.ui.adapter
import android.widget.ImageView
import com.lxm.module_library.utils.DisplayUtils
import com.lxm.wanandroid.R
import com.lxm.wanandroid.repository.model.Welfare
import com.lxm.wanandroid.ui.base.BaseRecyclerAdapter
import com.lxm.wanandroid.ui.base.BaseRecyclerViewHolder
import com.lxm.wanandroid.utils.GlideUtil
class WelfareAdapter : BaseRecyclerAdapter<Welfare>() {
override fun getItemLayout(): Int {
return R.layout.item_view_welfare
}
override fun onBindViewHoder(holder: BaseRecyclerViewHolder, position: Int) {
var welfare: Welfare = mutableList?.get(position)
val imageView: ImageView = holder.getView(R.id.iv_welfare) as ImageView
GlideUtil.displayCircleCorner(imageView,welfare.url)
}
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/ui/base/BaseRecyclerAdapter.kt
================================================
package com.lxm.wanandroid.ui.base
import android.content.Context
import android.support.annotation.IntRange
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.ViewGroup
abstract class BaseRecyclerAdapter<T> : RecyclerView.Adapter<BaseRecyclerViewHolder>() {
lateinit var context: Context
var layoutRes: Int = 0
var mutableList: MutableList<T> = mutableListOf()
var listener: OnItemClickListener<T>? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseRecyclerViewHolder {
context = parent.context
return BaseRecyclerViewHolder(
LayoutInflater.from(context).inflate(
getItemLayout(),
null
)
)
}
fun setOnItemClickListener(listener: OnItemClickListener<T>) {
this.listener = listener
}
override fun onBindViewHolder(holder: BaseRecyclerViewHolder, position: Int) {
onBindViewHoder(holder, position)
holder.itemView.setOnClickListener {
listener?.onClick(mutableList.get(position),position)
}
}
override fun getItemCount(): Int {
return mutableList.size
}
fun setData(items: List<T>?) {
this.mutableList = items as MutableList<T>
notifyDataSetChanged()
}
fun addData(@IntRange(from = 0) position: Int, data: T) {
mutableList.add(position, data)
notifyItemInserted(position)
compatibilityDataSizeChanged(1)
}
fun addData(data: T) {
mutableList.add(data)
notifyItemInserted(mutableList?.size)
}
fun addDataAll(data: List<T>) {
mutableList.addAll(data)
notifyDataSetChanged()
}
fun addAdd(data: T) {
mutableList.add(data)
notifyItemInserted(mutableList?.size)
}
fun remove(position: Int) {
mutableList.removeAt(position)
notifyItemRemoved(position)
notifyItemRangeChanged(position, mutableList!!.size - position)
}
private fun compatibilityDataSizeChanged(size: Int) {
val dataSize = if (mutableList == null) 0 else mutableList!!.size
if (dataSize == size) {
notifyDataSetChanged()
}
}
/**
* 需要重写的方法
* @param holder
* @param position
*/
abstract fun onBindViewHoder(holder: BaseRecyclerViewHolder, position: Int)
abstract fun getItemLayout(): Int
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/ui/base/BaseRecyclerViewHoder.kt
================================================
package com.lxm.wanandroid.ui.base
import android.support.v7.widget.RecyclerView
import android.text.TextUtils
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
open class BaseRecyclerViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val map = mutableMapOf<Int, View>()
fun getView(id: Int): View? {
var viewId = map[id]
if (viewId == null) {
viewId = itemView.findViewById(id)
map[id] = viewId
}
return viewId
}
fun setValue(id: Int, string: String?) {
val view = getView(id)
when (view) {
is TextView -> view.text = string
is ImageView -> showPic(view, string)
}
}
private fun showPic(view: ImageView, string: String?) {
if (TextUtils.isEmpty(string)) {
view.visibility = View.GONE
} else {
view.visibility = View.VISIBLE
Glide.with(view.context)
.load(string)
.transition(DrawableTransitionOptions.withCrossFade(500))
.into(view)
}
}
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/ui/base/OnItemClickListener.kt
================================================
package com.lxm.wanandroid.ui.base
interface OnItemClickListener<T> {
fun onClick(t: T, position: Int)
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/ui/base/OnItemLongClickListener.kt
================================================
package com.lxm.wanandroid.ui.base
interface OnItemLongClickListener<T> {
fun onLongClick(t: T, position: Int)
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/utils/CookieUtils.kt
================================================
package com.lxm.wanandroid.utils
import android.content.Context
import android.util.Log
import android.webkit.CookieManager
import android.webkit.CookieSyncManager
import com.google.android.gms.common.util.SharedPreferencesUtils
import okhttp3.Cookie
object CookieUtils {
/**
* clear Cookie
*
* @param context
*/
fun clearCookie(context: Context) {
CookieSyncManager.createInstance(context)
CookieSyncManager.getInstance().startSync()
CookieManager.getInstance().removeSessionCookie()
}
/**
* Sync Cookie
*/
fun syncCookie(context: Context, url: String,cookies:List<Cookie>) {
try {
CookieSyncManager.createInstance(context)
val cookieManager = CookieManager.getInstance()
cookies.forEach {
val name = it.name()
val value = it.value()
val cookieStr = "$name=$value"
cookieManager.setCookie(url,cookieStr)
}
cookieManager.flush()
} catch (e: Exception) {
}
}
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/utils/GlideUtil.kt
================================================
package com.lxm.wanandroid.utils
import android.content.Context
import android.graphics.Bitmap
import android.widget.ImageView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.Transformation
import com.bumptech.glide.load.resource.bitmap.CircleCrop
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
import jp.wasabeef.glide.transformations.BlurTransformation
import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
object GlideUtil {
private fun displayGaussian(context: Context, url: String, imageView: ImageView) {
// "23":模糊度;"4":图片缩放4倍后再进行模糊
Glide.with(context)
.load(url)
.transition(DrawableTransitionOptions.withCrossFade())
.transition(DrawableTransitionOptions.withCrossFade(500))
.transform(BlurTransformation(50, 8) as Transformation<Bitmap>)
.into(imageView)
}
/**
* 加载圆角图,暂时用到显示头像
*/
fun displayCircle(imageView: ImageView, imageUrl: String) {
Glide.with(imageView.context)
.load(imageUrl)
.transition(DrawableTransitionOptions.withCrossFade(500))
.transform(CircleCrop())
// .apply(bitmapTransform(new CircleCrop()))
// .transform(new GlideCircleTransform())
// .transform(new RoundedCorners(20))
// .transform(new CenterCrop(), new RoundedCorners(20))
.into(imageView)
}
fun displayImage(imageView: ImageView, imageUrl: String) {
Glide.with(imageView.context)
.load(imageUrl)
.into(imageView)
}
fun displayCircleCorner(imageView: ImageView, imageUrl: String){
//设置图片圆角角度
val roundedCorners = RoundedCorners(6)
//通过RequestOptions扩展功能,override:采样率,因为ImageView就这么大,可以压缩图片,降低内存消耗
val options = RequestOptions.bitmapTransform(roundedCorners)
Glide.with(imageView.context).load(imageUrl).apply(options).into(imageView)
}
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/utils/webview/WebViewActivity.java
================================================
package com.lxm.wanandroid.utils.webview;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.*;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.FrameLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.lxm.module_library.statusbar.StatusBarUtil;
import com.lxm.module_library.utils.BaseTools;
import com.lxm.module_library.utils.CheckNetwork;
import com.lxm.module_library.utils.ToastUtil;
import com.lxm.wanandroid.R;
import com.lxm.wanandroid.utils.webview.config.*;
/**
* 网页可以处理:
* 点击相应控件:拨打电话、发送短信、发送邮件、上传图片、播放视频
* 进度条、返回网页上一层、显示网页标题
* Thanks to: https://github.com/youlookwhat/WebViewStudy
* contact me: http://www.jianshu.com/users/e43c6e979831/latest_articles
*/
public class WebViewActivity extends AppCompatActivity implements IWebPageView {
// 进度条
private ProgressBar mProgressBar;
private WebView webView;
// 全屏时视频加载view
private FrameLayout videoFullView;
private Toolbar mTitleToolBar;
// 加载视频相关
private MyWebChromeClient mWebChromeClient;
// title
private String mTitle;
// 网页链接
private String mUrl;
// 可滚动的title 使用简单 没有渐变效果,文字两旁有阴影
private TextView tvGunTitle;
private boolean isTitleFix;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_web_view);
getIntentData();
initTitle();
initWebView();
webView.loadUrl(mUrl);
getDataFromBrowser(getIntent());
}
private void getIntentData() {
if (getIntent() != null) {
mTitle = getIntent().getStringExtra("mTitle");
mUrl = getIntent().getStringExtra("mUrl");
isTitleFix = getIntent().getBooleanExtra("isTitleFix", false);
}
}
private void initTitle() {
StatusBarUtil.setColor(this, getResources().getColor(R.color.colorTheme), 0);
mProgressBar = findViewById(R.id.pb_progress);
webView = findViewById(R.id.webview_detail);
videoFullView = findViewById(R.id.video_fullView);
mTitleToolBar = findViewById(R.id.title_tool_bar);
tvGunTitle = findViewById(R.id.tv_gun_title);
initToolBar();
}
private void initToolBar() {
setSupportActionBar(mTitleToolBar);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
//去除默认Title显示
actionBar.setDisplayShowTitleEnabled(false);
}
mTitleToolBar.setOverflowIcon(ContextCompat.getDrawable(this, R.drawable.actionbar_more));
tvGunTitle.postDelayed(() -> tvGunTitle.setSelected(true), 1900);
tvGunTitle.setText(mTitle);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.webview_menu, menu);
return true;
}
@Override
public void setTitle(String mTitle) {
if (!isTitleFix) {
tvGunTitle.setText(mTitle);
this.mTitle = mTitle;
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// 返回键
handleFinish();
break;
case R.id.actionbar_share:
// 分享到
break;
case R.id.actionbar_cope:
// 复制链接
BaseTools.copy(webView.getUrl());
ToastUtil.showToast("复制成功");
break;
case R.id.actionbar_open:
// 打开链接
BaseTools.openLink(WebViewActivity.this, webView.getUrl());
break;
case R.id.actionbar_webview_refresh:
// 刷新页面
if (webView != null) {
webView.reload();
}
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
@SuppressLint("SetJavaScriptEnabled")
private void initWebView() {
mProgressBar.setVisibility(View.VISIBLE);
WebSettings ws = webView.getSettings();
// 网页内容的宽度是否可大于WebView控件的宽度
ws.setLoadWithOverviewMode(false);
// 保存表单数据
ws.setSaveFormData(true);
// 是否应该支持使用其屏幕缩放控件和手势缩放
ws.setSupportZoom(true);
ws.setBuiltInZoomControls(true);
ws.setDisplayZoomControls(false);
// 启动应用缓存
ws.setAppCacheEnabled(true);
// 设置缓存模式
ws.setCacheMode(WebSettings.LOAD_DEFAULT);
// setDefaultZoom api19被弃用
// 设置此属性,可任意比例缩放。
ws.setUseWideViewPort(true);
// 不缩放
webView.setInitialScale(100);
// 告诉WebView启用JavaScript执行。默认的是false。
ws.setJavaScriptEnabled(true);
// 页面加载好以后,再放开图片
ws.setBlockNetworkImage(false);
// 使用localStorage则必须打开
ws.setDomStorageEnabled(true);
// 排版适应屏幕
ws.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
// WebView是否新窗口打开(加了后可能打不开网页)
// ws.setSupportMultipleWindows(true);
// webview从5.0开始默认不允许混合模式,https中不能加载http资源,需要设置开启。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
ws.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
/** 设置字体默认缩放大小(改变网页字体大小,setTextSize api14被弃用)*/
ws.setTextZoom(100);
mWebChromeClient = new MyWebChromeClient(this);
webView.setWebChromeClient(mWebChromeClient);
// 与js交互
webView.addJavascriptInterface(new ImageClickInterface(this), "injectedObject");
webView.setWebViewClient(new MyWebViewClient(this));
webView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
return handleLongImage();
}
});
}
@Override
public void hindProgressBar() {
mProgressBar.setVisibility(View.GONE);
}
@Override
public void showWebView() {
webView.setVisibility(View.VISIBLE);
}
@Override
public void hindWebView() {
webView.setVisibility(View.INVISIBLE);
}
@Override
public void fullViewAddView(View view) {
FrameLayout decor = (FrameLayout) getWindow().getDecorView();
videoFullView = new FullscreenHolder(WebViewActivity.this);
videoFullView.addView(view);
decor.addView(videoFullView);
}
@Override
public void showVideoFullView() {
videoFullView.setVisibility(View.VISIBLE);
}
@Override
public void hindVideoFullView() {
videoFullView.setVisibility(View.GONE);
}
@Override
public void startProgress(int newProgress) {
mProgressBar.setVisibility(View.VISIBLE);
mProgressBar.setProgress(newProgress);
if (newProgress == 100) {
mProgressBar.setVisibility(View.GONE);
}
}
@Override
public void addImageClickListener() {
// loadImageClickJS();
// loadTextClickJS();
}
private void loadImageClickJS() {
// 这段js函数的功能就是,遍历所有的img节点,并添加onclick函数,函数的功能是在图片点击的时候调用本地java接口并传递url过去
webView.loadUrl("javascript:(function(){" +
"var objs = document.getElementsByTagName(\"img\");" +
"for(var i=0;i<objs.length;i++)" +
"{" +
"objs[i].onclick=function(){window.injectedObject.imageClick(this.getAttribute(\"src\"),this.getAttribute(\"has_link\"));}" +
"}" +
"})()");
}
private void loadTextClickJS() {
// 遍历所有的a节点,将节点里的属性传递过去(属性自定义,用于页面跳转)
webView.loadUrl("javascript:(function(){" +
"var objs =document.getElementsByTagName(\"a\");" +
"for(var i=0;i<objs.length;i++)" +
"{" +
"objs[i].onclick=function(){" +
"window.injectedObject.textClick(this.getAttribute(\"type\"),this.getAttribute(\"item_pk\"));}" +
"}" +
"})()");
}
public FrameLayout getVideoFullView() {
return videoFullView;
}
/**
* 全屏时按返加键执行退出全屏方法
*/
public void hideCustomView() {
mWebChromeClient.onHideCustomView();
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
/**
* 上传图片之后的回调
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == MyWebChromeClient.FILECHOOSER_RESULTCODE) {
mWebChromeClient.mUploadMessage(intent, resultCode);
} else if (requestCode == MyWebChromeClient.FILECHOOSER_RESULTCODE_FOR_ANDROID_5) {
mWebChromeClient.mUploadMessageForAndroid5(intent, resultCode);
}
}
/**
* 使用singleTask启动模式的Activity在系统中只会存在一个实例。
* 如果这个实例已经存在,intent就会通过onNewIntent传递到这个Activity。
* 否则新的Activity实例被创建。
*/
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
getDataFromBrowser(intent);
}
/**
* 作为三方浏览器打开
* Scheme: https
* host: www.jianshu.com
* path: /p/1cbaf784c29c
* url = scheme + "://" + host + path;
*/
private void getDataFromBrowser(Intent intent) {
Uri data = intent.getData();
if (data != null) {
try {
String scheme = data.getScheme();
String host = data.getHost();
String path = data.getPath();
// String text = "Scheme: " + scheme + "\n" + "host: " + host + "\n" + "path: " + path;
// Log.e("data", text);
String url = scheme + "://" + host + path;
webView.loadUrl(url);
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 长按图片事件处理
*/
private boolean handleLongImage() {
final WebView.HitTestResult hitTestResult = webView.getHitTestResult();
// 如果是图片类型或者是带有图片链接的类型
if (hitTestResult.getType() == WebView.HitTestResult.IMAGE_TYPE ||
hitTestResult.getType() == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE) {
// 弹出保存图片的对话框
new AlertDialog.Builder(WebViewActivity.this)
.setItems(new String[]{"查看大图", "保存图片到相册"}, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String picUrl = hitTestResult.getExtra();
//获取图片
// Log.e("picUrl", picUrl);
// switch (which) {
// case 0:
// ViewBigImageActivity.start(WebViewActivity.this, picUrl, picUrl);
// break;
// case 1:
// if (!PermissionHandler.isHandlePermission(WebViewActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// return;
// }
// RxSaveImage.saveImageToGallery(WebViewActivity.this, picUrl, picUrl);
// break;
// default:
// break;
// }
}
})
.show();
return true;
}
return false;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
//全屏播放退出全屏
if (mWebChromeClient.inCustomView()) {
hideCustomView();
return true;
//返回网页上一页
} else if (webView.canGoBack()) {
webView.goBack();
return true;
//退出网页
} else {
handleFinish();
}
}
return false;
}
/**
* 直接通过三方浏览器打开时,回退到首页
*/
public void handleFinish() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
finishAfterTransition();
} else {
finish();
}
}
@Override
protected void onPause() {
super.onPause();
webView.onPause();
}
@Override
protected void onResume() {
super.onResume();
webView.onResume();
// 支付宝网页版在打开文章详情之后,无法点击按钮下一步
webView.resumeTimers();
// 设置为横屏
if (getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
}
@Override
protected void onDestroy() {
if (videoFullView != null) {
videoFullView.clearAnimation();
videoFullView.removeAllViews();
}
if (webView != null) {
webView.loadDataWithBaseURL(null, "", "text/html", "utf-8", null);
webView.clearHistory();
ViewGroup parent = (ViewGroup) webView.getParent();
if (parent != null) {
parent.removeView(webView);
}
webView.removeAllViews();
webView.stopLoading();
webView.setWebChromeClient(null);
webView.setWebViewClient(null);
webView.destroy();
webView = null;
mProgressBar.clearAnimation();
tvGunTitle.clearAnimation();
tvGunTitle.clearFocus();
}
super.onDestroy();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (newConfig.fontScale != 1) {
getResources();
}
}
/**
* 禁止改变字体大小
*/
@Override
public Resources getResources() {
Resources res = super.getResources();
Configuration config = new Configuration();
config.setToDefaults();
res.updateConfiguration(config, res.getDisplayMetrics());
return res;
}
/**
* 打开网页:
*
* @param mContext 上下文
* @param mUrl 要加载的网页url
* @param mTitle title
*/
public static void loadUrl(Context mContext, String mUrl, String mTitle) {
loadUrl(mContext, mUrl, mTitle, false);
}
/**
* 打开网页:
*
* @param mContext 上下文
* @param mUrl 要加载的网页url
* @param mTitle title
* @param isTitleFixed title是否固定
*/
public static void loadUrl(Context mContext, String mUrl, String mTitle, boolean isTitleFixed) {
if (CheckNetwork.isNetworkConnected(mContext)) {
Intent intent = new Intent(mContext, WebViewActivity.class);
intent.putExtra("mUrl", mUrl);
intent.putExtra("isTitleFix", isTitleFixed);
intent.putExtra("mTitle", mTitle == null ? "" : mTitle);
mContext.startActivity(intent);
} else {
ToastUtil.showToastLong("当前网络不可用,请检查你的网络设置");
}
}
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/utils/webview/config/FullscreenHolder.java
================================================
package com.lxm.wanandroid.utils.webview.config;
import android.content.Context;
import android.view.MotionEvent;
import android.widget.FrameLayout;
/**
* Created by jingbin on 2016/11/17.
*/
public class FullscreenHolder extends FrameLayout {
public FullscreenHolder(Context ctx) {
super(ctx);
setBackgroundColor(ctx.getResources().getColor(android.R.color.black));
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return true;
}
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/utils/webview/config/IWebPageView.java
================================================
package com.lxm.wanandroid.utils.webview.config;
import android.view.View;
/**
* Created by jingbin on 2016/11/17.
*/
public interface IWebPageView {
// 隐藏进度条
void hindProgressBar();
// 显示webview
void showWebView();
// 隐藏webview
void hindWebView();
/**
* 进度条变化时调用
*/
void startProgress(int newProgress);
/**
* 添加js监听
*/
void addImageClickListener();
/**
* 播放网络视频全屏调用
*/
void fullViewAddView(View view);
void showVideoFullView();
void hindVideoFullView();
/**
* 得到网页标题
*/
void setTitle(String title);
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/utils/webview/config/ImageClickInterface.java
================================================
package com.lxm.wanandroid.utils.webview.config;
import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;
import android.util.Log;
import android.webkit.JavascriptInterface;
import android.widget.Toast;
import com.lxm.wanandroid.ui.ViewBigImageActivity;
/**
* Created by jingbin on 2016/11/17.
* js通信接口
*/
public class ImageClickInterface {
private Context context;
public ImageClickInterface(Context context) {
this.context = context;
}
@JavascriptInterface
public void imageClick(String imgUrl, String hasLink) {
Toast.makeText(context, "----点击了图片", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(context, ViewBigImageActivity.class);
context.startActivity(intent);
Log.e("----点击了图片 url: ", "" + imgUrl);
}
@JavascriptInterface
public void textClick(String type, String item_pk) {
if (!TextUtils.isEmpty(type) && !TextUtils.isEmpty(item_pk)) {
Log.e("----点击了文字", "");
}
}
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/utils/webview/config/MyWebChromeClient.java
================================================
package com.lxm.wanandroid.utils.webview.config;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import com.lxm.wanandroid.utils.webview.WebViewActivity;
import static android.app.Activity.RESULT_OK;
/**
* Created by jingbin on 2016/11/17.
* - 播放网络视频配置
* - 上传图片(兼容)
* 点击空白区域的左边,因是公司图片,自己编辑过,所以显示不全,见谅
*/
public class MyWebChromeClient extends WebChromeClient {
private ValueCallback<Uri> mUploadMessage;
private ValueCallback<Uri[]> mUploadMessageForAndroid5;
public static int FILECHOOSER_RESULTCODE = 1;
public static int FILECHOOSER_RESULTCODE_FOR_ANDROID_5 = 2;
private View mXProgressVideo;
private WebViewActivity mActivity;
private IWebPageView mIWebPageView;
private View mXCustomView;
private CustomViewCallback mXCustomViewCallback;
public MyWebChromeClient(IWebPageView mIWebPageView) {
this.mIWebPageView = mIWebPageView;
this.mActivity = (WebViewActivity) mIWebPageView;
}
// 播放网络视频时全屏会被调用的方法
@Override
public void onShowCustomView(View view, CustomViewCallback callback) {
mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
mIWebPageView.hindWebView();
// 如果一个视图已经存在,那么立刻终止并新建一个
if (mXCustomView != null) {
callback.onCustomViewHidden();
return;
}
mActivity.fullViewAddView(view);
mXCustomView = view;
mXCustomViewCallback = callback;
mIWebPageView.showVideoFullView();
}
// 视频播放退出全屏会被调用的
@Override
public void onHideCustomView() {
if (mXCustomView == null)// 不是全屏播放状态
return;
mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
mXCustomView.setVisibility(View.GONE);
if (mActivity.getVideoFullView() != null) {
mActivity.getVideoFullView().removeView(mXCustomView);
}
mXCustomView = null;
mIWebPageView.hindVideoFullView();
mXCustomViewCallback.onCustomViewHidden();
mIWebPageView.showWebView();
}
// 视频加载时进程loading
@Override
public View getVideoLoadingProgressView() {
if (mXProgressVideo == null) {
LayoutInflater inflater = LayoutInflater.from(mActivity);
// mXProgressVideo = inflater.inflate(R.layout.video_loading_progress, null);
}
return mXProgressVideo;
}
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
mIWebPageView.startProgress(newProgress);
}
/**
* 判断是否是全屏
*/
public boolean inCustomView() {
return (mXCustomView != null);
}
@Override
public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view, title);
mIWebPageView.setTitle(title);
// // 设置title
// mActivity.setTitle(title);
// this.title = title;
}
// private String title = "";
// public String getTitle() {
// return title + " ";
// }
//扩展浏览器上传文件
//3.0++版本
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
openFileChooserImpl(uploadMsg);
}
//3.0--版本
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
openFileChooserImpl(uploadMsg);
}
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
openFileChooserImpl(uploadMsg);
}
// For Android > 5.0
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> uploadMsg, FileChooserParams fileChooserParams) {
openFileChooserImplForAndroid5(uploadMsg);
return true;
}
private void openFileChooserImpl(ValueCallback<Uri> uploadMsg) {
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
mActivity.startActivityForResult(Intent.createChooser(i, "文件选择"), FILECHOOSER_RESULTCODE);
}
private void openFileChooserImplForAndroid5(ValueCallback<Uri[]> uploadMsg) {
mUploadMessageForAndroid5 = uploadMsg;
Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
contentSelectionIntent.setType("image/*");
Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
chooserIntent.putExtra(Intent.EXTRA_TITLE, "图片选择");
mActivity.startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE_FOR_ANDROID_5);
}
/**
* 5.0以下 上传图片成功后的回调
*/
public void mUploadMessage(Intent intent, int resultCode) {
if (null == mUploadMessage)
return;
Uri result = intent == null || resultCode != RESULT_OK ? null : intent.getData();
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
}
/**
* 5.0以上 上传图片成功后的回调
*/
public void mUploadMessageForAndroid5(Intent intent, int resultCode) {
if (null == mUploadMessageForAndroid5)
return;
Uri result = (intent == null || resultCode != RESULT_OK) ? null : intent.getData();
if (result != null) {
mUploadMessageForAndroid5.onReceiveValue(new Uri[]{result});
} else {
mUploadMessageForAndroid5.onReceiveValue(new Uri[]{});
}
mUploadMessageForAndroid5 = null;
}
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/utils/webview/config/MyWebViewClient.java
================================================
package com.lxm.wanandroid.utils.webview.config;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.text.TextUtils;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import com.lxm.module_library.utils.BaseTools;
import com.lxm.module_library.utils.CheckNetwork;
import com.lxm.wanandroid.utils.webview.WebViewActivity;
/**
* Created by jingbin on 2016/11/17.
* 监听网页链接:
* - 优酷视频直接跳到自带浏览器
* - 根据标识:打电话、发短信、发邮件
* - 进度条的显示
* - 添加javascript监听
*/
public class MyWebViewClient extends WebViewClient {
private IWebPageView mIWebPageView;
private WebViewActivity mActivity;
public MyWebViewClient(IWebPageView mIWebPageView) {
this.mIWebPageView = mIWebPageView;
mActivity = (WebViewActivity) mIWebPageView;
}
@SuppressWarnings("deprecation")
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// DebugUtil.error("----url:"+url);
if (TextUtils.isEmpty(url)) {
return false;
}
if (url.startsWith("http:") || url.startsWith("https:")) {
// 可能有提示下载Apk文件
if (url.contains(".apk")) {
handleOtherwise(mActivity, url);
return true;
}
return false;
}
handleOtherwise(mActivity, url);
return true;
}
@Override
public void onPageFinished(WebView view, String url) {
if (!CheckNetwork.isNetworkConnected(mActivity)) {
mIWebPageView.hindProgressBar();
}
// html加载完成之后,添加监听图片的点击js函数
mIWebPageView.addImageClickListener();
super.onPageFinished(view, url);
}
// 视频全屏播放按返回页面被放大的问题
@Override
public void onScaleChanged(WebView view, float oldScale, float newScale) {
super.onScaleChanged(view, oldScale, newScale);
if (newScale - oldScale > 7) {
view.setInitialScale((int) (oldScale / newScale * 100)); //异常放大,缩回去。
}
}
/**
* 网页里可能唤起其他的app
*/
private void handleOtherwise(Activity activity, String url) {
String appPackageName = "";
// 支付宝支付
if (url.contains("alipays")) {
appPackageName = "com.eg.android.AlipayGphone";
// 微信支付
} else if (url.contains("weixin://wap/pay")) {
appPackageName = "com.tencent.mm";
// 京东产品详情
} else if (url.contains("openapp.jdmobile")) {
appPackageName = "com.jingdong.app.mall";
} else {
startActivity(url);
}
if (BaseTools.isApplicationAvilible(activity, appPackageName)) {
startActivity(url);
}
}
private void startActivity(String url) {
try {
Intent intent1 = new Intent();
intent1.setAction("android.intent.action.VIEW");
Uri uri = Uri.parse(url);
intent1.setData(uri);
intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mActivity.startActivity(intent1);
} catch (Exception e) {
e.printStackTrace();
}
}
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/viewmodel/ArticleViewModel.kt
================================================
package com.lxm.wanandroid.viewmodel
import android.arch.lifecycle.MutableLiveData
import com.lxm.module_library.base.BaseViewModel
import com.lxm.module_library.helper.RxHelper
import com.lxm.wanandroid.repository.model.*
import com.lxm.wanandroid.repository.remote.httpClient.RetrofitClient
import io.reactivex.functions.Consumer
class ArticleViewModel : BaseViewModel() {
var mPage = 0
var banner = MutableLiveData<HttpResponse<List<Banner>>>()
val pagedList = MutableLiveData<HttpResponse<ArticleResponseBody<ArticleBean>>>()
val loadStatus by lazy {
MutableLiveData<Resource<String>>()
}
fun getHomeList(): Listing<HttpResponse<ArticleResponseBody<ArticleBean>>> {
loadStatus.postValue(Resource.loading())
val subscribe = RetrofitClient.getInstance(RetrofitClient.WAN_BASE_URL).getArticleList(mPage)
.compose(RxHelper.rxSchedulerHelper())
.subscribe(Consumer<HttpResponse<ArticleResponseBody<ArticleBean>>> {
if(it.data != null){
loadStatus.postValue(Resource.success())
pagedList.value = it
}else{
loadStatus.postValue(Resource.error())
}
}, Consumer<Throwable> {
if (mPage > 0) {
mPage--
}
loadStatus.postValue(Resource.error())
})
addDisposable(subscribe)
return Listing(pagedList,loadStatus)
}
fun getBanners(): MutableLiveData<HttpResponse<List<Banner>>> {
val subscribe = RetrofitClient.getInstance(RetrofitClient.WAN_BASE_URL).getHomeBanner()
.compose(RxHelper.rxSchedulerHelper())
.subscribe(Consumer<HttpResponse<List<Banner>>>{
banner.postValue(it)
}, Consumer<Throwable> {
banner.postValue(null)
})
addDisposable(subscribe)
return banner
}
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/viewmodel/CategoryViewModel.kt
================================================
package com.lxm.wanandroid.viewmodel
import android.arch.lifecycle.MutableLiveData
import com.lxm.module_library.base.BaseViewModel
import com.lxm.module_library.helper.RxHelper
import com.lxm.wanandroid.repository.model.*
import com.lxm.wanandroid.repository.remote.httpClient.RetrofitClient
import io.reactivex.functions.Consumer
class CategoryViewModel: BaseViewModel() {
var mPage = 0
val pagedList = MutableLiveData<HttpResponse<ArticleResponseBody<ArticleBean>>>()
val loadStatus by lazy {
MutableLiveData<Resource<String>>()
}
fun getCategory(id: Int): Listing<HttpResponse<ArticleResponseBody<ArticleBean>>> {
loadStatus.postValue(Resource.loading())
val subscribe = RetrofitClient.getInstance(RetrofitClient.WAN_BASE_URL).getCategory(mPage,id)
.compose(RxHelper.rxSchedulerHelper())
.subscribe(Consumer<HttpResponse<ArticleResponseBody<ArticleBean>>> {
if(it.data != null){
loadStatus.postValue(Resource.success())
pagedList.value = it
}else{
loadStatus.postValue(Resource.error())
}
}, Consumer<Throwable> {
if (mPage > 0) {
mPage--
}
loadStatus.postValue(Resource.error())
})
addDisposable(subscribe)
return Listing(pagedList,loadStatus)
}
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/viewmodel/CollectViewModel.kt
================================================
package com.lxm.wanandroid.viewmodel
import android.arch.lifecycle.MutableLiveData
import com.lxm.module_library.base.BaseViewModel
import com.lxm.module_library.helper.RxHelper
import com.lxm.wanandroid.repository.model.*
import com.lxm.wanandroid.repository.remote.httpClient.RetrofitClient
import com.lxm.wanandroid.ui.adapter.ArticleAdapter
import io.reactivex.functions.Consumer
class CollectViewModel : BaseViewModel() {
var mPage = 0
val collectionList = MutableLiveData<HttpResponse<ArticleResponseBody<ArticleBean>>>()
val loadStatus by lazy {
MutableLiveData<Resource<String>>()
}
fun getCollect(): Listing<HttpResponse<ArticleResponseBody<ArticleBean>>> {
loadStatus.postValue(Resource.loading())
val subscribe = RetrofitClient.getInstance(RetrofitClient.WAN_BASE_URL).getCollectList(mPage)
.compose(RxHelper.rxSchedulerHelper())
.subscribe(Consumer<HttpResponse<ArticleResponseBody<ArticleBean>>> {
if(it.data != null){
loadStatus.postValue(Resource.success())
collectionList.value = it
}else{
loadStatus.postValue(Resource.error())
}
}, Consumer<Throwable> {
if (mPage > 0) {
mPage--
}
loadStatus.postValue(Resource.error())
})
addDisposable(subscribe)
return Listing(collectionList,loadStatus)
}
fun collect(id:Int,collectionObserver: ArticleAdapter.CollectionObserver<HttpResponse<Any>>) {
val subscribe = RetrofitClient.getInstance(RetrofitClient.WAN_BASE_URL).collect(id)
.compose(RxHelper.rxSchedulerHelper())
.subscribe(Consumer<HttpResponse<Any>> {
collectionObserver.onChanged(it)
}, Consumer<Throwable> {
collectionObserver.onChanged(null)
})
addDisposable(subscribe)
}
fun unCollect(id:Int,collectionObserver: ArticleAdapter.CollectionObserver<HttpResponse<Any>>) {
val subscribe = RetrofitClient.getInstance(RetrofitClient.WAN_BASE_URL).unCollect(id)
.compose(RxHelper.rxSchedulerHelper())
.subscribe(Consumer<HttpResponse<Any>> {
collectionObserver.onChanged(it)
}, Consumer<Throwable> {
collectionObserver.onChanged(null)
})
addDisposable(subscribe)
}
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/viewmodel/LoginViewModel.kt
================================================
package com.lxm.wanandroid.viewmodel
import android.arch.lifecycle.Transformations
import com.lxm.module_library.base.BaseViewModel
import com.lxm.wanandroid.repository.remote.LoginRepository
class LoginViewModel(val loginRepository: LoginRepository) : BaseViewModel() {
var loginStatus = Transformations.map(loginRepository.login){it}
var registerStauts = Transformations.map(loginRepository.register){it}
var logoutStatus = Transformations.map(loginRepository.logout){it}
fun login(username:String,password:String) {
loginRepository.login(username,password)
}
fun logout() {
loginRepository.logout()
}
fun register(username:String,password:String,repassword:String) {
loginRepository.register(username,password,repassword)
}
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/viewmodel/NaviViewModelView.kt
================================================
package com.lxm.wanandroid.viewmodel
import android.arch.lifecycle.MutableLiveData
import com.lxm.module_library.base.BaseViewModel
import com.lxm.module_library.helper.RxHelper
import com.lxm.wanandroid.repository.model.Navigation
import com.lxm.wanandroid.repository.model.Resource
import com.lxm.wanandroid.repository.remote.httpClient.RetrofitClient
class NaviViewModelView : BaseViewModel() {
private val naviList = MutableLiveData<List<Navigation>>()
val loadStatus by lazy {
MutableLiveData<Resource<String>>()
}
fun getVavigations(): MutableLiveData<List<Navigation>> {
RetrofitClient.getInstance(RetrofitClient.WAN_BASE_URL).getNavigation()
.compose(RxHelper.rxSchedulerHelper())
.subscribe({
naviList.postValue(it.data)
}, {
loadStatus.postValue(Resource.error())
})
return naviList
}
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/viewmodel/ProjectViewModel.kt
================================================
package com.lxm.wanandroid.viewmodel
import android.arch.lifecycle.MutableLiveData
import com.lxm.module_library.base.BaseViewModel
import com.lxm.module_library.helper.RxHelper
import com.lxm.wanandroid.repository.model.*
import com.lxm.wanandroid.repository.remote.httpClient.RetrofitClient
import io.reactivex.functions.Consumer
class ProjectViewModel : BaseViewModel() {
var mPage = 0
val pagedList = MutableLiveData<HttpResponse<ArticleResponseBody<ArticleBean>>>()
val loadStatus by lazy {
MutableLiveData<Resource<String>>()
}
fun getProjects(): Listing<HttpResponse<ArticleResponseBody<ArticleBean>>> {
loadStatus.postValue(Resource.loading())
val subscribe = RetrofitClient.getInstance(RetrofitClient.WAN_BASE_URL).getProjectList(mPage)
.compose(RxHelper.rxSchedulerHelper())
.subscribe(Consumer<HttpResponse<ArticleResponseBody<ArticleBean>>> {
if(it.data != null){
loadStatus.postValue(Resource.success())
pagedList.value = it
}else{
loadStatus.postValue(Resource.error())
}
}, Consumer<Throwable> {
if (mPage > 0) {
mPage--
}
loadStatus.postValue(Resource.error())
})
addDisposable(subscribe)
return Listing(pagedList,loadStatus)
}
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/viewmodel/TreeViewModel.kt
================================================
package com.lxm.wanandroid.viewmodel
import android.arch.lifecycle.MutableLiveData
import com.lxm.module_library.base.BaseViewModel
import com.lxm.module_library.helper.RxHelper
import com.lxm.wanandroid.repository.model.Resource
import com.lxm.wanandroid.repository.model.TreeBean
import com.lxm.wanandroid.repository.remote.httpClient.RetrofitClient
class TreeViewModel : BaseViewModel() {
private val treeList = MutableLiveData<List<TreeBean>>()
val loadStatus by lazy {
MutableLiveData<Resource<String>>()
}
fun getTrees(): MutableLiveData<List<TreeBean>> {
RetrofitClient.getInstance(RetrofitClient.WAN_BASE_URL).getTrees()
.compose(RxHelper.rxSchedulerHelper())
.subscribe({
treeList.postValue(it.data)
}, {
loadStatus.postValue(Resource.error())
})
return treeList
}
}
================================================
FILE: app/src/main/java/com/lxm/wanandroid/viewmodel/WelfareModelView.kt
================================================
package com.lxm.wanandroid.viewmodel
import android.arch.lifecycle.MutableLiveData
import com.lxm.module_library.base.BaseViewModel
import com.lxm.module_library.helper.RxHelper
import com.lxm.wanandroid.repository.model.Resource
import com.lxm.wanandroid.repository.model.WelfareResponse
import com.lxm.wanandroid.repository.remote.httpClient.RetrofitClient
const val PAGE_SIZE = 20
class WelfareModelView : BaseViewModel() {
var mPage = 1
val loadStatus by lazy {
MutableLiveData<Resource<String>>()
}
fun getWelfare(): MutableLiveData<WelfareResponse> {
val welfare = MutableLiveData<WelfareResponse>()
RetrofitClient.getInstance(RetrofitClient.GAN_BASE_URL).getWelfare("福利",PAGE_SIZE,mPage)
.compose(RxHelper.rxSchedulerHelper())
.subscribe({
welfare.postValue(it)
}, {
loadStatus.postValue(Resource.error())
})
return welfare
}
}
================================================
FILE: app/src/main/res/drawable/ic_launcher_background.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:height="108dp"
android:width="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path android:fillColor="#008577"
android:pathData="M0,0h108v108h-108z"/>
<path android:fillColor="#00000000" android:pathData="M9,0L9,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,0L19,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M29,0L29,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M39,0L39,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M49,0L49,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M59,0L59,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M69,0L69,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M79,0L79,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M89,0L89,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M99,0L99,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,9L108,9"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,19L108,19"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,29L108,29"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,39L108,39"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,49L108,49"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,59L108,59"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,69L108,69"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,79L108,79"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,89L108,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,99L108,99"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,29L89,29"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,39L89,39"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,49L89,49"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,59L89,59"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,69L89,69"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,79L89,79"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M29,19L29,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M39,19L39,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M49,19L49,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M59,19L59,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M69,19L69,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M79,19L79,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
</vector>
================================================
FILE: app/src/main/res/drawable/process_bg.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 背景 gradient是渐变,corners定义的是圆角 -->
<item android:id="@android:id/background">
<shape>
<corners android:radius="10dp" />
<solid android:color="#00ffffff" />
</shape>
</item>
<!-- 第二条进度条颜色 -->
<item android:id="@android:id/secondaryProgress">
<clip>
<shape>
<corners android:radius="10dip" />
<solid android:color="#00ffffff" />
</shape>
</clip>
</item>
<!-- 进度条 -->
<item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="10dip" />
<gradient
android:angle="180"
android:endColor="#FFFFFF"
android:startColor="#f00" />
</shape>
</clip>
</item>
</layer-list>
================================================
FILE: app/src/main/res/drawable/selector_bg_tree_tag.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false">
<shape android:shape="rectangle">
<solid android:color="@color/colorTheme" />
<corners android:radius="15dp" />
<padding android:bottom="7dp" android:left="16dp" android:right="16dp" android:top="7dp" />
</shape>
</item>
<item android:state_pressed="true">
<shape>
<corners android:radius="15dp" />
<padding android:bottom="7dp" android:left="16dp" android:right="16dp" android:top="7dp" />
<solid android:color="@color/colorSmallRed" />
</shape>
</item>
</selector>
================================================
FILE: app/src/main/res/drawable/selector_collect_check.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_collect" android:state_checked="true" />
<item android:drawable="@drawable/ic_un_collect" />
</selector>
================================================
FILE: app/src/main/res/drawable-v24/ic_launcher_foreground.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillType="evenOdd"
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
android:strokeColor="#00000000"
android:strokeWidth="1">
<aapt:attr name="android:fillColor">
<gradient
android:endX="78.5885"
android:endY="90.9159"
android:startX="48.7653"
android:startY="61.0927"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0"/>
<item
android:color="#00000000"
android:offset="1.0"/>
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
android:strokeColor="#00000000"
android:strokeWidth="1"/>
</vector>
================================================
FILE: app/src/main/res/layout/activity_collection.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:background="@color/colorSubtitle"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
app:navigationIcon="@drawable/icon_back"
android:id="@+id/toolbar"
android:background="@color/colorTheme"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:textSize="20sp"
android:id="@+id/tv_title"
android:textColor="@color/white"
android:text="我的收藏"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</android.support.v7.widget.Toolbar>
<FrameLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
================================================
FILE: app/src/main/res/layout/activity_login.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:background="@color/colorSubtitle"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
app:navigationIcon="@drawable/icon_back"
android:id="@+id/toolbar"
android:background="@color/colorTheme"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:textSize="20sp"
android:id="@+id/tv_title"
android:textColor="@color/white"
android:text="Login"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</android.support.v7.widget.Toolbar>
<com.lxm.module_library.materialLogin.MaterialLoginView
android:id="@+id/login"
app:registerIcon="@drawable/ic_person_add_white_24dp"
app:loginView="@layout/custom_login_view"
app:registerView="@layout/custom_register_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
================================================
FILE: app/src/main/res/layout/activity_main.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
tools:openDrawer="start">
<include
android:id="@+id/mainContent"
layout="@layout/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<android.support.design.widget.NavigationView
android:id="@+id/navigationView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/drawer_header_layout"
app:itemIconTint="@color/colorTheme"
app:itemTextColor="@color/black"
app:menu="@menu/navigation"/>
</android.support.v4.widget.DrawerLayout>
================================================
FILE: app/src/main/res/layout/activity_show_image.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000">
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:id="@+id/viewpager_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="25dp"
android:textColor="#fff"
android:textSize="14sp" />
</RelativeLayout>
================================================
FILE: app/src/main/res/layout/activity_web_view.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".utils.webview.WebViewActivity">
<!--播放全屏视频时用-->
<FrameLayout
android:id="@+id/video_fullView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="gone" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/title_tool_bar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorTheme"
app:contentInsetStartWithNavigation="0dp"
app:layout_scrollFlags="enterAlways|scroll"
app:navigationContentDescription="返回"
app:navigationIcon="@drawable/icon_back"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:theme="@style/ToolbarStyle">
<TextView
android:id="@+id/tv_gun_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:singleLine="true"
android:textColor="@color/colorWhite"
android:textSize="18sp"
android:visibility="visible"
tools:text="@string/app_name" />
</android.support.v7.widget.Toolbar>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView
android:id="@+id/webview_detail"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbarSize="3dp"
android:scrollbarThumbVertical="@color/tabBackground" />
<ProgressBar
android:id="@+id/pb_progress"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="3dp"
android:layout_alignParentTop="true"
android:max="100"
android:progress="0"
android:progressDrawable="@drawable/process_bg"
android:visibility="gone" />
</RelativeLayout>
</LinearLayout>
</RelativeLayout>
================================================
FILE: app/src/main/res/layout/article_banner.xml
================================================
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_height="match_parent"
android:layout_width="match_parent">
<com.zhouwei.mzbanner.MZBannerView
android:id="@+id/banner"
android:layout_width="match_parent"
android:layout_height="180dp"
app:open_mz_mode="true"
app:canLoop="true"
app:indicatorAlign="center"
app:indicatorPaddingLeft="10dp"
/>
</FrameLayout>
================================================
FILE: app/src/main/res/layout/article_fragment.xml
================================================
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent">
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.lxm.module_library.xrecycleview.XRecyclerView
android:background="#EEEEEE"
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbarAlwaysDrawVerticalTrack="true"
android:scrollbarFadeDuration="1"
android:scrollbarSize="4dp"
android:scrollbars="vertical"/>
</android.support.v4.widget.SwipeRefreshLayout>
</FrameLayout>
================================================
FILE: app/src/main/res/layout/category_activity.xml
================================================
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent">
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.lxm.module_library.xrecycleview.XRecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbarAlwaysDrawVerticalTrack="true"
android:scrollbarFadeDuration="1"
android:scrollbarSize="4dp"
android:scrollbars="vertical"/>
</android.support.v4.widget.SwipeRefreshLayout>
</FrameLayout>
================================================
FILE: app/src/main/res/layout/drawer_header_layout.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="180dp"
android:background="@color/colorTheme">
<de.hdodenhof.circleimageview.CircleImageView
app:civ_border_width="2dp"
app:civ_border_color="#FFFFFF"
android:src="@drawable/ic_photo"
android:id="@+id/ivHeadView"
android:layout_width="65dp"
android:layout_height="65dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/tvUserName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="username"
android:textSize="16sp"
android:textColor="@android:color/white"
android:textStyle="normal"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/ivHeadView"/>
</android.support.constraint.ConstraintLayout>
================================================
FILE: app/src/main/res/layout/item_article.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:paddingBottom="6dp"
android:layout_width="match_parent">
<android.support.v7.widget.CardView
android:elevation="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground">
<LinearLayout
android:id="@+id/ll_all"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackgroundBorderless"
android:orientation="vertical"
android:paddingTop="12dp">
<ImageView
android:layout_alignParentLeft="true"
android:src="@drawable/ic_article_new"
android:id="@+id/iv_new"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="center_vertical"
android:layout_marginStart="5dp"
android:scaleType="centerCrop"/>
<LinearLayout
android:id="@+id/ll_middle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:orientation="horizontal">
<TextView
tools:text="我是一堆内容"
android:id="@+id/tv_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:lineSpacingExtra="4dp"
android:textColor="@color/colorContent"
android:textSize="15sp"/>
<ImageView
android:id="@+id/iv_image"
android:layout_width="60dp"
android:layout_height="80dp"
android:layout_gravity="center_vertical"
android:layout_marginStart="5dp"
android:background="@color/colorLine"
android:scaleType="centerCrop"
android:visibility="visible"/>
</LinearLayout>
<RelativeLayout
android:layout_alignBottom="@+id/ll_middle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="6dp"
android:paddingLeft="12dp"
android:paddingRight="12dp">
<TextView
tools:text="我是作者"
android:id="@+id/tv_author"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/colorSubtitle"
android:textSize="12sp"/>
<TextView
android:id="@+id/tv_content_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/tv_author"
android:textColor="@color/colorSubtitle"
android:textSize="12sp"
android:visibility="gone"/>
<TextView
tools:text="我是发表时间"
android:id="@+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:textColor="@color/colorSubtitle"
android:textSize="12sp"/>
</RelativeLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
</RelativeLayout>
================================================
FILE: app/src/main/res/layout/item_banner.xml
================================================
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent">
<ImageView
android:id="@+id/banner_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerInside"
/>
</FrameLayout>
================================================
FILE: app/src/main/res/layout/item_image_view_pager.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ff000000">
<uk.co.senab.photoview.PhotoView
android:id="@+id/zoom_image_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ProgressBar
android:id="@+id/loading"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center" />
</FrameLayout>
================================================
FILE: app/src/main/res/layout/item_tree.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/ll_item_top"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="8dp"
android:paddingTop="8dp"
android:paddingRight="8dp"
android:paddingBottom="16dp">
<TextView
android:layout_marginStart="6dp"
android:id="@+id/tv_tree_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/colorContent"
android:textSize="17sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="title"/>
<com.zhy.view.flowlayout.TagFlowLayout
android:id="@+id/fl_tree"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
app:itemSpacing="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_tree_title"
app:lineSpacing="8dp"/>
</android.support.constraint.ConstraintLayout>
================================================
FILE: app/src/main/res/layout/item_tree_tag.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/tv_tag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/selector_bg_tree_tag"
android:textColor="@color/colorWhite"
android:textSize="12sp"
android:padding="8dp"
tools:text="title"/>
================================================
FILE: app/src/main/res/layout/item_view.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:paddingBottom="6dp"
>
<android.support.design.card.MaterialCardView
style="@style/AppTheme"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="3dp">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:foreground="?attr/selectableItemBackgroundBorderless"
android:paddingBottom="8dp"
android:paddingRight="8dp"
android:paddingTop="8dp">
<RelativeLayout
android:id="@+id/rl_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:src="@drawable/ic_article_new"
android:id="@+id/iv_new"
android:layout_width="40dp"
android:layout_height="25dp"
/>
<TextView
android:id="@+id/tv_tag_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:background="?selectableItemBackgroundBorderless"
android:textSize="13sp"
app:layout_constraintEnd_toEndOf="parent"
tools:text="技术博客"/>
</RelativeLayout>
<ImageView
android:id="@+id/iv_image"
android:layout_width="60dp"
android:layout_height="78dp"
android:layout_marginStart="8dp"
android:scaleType="centerCrop"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/rl_header"
tools:background="@color/colorLine"/>
<TextView
android:id="@+id/tv_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:ellipsize="end"
android:lineSpacingExtra="4dp"
android:maxLines="2"
android:textSize="14sp"
app:layout_constraintEnd_toStartOf="@+id/iv_collect"
app:layout_constraintStart_toEndOf="@+id/iv_image"
app:layout_constraintTop_toTopOf="@+id/iv_image"
tools:text="内容展示内容展示内容展示内容展示内容展示内容展示内容展示内容展示内容展示内容展示内容展示"/>
<CheckBox
android:background="?selectableItemBackgroundBorderless"
android:button="@drawable/selector_collect_check"
app:layout_constraintStart_toEndOf="@+id/tv_title"
app:layout_constraintTop_toTopOf="@+id/tv_title"
app:layout_constraintEnd_toEndOf="parent"
android:src="@drawable/ic_un_collect"
android:id="@+id/iv_collect"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="13dp"
android:textSize="11sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:text="日期"/>
<TextView
android:id="@+id/tv_author"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="11sp"
app:layout_constraintStart_toStartOf="@+id/tv_title"
app:layout_constraintTop_toBottomOf="@+id/tv_title"
app:layout_constraintBottom_toBottomOf="parent"
tools:text="author"/>
</android.support.constraint.ConstraintLayout>
</android.support.design.card.MaterialCardView>
</RelativeLayout>
================================================
FILE: app/src/main/res/layout/item_view_welfare.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:padding="6dp"
android:layout_height="wrap_content">
<android.support.design.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="6dp"
android:background="@color/colorWhite"
app:cardCornerRadius="8dp"
tools:targetApi="lollipop">
<ImageView
android:id="@+id/iv_welfare"
android:layout_width="match_parent"
android:layout_height="250dp"
android:scaleType="centerCrop"/>
</android.support.design.card.MaterialCardView>
</LinearLayout>
================================================
FILE: app/src/main/res/layout/main_content.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tl="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:background="@color/colorTheme"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<de.hdodenhof.circleimageview.CircleImageView
android:src="@drawable/ic_photo"
android:id="@+id/iv_photo"
android:layout_width="36dp"
android:layout_height="36dp"/>
<com.flyco.tablayout.SlidingTabLayout
android:paddingLeft="10dp"
android:id="@+id/tablayout"
android:layout_width="match_parent"
android:layout_height="58dp"
tl:tl_indicator_color="#FFFFFF"
tl:tl_indicator_height="1.5dp"
tl:tl_indicator_width_equal_title="true"
tl:tl_tab_padding="6dp"
tl:tl_textSelectColor="#FFFFFF"
tl:tl_textUnselectColor="#66FFFFFF"
tl:tl_underline_color="#1AFFFFFF"
tl:tl_underline_height="1dp"/>
</android.support.v7.widget.Toolbar>
<android.support.v4.view.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
</LinearLayout>
================================================
FILE: app/src/main/res/layout/tree_fragment.xml
================================================
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent">
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.lxm.module_library.xrecycleview.XRecyclerView
android:background="@color/colorKnowledge_bg"
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbarAlwaysDrawVerticalTrack="true"
android:scrollbarFadeDuration="1"
android:scrollbarSize="4dp"
android:scrollbars="vertical"/>
</android.support.v4.widget.SwipeRefreshLayout>
</FrameLayout>
================================================
FILE: app/src/main/res/menu/main.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_search"
android:icon="@drawable/ic_main_search"
android:orderInCategory="100"
android:title="搜索"
app:showAsAction="always" />
</menu>
================================================
FILE: app/src/main/res/menu/navigation.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/colletion"
android:icon="@drawable/ic_collection"
android:title="我的收藏"/>
<item
android:id="@+id/about"
android:icon="@drawable/ic_about"
android:title="关于"/>
<item
android:id="@+id/accout"
android:icon="@drawable/ic_login_menu"
android:title="登录"/>
</menu>
================================================
FILE: app/src/main/res/menu/webview_menu.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/actionbar_share"
android:orderInCategory="100"
android:title="@string/actionbar_webview_share"
app:showAsAction="never" />
<item
android:id="@+id/actionbar_webview_refresh"
android:orderInCategory="100"
android:title="@string/actionbar_webview_refresh"
app:showAsAction="never" />
<item
android:id="@+id/actionbar_cope"
android:orderInCategory="100"
android:title="@string/actionbar_webview_cope"
app:showAsAction="never" />
<item
android:id="@+id/actionbar_open"
android:orderInCategory="100"
android:title="@string/actionbar_webview_open"
app:showAsAction="never" />
</menu>
================================================
FILE: app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>
================================================
FILE: app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>
================================================
FILE: app/src/main/res/values/attrs_circle_view.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="circletextview">
<attr name="circle_color" format="color"/>
<attr name="circle_text_color" format="color"/>
<attr name="random_color" format="boolean"/>
<attr name="sub_first_character" format="boolean"/>
</declare-styleable>
<declare-styleable name="TextViewBorder">
<attr name="tvborderColor" format="color" />
<attr name="tvBorderWidth" format="integer" />
</declare-styleable>
</resources>
================================================
FILE: app/src/main/res/values/colors.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#008577</color>
<color name="colorPrimaryDark">#00574B</color>
<color name="colorAccent">#D81B60</color>
<!-- 主题色-->
<color name="colorTheme">#343434</color>
<color name="color_page_bg">#F1F3F4</color>
<color name="colorSmallRed">#faebeb</color>
<color name="colorKnowledge_bg">#FFFAFA</color>
</resources>
================================================
FILE: app/src/main/res/values/strings.xml
================================================
<resources>
<string name="app_name">WanAndroidKotlin</string>
<string name="navigation_open">打开</string>
<string name="navigation_close">关闭</string>
</resources>
================================================
FILE: app/src/main/res/values/styles.xml
================================================
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorTheme</item>
<item name="colorPrimaryDark">@color/colorTheme</item>
<item name="colorAccent">@color/colorTheme</item>
</style>
</resources>
================================================
FILE: app/src/test/java/com/lxm/wanandroid/ExampleUnitTest.kt
================================================
package com.lxm.wanandroid
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}
================================================
FILE: build.gradle
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.3.21'
repositories {
google()
jcenter()
maven { url 'https://jitpack.io' }
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
maven { url 'https://jitpack.io' }
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
ext{
retrofitVersion = '2.2.0'
okhttploggingVersion = '3.4.1'
okhttpVersion = '3.4.1'
rxjavaVersion = '2.0.1'
rxandroidVersion = '2.0.1'
rxbindingVersion = '2.0.0'
constraintVersion = '1.1.2'
butterknifeVwesion = '8.8.1'
glideVersion = '4.9.0'
glide_transformations = '3.0.1'
}
================================================
FILE: gradle/wrapper/gradle-wrapper.properties
================================================
#Thu Jun 13 22:10:05 CST 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
================================================
FILE: gradle.properties
================================================
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official
================================================
FILE: gradlew
================================================
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
================================================
FILE: gradlew.bat
================================================
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
================================================
FILE: module_library/.gitignore
================================================
/build
================================================
FILE: module_library/build.gradle
================================================
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
android {
compileSdkVersion 28
defaultConfig {
minSdkVersion 21
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
//动画
implementation ('com.github.ozodrukh:CircularReveal:2.0.1@aar') {
transitive = true;
}
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation "com.android.support:design:28.0.0"
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:design:28.0.0'
// Retrofit & okHttp
api "com.squareup.retrofit2:retrofit:$rootProject.retrofitVersion"
api "com.squareup.retrofit2:converter-gson:$rootProject.retrofitVersion"
api "com.squareup.retrofit2:adapter-rxjava2:$rootProject.retrofitVersion"
api "com.squareup.okhttp3:logging-interceptor:$rootProject.okhttploggingVersion"
api "com.squareup.okhttp3:okhttp:$rootProject.okhttpVersion"
// RxBinging
api "com.jakewharton.rxbinding2:rxbinding-appcompat-v7:$rootProject.rxbindingVersion"
// Glide
api "com.github.bumptech.glide:glide:$rootProject.glideVersion"
annotationProcessor "com.github.bumptech.glide:compiler:$rootProject.glideVersion"
// 高斯模糊和圆角等
api 'jp.wasabeef:glide-transformations:4.0.1'
//page
def paging_version = "1.0.0"
api "android.arch.paging:runtime:$paging_version"
testImplementation "android.arch.paging:common:$paging_version"
api 'android.arch.paging:rxjava2:1.0.0-rc1'
//lifecycle
def lifecycle_version = "1.1.1"
api "android.arch.lifecycle:extensions:$lifecycle_version"
api "android.arch.lifecycle:viewmodel:$lifecycle_version"
api "android.arch.lifecycle:livedata:$lifecycle_version"
api "android.arch.lifecycle:runtime:$lifecycle_version"
annotationProcessor "android.arch.lifecycle:compiler:$lifecycle_version"
api "android.arch.lifecycle:reactivestreams:$lifecycle_version"
//toast
implementation 'me.drakeet.support:toastcompat:1.1.0'
}
repositories {
mavenCentral()
}
================================================
FILE: module_library/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
================================================
FILE: module_library/src/androidTest/java/com/lxm/module_library/ExampleInstrumentedTest.java
================================================
package com.lxm.module_library;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("com.lxm.module_library.test", appContext.getPackageName());
}
}
================================================
FILE: module_library/src/main/AndroidManifest.xml
================================================
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.lxm.module_library">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
</manifest>
================================================
FILE: module_library/src/main/java/com/lxm/module_library/anim/AnimManager.kt
================================================
package com.lxm.module_library.anim
import android.content.Context
import android.os.Build
import android.view.View
import android.view.animation.AnimationUtils
/**
* Created by Horrarndoo on 2017/9/11.
*
*
*/
object AnimManager {
/**
* Alpha and scaleX 动画
* Alpha 0->1
* ScaleX 0.8->1
*
* @param context context
* @param view view
* @param startDelay 动画开始前延时(ms)
* @param duration 动画持续时间(ms)
*/
fun animAlphaAndScaleX(context: Context, view: View, startDelay: Int, duration: Int) {
view.alpha = 0f
view.scaleX = 0.8f
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
view.animate()
.alpha(1f)
.scaleX(1f)
.setStartDelay(startDelay.toLong())
.setDuration(duration.toLong())
.setInterpolator(AnimUtils.getFastOutSlowInInterpolator(context))
.start()
} else {
view.animate()
.alpha(1f)
.scaleX(1f)
.setStartDelay(startDelay.toLong())
.setDuration(duration.toLong())
.setInterpolator(AnimationUtils.loadInterpolator(context, android.R.interpolator.linear))
.start()
}
}
/**
* Alpha and scale X Y 动画
* Alpha 0->1
* ScaleX 0->1
* ScaleY 0->1
*
* @param context context
* @param view view
* @param startDelay 动画开始前延时(ms)
* @param duration 动画持续时间(ms)
*/
fun animAlphaAndScale(context: Context, view: View, startDelay: Int, duration: Int) {
view.alpha = 0f
view.scaleX = 0f
view.scaleY = 0f
view.animate()
.alpha(1f)
.scaleX(1f)
.scaleY(1f)
.setStartDelay(startDelay.toLong())
.setDuration(duration.toLong())
.setInterpolator(AnimationUtils.loadInterpolator(context,
android.R.interpolator.overshoot)).start()
}
}
================================================
FILE: module_library/src/main/java/com/lxm/module_library/anim/AnimUtils.kt
================================================
/*
* Copyright 2015 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.lxm.module_library.anim
import android.animation.Animator
import android.animation.TimeInterpolator
import android.content.Context
import android.os.Build
import android.support.annotation.RequiresApi
import android.transition.Transition
import android.util.ArrayMap
import android.util.Property
import android.view.animation.AnimationUtils
import android.view.animation.Interpolator
import java.util.*
/**
* Utility methods for working with animations.
*/
object AnimUtils {
private var fastOutSlowIn: Interpolator? = null
private var fastOutLinearIn: Interpolator? = null
private var linearOutSlowIn: Interpolator? = null
fun getFastOutSlowInInterpolator(context: Context): Interpolator? {
if (fastOutSlowIn == null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
fastOutSlowIn = AnimationUtils.loadInterpolator(context,
android.R.interpolator.fast_out_slow_in)
}
}
return fastOutSlowIn
}
fun getFastOutLinearInInterpolator(context: Context): Interpolator? {
if (fastOutLinearIn == null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
fastOutLinearIn = AnimationUtils.loadInterpolator(context,
android.R.interpolator.fast_out_linear_in)
}
}
return fastOutLinearIn
}
fun getLinearOutSlowInInterpolator(context: Context): Interpolator? {
if (linearOutSlowIn == null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
linearOutSlowIn = AnimationUtils.loadInterpolator(context,
android.R.interpolator.linear_out_slow_in)
}
}
return linearOutSlowIn
}
/**
* Linear interpolate between a and b with parameter t.
*/
fun lerp(a: Float, b: Float, t: Float): Float {
return a + (b - a) * t
}
/**
* An implementation of [Property] to be used specifically with fields of
* type
* `float`. This type-specific subclass enables performance benefit by allowing
* calls to a [set()][.set] function that takes the primitive
* `float` type and avoids autoboxing and other overhead associated with the
* `Float` class.
*
* @param <T> The class on which the Property is declared.
</T> */
abstract class FloatProperty<T>(name: String) : Property<T, Float>(Float::class.java, name) {
/**
* A type-specific override of the [.set] that is faster when dealing
* with fields of type `float`.
*/
abstract fun setValue(`object`: T, value: Float)
override fun set(`object`: T, value: Float?) {
setValue(`object`, value!!)
}
}
/**
* An implementation of [Property] to be used specifically with fields of
* type
* `int`. This type-specific subclass enables performance benefit by allowing
* calls to a [set()][.set] function that takes the primitive
* `int` type and avoids autoboxing and other overhead associated with the
* `Integer` class.
*
* @param <T> The class on which the Property is declared.
</T> */
abstract class IntProperty<T>(name: String) : Property<T, Int>(Int::class.java, name) {
/**
* A type-specific override of the [.set] that
gitextract_0t5_wqvy/ ├── .gitignore ├── .idea/ │ ├── codeStyles/ │ │ ├── Project.xml │ │ └── codeStyleConfig.xml │ ├── compiler.xml │ ├── encodings.xml │ ├── gradle.xml │ ├── inspectionProfiles/ │ │ └── Project_Default.xml │ ├── misc.xml │ ├── runConfigurations.xml │ └── vcs.xml ├── README.md ├── app/ │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src/ │ ├── androidTest/ │ │ └── java/ │ │ └── com/ │ │ └── lxm/ │ │ └── wanandroid/ │ │ └── ExampleInstrumentedTest.kt │ ├── main/ │ │ ├── AndroidManifest.xml │ │ ├── java/ │ │ │ └── com/ │ │ │ └── lxm/ │ │ │ └── wanandroid/ │ │ │ ├── MainActivity.kt │ │ │ ├── repository/ │ │ │ │ ├── model/ │ │ │ │ │ ├── ArticleResponse.kt │ │ │ │ │ ├── Banner.kt │ │ │ │ │ ├── HttpResponse.kt │ │ │ │ │ ├── Listing.kt │ │ │ │ │ ├── LoginBean.kt │ │ │ │ │ ├── Navigation.kt │ │ │ │ │ ├── Resource.kt │ │ │ │ │ ├── TreeBean.kt │ │ │ │ │ └── WelfareResponse.kt │ │ │ │ └── remote/ │ │ │ │ ├── LoginResposity.kt │ │ │ │ └── httpClient/ │ │ │ │ ├── API.kt │ │ │ │ └── RetrofitClient.kt │ │ │ ├── ui/ │ │ │ │ ├── ArticleFragment.kt │ │ │ │ ├── CollectActivity.kt │ │ │ │ ├── LoginActivity.kt │ │ │ │ ├── NavigationFragment.kt │ │ │ │ ├── ProjectFragment.kt │ │ │ │ ├── TagArticleActivity.kt │ │ │ │ ├── TreeFragment.kt │ │ │ │ ├── ViewBigImageActivity.kt │ │ │ │ ├── WelfareFragment.kt │ │ │ │ ├── adapter/ │ │ │ │ │ ├── ArticleAdapter.kt │ │ │ │ │ ├── NaviAdapter.kt │ │ │ │ │ ├── TreeAdapter.kt │ │ │ │ │ └── WelfareAdapter.kt │ │ │ │ └── base/ │ │ │ │ ├── BaseRecyclerAdapter.kt │ │ │ │ ├── BaseRecyclerViewHoder.kt │ │ │ │ ├── OnItemClickListener.kt │ │ │ │ └── OnItemLongClickListener.kt │ │ │ ├── utils/ │ │ │ │ ├── CookieUtils.kt │ │ │ │ ├── GlideUtil.kt │ │ │ │ └── webview/ │ │ │ │ ├── WebViewActivity.java │ │ │ │ └── config/ │ │ │ │ ├── FullscreenHolder.java │ │ │ │ ├── IWebPageView.java │ │ │ │ ├── ImageClickInterface.java │ │ │ │ ├── MyWebChromeClient.java │ │ │ │ └── MyWebViewClient.java │ │ │ └── viewmodel/ │ │ │ ├── ArticleViewModel.kt │ │ │ ├── CategoryViewModel.kt │ │ │ ├── CollectViewModel.kt │ │ │ ├── LoginViewModel.kt │ │ │ ├── NaviViewModelView.kt │ │ │ ├── ProjectViewModel.kt │ │ │ ├── TreeViewModel.kt │ │ │ └── WelfareModelView.kt │ │ └── res/ │ │ ├── drawable/ │ │ │ ├── ic_launcher_background.xml │ │ │ ├── process_bg.xml │ │ │ ├── selector_bg_tree_tag.xml │ │ │ └── selector_collect_check.xml │ │ ├── drawable-v24/ │ │ │ └── ic_launcher_foreground.xml │ │ ├── layout/ │ │ │ ├── activity_collection.xml │ │ │ ├── activity_login.xml │ │ │ ├── activity_main.xml │ │ │ ├── activity_show_image.xml │ │ │ ├── activity_web_view.xml │ │ │ ├── article_banner.xml │ │ │ ├── article_fragment.xml │ │ │ ├── category_activity.xml │ │ │ ├── drawer_header_layout.xml │ │ │ ├── item_article.xml │ │ │ ├── item_banner.xml │ │ │ ├── item_image_view_pager.xml │ │ │ ├── item_tree.xml │ │ │ ├── item_tree_tag.xml │ │ │ ├── item_view.xml │ │ │ ├── item_view_welfare.xml │ │ │ ├── main_content.xml │ │ │ └── tree_fragment.xml │ │ ├── menu/ │ │ │ ├── main.xml │ │ │ ├── navigation.xml │ │ │ └── webview_menu.xml │ │ ├── mipmap-anydpi-v26/ │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ └── values/ │ │ ├── attrs_circle_view.xml │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test/ │ └── java/ │ └── com/ │ └── lxm/ │ └── wanandroid/ │ └── ExampleUnitTest.kt ├── build.gradle ├── gradle/ │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat ├── module_library/ │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src/ │ ├── androidTest/ │ │ └── java/ │ │ └── com/ │ │ └── lxm/ │ │ └── module_library/ │ │ └── ExampleInstrumentedTest.java │ ├── main/ │ │ ├── AndroidManifest.xml │ │ ├── java/ │ │ │ └── com/ │ │ │ └── lxm/ │ │ │ └── module_library/ │ │ │ ├── anim/ │ │ │ │ ├── AnimManager.kt │ │ │ │ ├── AnimUtils.kt │ │ │ │ └── ToolbarAnimManager.kt │ │ │ ├── base/ │ │ │ │ ├── BaseActivity.kt │ │ │ │ ├── BaseFragment.kt │ │ │ │ ├── BaseViewModel.kt │ │ │ │ └── NoViewModel.java │ │ │ ├── global/ │ │ │ │ ├── AppManager.java │ │ │ │ └── GlobalApplication.java │ │ │ ├── helper/ │ │ │ │ ├── RetrofitCreateHelper.java │ │ │ │ ├── RxHelper.java │ │ │ │ └── okhttp/ │ │ │ │ ├── TrustManager.java │ │ │ │ ├── cache/ │ │ │ │ │ ├── CacheInterceptor.java │ │ │ │ │ └── HttpCache.java │ │ │ │ └── cookies/ │ │ │ │ ├── CookieManger.java │ │ │ │ ├── OkHttpCookies.java │ │ │ │ └── PersistentCookieStore.java │ │ │ ├── materialLogin/ │ │ │ │ ├── DefaultLoginView.java │ │ │ │ ├── DefaultRegisterView.java │ │ │ │ ├── MaterialLoginView.java │ │ │ │ └── RegisterView.java │ │ │ ├── statusbar/ │ │ │ │ ├── StatusBarUtil.java │ │ │ │ └── StatusBarView.java │ │ │ ├── utils/ │ │ │ │ ├── AppUtils.kt │ │ │ │ ├── BaseTools.java │ │ │ │ ├── BitmapUtils.kt │ │ │ │ ├── CheckNetwork.java │ │ │ │ ├── ClassUtil.kt │ │ │ │ ├── DateUtils.kt │ │ │ │ ├── DialogUtils.kt │ │ │ │ ├── DisplayUtils.kt │ │ │ │ ├── FileUtils.kt │ │ │ │ ├── HtmlUtils.kt │ │ │ │ ├── HttpUtils.kt │ │ │ │ ├── ImageUtils.kt │ │ │ │ ├── JsonUtils.kt │ │ │ │ ├── MD5Utils.kt │ │ │ │ ├── MyDividerItemDecoration.java │ │ │ │ ├── NetworkConnectionUtils.kt │ │ │ │ ├── PreferencesUtil.kt │ │ │ │ ├── RefreshHelper.kt │ │ │ │ ├── ResourcesUtils.kt │ │ │ │ ├── ScreenAdapterUtils.kt │ │ │ │ ├── ScreenUtils.kt │ │ │ │ ├── SnackbarUtils.kt │ │ │ │ ├── StatusBarUtils.kt │ │ │ │ ├── StringUtils.kt │ │ │ │ ├── TimestampUtils.kt │ │ │ │ ├── ToastUtil.java │ │ │ │ ├── ToastUtils.kt │ │ │ │ ├── UnicodeUtils.kt │ │ │ │ └── WifiAutoConnectManager.kt │ │ │ └── xrecycleview/ │ │ │ ├── BaseRefreshHeader.java │ │ │ ├── LoadingMoreFooter.java │ │ │ ├── WrapAdapter.java │ │ │ ├── XRecyclerView.java │ │ │ └── YunRefreshHeader.java │ │ └── res/ │ │ ├── drawable/ │ │ │ ├── app_loading_anim.xml │ │ │ ├── common_progress_cirle.xml │ │ │ ├── header_loading_anim.xml │ │ │ ├── ic_add.xml │ │ │ ├── ic_clear.xml │ │ │ ├── login_back.xml │ │ │ └── shape_line.xml │ │ ├── layout/ │ │ │ ├── activity_base.xml │ │ │ ├── custom_login_view.xml │ │ │ ├── custom_register_view.xml │ │ │ ├── default_login_view.xml │ │ │ ├── default_register_view.xml │ │ │ ├── fragment_base.xml │ │ │ ├── layout_loading_error.xml │ │ │ ├── layout_loading_view.xml │ │ │ ├── login_layout.xml │ │ │ ├── login_view.xml │ │ │ ├── refresh_footer.xml │ │ │ ├── refresh_header.xml │ │ │ └── register_layout.xml │ │ ├── values/ │ │ │ ├── attrs.xml │ │ │ ├── colors.xml │ │ │ ├── dimen.xml │ │ │ ├── drawables.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ └── values-w600dp/ │ │ └── dimen.xml │ └── test/ │ └── java/ │ └── com/ │ └── lxm/ │ └── module_library/ │ └── ExampleUnitTest.java └── settings.gradle
SYMBOL INDEX (310 symbols across 34 files)
FILE: app/src/main/java/com/lxm/wanandroid/utils/webview/WebViewActivity.java
class WebViewActivity (line 38) | public class WebViewActivity extends AppCompatActivity implements IWebPa...
method onCreate (line 56) | @Override
method getIntentData (line 67) | private void getIntentData() {
method initTitle (line 75) | private void initTitle() {
method initToolBar (line 86) | private void initToolBar() {
method onCreateOptionsMenu (line 98) | @Override
method setTitle (line 104) | @Override
method onOptionsItemSelected (line 112) | @Override
method initWebView (line 143) | @SuppressLint("SetJavaScriptEnabled")
method hindProgressBar (line 195) | @Override
method showWebView (line 200) | @Override
method hindWebView (line 205) | @Override
method fullViewAddView (line 210) | @Override
method showVideoFullView (line 218) | @Override
method hindVideoFullView (line 223) | @Override
method startProgress (line 228) | @Override
method addImageClickListener (line 237) | @Override
method loadImageClickJS (line 243) | private void loadImageClickJS() {
method loadTextClickJS (line 254) | private void loadTextClickJS() {
method getVideoFullView (line 266) | public FrameLayout getVideoFullView() {
method hideCustomView (line 273) | public void hideCustomView() {
method onActivityResult (line 281) | @Override
method onNewIntent (line 295) | @Override
method getDataFromBrowser (line 308) | private void getDataFromBrowser(Intent intent) {
method handleLongImage (line 328) | private boolean handleLongImage() {
method onKeyDown (line 362) | @Override
method handleFinish (line 386) | public void handleFinish() {
method onPause (line 395) | @Override
method onResume (line 401) | @Override
method onDestroy (line 413) | @Override
method onConfigurationChanged (line 439) | @Override
method getResources (line 450) | @Override
method loadUrl (line 466) | public static void loadUrl(Context mContext, String mUrl, String mTitl...
method loadUrl (line 478) | public static void loadUrl(Context mContext, String mUrl, String mTitl...
FILE: app/src/main/java/com/lxm/wanandroid/utils/webview/config/FullscreenHolder.java
class FullscreenHolder (line 11) | public class FullscreenHolder extends FrameLayout {
method FullscreenHolder (line 13) | public FullscreenHolder(Context ctx) {
method onTouchEvent (line 18) | @Override
FILE: app/src/main/java/com/lxm/wanandroid/utils/webview/config/IWebPageView.java
type IWebPageView (line 8) | public interface IWebPageView {
method hindProgressBar (line 11) | void hindProgressBar();
method showWebView (line 14) | void showWebView();
method hindWebView (line 17) | void hindWebView();
method startProgress (line 22) | void startProgress(int newProgress);
method addImageClickListener (line 27) | void addImageClickListener();
method fullViewAddView (line 32) | void fullViewAddView(View view);
method showVideoFullView (line 34) | void showVideoFullView();
method hindVideoFullView (line 36) | void hindVideoFullView();
method setTitle (line 41) | void setTitle(String title);
FILE: app/src/main/java/com/lxm/wanandroid/utils/webview/config/ImageClickInterface.java
class ImageClickInterface (line 15) | public class ImageClickInterface {
method ImageClickInterface (line 18) | public ImageClickInterface(Context context) {
method imageClick (line 22) | @JavascriptInterface
method textClick (line 30) | @JavascriptInterface
FILE: app/src/main/java/com/lxm/wanandroid/utils/webview/config/MyWebChromeClient.java
class MyWebChromeClient (line 22) | public class MyWebChromeClient extends WebChromeClient {
method MyWebChromeClient (line 35) | public MyWebChromeClient(IWebPageView mIWebPageView) {
method onShowCustomView (line 41) | @Override
method onHideCustomView (line 58) | @Override
method getVideoLoadingProgressView (line 75) | @Override
method onProgressChanged (line 84) | @Override
method inCustomView (line 93) | public boolean inCustomView() {
method onReceivedTitle (line 97) | @Override
method openFileChooser (line 114) | public void openFileChooser(ValueCallback<Uri> uploadMsg, String accep...
method openFileChooser (line 119) | public void openFileChooser(ValueCallback<Uri> uploadMsg) {
method openFileChooser (line 123) | public void openFileChooser(ValueCallback<Uri> uploadMsg, String accep...
method onShowFileChooser (line 128) | @Override
method openFileChooserImpl (line 134) | private void openFileChooserImpl(ValueCallback<Uri> uploadMsg) {
method openFileChooserImplForAndroid5 (line 142) | private void openFileChooserImplForAndroid5(ValueCallback<Uri[]> uploa...
method mUploadMessage (line 158) | public void mUploadMessage(Intent intent, int resultCode) {
method mUploadMessageForAndroid5 (line 169) | public void mUploadMessageForAndroid5(Intent intent, int resultCode) {
FILE: app/src/main/java/com/lxm/wanandroid/utils/webview/config/MyWebViewClient.java
class MyWebViewClient (line 22) | public class MyWebViewClient extends WebViewClient {
method MyWebViewClient (line 27) | public MyWebViewClient(IWebPageView mIWebPageView) {
method shouldOverrideUrlLoading (line 33) | @SuppressWarnings("deprecation")
method onPageFinished (line 53) | @Override
method onScaleChanged (line 64) | @Override
method handleOtherwise (line 75) | private void handleOtherwise(Activity activity, String url) {
method startActivity (line 96) | private void startActivity(String url) {
FILE: module_library/src/androidTest/java/com/lxm/module_library/ExampleInstrumentedTest.java
class ExampleInstrumentedTest (line 17) | @RunWith(AndroidJUnit4.class)
method useAppContext (line 19) | @Test
FILE: module_library/src/main/java/com/lxm/module_library/base/NoViewModel.java
class NoViewModel (line 5) | public class NoViewModel extends ViewModel {
FILE: module_library/src/main/java/com/lxm/module_library/global/AppManager.java
class AppManager (line 15) | public class AppManager {
method AppManager (line 19) | private AppManager() {
method getAppManager (line 25) | public static AppManager getAppManager() {
method addActivity (line 35) | public void addActivity(Activity activity) {
method currentActivity (line 45) | public Activity currentActivity() {
method finishActivity (line 53) | public void finishActivity() {
method finishActivity (line 61) | public void finishActivity(Activity activity) {
method finishActivity (line 72) | public void finishActivity(Class<?> cls) {
method finishAllActivity (line 83) | public void finishAllActivity() {
method AppExit (line 95) | public void AppExit(Context context) {
method isAppExit (line 106) | public boolean isAppExit() {
FILE: module_library/src/main/java/com/lxm/module_library/global/GlobalApplication.java
class GlobalApplication (line 15) | public class GlobalApplication extends Application {
method getInstance (line 22) | public static GlobalApplication getInstance() {
method onCreate (line 26) | @Override
method getContext (line 42) | public static Context getContext() {
method getHandler (line 51) | public static Handler getHandler() {
method getMainThreadId (line 60) | public static int getMainThreadId() {
FILE: module_library/src/main/java/com/lxm/module_library/helper/RetrofitCreateHelper.java
class RetrofitCreateHelper (line 21) | public class RetrofitCreateHelper {
method createApi (line 48) | public static <T> T createApi(Class<T> clazz, String url) {
FILE: module_library/src/main/java/com/lxm/module_library/helper/RxHelper.java
class RxHelper (line 12) | public class RxHelper {
method rxSchedulerHelper (line 19) | public static <T> ObservableTransformer<T, T> rxSchedulerHelper() {//c...
method createFlowable (line 36) | public static <T> Flowable<T> createFlowable(final T t) {
method createObservable (line 56) | public static <T> Observable<T> createObservable(final T t) {
FILE: module_library/src/main/java/com/lxm/module_library/helper/okhttp/TrustManager.java
class TrustManager (line 13) | public class TrustManager {
method getUnsafeOkHttpClient (line 15) | public static SSLSocketFactory getUnsafeOkHttpClient() {
FILE: module_library/src/main/java/com/lxm/module_library/helper/okhttp/cache/CacheInterceptor.java
class CacheInterceptor (line 20) | public class CacheInterceptor implements Interceptor {
method intercept (line 22) | @Override
FILE: module_library/src/main/java/com/lxm/module_library/helper/okhttp/cache/HttpCache.java
class HttpCache (line 12) | public class HttpCache {
method getCache (line 16) | public static Cache getCache() {
FILE: module_library/src/main/java/com/lxm/module_library/helper/okhttp/cookies/CookieManger.java
class CookieManger (line 15) | public class CookieManger implements CookieJar {
method CookieManger (line 22) | public CookieManger(Context context) {
method saveFromResponse (line 31) | @Override
method loadForRequest (line 40) | @Override
method clearAllCookies (line 46) | public static void clearAllCookies() {
FILE: module_library/src/main/java/com/lxm/module_library/helper/okhttp/cookies/OkHttpCookies.java
class OkHttpCookies (line 11) | public class OkHttpCookies implements Serializable {
method OkHttpCookies (line 16) | public OkHttpCookies(Cookie cookies) {
method getCookies (line 20) | public Cookie getCookies() {
method writeObject (line 28) | private void writeObject(ObjectOutputStream out) throws IOException {
method readObject (line 40) | private void readObject(ObjectInputStream in) throws IOException, Clas...
FILE: module_library/src/main/java/com/lxm/module_library/helper/okhttp/cookies/PersistentCookieStore.java
class PersistentCookieStore (line 15) | public class PersistentCookieStore {
method PersistentCookieStore (line 24) | public PersistentCookieStore(Context context) {
method getCookieToken (line 47) | protected String getCookieToken(Cookie cookie) {
method add (line 51) | public void add(HttpUrl url, Cookie cookie) {
method get (line 66) | public List<Cookie> get(HttpUrl url) {
method removeAll (line 74) | public boolean removeAll() {
method encodeCookie (line 92) | protected String encodeCookie(OkHttpCookies cookie) {
method decodeCookie (line 113) | protected Cookie decodeCookie(String cookieString) {
method byteArrayToHexString (line 135) | protected String byteArrayToHexString(byte[] bytes) {
method hexStringToByteArray (line 153) | protected byte[] hexStringToByteArray(String hexString) {
FILE: module_library/src/main/java/com/lxm/module_library/materialLogin/DefaultLoginView.java
class DefaultLoginView (line 19) | public class DefaultLoginView extends FrameLayout {
type DefaultLoginViewListener (line 21) | public interface DefaultLoginViewListener {
method onLogin (line 22) | void onLogin(TextInputLayout loginUser, TextInputLayout loginPass);
method DefaultLoginView (line 28) | public DefaultLoginView(Context context) {
method DefaultLoginView (line 32) | public DefaultLoginView(Context context, AttributeSet attrs) {
method DefaultLoginView (line 36) | public DefaultLoginView(Context context, AttributeSet attrs, int defSt...
method DefaultLoginView (line 41) | @TargetApi(Build.VERSION_CODES.LOLLIPOP)
method init (line 47) | private void init(Context context, AttributeSet attrs) {
method setListener (line 99) | public void setListener(DefaultLoginViewListener listener) {
FILE: module_library/src/main/java/com/lxm/module_library/materialLogin/DefaultRegisterView.java
class DefaultRegisterView (line 19) | public class DefaultRegisterView extends FrameLayout implements Register...
type DefaultRegisterViewListener (line 21) | public interface DefaultRegisterViewListener {
method onRegister (line 22) | void onRegister(TextInputLayout registerUser, TextInputLayout regist...
method DefaultRegisterView (line 29) | public DefaultRegisterView(Context context) {
method DefaultRegisterView (line 33) | public DefaultRegisterView(Context context, AttributeSet attrs) {
method DefaultRegisterView (line 37) | public DefaultRegisterView(Context context, AttributeSet attrs, int de...
method DefaultRegisterView (line 42) | @TargetApi(Build.VERSION_CODES.LOLLIPOP)
method init (line 48) | private void init(Context context, AttributeSet attrs) {
method setListener (line 110) | public void setListener(DefaultRegisterViewListener listener) {
method getCancelRegisterView (line 114) | @Override
FILE: module_library/src/main/java/com/lxm/module_library/materialLogin/MaterialLoginView.java
class MaterialLoginView (line 34) | @SuppressLint("RestrictedApi")
method MaterialLoginView (line 46) | public MaterialLoginView(Context context) {
method MaterialLoginView (line 50) | public MaterialLoginView(Context context, AttributeSet attrs) {
method MaterialLoginView (line 54) | public MaterialLoginView(Context context, AttributeSet attrs, int defS...
method MaterialLoginView (line 59) | @TargetApi(Build.VERSION_CODES.LOLLIPOP)
method init (line 65) | private void init(Context context, AttributeSet attrs) {
method animateRegister (line 133) | private void animateRegister() {
method isRTL (line 189) | private boolean isRTL() {
method getCircularRevealAnimation (line 193) | private Animator getCircularRevealAnimation(View view, int centerX, in...
method animateLogin (line 199) | public void animateLogin() {
method getLoginView (line 244) | public View getLoginView() {
method getRegisterView (line 248) | public View getRegisterView() {
class FabAnimation (line 252) | class FabAnimation extends Animation {
method FabAnimation (line 256) | public FabAnimation(Path path) {
method applyTransformation (line 262) | @Override
FILE: module_library/src/main/java/com/lxm/module_library/materialLogin/RegisterView.java
type RegisterView (line 8) | public interface RegisterView {
method getCancelRegisterView (line 10) | View getCancelRegisterView();
FILE: module_library/src/main/java/com/lxm/module_library/statusbar/StatusBarUtil.java
class StatusBarUtil (line 22) | public class StatusBarUtil {
method setColor (line 32) | public static void setColor(Activity activity, @ColorInt int color) {
method setColor (line 44) | public static void setColor(Activity activity, @ColorInt int color, in...
method setColorNoTranslucent (line 69) | public static void setColorNoTranslucent(Activity activity, @ColorInt ...
method setColorDiff (line 79) | @Deprecated
method setTranslucent (line 104) | public static void setTranslucent(Activity activity) {
method setTranslucent (line 116) | public static void setTranslucent(Activity activity, int statusBarAlph...
method setTranslucentForCoordinatorLayout (line 132) | public static void setTranslucentForCoordinatorLayout(Activity activit...
method setTransparent (line 145) | public static void setTransparent(Activity activity) {
method setTranslucentDiff (line 160) | @Deprecated
method setColorForDrawerLayout (line 176) | public static void setColorForDrawerLayout(Activity activity, DrawerLa...
method setColorNoTranslucentForDrawerLayout (line 187) | public static void setColorNoTranslucentForDrawerLayout(Activity activ...
method setColorForDrawerLayout (line 199) | public static void setColorForDrawerLayout(Activity activity, DrawerLa...
method setColorForDrawerLayoutDiff (line 243) | @Deprecated
method setTranslucentForDrawerLayout (line 275) | public static void setTranslucentForDrawerLayout(Activity activity, Dr...
method setTranslucentForDrawerLayout (line 285) | public static void setTranslucentForDrawerLayout(Activity activity, Dr...
method setTransparentForDrawerLayout (line 299) | public static void setTransparentForDrawerLayout(Activity activity, Dr...
method setTranslucentForDrawerLayoutDiff (line 331) | @Deprecated
method setTransparentForImageView (line 354) | public static void setTransparentForImageView(Activity activity, View ...
method setTranslucentForImageView (line 364) | public static void setTranslucentForImageView(Activity activity, View ...
method setTranslucentForImageView (line 375) | public static void setTranslucentForImageView(Activity activity, int s...
method setMargin (line 401) | public static void setMargin(Activity activity, View needOffsetView) {
method setTranslucentForImageViewInFragment (line 417) | public static void setTranslucentForImageViewInFragment(Activity activ...
method setTransparentForImageViewInFragment (line 427) | public static void setTransparentForImageViewInFragment(Activity activ...
method setTranslucentForImageViewInFragment (line 438) | public static void setTranslucentForImageViewInFragment(Activity activ...
method clearPreviousSetting (line 445) | @TargetApi(Build.VERSION_CODES.KITKAT)
method addTranslucentView (line 462) | private static void addTranslucentView(Activity activity, int statusBa...
method createStatusBarView (line 478) | private static StatusBarView createStatusBarView(Activity activity, @C...
method createStatusBarView (line 496) | private static StatusBarView createStatusBarView(Activity activity, @C...
method setRootView (line 509) | private static void setRootView(Activity activity) {
method transparentStatusBar (line 518) | @TargetApi(Build.VERSION_CODES.KITKAT)
method createTranslucentStatusBarView (line 536) | private static StatusBarView createTranslucentStatusBarView(Activity a...
method getStatusBarHeight (line 552) | public static int getStatusBarHeight(Context context) {
method calculateStatusColor (line 565) | private static int calculateStatusColor(@ColorInt int color, int alpha) {
FILE: module_library/src/main/java/com/lxm/module_library/statusbar/StatusBarView.java
class StatusBarView (line 13) | public class StatusBarView extends View {
method StatusBarView (line 14) | public StatusBarView(Context context, AttributeSet attrs) {
method StatusBarView (line 18) | public StatusBarView(Context context) {
FILE: module_library/src/main/java/com/lxm/module_library/utils/BaseTools.java
class BaseTools (line 31) | public class BaseTools {
method getDir (line 34) | public static String getDir(String path) {
method getWindowWidth (line 39) | public static int getWindowWidth(Context context) {
method getWindowHeigh (line 49) | public static int getWindowHeigh(Context context) {
method getStatusBarHeight (line 60) | public static int getStatusBarHeight(Context context) {
method formatCurrency (line 84) | public static String formatCurrency(double d) {
method formatMoney (line 101) | public static String formatMoney(double d) {
method getTopActivityName (line 115) | public String getTopActivityName(Context context) {
method setText (line 121) | public static void setText(String text, TextView textView) {
method getVersionName (line 134) | public static String getVersionName() {
method copy (line 153) | public static void copy(String content) {
method clearClipboard (line 171) | public static void clearClipboard() {
method openLink (line 186) | public static void openLink(Context context, String content) {
method isApplicationAvilible (line 199) | public static boolean isApplicationAvilible(Context context, String ap...
method hideSoftKeyBoard (line 224) | public static void hideSoftKeyBoard(Activity activity) {
method showSoftKeyBoard (line 240) | public static void showSoftKeyBoard(Activity activity, View view) {
method joinQQGroup (line 250) | public static void joinQQGroup(Context context, String key) {
method joinQQChat (line 262) | public static void joinQQChat(Context context, String qqNumber) {
FILE: module_library/src/main/java/com/lxm/module_library/utils/CheckNetwork.java
class CheckNetwork (line 12) | public class CheckNetwork {
method isNetworkConnected (line 17) | public static boolean isNetworkConnected(Context context) {
method isWifiConnected (line 37) | public static boolean isWifiConnected(Context context) {
FILE: module_library/src/main/java/com/lxm/module_library/utils/MyDividerItemDecoration.java
class MyDividerItemDecoration (line 15) | public class MyDividerItemDecoration extends RecyclerView.ItemDecoration {
method MyDividerItemDecoration (line 40) | public MyDividerItemDecoration(Context context, int orientation, boole...
method MyDividerItemDecoration (line 44) | public MyDividerItemDecoration(Context context, int orientation,
method setOrientation (line 66) | public void setOrientation(int orientation) {
method setDrawable (line 79) | public void setDrawable(@NonNull Drawable drawable) {
method onDraw (line 86) | @Override
method drawVertical (line 98) | private void drawVertical(Canvas canvas, RecyclerView parent, Recycler...
method drawHorizontal (line 138) | private void drawHorizontal(Canvas canvas, RecyclerView parent, Recycl...
method getItemOffsets (line 178) | @Override
FILE: module_library/src/main/java/com/lxm/module_library/utils/ToastUtil.java
class ToastUtil (line 16) | public class ToastUtil {
method showToast (line 20) | @SuppressLint("ShowToast")
method showToastLong (line 35) | @SuppressLint("ShowToast")
FILE: module_library/src/main/java/com/lxm/module_library/xrecycleview/BaseRefreshHeader.java
type BaseRefreshHeader (line 6) | interface BaseRefreshHeader {
method onMove (line 13) | void onMove(float delta);
method releaseAction (line 15) | boolean releaseAction();
method refreshComplate (line 17) | void refreshComplate();
method getVisiableHeight (line 19) | int getVisiableHeight();
FILE: module_library/src/main/java/com/lxm/module_library/xrecycleview/LoadingMoreFooter.java
class LoadingMoreFooter (line 14) | public class LoadingMoreFooter extends LinearLayout {
method LoadingMoreFooter (line 23) | public LoadingMoreFooter(Context context) {
method LoadingMoreFooter (line 32) | public LoadingMoreFooter(Context context, AttributeSet attrs) {
method initView (line 37) | public void initView(Context context) {
method setState (line 48) | public void setState(int state) {
method reSet (line 76) | public void reSet() {
FILE: module_library/src/main/java/com/lxm/module_library/xrecycleview/WrapAdapter.java
class WrapAdapter (line 13) | public class WrapAdapter extends RecyclerView.Adapter<RecyclerView.ViewH...
method WrapAdapter (line 26) | public WrapAdapter(SparseArray<View> headerViews, SparseArray<View> fo...
method onAttachedToRecyclerView (line 32) | @Override
method onViewAttachedToWindow (line 48) | @Override
method isHeader (line 60) | public boolean isHeader(int position) {
method isFooter (line 64) | public boolean isFooter(int position) {
method isRefreshHeader (line 68) | public boolean isRefreshHeader(int position) {
method getHeadersCount (line 72) | public int getHeadersCount() {
method getFootersCount (line 76) | public int getFootersCount() {
method onCreateViewHolder (line 80) | @Override
method onBindViewHolder (line 92) | @Override
method getItemCount (line 107) | @Override
method getItemViewType (line 116) | @Override
method getItemId (line 138) | @Override
method unregisterAdapterDataObserver (line 150) | @Override
method registerAdapterDataObserver (line 157) | @Override
class SimpleViewHolder (line 164) | private class SimpleViewHolder extends RecyclerView.ViewHolder {
method SimpleViewHolder (line 165) | public SimpleViewHolder(View itemView) {
FILE: module_library/src/main/java/com/lxm/module_library/xrecycleview/XRecyclerView.java
class XRecyclerView (line 20) | public class XRecyclerView extends RecyclerView {
method XRecyclerView (line 36) | public XRecyclerView(Context context) {
method XRecyclerView (line 40) | public XRecyclerView(Context context, AttributeSet attrs) {
method XRecyclerView (line 44) | public XRecyclerView(Context context, AttributeSet attrs, int defStyle) {
method init (line 49) | private void init(Context context) {
method addFootView (line 65) | public void addFootView(final View view, boolean isOther) {
method clearHeader (line 78) | public void clearHeader() {
method addHeaderView (line 86) | public void addHeaderView(View view) {
method loadMoreComplete (line 95) | private void loadMoreComplete() {
method noMoreLoading (line 115) | public void noMoreLoading() {
method refreshComplete (line 130) | public void refreshComplete() {
method setAdapter (line 139) | @Override
method onScrollStateChanged (line 146) | @Override
method onTouchEvent (line 191) | @Override
method findMax (line 232) | private int findMax(int[] lastPositions) {
method findMin (line 242) | private int findMin(int[] firstPositions) {
method isOnTop (line 252) | public boolean isOnTop() {
method onChanged (line 266) | @Override
method onItemRangeInserted (line 271) | @Override
method onItemRangeChanged (line 276) | @Override
method onItemRangeChanged (line 281) | @Override
method onItemRangeRemoved (line 286) | @Override
method onItemRangeMoved (line 291) | @Override
method setLoadingListener (line 298) | public void setLoadingListener(LoadingListener listener) {
method setPullRefreshEnabled (line 302) | public void setPullRefreshEnabled(boolean pullRefreshEnabled) {
method setLoadingMoreEnabled (line 306) | public void setLoadingMoreEnabled(boolean loadingMoreEnabled) {
method setLoadMoreGone (line 321) | public void setLoadMoreGone() {
type LoadingListener (line 331) | public interface LoadingListener {
method onRefresh (line 333) | void onRefresh();
method onLoadMore (line 335) | void onLoadMore();
method isNetWorkConnected (line 344) | public static boolean isNetWorkConnected(Context context) {
method reset (line 355) | public void reset() {
method isLoadingData (line 367) | public boolean isLoadingData() {
FILE: module_library/src/main/java/com/lxm/module_library/xrecycleview/YunRefreshHeader.java
class YunRefreshHeader (line 19) | public class YunRefreshHeader extends LinearLayout implements BaseRefres...
method YunRefreshHeader (line 27) | public YunRefreshHeader(Context context) {
method YunRefreshHeader (line 31) | public YunRefreshHeader(Context context, AttributeSet attrs) {
method YunRefreshHeader (line 35) | public YunRefreshHeader(Context context, AttributeSet attrs, int defSt...
method initView (line 41) | private void initView() {
method onMove (line 59) | @Override
method setState (line 73) | private void setState(int state) {
method releaseAction (line 101) | @Override
method refreshComplate (line 126) | @Override
method reset (line 136) | public void reset() {
method smoothScrollTo (line 141) | private void smoothScrollTo(int destHeight) {
method setVisiableHeight (line 153) | private void setVisiableHeight(int height) {
method getVisiableHeight (line 162) | @Override
method getState (line 167) | public int getState() {
FILE: module_library/src/test/java/com/lxm/module_library/ExampleUnitTest.java
class ExampleUnitTest (line 12) | public class ExampleUnitTest {
method addition_isCorrect (line 13) | @Test
Condensed preview — 192 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (476K chars).
[
{
"path": ".gitignore",
"chars": 203,
"preview": "*.iml\n.gradle\n/local.properties\n/.idea/caches\n/.idea/libraries\n/.idea/modules.xml\n/.idea/workspace.xml\n/.idea/navEditor."
},
{
"path": ".idea/codeStyles/Project.xml",
"chars": 3461,
"preview": "<component name=\"ProjectCodeStyleConfiguration\">\n <code_scheme name=\"Project\" version=\"173\">\n <JetCodeStyleSettings>"
},
{
"path": ".idea/codeStyles/codeStyleConfig.xml",
"chars": 142,
"preview": "<component name=\"ProjectCodeStyleConfiguration\">\n <state>\n <option name=\"USE_PER_PROJECT_SETTINGS\" value=\"true\" />\n "
},
{
"path": ".idea/compiler.xml",
"chars": 449,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"CompilerConfiguration\">\n <wildcardRes"
},
{
"path": ".idea/encodings.xml",
"chars": 191,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"Encoding\" addBOMForNewFiles=\"with NO BOM"
},
{
"path": ".idea/gradle.xml",
"chars": 686,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"GradleSettings\">\n <option name=\"linke"
},
{
"path": ".idea/inspectionProfiles/Project_Default.xml",
"chars": 1444,
"preview": "<component name=\"InspectionProjectProfileManager\">\n <profile version=\"1.0\">\n <option name=\"myName\" value=\"Project De"
},
{
"path": ".idea/misc.xml",
"chars": 515,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"CMakeSettings\">\n <configurations>\n "
},
{
"path": ".idea/runConfigurations.xml",
"chars": 564,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"RunConfigurationProducerService\">\n <o"
},
{
"path": ".idea/vcs.xml",
"chars": 180,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"VcsDirectoryMappings\">\n <mapping dire"
},
{
"path": "README.md",
"chars": 2593,
"preview": "# Awesome-Kotlin-WanAndroid\n\n## 简介\n项目主要用来入门`kotlin`语言和google推荐的`MVVM`架构,使用了一些`Jetpack`组件来配合MVVM使用,采用了很多流行的开源库,`Okhttp`,`"
},
{
"path": "app/.gitignore",
"chars": 7,
"preview": "/build\n"
},
{
"path": "app/build.gradle",
"chars": 2877,
"preview": "apply plugin: 'com.android.application'\n\napply plugin: 'kotlin-android'\napply plugin: 'kotlin-kapt'\napply plugin: 'kotli"
},
{
"path": "app/proguard-rules.pro",
"chars": 751,
"preview": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguar"
},
{
"path": "app/src/androidTest/java/com/lxm/wanandroid/ExampleInstrumentedTest.kt",
"chars": 638,
"preview": "package com.lxm.wanandroid\n\nimport android.support.test.InstrumentationRegistry\nimport android.support.test.runner.Andro"
},
{
"path": "app/src/main/AndroidManifest.xml",
"chars": 1584,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n pa"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/MainActivity.kt",
"chars": 6484,
"preview": "package com.lxm.wanandroid\n\nimport android.arch.lifecycle.Observer\nimport android.arch.lifecycle.ViewModel\nimport androi"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/repository/model/ArticleResponse.kt",
"chars": 2682,
"preview": "package com.lxm.wanandroid.repository.model\n\n\n\n/**\n * curPage : 1\n * datas : [{\"apkLink\":\"\",\"author\":\"红橙Darren\",\"chapter"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/repository/model/Banner.kt",
"chars": 237,
"preview": "package com.lxm.wanandroid.repository.model\n\ndata class Banner(\n val desc: String,\n val id: Int,\n val imagePath"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/repository/model/HttpResponse.kt",
"chars": 700,
"preview": "package com.lxm.wanandroid.repository.model\n/**\n * data : {\"curPage\":1,\"datas\":[{\"apkLink\":\"\",\"author\":\"红橙Darren\",\"chapt"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/repository/model/Listing.kt",
"chars": 226,
"preview": "package com.lxm.wanandroid.repository.model\n\nimport android.arch.lifecycle.MutableLiveData\n\ndata class Listing<T>(\n "
},
{
"path": "app/src/main/java/com/lxm/wanandroid/repository/model/LoginBean.kt",
"chars": 336,
"preview": "package com.lxm.wanandroid.repository.model\n\ndata class LoginBean(\n val admin: Boolean,\n val chapterTops: List<Any"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/repository/model/Navigation.kt",
"chars": 146,
"preview": "package com.lxm.wanandroid.repository.model\n\ndata class Navigation(\n val articles: List<ArticleBean>,\n val cid: In"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/repository/model/Resource.kt",
"chars": 665,
"preview": "package com.lxm.wanandroid.repository.model\n\n/**\n * Created by juan on 2018/05/23.\n */\ndata class Resource<out T>(val st"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/repository/model/TreeBean.kt",
"chars": 314,
"preview": "package com.lxm.wanandroid.repository.model\n\nimport java.io.Serializable\n\ndata class TreeBean(\n val children: List<Tr"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/repository/model/WelfareResponse.kt",
"chars": 361,
"preview": "package com.lxm.wanandroid.repository.model\n\ndata class WelfareResponse(\n val error: Boolean,\n val results: List<W"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/repository/remote/LoginResposity.kt",
"chars": 1684,
"preview": "package com.lxm.wanandroid.repository.remote\n\nimport android.arch.lifecycle.MutableLiveData\nimport com.lxm.module_librar"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/repository/remote/httpClient/API.kt",
"chars": 2735,
"preview": "package com.lxm.wanandroid.repository.remote.httpClient\n\nimport com.lxm.wanandroid.repository.model.*\nimport io.reactive"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/repository/remote/httpClient/RetrofitClient.kt",
"chars": 417,
"preview": "package com.lxm.wanandroid.repository.remote.httpClient\n\nimport com.lxm.module_library.helper.RetrofitCreateHelper\n\n\nobj"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/ui/ArticleFragment.kt",
"chars": 4522,
"preview": "package com.lxm.wanandroid.ui\n\nimport android.arch.lifecycle.Observer\nimport android.content.Context\nimport android.os.B"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/ui/CollectActivity.kt",
"chars": 2761,
"preview": "package com.lxm.wanandroid.ui\n\nimport android.arch.lifecycle.Observer\nimport android.os.Bundle\nimport com.lxm.module_lib"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/ui/LoginActivity.kt",
"chars": 4381,
"preview": "package com.lxm.wanandroid.ui\n\nimport android.arch.lifecycle.Observer\nimport android.arch.lifecycle.ViewModel\nimport and"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/ui/NavigationFragment.kt",
"chars": 2850,
"preview": "package com.lxm.wanandroid.ui\n\nimport android.arch.lifecycle.Observer\nimport android.os.Bundle\nimport android.support.v7"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/ui/ProjectFragment.kt",
"chars": 3047,
"preview": "package com.lxm.wanandroid.ui\n\nimport android.arch.lifecycle.Observer\nimport android.os.Bundle\nimport com.lxm.module_lib"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/ui/TagArticleActivity.kt",
"chars": 2920,
"preview": "package com.lxm.wanandroid.ui\n\nimport android.arch.lifecycle.Observer\nimport android.os.Bundle\nimport com.lxm.module_lib"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/ui/TreeFragment.kt",
"chars": 2850,
"preview": "package com.lxm.wanandroid.ui\n\nimport android.arch.lifecycle.Observer\nimport android.content.Intent\nimport android.os.Bu"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/ui/ViewBigImageActivity.kt",
"chars": 6137,
"preview": "package com.lxm.wanandroid.ui\n\nimport android.content.Context\nimport android.content.Intent\nimport android.graphics.draw"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/ui/WelfareFragment.kt",
"chars": 3830,
"preview": "package com.lxm.wanandroid.ui\n\nimport android.arch.lifecycle.Observer\nimport android.os.Bundle\nimport android.support.v7"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/ui/adapter/ArticleAdapter.kt",
"chars": 4029,
"preview": "package com.lxm.wanandroid.ui.adapter\n\n\nimport android.content.Intent\nimport android.graphics.Paint\nimport android.view."
},
{
"path": "app/src/main/java/com/lxm/wanandroid/ui/adapter/NaviAdapter.kt",
"chars": 3144,
"preview": "package com.lxm.wanandroid.ui.adapter\n\nimport android.graphics.Color\nimport android.graphics.drawable.Drawable\nimport an"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/ui/adapter/TreeAdapter.kt",
"chars": 2934,
"preview": "package com.lxm.wanandroid.ui.adapter\n\nimport android.graphics.Color\nimport android.graphics.drawable.Drawable\nimport an"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/ui/adapter/WelfareAdapter.kt",
"chars": 788,
"preview": "package com.lxm.wanandroid.ui.adapter\n\n\nimport android.widget.ImageView\nimport com.lxm.module_library.utils.DisplayUtils"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/ui/base/BaseRecyclerAdapter.kt",
"chars": 2457,
"preview": "package com.lxm.wanandroid.ui.base\n\nimport android.content.Context\nimport android.support.annotation.IntRange\nimport and"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/ui/base/BaseRecyclerViewHoder.kt",
"chars": 1255,
"preview": "package com.lxm.wanandroid.ui.base\n\nimport android.support.v7.widget.RecyclerView\nimport android.text.TextUtils\nimport a"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/ui/base/OnItemClickListener.kt",
"chars": 111,
"preview": "package com.lxm.wanandroid.ui.base\n\n\ninterface OnItemClickListener<T> {\n fun onClick(t: T, position: Int)\n}\n"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/ui/base/OnItemLongClickListener.kt",
"chars": 119,
"preview": "package com.lxm.wanandroid.ui.base\n\n\ninterface OnItemLongClickListener<T> {\n fun onLongClick(t: T, position: Int)\n}\n"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/utils/CookieUtils.kt",
"chars": 1091,
"preview": "package com.lxm.wanandroid.utils\n\nimport android.content.Context\nimport android.util.Log\nimport android.webkit.CookieMan"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/utils/GlideUtil.kt",
"chars": 2085,
"preview": "package com.lxm.wanandroid.utils\n\nimport android.content.Context\nimport android.graphics.Bitmap\nimport android.widget.Im"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/utils/webview/WebViewActivity.java",
"chars": 15791,
"preview": "package com.lxm.wanandroid.utils.webview;\n\nimport android.annotation.SuppressLint;\nimport android.content.Context;\nimpor"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/utils/webview/config/FullscreenHolder.java",
"chars": 496,
"preview": "package com.lxm.wanandroid.utils.webview.config;\n\nimport android.content.Context;\nimport android.view.MotionEvent;\nimpor"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/utils/webview/config/IWebPageView.java",
"chars": 619,
"preview": "package com.lxm.wanandroid.utils.webview.config;\n\nimport android.view.View;\n\n/**\n * Created by jingbin on 2016/11/17.\n *"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/utils/webview/config/ImageClickInterface.java",
"chars": 1033,
"preview": "package com.lxm.wanandroid.utils.webview.config;\n\nimport android.content.Context;\nimport android.content.Intent;\nimport "
},
{
"path": "app/src/main/java/com/lxm/wanandroid/utils/webview/config/MyWebChromeClient.java",
"chars": 5790,
"preview": "package com.lxm.wanandroid.utils.webview.config;\n\nimport android.content.Intent;\nimport android.content.pm.ActivityInfo;"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/utils/webview/config/MyWebViewClient.java",
"chars": 3133,
"preview": "package com.lxm.wanandroid.utils.webview.config;\n\nimport android.app.Activity;\nimport android.content.Intent;\nimport and"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/viewmodel/ArticleViewModel.kt",
"chars": 1969,
"preview": "package com.lxm.wanandroid.viewmodel\n\nimport android.arch.lifecycle.MutableLiveData\nimport com.lxm.module_library.base.B"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/viewmodel/CategoryViewModel.kt",
"chars": 1446,
"preview": "package com.lxm.wanandroid.viewmodel\n\nimport android.arch.lifecycle.MutableLiveData\nimport com.lxm.module_library.base.B"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/viewmodel/CollectViewModel.kt",
"chars": 2482,
"preview": "package com.lxm.wanandroid.viewmodel\n\nimport android.arch.lifecycle.MutableLiveData\nimport com.lxm.module_library.base.B"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/viewmodel/LoginViewModel.kt",
"chars": 798,
"preview": "package com.lxm.wanandroid.viewmodel\n\nimport android.arch.lifecycle.Transformations\nimport com.lxm.module_library.base.B"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/viewmodel/NaviViewModelView.kt",
"chars": 923,
"preview": "package com.lxm.wanandroid.viewmodel\n\nimport android.arch.lifecycle.MutableLiveData\nimport com.lxm.module_library.base.B"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/viewmodel/ProjectViewModel.kt",
"chars": 1439,
"preview": "package com.lxm.wanandroid.viewmodel\n\nimport android.arch.lifecycle.MutableLiveData\nimport com.lxm.module_library.base.B"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/viewmodel/TreeViewModel.kt",
"chars": 902,
"preview": "package com.lxm.wanandroid.viewmodel\n\nimport android.arch.lifecycle.MutableLiveData\nimport com.lxm.module_library.base.B"
},
{
"path": "app/src/main/java/com/lxm/wanandroid/viewmodel/WelfareModelView.kt",
"chars": 970,
"preview": "package com.lxm.wanandroid.viewmodel\n\nimport android.arch.lifecycle.MutableLiveData\nimport com.lxm.module_library.base.B"
},
{
"path": "app/src/main/res/drawable/ic_launcher_background.xml",
"chars": 4887,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector\n xmlns:android=\"http://schemas.android.com/apk/res/android\"\n "
},
{
"path": "app/src/main/res/drawable/process_bg.xml",
"chars": 980,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layer-list xmlns:android=\"http://schemas.android.com/apk/res/android\" >\n\n <!-"
},
{
"path": "app/src/main/res/drawable/selector_bg_tree_tag.xml",
"chars": 732,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <item a"
},
{
"path": "app/src/main/res/drawable/selector_collect_check.xml",
"chars": 260,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n <item "
},
{
"path": "app/src/main/res/drawable-v24/ic_launcher_foreground.xml",
"chars": 1969,
"preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:aapt=\"http://schemas.android.com/aapt\"\n"
},
{
"path": "app/src/main/res/layout/activity_collection.xml",
"chars": 1193,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n android:background=\"@color/colorSubtitle\"\n xmlns:app"
},
{
"path": "app/src/main/res/layout/activity_login.xml",
"chars": 1415,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n android:background=\"@color/colorSubtitle\"\n xmlns:app"
},
{
"path": "app/src/main/res/layout/activity_main.xml",
"chars": 1177,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.v4.widget.DrawerLayout\n xmlns:android=\"http://schemas.and"
},
{
"path": "app/src/main/res/layout/activity_show_image.xml",
"chars": 766,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n an"
},
{
"path": "app/src/main/res/layout/activity_web_view.xml",
"chars": 2745,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xm"
},
{
"path": "app/src/main/res/layout/article_banner.xml",
"chars": 569,
"preview": "<FrameLayout\n xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:app=\"http://schemas.androi"
},
{
"path": "app/src/main/res/layout/article_fragment.xml",
"chars": 892,
"preview": "<FrameLayout\n xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:layout_height=\"match_par"
},
{
"path": "app/src/main/res/layout/category_activity.xml",
"chars": 847,
"preview": "<FrameLayout\n xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:layout_height=\"match_par"
},
{
"path": "app/src/main/res/layout/drawer_header_layout.xml",
"chars": 1457,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.constraint.ConstraintLayout\n xmlns:android=\"http://schema"
},
{
"path": "app/src/main/res/layout/item_article.xml",
"chars": 4510,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\n xmlns:tools=\"http://schemas.android.com/tools\"\n xm"
},
{
"path": "app/src/main/res/layout/item_banner.xml",
"chars": 392,
"preview": "<FrameLayout\n xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:layout_height=\"match_par"
},
{
"path": "app/src/main/res/layout/item_image_view_pager.xml",
"chars": 581,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n andro"
},
{
"path": "app/src/main/res/layout/item_tree.xml",
"chars": 1654,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.constraint.ConstraintLayout\n xmlns:android=\"http://schema"
},
{
"path": "app/src/main/res/layout/item_tree_tag.xml",
"chars": 499,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<TextView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xm"
},
{
"path": "app/src/main/res/layout/item_view.xml",
"chars": 5020,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\n xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n "
},
{
"path": "app/src/main/res/layout/item_view_welfare.xml",
"chars": 949,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n "
},
{
"path": "app/src/main/res/layout/main_content.xml",
"chars": 1781,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n "
},
{
"path": "app/src/main/res/layout/tree_fragment.xml",
"chars": 910,
"preview": "<FrameLayout\n xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:layout_height=\"match_par"
},
{
"path": "app/src/main/res/menu/main.xml",
"chars": 368,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:app=\"h"
},
{
"path": "app/src/main/res/menu/navigation.xml",
"chars": 506,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n <item\n "
},
{
"path": "app/src/main/res/menu/webview_menu.xml",
"chars": 908,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:app=\"h"
},
{
"path": "app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
"chars": 270,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <b"
},
{
"path": "app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
"chars": 270,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <b"
},
{
"path": "app/src/main/res/values/attrs_circle_view.xml",
"chars": 534,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <declare-styleable name=\"circletextview\">\n <attr name=\"cir"
},
{
"path": "app/src/main/res/values/colors.xml",
"chars": 421,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <color name=\"colorPrimary\">#008577</color>\n <color name=\"color"
},
{
"path": "app/src/main/res/values/strings.xml",
"chars": 174,
"preview": "<resources>\n <string name=\"app_name\">WanAndroidKotlin</string>\n <string name=\"navigation_open\">打开</string>\n <st"
},
{
"path": "app/src/main/res/values/styles.xml",
"chars": 372,
"preview": "<resources>\n\n <!-- Base application theme. -->\n <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.NoActionBar\">"
},
{
"path": "app/src/test/java/com/lxm/wanandroid/ExampleUnitTest.kt",
"chars": 343,
"preview": "package com.lxm.wanandroid\n\nimport org.junit.Test\n\nimport org.junit.Assert.*\n\n/**\n * Example local unit test, which will"
},
{
"path": "build.gradle",
"chars": 1048,
"preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n e"
},
{
"path": "gradle/wrapper/gradle-wrapper.properties",
"chars": 232,
"preview": "#Thu Jun 13 22:10:05 CST 2019\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_"
},
{
"path": "gradle.properties",
"chars": 817,
"preview": "# Project-wide Gradle settings.\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will ov"
},
{
"path": "gradlew",
"chars": 5296,
"preview": "#!/usr/bin/env sh\n\n##############################################################################\n##\n## Gradle start up"
},
{
"path": "gradlew.bat",
"chars": 2176,
"preview": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem "
},
{
"path": "module_library/.gitignore",
"chars": 7,
"preview": "/build\n"
},
{
"path": "module_library/build.gradle",
"chars": 2827,
"preview": "apply plugin: 'com.android.library'\napply plugin: 'kotlin-android-extensions'\napply plugin: 'kotlin-android'\napply plugi"
},
{
"path": "module_library/proguard-rules.pro",
"chars": 751,
"preview": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguar"
},
{
"path": "module_library/src/androidTest/java/com/lxm/module_library/ExampleInstrumentedTest.java",
"chars": 733,
"preview": "package com.lxm.module_library;\n\nimport android.content.Context;\nimport android.support.test.InstrumentationRegistry;\nim"
},
{
"path": "module_library/src/main/AndroidManifest.xml",
"chars": 503,
"preview": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n package=\"com.lxm.module_library\">\n\n\n<uses"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/anim/AnimManager.kt",
"chars": 2123,
"preview": "package com.lxm.module_library.anim\nimport android.content.Context\nimport android.os.Build\nimport android.view.View\nimpo"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/anim/AnimUtils.kt",
"chars": 8637,
"preview": "/*\n * Copyright 2015 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/anim/ToolbarAnimManager.kt",
"chars": 2365,
"preview": "package com.lxm.module_library.anim\n\nimport android.content.Context\nimport android.support.v7.widget.ActionMenuView\nimpo"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/base/BaseActivity.kt",
"chars": 5702,
"preview": "package com.lxm.module_library.base\n\nimport android.arch.lifecycle.ViewModel\nimport android.arch.lifecycle.ViewModelProv"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/base/BaseFragment.kt",
"chars": 6286,
"preview": "package com.lxm.module_library.base\n\nimport android.arch.lifecycle.ViewModel\nimport android.arch.lifecycle.ViewModelProv"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/base/BaseViewModel.kt",
"chars": 730,
"preview": "package com.lxm.module_library.base\n\nimport android.arch.lifecycle.ViewModel\nimport io.reactivex.disposables.CompositeDi"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/base/NoViewModel.java",
"chars": 128,
"preview": "package com.lxm.module_library.base;\n\nimport android.arch.lifecycle.ViewModel;\n\npublic class NoViewModel extends ViewMod"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/global/AppManager.java",
"chars": 2483,
"preview": "package com.lxm.module_library.global;\n\nimport android.app.Activity;\nimport android.app.ActivityManager;\nimport android."
},
{
"path": "module_library/src/main/java/com/lxm/module_library/global/GlobalApplication.java",
"chars": 1269,
"preview": "package com.lxm.module_library.global;\n\nimport android.app.Application;\nimport android.content.Context;\nimport android.o"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/helper/RetrofitCreateHelper.java",
"chars": 2291,
"preview": "package com.lxm.module_library.helper;\n\nimport com.lxm.module_library.utils.AppUtils;\nimport com.lxm.module_library.help"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/helper/RxHelper.java",
"chars": 1827,
"preview": "package com.lxm.module_library.helper;\n\n\nimport io.reactivex.*;\nimport io.reactivex.android.schedulers.AndroidSchedulers"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/helper/okhttp/TrustManager.java",
"chars": 1736,
"preview": "package com.lxm.module_library.helper.okhttp;\n\nimport javax.net.ssl.SSLContext;\nimport javax.net.ssl.SSLSocketFactory;\ni"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/helper/okhttp/cache/CacheInterceptor.java",
"chars": 1928,
"preview": "package com.lxm.module_library.helper.okhttp.cache;\n\n\nimport com.lxm.module_library.utils.AppUtils;\nimport com.lxm.modul"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/helper/okhttp/cache/HttpCache.java",
"chars": 564,
"preview": "package com.lxm.module_library.helper.okhttp.cache;\n\nimport com.lxm.module_library.utils.AppUtils;\nimport okhttp3.Cache;"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/helper/okhttp/cookies/CookieManger.java",
"chars": 1045,
"preview": "package com.lxm.module_library.helper.okhttp.cookies;\n\nimport android.content.Context;\nimport okhttp3.Cookie;\nimport okh"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/helper/okhttp/cookies/OkHttpCookies.java",
"chars": 2032,
"preview": "package com.lxm.module_library.helper.okhttp.cookies;\n\nimport okhttp3.Cookie;\n\nimport java.io.IOException;\nimport java.i"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/helper/okhttp/cookies/PersistentCookieStore.java",
"chars": 5214,
"preview": "package com.lxm.module_library.helper.okhttp.cookies;\n\nimport android.content.Context;\nimport android.content.SharedPref"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/materialLogin/DefaultLoginView.java",
"chars": 3500,
"preview": "package com.lxm.module_library.materialLogin;\n\nimport android.annotation.TargetApi;\nimport android.content.Context;\nimpo"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/materialLogin/DefaultRegisterView.java",
"chars": 4215,
"preview": "package com.lxm.module_library.materialLogin;\n\nimport android.annotation.TargetApi;\nimport android.content.Context;\nimpo"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/materialLogin/MaterialLoginView.java",
"chars": 10189,
"preview": "package com.lxm.module_library.materialLogin;\n\nimport android.animation.Animator;\nimport android.animation.AnimatorSet;\n"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/materialLogin/RegisterView.java",
"chars": 185,
"preview": "package com.lxm.module_library.materialLogin;\n\nimport android.view.View;\n\n/**\n * Created by shem on 16/09/2016.\n */\npubl"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/statusbar/StatusBarUtil.java",
"chars": 21717,
"preview": "package com.lxm.module_library.statusbar;\n\nimport android.annotation.TargetApi;\nimport android.app.Activity;\nimport andr"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/statusbar/StatusBarView.java",
"chars": 469,
"preview": "package com.lxm.module_library.statusbar;\n\nimport android.content.Context;\nimport android.util.AttributeSet;\nimport andr"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/utils/AppUtils.kt",
"chars": 4873,
"preview": "package com.lxm.module_library.utils\n\nimport android.Manifest\nimport android.annotation.SuppressLint\nimport android.cont"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/utils/BaseTools.java",
"chars": 8593,
"preview": "package com.lxm.module_library.utils;\n\nimport android.app.Activity;\nimport android.app.ActivityManager;\nimport android.c"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/utils/BitmapUtils.kt",
"chars": 6691,
"preview": "package com.lxm.module_library.utils\n\nimport android.content.Context\nimport android.content.res.Resources\nimport android"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/utils/CheckNetwork.java",
"chars": 1366,
"preview": "package com.lxm.module_library.utils;\n\nimport android.content.Context;\nimport android.net.ConnectivityManager;\nimport an"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/utils/ClassUtil.kt",
"chars": 1059,
"preview": "package com.lxm.module_library.utils\n\nimport android.arch.lifecycle.AndroidViewModel\nimport android.arch.lifecycle.ViewM"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/utils/DateUtils.kt",
"chars": 7117,
"preview": "package com.lxm.module_library.utils\n\n\nimport android.annotation.SuppressLint\nimport android.text.TextUtils\nimport andro"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/utils/DialogUtils.kt",
"chars": 1044,
"preview": "package com.lxm.module_library.utils\n\nimport android.app.Dialog\nimport android.content.Context\nimport android.content.Di"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/utils/DisplayUtils.kt",
"chars": 3133,
"preview": "package com.lxm.module_library.utils\n\nimport android.app.Activity\nimport android.content.Context\nimport android.util.Dis"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/utils/FileUtils.kt",
"chars": 8836,
"preview": "package com.lxm.module_library.utils\n\nimport android.content.ContentResolver\nimport android.content.Context\nimport andro"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/utils/HtmlUtils.kt",
"chars": 1931,
"preview": "package com.lxm.module_library.utils\n\n/**\n * Created by Horrarndoo on 2017/8/31.\n *\n * Html工具类\n */\nobject HtmlUtils {\n\n "
},
{
"path": "module_library/src/main/java/com/lxm/module_library/utils/HttpUtils.kt",
"chars": 2278,
"preview": "package com.lxm.module_library.utils\n\nimport android.os.Build\nimport android.webkit.WebSettings\nimport java.util.*\nimpor"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/utils/ImageUtils.kt",
"chars": 9246,
"preview": "package com.lxm.module_library.utils\n\nimport android.annotation.TargetApi\nimport android.app.Activity\nimport android.con"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/utils/JsonUtils.kt",
"chars": 1275,
"preview": "package com.lxm.module_library.utils\n\nimport com.google.gson.Gson\nimport com.google.gson.JsonObject\nimport com.google.gs"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/utils/MD5Utils.kt",
"chars": 934,
"preview": "package com.lxm.module_library.utils\n\nimport java.security.MessageDigest\n\n/**\n *\n * MD5加密工具类\n */\nobject MD5Utils {\n /"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/utils/MyDividerItemDecoration.java",
"chars": 8464,
"preview": "package com.lxm.module_library.utils;\n\n\nimport android.content.Context;\nimport android.content.res.TypedArray;\nimport an"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/utils/NetworkConnectionUtils.kt",
"chars": 6159,
"preview": "package com.lxm.module_library.utils\n\nimport android.app.Activity\nimport android.content.ComponentName\nimport android.co"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/utils/PreferencesUtil.kt",
"chars": 1993,
"preview": "package com.lxm.module_library.utils\n\n\nimport android.content.Context\nimport android.content.SharedPreferences\nimport ko"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/utils/RefreshHelper.kt",
"chars": 1169,
"preview": "package com.lxm.module_library.utils\n\nimport android.support.v4.content.ContextCompat\nimport android.support.v7.widget.D"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/utils/ResourcesUtils.kt",
"chars": 1617,
"preview": "package com.lxm.module_library.utils\n\nimport android.content.res.ColorStateList\nimport android.graphics.drawable.Drawabl"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/utils/ScreenAdapterUtils.kt",
"chars": 2807,
"preview": "package com.lxm.module_library.utils\n\nimport android.app.Activity\nimport android.content.res.Resources\n\n/**\n *屏幕适配相关\n *\n"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/utils/ScreenUtils.kt",
"chars": 6594,
"preview": "package com.lxm.module_library.utils\n\nimport android.app.Activity\nimport android.app.ActivityGroup\nimport android.conten"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/utils/SnackbarUtils.kt",
"chars": 4705,
"preview": "package com.lxm.module_library.utils\n\nimport android.graphics.Color\nimport android.support.design.widget.Snackbar\nimport"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/utils/StatusBarUtils.kt",
"chars": 2069,
"preview": "package com.lxm.module_library.utils\n\nimport android.app.Activity\nimport android.graphics.Color\nimport android.os.Build\n"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/utils/StringUtils.kt",
"chars": 2966,
"preview": "package com.lxm.module_library.utils\n\nimport android.text.TextUtils\nimport java.util.regex.Pattern\n\n/**\n * 字符串工具类\n */\nob"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/utils/TimestampUtils.kt",
"chars": 1186,
"preview": "package com.lxm.module_library.utils\n\nimport java.text.SimpleDateFormat\nimport java.util.*\n\nobject TimestampUtils {\n "
},
{
"path": "module_library/src/main/java/com/lxm/module_library/utils/ToastUtil.java",
"chars": 1635,
"preview": "package com.lxm.module_library.utils;\n\nimport android.annotation.SuppressLint;\nimport android.text.TextUtils;\nimport and"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/utils/ToastUtils.kt",
"chars": 1454,
"preview": "package com.lxm.module_library.utils\n\nimport android.content.Context\nimport android.widget.Toast\nimport com.lxm.module_l"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/utils/UnicodeUtils.kt",
"chars": 2732,
"preview": "package com.lxm.module_library.utils\n\n/**\n * Created by Horrarndoo on 2017/10/11.\n *\n */\nobject UnicodeUtils {\n /**\n "
},
{
"path": "module_library/src/main/java/com/lxm/module_library/utils/WifiAutoConnectManager.kt",
"chars": 6501,
"preview": "package com.lxm.module_library.utils\n\nimport android.content.Context\nimport android.net.wifi.WifiConfiguration\nimport an"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/xrecycleview/BaseRefreshHeader.java",
"chars": 363,
"preview": "package com.lxm.module_library.xrecycleview;\n\n/**\n * Created by jianghejie on 15/11/22.\n */\ninterface BaseRefreshHeader "
},
{
"path": "module_library/src/main/java/com/lxm/module_library/xrecycleview/LoadingMoreFooter.java",
"chars": 2702,
"preview": "package com.lxm.module_library.xrecycleview;\n\nimport android.content.Context;\nimport android.graphics.drawable.Animation"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/xrecycleview/WrapAdapter.java",
"chars": 5607,
"preview": "package com.lxm.module_library.xrecycleview;\n\nimport android.support.v7.widget.GridLayoutManager;\nimport android.support"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/xrecycleview/XRecyclerView.java",
"chars": 12469,
"preview": "package com.lxm.module_library.xrecycleview;\n\n\nimport android.content.Context;\nimport android.net.ConnectivityManager;\ni"
},
{
"path": "module_library/src/main/java/com/lxm/module_library/xrecycleview/YunRefreshHeader.java",
"chars": 5521,
"preview": "package com.lxm.module_library.xrecycleview;\n\nimport android.animation.ValueAnimator;\nimport android.content.Context;\nim"
},
{
"path": "module_library/src/main/res/drawable/app_loading_anim.xml",
"chars": 540,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<animation-list xmlns:android=\"http://schemas.android.com/apk/res/android\"\n an"
},
{
"path": "module_library/src/main/res/drawable/common_progress_cirle.xml",
"chars": 270,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<rotate xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:dr"
},
{
"path": "module_library/src/main/res/drawable/header_loading_anim.xml",
"chars": 552,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<animation-list xmlns:android=\"http://schemas.android.com/apk/res/android\"\n an"
},
{
"path": "module_library/src/main/res/drawable/ic_add.xml",
"chars": 325,
"preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:width=\"24dp\"\n android:height=\""
},
{
"path": "module_library/src/main/res/drawable/ic_clear.xml",
"chars": 389,
"preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:width=\"24dp\"\n android:height=\""
},
{
"path": "module_library/src/main/res/drawable/login_back.xml",
"chars": 305,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:sha"
},
{
"path": "module_library/src/main/res/drawable/shape_line.xml",
"chars": 184,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <size andr"
},
{
"path": "module_library/src/main/res/layout/activity_base.xml",
"chars": 2036,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
},
{
"path": "module_library/src/main/res/layout/custom_login_view.xml",
"chars": 551,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<com.lxm.module_library.materialLogin.DefaultLoginView\n xmlns:android=\"ht"
},
{
"path": "module_library/src/main/res/layout/custom_register_view.xml",
"chars": 673,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<com.lxm.module_library.materialLogin.DefaultRegisterView\n xmlns:android="
},
{
"path": "module_library/src/main/res/layout/default_login_view.xml",
"chars": 252,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<com.lxm.module_library.materialLogin.DefaultLoginView\nxmlns:android=\"http://sch"
},
{
"path": "module_library/src/main/res/layout/default_register_view.xml",
"chars": 255,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<com.lxm.module_library.materialLogin.DefaultRegisterView\nxmlns:android=\"http://"
},
{
"path": "module_library/src/main/res/layout/fragment_base.xml",
"chars": 1080,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout\n android:layout_width=\"match_parent\"\n android:layout_h"
},
{
"path": "module_library/src/main/res/layout/layout_loading_error.xml",
"chars": 1251,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.constraint.ConstraintLayout xmlns:android=\"http://schemas.androi"
},
{
"path": "module_library/src/main/res/layout/layout_loading_view.xml",
"chars": 1144,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.constraint.ConstraintLayout xmlns:android=\"http://schemas.androi"
},
{
"path": "module_library/src/main/res/layout/login_layout.xml",
"chars": 2990,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n xmlns:android=\"http://schemas.android.com/apk/res/android\"\n "
},
{
"path": "module_library/src/main/res/layout/login_view.xml",
"chars": 1816,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<android.support.design.widget.CoordinatorLayout\nxmlns:android=\"http://schemas.a"
},
{
"path": "module_library/src/main/res/layout/refresh_footer.xml",
"chars": 1015,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n andr"
},
{
"path": "module_library/src/main/res/layout/refresh_header.xml",
"chars": 1015,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n andr"
},
{
"path": "module_library/src/main/res/layout/register_layout.xml",
"chars": 4588,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<LinearLayout\n xmlns:android=\"http://schemas.android.com/apk/res/android\"\n "
},
{
"path": "module_library/src/main/res/values/attrs.xml",
"chars": 1140,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n <declare-styleable name=\"MaterialLoginView\">\n <attr name="
},
{
"path": "module_library/src/main/res/values/colors.xml",
"chars": 973,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n\n <color name=\"colorTheme\">#343434</color>\n <color name=\"color"
},
{
"path": "module_library/src/main/res/values/dimen.xml",
"chars": 108,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <dimen name=\"dialog_width\">250dp</dimen>\n</resources>"
},
{
"path": "module_library/src/main/res/values/drawables.xml",
"chars": 172,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <item name=\"toolbarItemBackground\" type=\"drawable\">@drawable/abc_"
},
{
"path": "module_library/src/main/res/values/strings.xml",
"chars": 1060,
"preview": "<resources>\n <string name=\"app_name\">module_library</string>\n <string name=\"listview_header_hint_normal\">下拉刷新...</"
},
{
"path": "module_library/src/main/res/values/styles.xml",
"chars": 3217,
"preview": "<resources xmlns:tools=\"http://schemas.android.com/tools\">\n\n <!-- Base application theme. -->\n\n <style name=\"AppTh"
},
{
"path": "module_library/src/main/res/values-w600dp/dimen.xml",
"chars": 109,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n <dimen name=\"dialog_width\">400dp</dimen>\n</resources>"
},
{
"path": "module_library/src/test/java/com/lxm/module_library/ExampleUnitTest.java",
"chars": 383,
"preview": "package com.lxm.module_library;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit te"
},
{
"path": "settings.gradle",
"chars": 34,
"preview": "include ':app', ':module_library'\n"
}
]
// ... and 1 more files (download for full content)
About this extraction
This page contains the full source code of the malonecoder/Awesome-Kotlin-WanAndroid GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 192 files (419.2 KB), approximately 104.9k tokens, and a symbol index with 310 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.