diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..1207ec8
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,201 @@
+Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright 2022 Leaqi
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..475608a
--- /dev/null
+++ b/README.md
@@ -0,0 +1,65 @@
+# SwipeDrawer · [![Star](https://img.shields.io/github/stars/Leaqi/SwipeDrawer?color=fb6698&label=Star "Star")](https://github.com/Leaqi/SwipeDrawer/stargazers "Star") [![Fork](https://img.shields.io/github/forks/Leaqi/SwipeDrawer?color=2196f3&label=Fork "Fork")](https://github.com/Leaqi/SwipeDrawer/network "Fork") [![API](https://img.shields.io/badge/API-14%2B-04d8bb "API")](https://github.com/Leaqi/SwipeDrawer/ "API") [![JitPack](https://jitpack.io/v/Leaqi/SwipeDrawer.svg "JitPack")](https://jitpack.io/#cn.Leaqi/SwipeDrawer "JitPack") [![Release](https://img.shields.io/github/v/release/Leaqi/SwipeDrawer?label=Release&color=06da47 "Release")](https://github.com/Leaqi/SwipeDrawer/releases "Release") [![License](https://img.shields.io/badge/License-Apache--2.0-e0b003 "License")](https://github.com/Leaqi/SwipeDrawer/blob/master/LICENSE "License") [![Download Demo Apk](https://img.shields.io/badge/Download-Demo%20Apk-45c703 "Download Demo Apk")](https://github.com/Leaqi/SwipeDrawer/releases/download/1.0/demo.apk "Download Demo Apk")
+#### 中文 README | [English README](https://github.com/Leaqi/SwipeDrawer/blob/master/README_en.md "English README")
+Android SwipeDrawer滑动抽屉库,可同时添加上下左右四个方向抽屉布局,抽屉打开模式有抽屉模式、覆盖模式、固定模式三种,支持无限嵌套,支持边缘滑动打开等,SwipeDrawer还可以当做下拉刷新布局使用,支持ListView、RecyclerView、GridView、ScrollView等。
+#### 中文:
+[![点击查看使用文档](https://img.shields.io/badge/SwipeDrawer-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3-blue "点击查看使用文档")](https://Leaqi.github.io/SwipeDrawer/ "点击查看使用文档") [![点击查看功能详解](https://img.shields.io/badge/SwipeDrawer-%E5%8A%9F%E8%83%BD%E8%AF%A6%E8%A7%A3-orange "点击查看功能详解")](https://Leaqi.github.io/SwipeDrawer/code.html "点击查看功能详解") [![点击查看图片演示](https://img.shields.io/badge/SwipeDrawer-%E5%9B%BE%E7%89%87%E6%BC%94%E7%A4%BA-green "点击查看图片演示")](https://Leaqi.github.io/SwipeDrawer/pics.html "点击查看图片演示")
+
+#### English:
+[![Click to view Use Docs](https://img.shields.io/badge/SwipeDrawer-Use%20Docs-blue "Click to view Use Docs")](https://Leaqi.github.io/SwipeDrawer_en/ "Click to view Use Docs") [![Click to view Detailed Docs](https://img.shields.io/badge/SwipeDrawer-Detailed%20Docs-orange "Click to view Detailed Docs")](https://Leaqi.github.io/SwipeDrawer_en/code.html "Click to view Detailed Docs") [![Click to view Picture Preview](https://img.shields.io/badge/SwipeDrawer-Picture%20Preview-green "Click to view Picture Preview")](https://Leaqi.github.io/SwipeDrawer_en/pics.html "Click to view Picture Preview")
+
+## 开始使用
+添加 `jitpack` 仓库地址:
+
+ allprojects {
+ repositories {
+ ...
+ maven { url "https://jitpack.io" }
+ }
+ }
+
+添加 `SwipeDrawer` 依赖:
+
+ dependencies {
+ ...
+ implementation 'cn.Leaqi.SwipeDrawer:1.0'
+ }
+
+在布局文件中加入 `SwipeDrawer` :
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+## 图片预览 · [![查看更多](https://img.shields.io/badge/More-%E6%9F%A5%E7%9C%8B%E6%9B%B4%E5%A4%9A-blue "查看更多")](https://Leaqi.github.io/SwipeDrawer/pics.html "查看更多")
+[![Demo](https://p.ssl.qhimg.com/t0127d8ad395f6aff6f.jpg "Demo")](https://Leaqi.github.io/SwipeDrawer/pics.html "Demo") [![Demo](https://p.ssl.qhimg.com/t017c6a31eaa1242d0a.jpg "Demo")](https://Leaqi.github.io/SwipeDrawer/pics.html "Demo") [![Demo](https://p.ssl.qhimg.com/t0131cdd3e8c2ca7d41.jpg "Demo")](https://Leaqi.github.io/SwipeDrawer/pics.html "Demo") [![Demo](https://p.ssl.qhimg.com/t019aa5b68b427443c9.jpg "Demo")](https://Leaqi.github.io/SwipeDrawer/pics.html "Demo")
+
+## License
+[Apache-2.0 License](https://github.com/Leaqi/SwipeDrawer/blob/master/LICENSE "Apache-2.0 License")
+
+Copyright (c) 2022 Leaqi
\ No newline at end of file
diff --git a/README_en.md b/README_en.md
new file mode 100644
index 0000000..ce953cf
--- /dev/null
+++ b/README_en.md
@@ -0,0 +1,66 @@
+# SwipeDrawer · [![Star](https://img.shields.io/github/stars/Leaqi/SwipeDrawer?color=fb6698&label=Star "Star")](https://github.com/Leaqi/SwipeDrawer/stargazers "Star") [![Fork](https://img.shields.io/github/forks/Leaqi/SwipeDrawer?color=2196f3&label=Fork "Fork")](https://github.com/Leaqi/SwipeDrawer/network "Fork") [![API](https://img.shields.io/badge/API-14%2B-04d8bb "API")](https://github.com/Leaqi/SwipeDrawer/ "API") [![JitPack](https://jitpack.io/v/Leaqi/SwipeDrawer.svg "JitPack")](https://jitpack.io/#cn.Leaqi/SwipeDrawer "JitPack") [![Release](https://img.shields.io/github/v/release/Leaqi/SwipeDrawer?label=Release&color=06da47 "Release")](https://github.com/Leaqi/SwipeDrawer/releases "Release") [![License](https://img.shields.io/badge/License-Apache--2.0-e0b003 "License")](https://github.com/Leaqi/SwipeDrawer/blob/master/LICENSE "License") [![Download Demo Apk](https://img.shields.io/badge/Download-Demo%20Apk-45c703 "Download Demo Apk")](https://github.com/Leaqi/SwipeDrawer/releases/download/1.0/demo.apk "Download Demo Apk")
+#### English README | [中文 README](https://github.com/Leaqi/SwipeDrawer/ "中文 README")
+Android SwipeDrawer sliding drawer library can add up, down, left and right drawer layouts at the same time. There are three drawer opening modes: drawer mode, overlay mode and fixed mode. It supports unlimited nesting and edge sliding opening. Swipedrawer can also be used as a drop-down refresh layout, and supports listview, recyclerview, GridView, Scrollview, etc.
+
+#### English:
+[![Click to view Use Docs](https://img.shields.io/badge/SwipeDrawer-Use%20Docs-blue "Click to view Use Docs")](https://Leaqi.github.io/SwipeDrawer_en/ "Click to view Use Docs") [![Click to view Detailed Docs](https://img.shields.io/badge/SwipeDrawer-Detailed%20Docs-orange "Click to view Detailed Docs")](https://Leaqi.github.io/SwipeDrawer_en/code.html "Click to view Detailed Docs") [![Click to view Picture Preview](https://img.shields.io/badge/SwipeDrawer-Picture%20Preview-green "Click to view Picture Preview")](https://Leaqi.github.io/SwipeDrawer_en/pics.html "Click to view Picture Preview")
+
+#### 中文:
+[![点击查看使用文档](https://img.shields.io/badge/SwipeDrawer-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3-blue "点击查看使用文档")](https://Leaqi.github.io/SwipeDrawer/ "点击查看使用文档") [![点击查看功能详解](https://img.shields.io/badge/SwipeDrawer-%E5%8A%9F%E8%83%BD%E8%AF%A6%E8%A7%A3-orange "点击查看功能详解")](https://Leaqi.github.io/SwipeDrawer/code.html "点击查看功能详解") [![点击查看图片演示](https://img.shields.io/badge/SwipeDrawer-%E5%9B%BE%E7%89%87%E6%BC%94%E7%A4%BA-green "点击查看图片演示")](https://Leaqi.github.io/SwipeDrawer/pics.html "点击查看图片演示")
+
+## Setup
+Add `jitpack` repositories:
+
+ allprojects {
+ repositories {
+ ...
+ maven { url "https://jitpack.io" }
+ }
+ }
+
+Add `SwipeDrawer` dependencies:
+
+ dependencies {
+ ...
+ implementation 'cn.Leaqi.SwipeDrawer:1.0'
+ }
+
+Add `SwipeDrawer` to the layout file :
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+## Picture preview · [![See More](https://img.shields.io/badge/See-More-blue "See More")](https://Leaqi.github.io/SwipeDrawer/pics.html "See More")
+[![Demo](https://p.ssl.qhimg.com/t0127d8ad395f6aff6f.jpg "Demo")](https://Leaqi.github.io/SwipeDrawer/pics.html "Demo") [![Demo](https://p.ssl.qhimg.com/t017c6a31eaa1242d0a.jpg "Demo")](https://Leaqi.github.io/SwipeDrawer/pics.html "Demo") [![Demo](https://p.ssl.qhimg.com/t0131cdd3e8c2ca7d41.jpg "Demo")](https://Leaqi.github.io/SwipeDrawer/pics.html "Demo") [![Demo](https://p.ssl.qhimg.com/t019aa5b68b427443c9.jpg "Demo")](https://Leaqi.github.io/SwipeDrawer/pics.html "Demo")
+
+## License
+[Apache-2.0 License](https://github.com/Leaqi/SwipeDrawer/blob/master/LICENSE "Apache-2.0 License")
+
+Copyright (c) 2022 Leaqi
\ No newline at end of file
diff --git a/apk/README.md b/apk/README.md
new file mode 100644
index 0000000..27e360d
--- /dev/null
+++ b/apk/README.md
@@ -0,0 +1,32 @@
+# Demo-App · [![下载APK](https://img.shields.io/badge/Download-Demo%20Apk-45c703 "下载APK")](https://github.com/Leaqi/SwipeDrawer/releases/download/1.0/demo.apk "下载APK")
+## 图片预览 · [![查看更多](https://img.shields.io/badge/More-%E6%9F%A5%E7%9C%8B%E6%9B%B4%E5%A4%9A-blue "查看更多")](https://Leaqi.github.io/SwipeDrawer/pics.html "查看更多")
+### Demo Home:
+[![Demo Home](https://p.ssl.qhimg.com/t01b36f1353d11068a0.jpg "Demo Home")](https://Leaqi.github.io/SwipeDrawer/pics.html "Demo Home")
+### Demo 1:
+[![Demo 1](https://p.ssl.qhimg.com/t01433cdb424d19230d.jpg "Demo 1")](https://Leaqi.github.io/SwipeDrawer/pics.html "Demo 1")
+### Demo 2:
+[![Demo 2](https://p.ssl.qhimg.com/t01b761c28a2bc1308a.jpg "Demo 2")](https://Leaqi.github.io/SwipeDrawer/pics.html "Demo 2")
+### Demo 3:
+[![Demo 3](https://p.ssl.qhimg.com/t0193c2274ce418c2c7.jpg "Demo 3")](https://Leaqi.github.io/SwipeDrawer/pics.html "Demo 3")
+### Demo 4:
+[![Demo 4](https://p.ssl.qhimg.com/t01c2dc0d5aa1e6af03.jpg "Demo 4")](https://Leaqi.github.io/SwipeDrawer/pics.html "Demo 4")
+### Demo 5:
+[![Demo 5](https://p.ssl.qhimg.com/t0111a3d372c8b617f8.jpg "Demo 5")](https://Leaqi.github.io/SwipeDrawer/pics.html "Demo 5")
+### Demo 6:
+[![Demo 6](https://p.ssl.qhimg.com/t0113a7f76f1bb376de.jpg "Demo 6")](https://Leaqi.github.io/SwipeDrawer/pics.html "Demo 6")
+### Demo 7:
+[![Demo 7](https://p.ssl.qhimg.com/t011f4aa76371a97c2d.jpg "Demo 7")](https://Leaqi.github.io/SwipeDrawer/pics.html "Demo 7")
+### Demo 8:
+[![Demo 8](https://p.ssl.qhimg.com/t018869655c0d14c571.jpg "Demo 8")](https://Leaqi.github.io/SwipeDrawer/pics.html "Demo 8")
+### Demo 9:
+[![Demo 9](https://p.ssl.qhimg.com/t012558e45962de481d.jpg "Demo 9")](https://Leaqi.github.io/SwipeDrawer/pics.html "Demo 9")
+### Demo 10:
+[![Demo 10](https://p.ssl.qhimg.com/t01160d20033ea317c6.jpg "Demo 10")](https://Leaqi.github.io/SwipeDrawer/pics.html "Demo 10")
+### Demo 11:
+[![Demo 11](https://p.ssl.qhimg.com/t01ae673f305442d7b9.jpg "Demo 11")](https://Leaqi.github.io/SwipeDrawer/pics.html "Demo 11")
+### Demo 12:
+[![Demo 12](https://p.ssl.qhimg.com/t01c6421d5583a403bb.jpg "Demo 12")](https://Leaqi.github.io/SwipeDrawer/pics.html "Demo 12")
+### Demo 13:
+[![Demo 13](https://p.ssl.qhimg.com/t01fedfa4a1f176dc57.jpg "Demo 13")](https://Leaqi.github.io/SwipeDrawer/pics.html "Demo 13")
+### Demo 14:
+[![Demo 14](https://p.ssl.qhimg.com/t012f200826d70e56be.jpg "Demo 14")](https://Leaqi.github.io/SwipeDrawer/pics.html "Demo 14")
diff --git a/apk/demo-app.apk b/apk/demo-app.apk
new file mode 100644
index 0000000..b4db8fa
Binary files /dev/null and b/apk/demo-app.apk differ
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 0000000..e17955b
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,26 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 29
+ buildToolsVersion "29.0.3"
+ defaultConfig {
+ applicationId "cn.leaqi.drawerapp"
+ minSdkVersion 16
+ targetSdkVersion 29
+ versionCode 1
+ versionName "1.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ implementation project(path: ':drawer')
+ implementation 'androidx.appcompat:appcompat:1.3.1'
+ implementation 'androidx.recyclerview:recyclerview:1.1.0'
+ implementation 'com.google.android.material:material:1.2.0'
+}
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000..f1b4245
--- /dev/null
+++ b/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..8da6e7b
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,212 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/cn/leaqi/drawerapp/Demo10Activity.java b/app/src/main/java/cn/leaqi/drawerapp/Demo10Activity.java
new file mode 100644
index 0000000..3f2f435
--- /dev/null
+++ b/app/src/main/java/cn/leaqi/drawerapp/Demo10Activity.java
@@ -0,0 +1,736 @@
+package cn.leaqi.drawerapp;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.drawable.AnimationDrawable;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.viewpager.widget.PagerAdapter;
+import androidx.viewpager.widget.ViewPager;
+import androidx.viewpager2.widget.ViewPager2;
+
+import com.google.android.material.tabs.TabLayout;
+import cn.leaqi.drawerapp.Utils.Common;
+import cn.leaqi.drawerapp.Utils.Config;
+import cn.leaqi.drawerapp.Views.MarqueView;
+import cn.leaqi.drawerapp.Views.TopBar;
+import cn.leaqi.drawerapp.Views.UserComment;
+import cn.leaqi.drawerapp.Views.UserHome;
+import cn.leaqi.drawerapp.Views.UserMenu;
+import cn.leaqi.drawerapp.Views.UserShare;
+import cn.leaqi.drawerapp.Views.VideoPlay;
+import cn.leaqi.drawer.SwipeDrawer;
+import cn.leaqi.drawer.OnDrawerChange;
+import cn.leaqi.drawer.OnDrawerState;
+import cn.leaqi.drawer.OnDrawerSwitch;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class Demo10Activity extends Activity implements View.OnClickListener, OnDrawerState, OnDrawerSwitch {
+
+ TopBar topBar = null;
+ SwipeDrawer lastDrawer = null;
+ SwipeDrawer rootDrawer = null;
+ ViewPager mainView = null;
+ List viewList = null;
+ TabLayout tabLayout = null;
+ View topTab = null;
+ View topSet = null;
+ View topSo = null;
+ View topLoad = null;
+ EditText soVal = null;
+ UserHome userHome;
+ List tabList = new ArrayList(){{
+ add("同城");
+ add("关注");
+ add("推荐");
+ }};
+ List viewPagerList = new ArrayList<>();
+ List viewAdapterList = new ArrayList<>();
+
+ RecyclerView topList = null;
+ List topListData = null;
+ TopListAdapter topListAdapter = null;
+
+ int tabIndex = 0;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_demo10);
+ topBar = new TopBar(this, false); // 头部操作类
+ rootDrawer = findViewById(R.id.rootDrawer);
+ mainView = findViewById(R.id.mainView);
+ tabLayout = findViewById(R.id.tabLayout);
+ topTab = findViewById(R.id.topTab);
+ topSet = findViewById(R.id.topSet);
+ topSo = findViewById(R.id.topSo);
+ soVal = findViewById(R.id.soVal);
+ topLoad = findViewById(R.id.topLoad);
+ viewList = new ArrayList<>();
+ userHome = new UserHome(this); // 用户主页类
+ new UserMenu(this); // 左侧边栏用户菜单操作类
+ new UserShare(this); // 用户分享类
+ topBar.setNavigationBar();
+ AppInit();
+ }
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ if (keyCode == KeyEvent.KEYCODE_BACK) { // 监听返回键
+ if (closeLast()) { // 如果是打开状态则关闭
+ return true; // 拦截
+ }
+ }
+ return super.onKeyDown(keyCode, event);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ playVideo(true);
+ }
+
+ @Override
+ protected void onStop() {
+ playVideo(false);
+ super.onStop();
+ }
+
+ @Override
+ public void onClick(View view) {
+ int getId = view.getId();
+ switch (getId) {
+ case R.id.shareClose : // 视频分享关闭按钮
+ case R.id.soBack : // 搜索顶部返回按钮
+ rootDrawer.closeDrawer(); // 关闭
+ break;
+ case R.id.topSet : // 顶部左边设置按钮
+ rootDrawer.openDrawer(SwipeDrawer.DIRECTION_LEFT); // 打开Left方向
+ break;
+ case R.id.topSo : // 顶部右边搜索按钮
+ rootDrawer.openDrawer(SwipeDrawer.DIRECTION_TOP); // 打开Top方向
+ break;
+ case R.id.soCode : // 搜索扫码按钮
+ Common.showToast("扫码");
+ break;
+ case R.id.soBtn : // 搜索提交按钮
+ // 提交搜索词至搜索记录 list
+ String getText = soVal.getText().toString();
+ if (getText.length() > 0) {
+ Common.hideInput(this);
+ topListData.add(0, getText);
+ topListAdapter.notifyItemInserted(0);
+ topList.scrollToPosition(0);
+ soVal.setText("");
+ }
+ break;
+ }
+ }
+
+ @Override
+ public void onStart(int type) { }
+
+ @Override
+ public void onMove(int type, float progress) {
+ topTab.setAlpha(1 - progress);
+ }
+
+ @Override
+ public void onOpen(int type) { }
+
+ @Override
+ public void onClose(int type) { }
+
+ @Override
+ public void onCancel(int type) { }
+
+ @Override
+ public void onOpen(SwipeDrawer view) { // 打开
+ closeLast();
+ lastDrawer = view;
+ if (view == rootDrawer) { // 如果是最外层 SwipeDrawer 则暂停视频
+ playVideo(false);
+ }
+ }
+
+ @Override
+ public void onClose(SwipeDrawer view) { // 关闭
+ lastDrawer = null;
+ if (view == rootDrawer) { // 如果是最外层 SwipeDrawer 则播放视频
+ playVideo(true);
+ soVal.setText("");
+ }
+ Common.hideInput(this);
+ }
+
+ private void AppInit() {
+ final View userTop = findViewById(R.id.userTop);
+ final View topLayout = findViewById(R.id.topLayout);
+ // 空出状态栏高度
+ topTab.setPadding(0, topBar.getStatusHeight(), 0, 0);
+ userTop.setPadding(0, topBar.getStatusHeight(), 0, 0);
+ topLayout.setPadding(0, topBar.getStatusHeight(), 0, 0);
+ // 绑定按钮点击事件
+ findViewById(R.id.shareClose).setOnClickListener(this);
+ findViewById(R.id.soBack).setOnClickListener(this);
+ findViewById(R.id.soCode).setOnClickListener(this);
+ findViewById(R.id.soBtn).setOnClickListener(this);
+ topSet.setOnClickListener(this);
+ topSo.setOnClickListener(this);
+
+ createPage(0); // 同城Page
+ createPage(1); // 关注Page
+ createPage(2); // 推荐Page
+
+ tabLayout.setupWithViewPager(mainView); // tab绑定ViewPager
+
+ mainView.setOffscreenPageLimit(3);
+ mainView.setAdapter(new ListPageAdapter(viewList));
+ mainView.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
+ @Override
+ public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { }
+ @Override
+ public void onPageSelected(int position) {
+ tabLayout.getTabAt(position).select();
+ closeLast();
+ playVideo(true); // ViewPager切换后播放视频
+ }
+ @Override
+ public void onPageScrollStateChanged(int state) {
+ if (state == ViewPager.SCROLL_STATE_DRAGGING) { // ViewPager切换时
+ VideoPlay.setViewAlpha(0); // 隐藏视频控制器
+ setViewAlpha(0.2f); // 主体内容透明
+ } else { // ViewPager切换完毕
+ VideoPlay.setViewAlpha(1); // 显示视频控制器
+ setViewAlpha(1f); // 恢复主体内容透明
+ }
+ }
+ });
+
+ tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
+ @Override
+ public void onTabSelected(TabLayout.Tab tab) { }
+ @Override
+ public void onTabUnselected(TabLayout.Tab tab) { }
+ @Override
+ public void onTabReselected(TabLayout.Tab tab) { // 点击tab按钮
+ if (tabIndex == tab.getPosition()) { // 如果点击是当前位置按钮则执行刷新
+ topSet.setVisibility(View.GONE); // 隐藏设置按钮
+ topSo.setVisibility(View.GONE); // 隐藏搜索按钮
+ topLoad.setVisibility(View.VISIBLE); // 显示刷新布局
+ ((AnimationDrawable) topLoad.getBackground()).start(); // 执行刷新动画
+ // 动画延迟1.5秒
+ topLoad.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ // 刷新更新数据
+ viewAdapterList.get(tabIndex).randData();
+ viewPagerList.get(tabIndex).setAdapter(viewAdapterList.get(tabIndex));
+ topSet.setVisibility(View.VISIBLE);
+ topSo.setVisibility(View.VISIBLE);
+ topLoad.setVisibility(View.GONE);
+ ((AnimationDrawable) topLoad.getBackground()).stop();
+ }
+ }, 1500);
+ }
+ tabIndex = tab.getPosition();
+ }
+ });
+
+ // 监听 SwipeDrawer 状态
+ rootDrawer.setOnDrawerState(this);
+ rootDrawer.setOnDrawerSwitch(this);
+ tabLayout.getTabAt(2).select(); // 默认显示推荐tab
+ mainView.setCurrentItem(2); // 默认显示推荐Page
+
+ TopListData();
+ }
+
+ // 创建Page
+ private void createPage(final int index) {
+ final View page = LayoutInflater.from(this).inflate(R.layout.video_page, null);
+ final SwipeDrawer loadDrawer = page.findViewById(R.id.loadDrawer);
+ final ImageView reTopIcon = page.findViewById(R.id.reTopIcon);
+ final ViewPager2 mainPage = page.findViewById(R.id.mainPage);
+ final List mainList = new ArrayList(){{
+ for(int i = 0; i < Config.VideoList.size(); i++) {
+ int key = Config.VideoList.keyAt(i);
+ Config.UserBean user = Config.UserList.get(key);
+ Config.VideoBean video = Config.VideoList.get(key);
+ Config.MusicBean music = Config.MusicList.get(key);
+ add(new ItemBean(user, video, music));
+ }
+ }};
+ Collections.shuffle(mainList);
+ final VideoPageAdapter adapter = new VideoPageAdapter(mainList, index);
+ mainPage.setOffscreenPageLimit(3);
+ mainPage.setAdapter(adapter);
+
+
+ loadDrawer.setOnDrawerChange(new OnDrawerChange() {
+ private void topOver() {
+ // 当前Page下拉刷新完毕
+ adapter.randData();
+ mainPage.setAdapter(adapter);
+ ((AnimationDrawable) reTopIcon.getBackground()).stop();
+ reTopIcon.setScaleX(1);
+ reTopIcon.setScaleY(1);
+ // 0.3秒后关闭下拉属性布局
+ reTopIcon.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ loadDrawer.closeDrawer();
+ }
+ }, 300);
+ }
+ @Override
+ public void onChange(final SwipeDrawer view, int state, float progress) {
+ boolean isTop = view.getDirection() == SwipeDrawer.DIRECTION_TOP;
+ switch (state) {
+ case SwipeDrawer.STATE_PROGRESS :
+ if (!view.getShow()) {
+ if (progress > 1) progress = 1;
+ if (isTop) {
+ topTab.setAlpha(1 - progress); // 根据下拉进度设置头部透明度
+ // 根据下拉进度放大缩小刷新图标
+ reTopIcon.setScaleX(progress);
+ reTopIcon.setScaleY(progress);
+ }
+ }
+ break;
+ case SwipeDrawer.STATE_OPEN :
+ if (isTop) {
+ // 打开后执行动画
+ ((AnimationDrawable) reTopIcon.getBackground()).start();
+ // 1.5秒后执行关闭
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ if (view.getShow()) {
+ topOver();
+ }
+ }
+ }, 1500);
+ }
+ break;
+ case SwipeDrawer.STATE_ANIM_OVER:
+ if (!view.getShow()) {
+ if (isTop) {
+ // 刷新完毕初始化布局状态
+ ((AnimationDrawable) reTopIcon.getBackground()).stop();
+ reTopIcon.setScaleX(1);
+ reTopIcon.setScaleY(1);
+ }
+ }
+ break;
+ }
+ }
+ });
+
+ mainPage.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
+ @Override
+ public void onPageSelected(int position) {
+ adapter.playVideo(position); // 播放当前位置视频
+ }
+ @Override
+ public void onPageScrollStateChanged(int state) {
+ if (state == ViewPager2.SCROLL_STATE_DRAGGING) { // ViewPager2切换时
+ VideoPlay.setViewAlpha(0); // 隐藏视频控制器
+ setViewAlpha(0.2f); // 主体内容透明
+ } else { // ViewPager2切换完毕
+ VideoPlay.setViewAlpha(1); // 显示视频控制器
+ setViewAlpha(1f); // 恢复主体内容透明
+ }
+ }
+ });
+ viewAdapterList.add(adapter);
+ viewPagerList.add(mainPage);
+ viewList.add(page);
+ }
+
+ // 控制视频播放暂停
+ private void playVideo(boolean play) {
+ VideoPageAdapter adapter;
+ for (ViewPager2 view : viewPagerList) {
+ adapter = (VideoPageAdapter) view.getAdapter();
+ if (adapter != null) {
+ if (play) {
+ adapter.playVideo(view.getCurrentItem());
+ } else {
+ adapter.stopAll();
+ }
+ }
+ }
+ }
+
+ // 控制主体内容透明度及音乐旋转与滚动
+ private void setViewAlpha(float alpha) {
+ if (lastHolder.size() > 0) {
+ for (VideoPageAdapter.ListViewHolder holder : lastHolder) {
+ holder.infoBox.setAlpha(alpha);
+ holder.btnBox.setAlpha(alpha);
+ if (alpha >= 1 && holder.itemVideo.isPlaying()) {
+ Common.animRotate(holder.itemMusicIcon, 2000);
+ holder.itemMusicText.setFocused(true);
+ } else {
+ holder.itemMusicIcon.clearAnimation();
+ holder.itemMusicText.setFocused(false);
+ }
+ }
+ }
+ }
+
+ // 关闭最后一次打开的SwipeDrawer
+ private boolean closeLast() {
+ if (lastDrawer != null) {
+ if (lastDrawer.getShow()) {
+ lastDrawer.closeDrawer();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private class ListPageAdapter extends PagerAdapter {
+ private List list;
+
+ private ListPageAdapter(List l) {
+ list = l;
+ }
+
+ @Override
+ public int getCount() {
+ return list.size();
+ }
+
+ @Override
+ public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
+ return view == object;
+ }
+
+ @Override
+ public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
+ container.removeView(list.get(position));
+ }
+
+ @NonNull
+ @Override
+ public Object instantiateItem(@NonNull ViewGroup container, int position) {
+ container.addView(list.get(position));
+ return list.get(position);
+ }
+
+ @Nullable
+ @Override
+ public CharSequence getPageTitle(int position) {
+ return tabList.get(position);
+ }
+ }
+
+ private class ItemBean {
+ Config.UserBean user; // 用户类
+ Config.VideoBean video; // 视频类
+ Config.MusicBean music; // 音乐类
+ private ItemBean(Config.UserBean user, Config.VideoBean video, Config.MusicBean music) {
+ this.user = user;
+ this.video = video;
+ this.music = music;
+ }
+ }
+
+ private final List lastHolder = new ArrayList<>();
+
+ private class VideoPageAdapter extends RecyclerView.Adapter implements VideoPlay.OnPlayState {
+
+ private List list;
+ private int index = -1;
+ private Map playList = new HashMap<>();
+
+ private VideoPageAdapter(List l, int i) {
+ list = l;
+ index = i;
+ }
+
+ private void randData() {
+ Collections.shuffle(list);
+ }
+
+ private void playVideo(int position) {
+ stopAll();
+ ListViewHolder holder = playList.get(position);
+ if (holder != null && index == mainView.getCurrentItem()) {
+ holder.itemVideo.start();
+ ItemBean item = list.get(position);
+ userHome.upHome(item.user); // 更新用户主页为当前用户
+ // 是否已经关注
+ if (item.user.isFollow) {
+ holder.iconFollow.setVisibility(View.GONE);
+ } else {
+ holder.iconFollow.setImageResource(R.mipmap.follow_add);
+ holder.iconFollow.setVisibility(View.VISIBLE);
+ }
+ }
+ }
+
+ private void stopAll() {
+ for (Map.Entry val : playList.entrySet()) {
+ ListViewHolder item = val.getValue();
+ item.itemVideo.pause();
+ }
+ }
+
+ @Override
+ public void onStart(VideoPlay view) { }
+
+ @Override
+ public void onPlay(VideoPlay view) {
+ final ListViewHolder holder = (ListViewHolder) view.getTag();
+ if (holder != null) {
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ // 视频开始播放后音乐旋转滚动
+ Common.animRotate(holder.itemMusicIcon, 2000);
+ holder.itemMusicText.setFocused(true);
+ holder.itemVideo.setAlpha(1f);
+ holder.itemImg.setVisibility(View.GONE);
+ }
+ }, 300);
+ }
+ }
+
+ @Override
+ public void onStop(VideoPlay view) {
+ ListViewHolder holder = (ListViewHolder) view.getTag();
+ if (holder != null) {
+ // 视频暂停后音乐旋转滚动停止
+ holder.itemMusicIcon.clearAnimation();
+ holder.itemMusicText.setFocused(false);
+ }
+ }
+
+ @Override
+ public void onError(VideoPlay view) { }
+
+ @NonNull
+ @Override
+ public ListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ View view = LayoutInflater.from(Demo10Activity.this).inflate(R.layout.video_item, parent, false);
+ return new ListViewHolder(view);
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull ListViewHolder holder, int position) {
+ ItemBean item = list.get(position);
+ holder.itemTitle.setText(("@" + item.user.name)); // 视频标题
+ holder.itemText.setText(item.video.text); // 视频描述
+ holder.iconFavCount.setText(item.video.getFavCount()); // 点赞数量
+ holder.iconSayCount.setText(item.video.getSayCount()); // 评论数量
+ holder.iconShareCount.setText(item.video.getShareCount()); // 分享数量
+ holder.itemMusicText.setText(item.music.text); // 音乐名称
+ Common.setHttpImage(holder.itemImg, item.video.img); // 默认视频背景
+ Common.setHttpImage(holder.itemIcon, item.user.icon, R.mipmap.icon_user); // 用户头像
+ Common.setHttpImage(holder.iconMusic, item.music.icon, R.mipmap.icon); // 音乐图标
+ holder.iconFav.setImageResource(item.video.isFav ? R.mipmap.icon_fav_cur : R.mipmap.icon_fav); // 是否点赞
+ holder.iconFollow.setVisibility(item.user.isFollow ? View.GONE : View.VISIBLE); // 是都关注
+
+ playList.put(position, holder);
+ holder.itemVideo.setTag(holder);
+ holder.itemVideo.setVideoPath(item.video.src);
+ holder.itemVideo.setOnPlayState(this);
+ holder.userComment.setData(); // 设置评论数据
+ }
+
+ @Override
+ public void onViewAttachedToWindow(@NonNull ListViewHolder holder) {
+ super.onViewAttachedToWindow(holder);
+ lastHolder.add(holder);
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(@NonNull ListViewHolder holder) {
+ super.onViewDetachedFromWindow(holder);
+ lastHolder.remove(holder);
+ }
+
+ @Override
+ public int getItemCount() {
+ return list.size();
+ }
+
+ private class ListViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
+ private SwipeDrawer itemDrawer;
+ private ImageView itemImg;
+ private View itemVideoBox;
+ private VideoPlay itemVideo;
+ private ImageView itemIcon;
+ private ImageView iconFollow;
+ private View itemFav;
+ private ImageView iconFav;
+ private View itemSay;
+ private TextView iconFavCount;
+ private TextView iconSayCount;
+ private TextView iconShareCount;
+ private View sayClose;
+ private View itemShare;
+ private TextView itemTitle;
+ private TextView itemText;
+ private View itemMusicIcon;
+ private ImageView iconMusic;
+ private MarqueView itemMusicText;
+
+ private View infoBox;
+ private View btnBox;
+
+ private UserComment userComment;
+
+ private ListViewHolder(@NonNull View itemView) {
+ super(itemView);
+ itemDrawer = itemView.findViewById(R.id.itemDrawer);
+ itemImg = itemView.findViewById(R.id.itemImg);
+ itemVideoBox = itemView.findViewById(R.id.itemVideoBox);
+ itemVideo = itemView.findViewById(R.id.itemVideo);
+ itemIcon = itemView.findViewById(R.id.itemIcon);
+ iconFollow = itemView.findViewById(R.id.iconFollow);
+ itemFav = itemView.findViewById(R.id.itemFav);
+ iconFav = itemView.findViewById(R.id.iconFav);
+ itemSay = itemView.findViewById(R.id.itemSay);
+ iconFavCount = itemView.findViewById(R.id.iconFavCount);
+ iconSayCount = itemView.findViewById(R.id.iconSayCount);
+ iconShareCount = itemView.findViewById(R.id.iconShareCount);
+ sayClose = itemView.findViewById(R.id.sayClose);
+ itemShare = itemView.findViewById(R.id.itemShare);
+ itemTitle = itemView.findViewById(R.id.itemTitle);
+ itemText = itemView.findViewById(R.id.itemText);
+ itemMusicIcon = itemView.findViewById(R.id.itemMusicIcon);
+ itemMusicText = itemView.findViewById(R.id.itemMusicText);
+ iconMusic = itemView.findViewById(R.id.iconMusic);
+ infoBox = itemView.findViewById(R.id.infoBox);
+ btnBox = itemView.findViewById(R.id.btnBox);
+ userComment = new UserComment(Demo10Activity.this, itemView);
+ itemTitle.setOnClickListener(this);
+ itemIcon.setOnClickListener(this);
+ iconFollow.setOnClickListener(this);
+ itemFav.setOnClickListener(this);
+ itemSay.setOnClickListener(this);
+ sayClose.setOnClickListener(this);
+ itemShare.setOnClickListener(this);
+ itemDrawer.setOnDrawerState(Demo10Activity.this);
+ itemDrawer.setOnDrawerSwitch(Demo10Activity.this);
+ }
+
+ @Override
+ public void onClick(View view) {
+ int position = getAdapterPosition();
+ ItemBean item = list.get(position);
+ if (view == itemSay) { // 点击打开评论
+ itemDrawer.openDrawer(SwipeDrawer.DIRECTION_BOTTOM); // 打开Item下SwipeDrawer Bottom方向评论
+ } else if (view == sayClose) { // 点击关闭评论
+ itemDrawer.closeDrawer(); // 关闭Item下SwipeDrawer Bottom方向
+ } else if (view == iconFollow) { // 点击关注
+ if (item.user.isFollow) return;
+ item.user.isFollow = true;
+ // 关注加号的动画
+ iconFollow.setImageResource(R.mipmap.follow_ok);
+ Common.scaleHide(iconFollow, 150);
+ userHome.upHome(item.user); // 关注后更新用户主页
+ } else if (view == itemFav) { // 点击点赞
+ // 点赞与取消点赞的操作
+ item.video.isFav = !item.video.isFav;
+ item.video.favCount = item.video.isFav ? item.video.favCount + 1 : item.video.favCount - 1;
+ iconFav.setImageResource(item.video.isFav ? R.mipmap.icon_fav_cur : R.mipmap.icon_fav);
+ iconFavCount.setText(item.video.getFavCount());
+ } else if (view == itemShare) { // 点击分享
+ rootDrawer.openDrawer(SwipeDrawer.DIRECTION_BOTTOM); // 打开最外层SwipeDrawer Bottom方向分享
+ } else if (view == itemIcon || view == itemTitle) { // 点击用户头像或用户名称
+ rootDrawer.openDrawer(SwipeDrawer.DIRECTION_RIGHT); // 打开最外层SwipeDrawer Right方向用户主页
+ }
+ }
+
+ }
+ }
+
+ // 顶部搜索list
+ private void TopListData() {
+ topList = findViewById(R.id.topList);
+ topListData = new ArrayList(){{
+ add("DrawerApp");
+ add("SwipeDrawer");
+ }};
+ topListAdapter = new TopListAdapter(this, R.layout.item_so, topListData);
+ topList.setLayoutManager(new LinearLayoutManager(this));
+ topList.setAdapter(topListAdapter);
+ }
+
+ private class TopListAdapter extends RecyclerView.Adapter {
+ private int layout;
+ private LayoutInflater inflater;
+ private List list;
+
+ private TopListAdapter(Context context, int resource, List objects) {
+ layout = resource;
+ inflater = LayoutInflater.from(context);
+ list = objects;
+ notifyDataSetChanged();
+ }
+
+ @NonNull
+ @Override
+ public ListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ View addView = inflater.inflate(layout, parent, false);
+ return new ListViewHolder(addView);
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull ListViewHolder holder, int position) {
+ holder.title.setText(list.get(position));
+ }
+
+ @Override
+ public int getItemCount() {
+ return list.size();
+ }
+
+ private class ListViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
+ TextView title;
+ View del;
+
+ private ListViewHolder(View view) {
+ super(view);
+ title = view.findViewById(R.id.item_title);
+ del = view.findViewById(R.id.item_del);
+ title.setOnClickListener(this);
+ del.setOnClickListener(this);
+ }
+
+ @Override
+ public void onClick(View view) {
+ if (view == title) {
+ Common.showToast(list.get(getAdapterPosition()));
+ } else if (view == del) {
+ topListData.remove(getAdapterPosition());
+ topListAdapter.notifyItemRemoved(getAdapterPosition());
+ }
+ }
+ }
+
+ }
+
+}
diff --git a/app/src/main/java/cn/leaqi/drawerapp/Demo11Activity.java b/app/src/main/java/cn/leaqi/drawerapp/Demo11Activity.java
new file mode 100644
index 0000000..1a8db01
--- /dev/null
+++ b/app/src/main/java/cn/leaqi/drawerapp/Demo11Activity.java
@@ -0,0 +1,285 @@
+package cn.leaqi.drawerapp;
+
+import androidx.annotation.NonNull;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import cn.leaqi.drawerapp.Utils.Common;
+import cn.leaqi.drawerapp.Views.TopBar;
+import cn.leaqi.drawer.SwipeDrawer;
+import cn.leaqi.drawer.OnDrawerChange;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Demo11Activity extends Activity {
+
+ TopBar topBar = null;
+ private List listData;
+ private ListAdapter listAdapter;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_demo11);
+ topBar = new TopBar(this); // 头部操作类
+ topBar.setTitle("ListView 下拉刷新"); // 头部标题
+ topBar.showLeftBack(); // 显示头部返回按钮
+ AppInit();
+ }
+
+ public void AppInit() {
+ final SwipeDrawer mainDrawer = findViewById(R.id.mainDrawer);
+ final View gesture = findViewById(R.id.gesture); // 方向引导布局
+ final View loadBg1 = findViewById(R.id.loadBg1); // 背景1
+ final View loadBg2 = findViewById(R.id.loadBg2); // 背景2
+ final View loadMain = findViewById(R.id.loadMain); // 骑行区域
+ final View loadWheel1 = findViewById(R.id.loadWheel1); // 轮子1
+ final View loadWheel2 = findViewById(R.id.loadWheel2); // 轮子1
+ final View loadSun = findViewById(R.id.loadSun); // 太阳
+ final ImageView reBottomIcon = findViewById(R.id.reBottomIcon); // 底部加载图标
+
+
+ // 设置头部右边图标并设置点击事件
+ topBar.showRight(R.mipmap.icon_re, new TopBar.OnTopClickListener() {
+ @Override
+ public void onClick(View view) {
+ mainDrawer.openDrawer(SwipeDrawer.DIRECTION_TOP); // 点击开始刷新
+ }
+ });
+
+ // 监听 SwipeDrawer 改变
+ mainDrawer.setOnDrawerChange(new OnDrawerChange() {
+ private boolean isClose = false;
+ private void topOver() { // 刷新完毕
+ // 显示刷新完成状态
+ isClose = true;
+ SetList(0);
+ topBar.getTopRightIcon().clearAnimation();
+ topBar.getTopRightIcon().setRotation(0);
+ // 0.5秒后关闭
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ mainDrawer.closeDrawer();
+ }
+ }, 500);
+ }
+ private void bottomOver() { // 加载完毕
+ // 显示加载完成状态
+ isClose = true;
+ SetList(10);
+ topBar.getTopRightIcon().clearAnimation();
+ topBar.getTopRightIcon().setRotation(0);
+ reBottomIcon.clearAnimation();
+ reBottomIcon.setScaleX(1);
+ reBottomIcon.setScaleY(1);
+ reBottomIcon.setImageResource(R.mipmap.icon_complete);
+ // 0.5秒后关闭
+ reBottomIcon.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ mainDrawer.closeDrawer();
+ }
+ }, 500);
+ }
+ @Override
+ public void onChange(final SwipeDrawer view, int state, float progress) {
+ boolean isTop = view.getDirection() == SwipeDrawer.DIRECTION_TOP;
+ boolean isBottom = view.getDirection() == SwipeDrawer.DIRECTION_BOTTOM;
+ int setWidth = mainDrawer.getMeasuredWidth() / 2 - loadMain.getMeasuredWidth() / 2;
+ int bgWidth = loadBg1.getMeasuredWidth();
+ switch (state) {
+ case SwipeDrawer.STATE_START: // 拖拽开始
+ case SwipeDrawer.STATE_CALL_OPEN: // 调用 openDrawer 方法打开
+ Common.animHide(gesture, 200); // 隐藏方向引导
+ break;
+ case SwipeDrawer.STATE_PROGRESS : // 移动,progress 获取进度
+ if (progress > 2) progress = 2; // 限制进度最大2倍
+ if (!view.getShow() && view.getIntercept()) { // 非开启状态,且是手动拖拽
+ topBar.getTopRightIcon().setRotation(progress * 360); // 头部右边图标根据进度旋转
+ }
+ if (progress > 1) progress = 1f;
+ if (isTop) {
+ if (isClose) {
+ progress = 2 - progress;
+ loadMain.setX(progress * setWidth); // 骑行区域根据进度前进后退
+ } else if (!view.getShow()) {
+ loadMain.setX(progress * setWidth); // 骑行区域根据进度前进后退
+ loadBg1.setX(-(progress * bgWidth)); // 背景1无缝滚动
+ loadBg2.setX(bgWidth + -(progress * bgWidth)); // 背景2无缝滚动
+ loadWheel1.setRotation(progress * 1800); // 轮子1转动
+ loadWheel2.setRotation(progress * 1800); // 轮子2转动
+ loadSun.setRotation(progress * 360); // 太阳转动
+ }
+ } else if (isBottom) {
+ // 底部加载图标根据进度放大缩小
+ reBottomIcon.setScaleX(progress);
+ reBottomIcon.setScaleY(progress);
+ }
+ break;
+ case SwipeDrawer.STATE_OPEN : // 打开
+ Common.animRotate(topBar.getTopRightIcon(), 600); // 头部右边图标旋转动画
+ if (isTop) {
+ loadMain.setX(setWidth);
+ loadBg1.setX(0);
+ loadBg2.setX(bgWidth);
+ Common.animShake(loadMain, 0.2f ,6 , 2000); // 骑行区域抖动动画
+ Common.animTranslate(loadBg1, 0, -1, 0, 0, 3000); // 背景1无缝滚动动画
+ Common.animTranslate(loadBg2, 0, -1, 0, 0, 3000); // 背景2无缝滚动动画
+ Common.animRotate(loadWheel1, 500); // 轮子1旋转动画
+ Common.animRotate(loadWheel2, 500); // 轮子2旋转动画
+ Common.animRotate(loadSun, 2000); // 太阳旋转动画
+ // 2秒后结束刷新
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ if (view.getShow()) {
+ topOver();
+ }
+ }
+ }, 2000);
+ } else if (isBottom) {
+ Common.animShake(reBottomIcon, 8, 8, 1600); // 底部加载图标旋转动画
+ // 2秒后结束加载
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ if (view.getShow()) {
+ bottomOver();
+ }
+ }
+ }, 2000);
+ }
+ break;
+ case SwipeDrawer.STATE_ANIM_OVER: // 动画执行完毕
+ if (view.getShow()) {
+ Common.animHide(gesture, 200); // 隐藏方向引导
+ } else {
+ Common.animShow(gesture, 200); // 显示方向引导
+ topBar.getTopRightIcon().clearAnimation(); // 清除头部右边图标动画
+ topBar.getTopRightIcon().setRotation(0); // 回正头部右边图标方向
+ if (isTop) {
+ // 刷新完毕初始化布局状态
+ loadMain.clearAnimation();
+ loadBg1.clearAnimation();
+ loadBg2.clearAnimation();
+ loadWheel1.clearAnimation();
+ loadWheel2.clearAnimation();
+ loadSun.clearAnimation();
+ loadMain.setX(0);
+ loadBg1.setX(0);
+ loadBg2.setX(0);
+ loadWheel1.setRotation(0);
+ loadWheel2.setRotation(0);
+ loadSun.setRotation(0);
+ } else if (isBottom) {
+ // 加载完毕初始化布局状态
+ reBottomIcon.clearAnimation();
+ reBottomIcon.setScaleX(1);
+ reBottomIcon.setScaleY(1);
+ reBottomIcon.setImageResource(R.mipmap.icon_machine);
+ }
+ isClose = false;
+ }
+ break;
+ }
+ }
+ });
+
+ ListData();
+ }
+
+ /**
+ * 更新 list 数据
+ * @param num 更新条数
+ */
+ private void SetList(int num) {
+ if (num > 0) {
+ int sNum = listData.size();
+ int eNum = listData.size() + num;
+ for (int i = sNum; i < eNum; i++) {
+ listData.add("ListView : " + (i + 1));
+ }
+ listAdapter.notifyDataSetChanged();
+ } else {
+ listData.clear();
+ listAdapter.notifyDataSetChanged();
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ for (int i = 0; i < 20; i++) {
+ listData.add("ListView : " + (i + 1));
+ }
+ listAdapter.notifyDataSetChanged();
+ }
+ }, 100);
+ }
+ }
+
+ /**
+ * 给 ListView 填充数据
+ */
+ private void ListData() {
+ final ListView mainList = findViewById(R.id.mainList);
+ listData = new ArrayList(){{
+ for (int i = 0; i < 20; i++) {
+ add("ListView : " + (i + 1));
+ }
+ }};
+ listAdapter = new ListAdapter(this, R.layout.list_icon, listData);
+ mainList.setAdapter(listAdapter);
+ mainList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> adapterView, View view, int i, long l) {
+ Common.showToast(listData.get(i));
+ }
+ });
+ }
+
+ private class ListAdapter extends ArrayAdapter {
+ private int layout;
+ private LayoutInflater inflater;
+ private List list;
+
+ private ListAdapter(Context context, int resource, List objects) {
+ super(context, resource, objects);
+ layout = resource;
+ inflater = LayoutInflater.from(context);
+ list = objects;
+ }
+
+ @NonNull
+ public View getView(int position, View convertView, @NonNull ViewGroup parent) {
+ View view;
+ ViewHolder viewHolder;
+ if (convertView == null) {
+ view = inflater.inflate(layout, null);
+ viewHolder = new ViewHolder();
+ viewHolder.title = view.findViewById(R.id.item_title);
+ view.setTag(viewHolder);
+ } else {
+ view = convertView;
+ viewHolder = (ViewHolder) view.getTag();
+ }
+ viewHolder.title.setText(list.get(position));
+ return view;
+ }
+
+ private class ViewHolder {
+ TextView title;
+ }
+ }
+
+}
diff --git a/app/src/main/java/cn/leaqi/drawerapp/Demo12Activity.java b/app/src/main/java/cn/leaqi/drawerapp/Demo12Activity.java
new file mode 100644
index 0000000..c730a9c
--- /dev/null
+++ b/app/src/main/java/cn/leaqi/drawerapp/Demo12Activity.java
@@ -0,0 +1,282 @@
+package cn.leaqi.drawerapp;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.DividerItemDecoration;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import cn.leaqi.drawerapp.Utils.Common;
+import cn.leaqi.drawerapp.Views.TopBar;
+import cn.leaqi.drawer.SwipeDrawer;
+import cn.leaqi.drawer.OnDrawerChange;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Demo12Activity extends Activity {
+
+ TopBar topBar = null;
+ private List listData;
+ private ListAdapter listAdapter;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_demo12);
+ topBar = new TopBar(this); // 头部操作类
+ topBar.setTitle("RecyclerView 下拉刷新"); // 头部标题
+ topBar.showLeftBack(); // 显示头部返回按钮
+ AppInit();
+ }
+
+ public void AppInit() {
+ final SwipeDrawer mainDrawer = findViewById(R.id.mainDrawer);
+ final View gesture = findViewById(R.id.gesture); // 方向引导布局
+ final ImageView reTopIcon = findViewById(R.id.reTopIcon);
+ final TextView reTopText = findViewById(R.id.reTopText);
+ final ImageView reBottomIcon = findViewById(R.id.reBottomIcon);
+ final TextView reBottomText = findViewById(R.id.reBottomText);
+
+
+ // 设置头部右边图标并设置点击事件
+ topBar.showRight(R.mipmap.icon_re, new TopBar.OnTopClickListener() {
+ @Override
+ public void onClick(View view) {
+ mainDrawer.openDrawer(SwipeDrawer.DIRECTION_TOP); // 点击开始刷新
+ }
+ });
+
+ // 监听 SwipeDrawer 改变
+ mainDrawer.setOnDrawerChange(new OnDrawerChange() {
+ private void topOver() { // 刷新完毕
+ // 显示刷新完成状态
+ SetList(0);
+ topBar.getTopRightIcon().clearAnimation();
+ topBar.getTopRightIcon().setRotation(0);
+ reTopIcon.clearAnimation();
+ reTopIcon.setRotation(0);
+ reTopIcon.setVisibility(View.GONE);
+ reTopText.setText("刷新完成");
+ // 0.6秒后关闭
+ reTopText.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ mainDrawer.closeDrawer();
+ }
+ }, 600);
+ }
+ private void bottomOver() { // 加载完毕
+ // 显示加载完成状态
+ SetList(10);
+ topBar.getTopRightIcon().clearAnimation();
+ topBar.getTopRightIcon().setRotation(0);
+ reBottomIcon.clearAnimation();
+ reBottomIcon.setRotation(0);
+ reBottomIcon.setVisibility(View.GONE);
+ reBottomText.setText("加载完成");
+ // 0.6秒后关闭
+ reBottomText.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ mainDrawer.closeDrawer();
+ }
+ }, 600);
+ }
+ @Override
+ public void onChange(final SwipeDrawer view, int state, float progress) {
+ boolean isTop = view.getDirection() == SwipeDrawer.DIRECTION_TOP;
+ boolean isBottom = view.getDirection() == SwipeDrawer.DIRECTION_BOTTOM;
+ switch (state) {
+ case SwipeDrawer.STATE_START: // 拖拽开始
+ case SwipeDrawer.STATE_CALL_OPEN: // 调用 openDrawer 方法打开
+ Common.animHide(gesture, 200); // 隐藏方向引导
+ break;
+ case SwipeDrawer.STATE_PROGRESS : // 移动,progress 获取进度
+ if (!view.getShow() && view.getIntercept()) { // 非开启状态,且是手动拖拽
+ if (progress > 2) progress = 2; // 限制进度最大2倍
+ topBar.getTopRightIcon().setRotation(progress * 360); // 头部右边图标根据进度旋转
+ if (progress > 1) progress = 1;
+ if (isTop) {
+ reTopIcon.setRotation(progress * 360); // 顶部刷新图标根据进度旋转
+ } else if (isBottom) {
+ reBottomIcon.setRotation(progress * 360); // 底部加载图标根据进度旋转
+ }
+ }
+ break;
+ case SwipeDrawer.STATE_OPEN : // 打开
+ Common.animRotate(topBar.getTopRightIcon(), 600); // 头部右边图标旋转动画
+ if (isTop) {
+ reTopText.setText("正在刷新");
+ reTopIcon.setImageResource(R.mipmap.icon_more);
+ Common.animRotate(reTopIcon, 800); // 顶部刷新图标旋转动画
+ // 1.5秒后结束刷新
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ if (view.getShow()) {
+ topOver();
+ }
+ }
+ }, 1500);
+ } else if (isBottom) {
+ reBottomText.setText("正在加载");
+ reBottomIcon.setImageResource(R.mipmap.icon_more);
+ Common.animRotate(reBottomIcon, 800); // 底部加载图标旋转动画
+ // 1.5秒后结束加载
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ if (view.getShow()) {
+ bottomOver();
+ }
+ }
+ }, 1500);
+ }
+ break;
+ case SwipeDrawer.STATE_ANIM_OVER: // 动画执行完毕
+ if (view.getShow()) {
+ Common.animHide(gesture, 200); // 隐藏方向引导
+ } else {
+ Common.animShow(gesture, 200); // 显示方向引导
+ topBar.getTopRightIcon().clearAnimation(); // 清除头部右边图标动画
+ topBar.getTopRightIcon().setRotation(0); // 回正头部右边图标方向
+ if (isTop) {
+ // 刷新完毕初始化布局状态
+ reTopIcon.clearAnimation();
+ reTopIcon.setRotation(0);
+ reTopIcon.setVisibility(View.VISIBLE);
+ reTopIcon.setImageResource(R.mipmap.icon_down);
+ } else if (isBottom) {
+ // 加载完毕初始化布局状态
+ reBottomIcon.clearAnimation();
+ reBottomIcon.setRotation(0);
+ reBottomIcon.setVisibility(View.VISIBLE);
+ reBottomIcon.setImageResource(R.mipmap.icon_up);
+ }
+ }
+ break;
+ case SwipeDrawer.STATE_DRAG_INTO : // 拖拽超过 shrinkRange 距离
+ if (!view.getShow()) {
+ if (isTop) {
+ reTopText.setText("松开刷新");
+ } else if (isBottom) {
+ reBottomText.setText("松开加载");
+ }
+ }
+ break;
+ case SwipeDrawer.STATE_DRAG_OUT : // 拖拽未超过 shrinkRange 距离
+ if (!view.getShow()) {
+ if (isTop) {
+ reTopText.setText("下拉刷新");
+ } else if (isBottom) {
+ reBottomText.setText("上拉加载");
+ }
+ }
+ break;
+ }
+ }
+ });
+
+ ListData();
+ }
+
+ /**
+ * 更新 list 数据
+ * @param num 更新条数
+ */
+ private void SetList(int num) {
+ if (num > 0) {
+ int sNum = listData.size();
+ int eNum = listData.size() + num;
+ for (int i = sNum; i < eNum; i++) {
+ listData.add("RecyclerView : " + (i + 1));
+ }
+ listAdapter.notifyDataSetChanged();
+ } else {
+ listData.clear();
+ listAdapter.notifyDataSetChanged();
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ for (int i = 0; i < 20; i++) {
+ listData.add("RecyclerView : " + (i + 1));
+ }
+ listAdapter.notifyDataSetChanged();
+ }
+ }, 100);
+ }
+ }
+
+ /**
+ * 给 RecyclerView 填充数据
+ */
+ private void ListData() {
+ final RecyclerView mainList = findViewById(R.id.mainList);
+ listData = new ArrayList(){{
+ for (int i = 0; i < 20; i++) {
+ add("RecyclerView : " + (i + 1));
+ }
+ }};
+ listAdapter = new ListAdapter(this, R.layout.list_icon, listData);
+ mainList.setLayoutManager(new LinearLayoutManager(this));
+ mainList.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
+ mainList.setAdapter(listAdapter);
+ }
+
+ private class ListAdapter extends RecyclerView.Adapter {
+ private int layout;
+ private LayoutInflater inflater;
+ private List list;
+
+ private ListAdapter(Context context, int resource, List objects) {
+ layout = resource;
+ inflater = LayoutInflater.from(context);
+ list = objects;
+ notifyDataSetChanged();
+ }
+
+ @NonNull
+ @Override
+ public ListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ View addView = inflater.inflate(layout, parent, false);
+ return new ListViewHolder(addView);
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull ListViewHolder holder, int position) {
+ holder.title.setText(list.get(position));
+ }
+
+ @Override
+ public int getItemCount() {
+ return list.size();
+ }
+
+ private class ListViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
+ TextView title;
+
+ private ListViewHolder(View view) {
+ super(view);
+ title = view.findViewById(R.id.item_title);
+ view.setOnClickListener(this);
+ }
+
+ @Override
+ public void onClick(View view) {
+ Common.showToast(list.get(getAdapterPosition()));
+ }
+ }
+
+ }
+
+}
diff --git a/app/src/main/java/cn/leaqi/drawerapp/Demo13Activity.java b/app/src/main/java/cn/leaqi/drawerapp/Demo13Activity.java
new file mode 100644
index 0000000..f8fbcf9
--- /dev/null
+++ b/app/src/main/java/cn/leaqi/drawerapp/Demo13Activity.java
@@ -0,0 +1,258 @@
+package cn.leaqi.drawerapp;
+
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.GridView;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+
+import cn.leaqi.drawerapp.Utils.Common;
+import cn.leaqi.drawerapp.Views.TopBar;
+import cn.leaqi.drawer.SwipeDrawer;
+import cn.leaqi.drawer.OnDrawerChange;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Demo13Activity extends Activity {
+
+ TopBar topBar = null;
+ private List listData;
+ private ListAdapter listAdapter;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_demo13);
+ topBar = new TopBar(this); // 头部操作类
+ topBar.setTitle("GridView 下拉刷新"); // 头部标题
+ topBar.showLeftBack(); // 显示头部返回按钮
+ AppInit();
+ }
+
+ public void AppInit() {
+ final SwipeDrawer mainDrawer = findViewById(R.id.mainDrawer);
+ final View gesture = findViewById(R.id.gesture); // 方向引导布局
+ final ImageView reTopIcon = findViewById(R.id.reTopIcon);
+ final ImageView reBottomIcon = findViewById(R.id.reBottomIcon);
+
+
+ // 设置头部右边图标并设置点击事件
+ topBar.showRight(R.mipmap.icon_re, new TopBar.OnTopClickListener() {
+ @Override
+ public void onClick(View view) {
+ mainDrawer.openDrawer(SwipeDrawer.DIRECTION_TOP); // 点击开始刷新
+ }
+ });
+
+ // 监听 SwipeDrawer 改变
+ mainDrawer.setOnDrawerChange(new OnDrawerChange() {
+ private void topOver() { // 刷新完毕
+ // 显示刷新完成状态
+ SetList(0);
+ topBar.getTopRightIcon().clearAnimation();
+ topBar.getTopRightIcon().setRotation(0);
+ reTopIcon.clearAnimation();
+ reTopIcon.setRotation(0);
+ reTopIcon.setScaleX(1);
+ reTopIcon.setScaleY(1);
+ // 0.3秒后关闭
+ reTopIcon.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ mainDrawer.closeDrawer();
+ }
+ }, 300);
+ }
+ private void bottomOver() { // 加载完毕
+ // 显示加载完成状态
+ SetList(10);
+ topBar.getTopRightIcon().clearAnimation();
+ topBar.getTopRightIcon().setRotation(0);
+ reBottomIcon.clearAnimation();
+ reBottomIcon.setRotation(0);
+ reBottomIcon.setScaleX(1);
+ reBottomIcon.setScaleY(1);
+ // 0.3秒后关闭
+ reBottomIcon.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ mainDrawer.closeDrawer();
+ }
+ }, 300);
+ }
+ @Override
+ public void onChange(final SwipeDrawer view, int state, float progress) {
+ boolean isTop = view.getDirection() == SwipeDrawer.DIRECTION_TOP;
+ boolean isBottom = view.getDirection() == SwipeDrawer.DIRECTION_BOTTOM;
+ switch (state) {
+ case SwipeDrawer.STATE_START: // 拖拽开始
+ case SwipeDrawer.STATE_CALL_OPEN: // 调用 openDrawer 方法打开
+ Common.animHide(gesture, 200); // 隐藏方向引导
+ break;
+ case SwipeDrawer.STATE_PROGRESS : // 移动,progress 获取进度
+ if (!view.getShow()) {
+ if (progress > 1) progress = 1; // 限制进度最大1倍
+ if (view.getIntercept()) { // 手动拖拽
+ topBar.getTopRightIcon().setRotation(progress * 360); // 头部右边图标根据进度旋转
+ }
+ if (isTop) {
+ // 顶部刷新图标根据进度放大缩小
+ reTopIcon.setScaleX(progress);
+ reTopIcon.setScaleY(progress);
+ reTopIcon.setRotation(progress * 360); // 顶部刷新图标根据进度旋转
+ } else if (isBottom) {
+ // 底部加载图标根据进度放大缩小
+ reBottomIcon.setScaleX(progress);
+ reBottomIcon.setScaleY(progress);
+ reBottomIcon.setRotation(progress * 360); // 底部加载图标根据进度旋转
+ }
+ }
+ break;
+ case SwipeDrawer.STATE_OPEN : // 打开
+ Common.animRotate(topBar.getTopRightIcon(), 600);
+ if (isTop) {
+ Common.animRotate(reTopIcon, 800); // 顶部刷新图标旋转动画
+ // 1.5秒后结束刷新
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ if (view.getShow()) {
+ topOver();
+ }
+ }
+ }, 1500);
+ } else if (isBottom) {
+ Common.animRotate(reBottomIcon, 800); // 底部加载图标旋转动画
+ // 1.5秒后结束加载
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ if (view.getShow()) {
+ bottomOver();
+ }
+ }
+ }, 1500);
+ }
+ break;
+ case SwipeDrawer.STATE_ANIM_OVER: // 动画执行完毕
+ if (view.getShow()) {
+ Common.animHide(gesture, 200); // 隐藏方向引导
+ } else {
+ Common.animShow(gesture, 200); // 显示方向引导
+ topBar.getTopRightIcon().clearAnimation(); // 清除头部右边图标动画
+ topBar.getTopRightIcon().setRotation(0); // 回正头部右边图标方向
+ if (isTop) {
+ // 刷新完毕初始化布局状态
+ reTopIcon.clearAnimation();
+ reTopIcon.setRotation(0);
+ reTopIcon.setScaleX(1);
+ reTopIcon.setScaleY(1);
+ } else if (isBottom) {
+ // 加载完毕初始化布局状态
+ reBottomIcon.clearAnimation();
+ reBottomIcon.setRotation(0);
+ reBottomIcon.setScaleX(1);
+ reBottomIcon.setScaleY(1);
+ }
+ }
+ break;
+ }
+ }
+ });
+
+ ListData();
+ }
+
+ /**
+ * 更新 list 数据
+ * @param num 更新条数
+ */
+ private void SetList(int num) {
+ if (num > 0) {
+ int sNum = listData.size();
+ int eNum = listData.size() + num;
+ for (int i = sNum; i < eNum; i++) {
+ listData.add("GridView : " + (i + 1));
+ }
+ listAdapter.notifyDataSetChanged();
+ } else {
+ listData.clear();
+ listAdapter.notifyDataSetChanged();
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ for (int i = 0; i < 40; i++) {
+ listData.add("GridView : " + (i + 1));
+ }
+ listAdapter.notifyDataSetChanged();
+ }
+ }, 100);
+ }
+ }
+
+ /**
+ * 给 GridView 填充数据
+ */
+ private void ListData() {
+ final GridView mainList = findViewById(R.id.mainList);
+ listData = new ArrayList() {{
+ for (int i = 0; i < 40; i++) {
+ add("GridView : " + (i + 1));
+ }
+ }};
+ listAdapter = new ListAdapter(this, R.layout.grid_text, listData);
+ mainList.setAdapter(listAdapter);
+ mainList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> adapterView, View view, int i, long l) {
+ Common.showToast(listData.get(i));
+ }
+ });
+ }
+
+ private class ListAdapter extends ArrayAdapter {
+ private int layout;
+ private LayoutInflater inflater;
+ private List list;
+
+ private ListAdapter(Context context, int resource, List objects) {
+ super(context, resource, objects);
+ layout = resource;
+ inflater = LayoutInflater.from(context);
+ list = objects;
+ }
+
+ @NonNull
+ public View getView(int position, View convertView, @NonNull ViewGroup parent) {
+ View view;
+ ViewHolder viewHolder;
+ if (convertView == null) {
+ view = inflater.inflate(layout, null);
+ viewHolder = new ViewHolder();
+ viewHolder.title = view.findViewById(R.id.item_title);
+ view.setTag(viewHolder);
+ } else {
+ view = convertView;
+ viewHolder = (ViewHolder) view.getTag();
+ }
+ viewHolder.title.setText(list.get(position));
+ return view;
+ }
+
+ private class ViewHolder {
+ TextView title;
+ }
+ }
+
+}
diff --git a/app/src/main/java/cn/leaqi/drawerapp/Demo14Activity.java b/app/src/main/java/cn/leaqi/drawerapp/Demo14Activity.java
new file mode 100644
index 0000000..d528135
--- /dev/null
+++ b/app/src/main/java/cn/leaqi/drawerapp/Demo14Activity.java
@@ -0,0 +1,134 @@
+package cn.leaqi.drawerapp;
+
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.ScrollView;
+import android.widget.TextView;
+
+import cn.leaqi.drawerapp.Utils.Common;
+import cn.leaqi.drawerapp.Views.TopBar;
+import cn.leaqi.drawer.SwipeDrawer;
+import cn.leaqi.drawer.OnDrawerChange;
+
+public class Demo14Activity extends Activity {
+
+ TopBar topBar = null;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_demo14);
+ topBar = new TopBar(this); // 头部操作类
+ topBar.setTitle("ScrollView 下拉刷新"); // 头部标题
+ topBar.showLeftBack(); // 显示头部返回按钮
+ AppInit();
+ }
+
+ public void AppInit() {
+ final SwipeDrawer mainDrawer = findViewById(R.id.mainDrawer);
+ final ScrollView mainList = findViewById(R.id.mainList);
+ final View gesture = findViewById(R.id.gesture); // 方向引导布局
+ final ImageView reTopIcon = findViewById(R.id.reTopIcon);
+ final TextView reTopText = findViewById(R.id.reTopText);
+
+
+ // 设置头部右边图标并设置点击事件
+ topBar.showRight(R.mipmap.icon_re, new TopBar.OnTopClickListener() {
+ @Override
+ public void onClick(View view) {
+ mainDrawer.openDrawer(SwipeDrawer.DIRECTION_TOP); // 点击开始刷新
+ }
+ });
+
+ // 监听 SwipeDrawer 改变
+ mainDrawer.setOnDrawerChange(new OnDrawerChange() {
+ private void topOver() { // 刷新完毕
+ // 显示刷新完成状态
+ mainList.smoothScrollTo(0, 0);
+ topBar.getTopRightIcon().clearAnimation();
+ topBar.getTopRightIcon().setRotation(0);
+ reTopIcon.clearAnimation();
+ reTopIcon.setRotation(0);
+ reTopIcon.setImageResource(R.mipmap.icon_over);
+ reTopText.setText("刷新完成");
+ // 0.6秒后关闭
+ reTopText.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ mainDrawer.closeDrawer();
+ }
+ }, 600);
+ }
+ @Override
+ public void onChange(final SwipeDrawer view, int state, float progress) {
+ boolean isTop = view.getDirection() == SwipeDrawer.DIRECTION_TOP;
+ switch (state) {
+ case SwipeDrawer.STATE_START: // 拖拽开始
+ case SwipeDrawer.STATE_CALL_OPEN: // 调用 openDrawer 方法打开
+ Common.animHide(gesture, 200); // 隐藏方向引导
+ break;
+ case SwipeDrawer.STATE_PROGRESS : // 移动,progress 获取进度
+ if (!view.getShow() && view.getIntercept()) { // 非开启状态,且是手动拖拽
+ if (progress > 2) progress = 2; // 限制进度最大2倍
+ topBar.getTopRightIcon().setRotation(progress * 360); // 头部右边图标根据进度旋转
+ if (isTop) {
+ reTopIcon.setRotation(progress * 360); // 顶部刷新图标根据进度旋转
+ }
+ }
+ break;
+ case SwipeDrawer.STATE_OPEN : // 打开
+ Common.animRotate(topBar.getTopRightIcon(), 600); // 头部右边图标旋转动画
+ if (isTop) {
+ reTopText.setText("正在刷新");
+ Common.animRotate(reTopIcon, 600); // 顶部刷新图标旋转动画
+ // 1.5秒后结束刷新
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ if (view.getShow()) {
+ topOver();
+ }
+ }
+ }, 1500);
+ }
+ break;
+ case SwipeDrawer.STATE_ANIM_OVER: // 动画执行完毕
+ if (view.getShow()) {
+ Common.animHide(gesture, 200); // 隐藏方向引导
+ } else {
+ Common.animShow(gesture, 200); // 显示方向引导
+ topBar.getTopRightIcon().clearAnimation(); // 清除头部右边图标动画
+ topBar.getTopRightIcon().setRotation(0); // 回正头部右边图标方向
+ if (isTop) {
+ // 刷新完毕初始化布局状态
+ reTopIcon.clearAnimation();
+ reTopIcon.setRotation(0);
+ reTopIcon.setImageResource(R.mipmap.icon_load);
+ }
+ }
+ break;
+ case SwipeDrawer.STATE_DRAG_INTO : // 拖拽超过 shrinkRange 距离
+ if (!view.getShow()) {
+ if (isTop) {
+ reTopText.setText("松开刷新");
+ }
+ }
+ break;
+ case SwipeDrawer.STATE_DRAG_OUT : // 拖拽未超过 shrinkRange 距离
+ if (!view.getShow()) {
+ if (isTop) {
+ reTopText.setText("下拉刷新");
+ }
+ }
+ break;
+ }
+ }
+ });
+
+ }
+
+}
diff --git a/app/src/main/java/cn/leaqi/drawerapp/Demo1Activity.java b/app/src/main/java/cn/leaqi/drawerapp/Demo1Activity.java
new file mode 100644
index 0000000..89de799
--- /dev/null
+++ b/app/src/main/java/cn/leaqi/drawerapp/Demo1Activity.java
@@ -0,0 +1,209 @@
+package cn.leaqi.drawerapp;
+
+import androidx.annotation.NonNull;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import cn.leaqi.drawerapp.Utils.Common;
+import cn.leaqi.drawerapp.Views.TopBar;
+import cn.leaqi.drawer.DrawerHolder;
+import cn.leaqi.drawer.SwipeDrawer;
+import cn.leaqi.drawer.OnDrawerState;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Demo1Activity extends Activity {
+
+ TopBar topBar = null;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_demo1);
+ topBar = new TopBar(this); // 头部操作类
+ topBar.setTitle("ListView"); // 头部标题
+ topBar.showLeftBack(); // 显示头部返回按钮
+ AppInit();
+ }
+
+ public void AppInit() {
+ final SwipeDrawer mainDrawer = findViewById(R.id.mainDrawer);
+ final View gesture = findViewById(R.id.gesture); // 方向引导布局
+ // 监听 SwipeDrawer 状态
+ mainDrawer.setOnDrawerState(new OnDrawerState() {
+ @Override
+ public void onStart(int type) { // 拖拽开始
+ Common.animHide(gesture, 200); // 隐藏方向引导
+ }
+ @Override
+ public void onMove(int type, float progress) { }
+ @Override
+ public void onOpen(int type) { }
+ @Override
+ public void onClose(int type) { // 关闭
+ Common.animShow(gesture, 200); // 显示方向引导
+ }
+ @Override
+ public void onCancel(int type) { // 取消操作
+ if (mainDrawer.getShow()) { // 判断是否打开
+ Common.animHide(gesture, 200); // 隐藏方向引导
+ } else {
+ Common.animShow(gesture, 200); // 显示方向引导
+ }
+ }
+ });
+ ListData();
+ }
+
+ /**
+ * 给 ListView 填充数据
+ */
+ private void ListData() {
+ final ListView mainList = findViewById(R.id.mainList);
+ final List listData = new ArrayList(){{
+ for (int i = 0; i < 30; i++) {
+ add("ListView : " + (i + 1));
+ }
+ }};
+ final ListAdapter listAdapter = new ListAdapter(this, R.layout.list_item, listData);
+ // 绑定 item 点击事件
+ listAdapter.setOnItemClick(new OnItemClick() {
+ @Override
+ public void onClick(SwipeDrawer swipeDrawer, int position, int id) {
+ switch (id) {
+ case R.id.itemMain : // 点击了主布局
+ Common.showToast(listData.get(position));
+ break;
+ case R.id.itemDing : // 点击了 Left 置顶按钮
+ swipeDrawer.closeDrawer(false); // 非动画关闭当前 item
+ String getText = listData.get(position);
+ listData.remove(position); // 移除 item
+ listData.add(0, getText); // 添加到顶部
+ listAdapter.notifyDataSetChanged(); // 更新 list
+ break;
+ case R.id.itemDel : // 点击了 Right 删除按钮
+ swipeDrawer.closeDrawer(false); // 非动画关闭当前 item
+ listData.remove(position); // 删除 item
+ listAdapter.notifyDataSetChanged(); // 更新 list
+ break;
+ case R.id.itemClose : // 点击了 Right 关闭按钮
+ swipeDrawer.closeDrawer(true); // 关闭当前 item
+ break;
+ }
+ }
+ });
+ mainList.setAdapter(listAdapter);
+ final String autoText = "✔ 自动关闭";
+ final String shutText = "✘ 自动关闭";
+ // 自定义头部右边文本并设置点击事件
+ topBar.setRightText(shutText, new TopBar.OnTopClickListener() {
+ @Override
+ public void onClick(View view) {
+ String getText = ((TextView) view).getText().toString();
+ if (getText.equals(autoText)) {
+ topBar.setRightText(shutText); // 更新文本
+ listAdapter.setAutoClose(false); // 取消自动关闭
+ } else {
+ topBar.setRightText(autoText); // 更新文本
+ listAdapter.setAutoClose(true); // 设置自动关闭
+ }
+ }
+ });
+ }
+
+ private interface OnItemClick {
+ void onClick(SwipeDrawer swipeDrawer, int position, int id);
+ }
+
+ private class ListAdapter extends ArrayAdapter implements View.OnClickListener {
+ private int layout;
+ private LayoutInflater inflater;
+ private List list;
+ private OnItemClick onItemClick = null;
+ private boolean autoClose = false;
+
+ // 创建 DrawerHolder 对象,非自动关闭的情况保存 item 状态使用
+ private DrawerHolder drawerHolder = new DrawerHolder();
+
+ private ListAdapter(Context context, int resource, List objects) {
+ super(context, resource, objects);
+ layout = resource;
+ inflater = LayoutInflater.from(context);
+ list = objects;
+ }
+
+ private void setOnItemClick(OnItemClick click) {
+ onItemClick = click;
+ }
+
+ private void setAutoClose(boolean bool) {
+ autoClose = bool;
+ drawerHolder.clearHolder(); // 清除已保存状态并关闭所有已打开 item
+ notifyDataSetChanged(); // 更新 list
+ }
+
+ @Override
+ public void onClick(View view) {
+ int id = view.getId();
+ int position = (int) view.getTag();
+ SwipeDrawer swipeDrawer = SwipeDrawer.getParentDrawer(view);
+ if (swipeDrawer == null) return;
+ if (onItemClick != null) { // 点击事件回调
+ onItemClick.onClick(swipeDrawer, position, id);
+ }
+ }
+
+ @NonNull
+ public View getView(int position, View convertView, @NonNull ViewGroup parent) {
+ View view;
+ ViewHolder viewHolder;
+ if (convertView == null) {
+ view = inflater.inflate(layout, null);
+ viewHolder = new ViewHolder();
+ viewHolder.title = view.findViewById(R.id.item_title);
+ viewHolder.itemMain = view.findViewById(R.id.itemMain);
+ viewHolder.itemDing = view.findViewById(R.id.itemDing);
+ viewHolder.itemDel = view.findViewById(R.id.itemDel);
+ viewHolder.itemClose = view.findViewById(R.id.itemClose);
+ viewHolder.itemMain.setOnClickListener(this);
+ viewHolder.itemDing.setOnClickListener(this);
+ viewHolder.itemDel.setOnClickListener(this);
+ viewHolder.itemClose.setOnClickListener(this);
+ view.setTag(viewHolder);
+ } else {
+ view = convertView;
+ viewHolder = (ViewHolder) view.getTag();
+ }
+ SwipeDrawer swipeDrawer = ((SwipeDrawer) view);
+ swipeDrawer.setAutoClose(autoClose); // 设置是否自动关闭
+ viewHolder.itemMain.setTag(position);
+ viewHolder.itemDing.setTag(position);
+ viewHolder.itemDel.setTag(position);
+ viewHolder.itemClose.setTag(position);
+ viewHolder.title.setText(list.get(position));
+
+ // bindHolder 的第一个参数传递 item 的 SwipeDrawer 布局
+ // bindHolder 的第二个参数传递唯一对象
+ drawerHolder.bindHolder(swipeDrawer, list.get(position));
+ return view;
+ }
+
+ private class ViewHolder {
+ View itemMain;
+ View itemDing;
+ View itemDel;
+ View itemClose;
+ TextView title;
+ }
+ }
+
+}
diff --git a/app/src/main/java/cn/leaqi/drawerapp/Demo2Activity.java b/app/src/main/java/cn/leaqi/drawerapp/Demo2Activity.java
new file mode 100644
index 0000000..34196f3
--- /dev/null
+++ b/app/src/main/java/cn/leaqi/drawerapp/Demo2Activity.java
@@ -0,0 +1,216 @@
+package cn.leaqi.drawerapp;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.DividerItemDecoration;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import cn.leaqi.drawerapp.Utils.Common;
+import cn.leaqi.drawerapp.Views.TopBar;
+import cn.leaqi.drawer.DrawerHolder;
+import cn.leaqi.drawer.SwipeDrawer;
+import cn.leaqi.drawer.OnDrawerState;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Demo2Activity extends Activity {
+
+ TopBar topBar = null;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_demo2);
+ topBar = new TopBar(this); // 头部操作类
+ topBar.setTitle("RecyclerView"); // 头部标题
+ topBar.showLeftBack(); // 显示头部返回按钮
+ AppInit();
+ }
+
+ public void AppInit() {
+ final SwipeDrawer mainDrawer = findViewById(R.id.mainDrawer);
+ final View gesture = findViewById(R.id.gesture); // 方向引导布局
+ // 监听 SwipeDrawer 状态
+ mainDrawer.setOnDrawerState(new OnDrawerState() {
+ @Override
+ public void onStart(int type) { // 拖拽开始
+ Common.animHide(gesture, 200); // 隐藏方向引导
+ }
+ @Override
+ public void onMove(int type, float progress) { }
+ @Override
+ public void onOpen(int type) { }
+ @Override
+ public void onClose(int type) { // 关闭
+ Common.animShow(gesture, 200); // 显示方向引导
+ }
+ @Override
+ public void onCancel(int type) { // 取消操作
+ if (mainDrawer.getShow()) { // 判断是否打开
+ Common.animHide(gesture, 200); // 隐藏方向引导
+ } else {
+ Common.animShow(gesture, 200); // 显示方向引导
+ }
+ }
+ });
+ ListData();
+ }
+
+ /**
+ * 给 ListView 填充数据
+ */
+ private void ListData() {
+ final RecyclerView mainList = findViewById(R.id.mainList);
+ final List listData = new ArrayList(){{
+ for (int i = 0; i < 30; i++) {
+ add("RecyclerView : " + (i + 1));
+ }
+ }};
+ final ListAdapter listAdapter = new ListAdapter(this, R.layout.list_item, listData);
+ // 绑定 item 点击事件
+ listAdapter.setOnItemClick(new OnItemClick() {
+ @Override
+ public void onClick(SwipeDrawer swipeDrawer, int position, int id) {
+ switch (id) {
+ case R.id.itemMain : // 点击了主布局
+ Common.showToast(listData.get(position));
+ break;
+ case R.id.itemDing : // 点击了 Left 置顶按钮
+ swipeDrawer.closeDrawer(false); // 非动画关闭当前 item
+ String getText = listData.get(position);
+ listData.remove(position); // 移除 item
+ listData.add(0, getText); // 添加到顶部
+ // 更新 list
+ listAdapter.notifyItemRemoved(position);
+ listAdapter.notifyItemRangeInserted(0, 1);
+ break;
+ case R.id.itemDel : // 点击了 Right 删除按钮
+ swipeDrawer.closeDrawer(false); // 非动画关闭当前 item
+ listData.remove(position); // 删除 item
+ listAdapter.notifyItemRemoved(position); // 更新 list
+ break;
+ case R.id.itemClose : // 点击了 Right 关闭按钮
+ swipeDrawer.closeDrawer(true); // 关闭当前 item
+ break;
+ }
+ }
+ });
+ mainList.setLayoutManager(new LinearLayoutManager(this));
+ mainList.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
+ mainList.setAdapter(listAdapter);
+ // 自定义头部右边文本并设置点击事件
+ final String autoText = "✔ 自动关闭";
+ final String shutText = "✘ 自动关闭";
+ topBar.setRightText(autoText, new TopBar.OnTopClickListener() {
+ @Override
+ public void onClick(View view) {
+ String getText = ((TextView) view).getText().toString();
+ if (getText.equals(autoText)) {
+ topBar.setRightText(shutText); // 更新文本
+ listAdapter.setAutoClose(false); // 取消自动关闭
+ } else {
+ topBar.setRightText(autoText); // 更新文本
+ listAdapter.setAutoClose(true); // 设置自动关闭
+ }
+ }
+ });
+ }
+
+ private interface OnItemClick {
+ void onClick(SwipeDrawer swipeDrawer, int position, int id);
+ }
+
+ private class ListAdapter extends RecyclerView.Adapter {
+ private int layout;
+ private LayoutInflater inflater;
+ private List list;
+ private OnItemClick onItemClick = null;
+ private boolean autoClose = true;
+
+ // 创建 DrawerHolder 对象,非自动关闭的情况保存 item 状态使用
+ private DrawerHolder drawerHolder = new DrawerHolder();
+
+ private ListAdapter(Context context, int resource, List objects) {
+ layout = resource;
+ inflater = LayoutInflater.from(context);
+ list = objects;
+ notifyDataSetChanged();
+ }
+
+ private void setOnItemClick(OnItemClick click) {
+ onItemClick = click;
+ }
+
+ private void setAutoClose(boolean bool) {
+ autoClose = bool;
+ drawerHolder.clearHolder(); // 清除已保存状态并关闭所有已打开 item
+ notifyDataSetChanged(); // 更新 list
+ }
+
+ @NonNull
+ @Override
+ public ListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ View addView = inflater.inflate(layout, parent, false);
+ return new ListViewHolder(addView);
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull ListViewHolder holder, int position) {
+ holder.item.setAutoClose(autoClose); // 设置是否自动关闭
+ holder.title.setText(list.get(position));
+
+ // bindHolder 的第一个参数传递 item 的 SwipeDrawer 布局
+ // bindHolder 的第二个参数传递唯一对象
+ drawerHolder.bindHolder(holder.item, list.get(position));
+ }
+
+ @Override
+ public int getItemCount() {
+ return list.size();
+ }
+
+ private class ListViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
+ SwipeDrawer item;
+ View itemMain;
+ View itemDing;
+ View itemDel;
+ View itemClose;
+ TextView title;
+
+ private ListViewHolder(View view) {
+ super(view);
+ item = (SwipeDrawer) view;
+ title = view.findViewById(R.id.item_title);
+ itemMain = view.findViewById(R.id.itemMain);
+ itemDing = view.findViewById(R.id.itemDing);
+ itemDel = view.findViewById(R.id.itemDel);
+ itemClose = view.findViewById(R.id.itemClose);
+ itemMain.setOnClickListener(this);
+ itemDing.setOnClickListener(this);
+ itemDel.setOnClickListener(this);
+ itemClose.setOnClickListener(this);
+ }
+
+ @Override
+ public void onClick(View view) {
+ int id = view.getId();
+ int position = getAdapterPosition();
+ if (onItemClick != null) {
+ onItemClick.onClick(item, position, id);
+ }
+ }
+
+ }
+
+ }
+
+}
diff --git a/app/src/main/java/cn/leaqi/drawerapp/Demo3Activity.java b/app/src/main/java/cn/leaqi/drawerapp/Demo3Activity.java
new file mode 100644
index 0000000..f54c5d0
--- /dev/null
+++ b/app/src/main/java/cn/leaqi/drawerapp/Demo3Activity.java
@@ -0,0 +1,210 @@
+package cn.leaqi.drawerapp;
+
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.GridView;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+
+import cn.leaqi.drawerapp.Utils.Common;
+import cn.leaqi.drawerapp.Views.TopBar;
+import cn.leaqi.drawer.DrawerHolder;
+import cn.leaqi.drawer.SwipeDrawer;
+import cn.leaqi.drawer.OnDrawerState;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Demo3Activity extends Activity {
+
+ TopBar topBar = null;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_demo3);
+ topBar = new TopBar(this); // 头部操作类
+ topBar.setTitle("GridView"); // 头部标题
+ topBar.showLeftBack(); // 显示头部返回按钮
+ AppInit();
+ }
+
+ public void AppInit() {
+ final SwipeDrawer mainDrawer = findViewById(R.id.mainDrawer);
+ final View gesture = findViewById(R.id.gesture); // 方向引导布局
+ // 监听 SwipeDrawer 状态
+ mainDrawer.setOnDrawerState(new OnDrawerState() {
+ @Override
+ public void onStart(int type) { // 拖拽开始
+ Common.animHide(gesture, 200); // 隐藏方向引导
+ }
+ @Override
+ public void onMove(int type, float progress) { }
+ @Override
+ public void onOpen(int type) { }
+ @Override
+ public void onClose(int type) { // 关闭
+ Common.animShow(gesture, 200); // 显示方向引导
+ }
+ @Override
+ public void onCancel(int type) { // 取消操作
+ if (mainDrawer.getShow()) { // 判断是否打开
+ Common.animHide(gesture, 200); // 隐藏方向引导
+ } else {
+ Common.animShow(gesture, 200); // 显示方向引导
+ }
+ }
+ });
+ ListData();
+ }
+
+ /**
+ * 给 ListView 填充数据
+ */
+ private void ListData() {
+ final GridView mainList = findViewById(R.id.mainList);
+ final List listData = new ArrayList() {{
+ for (int i = 0; i < 50; i++) {
+ add("GridView : " + (i + 1));
+ }
+ }};
+ final ListAdapter listAdapter = new ListAdapter(this, R.layout.grid_item, listData);
+ // 绑定 item 点击事件
+ listAdapter.setOnItemClick(new OnItemClick() {
+ @Override
+ public void onClick(SwipeDrawer swipeDrawer, int position, int id) {
+ switch (id) {
+ case R.id.itemMain : // 点击了主布局
+ Common.showToast(listData.get(position));
+ break;
+ case R.id.itemDing : // 点击了 Left 置顶按钮
+ swipeDrawer.closeDrawer(false); // 非动画关闭当前 item
+ String getText = listData.get(position);
+ listData.remove(position); // 删除 item
+ listData.add(0, getText); // 添加到顶部
+ listAdapter.notifyDataSetChanged(); // 更新 list
+ break;
+ case R.id.itemDel : // 点击了 Right 删除按钮
+ swipeDrawer.closeDrawer(false); // 非动画关闭当前 item
+ listData.remove(position); // 删除 item
+ listAdapter.notifyDataSetChanged(); // 更新 list
+ break;
+ case R.id.itemClose : // 点击了 Right 关闭按钮
+ swipeDrawer.closeDrawer(true); // 关闭当前 item
+ break;
+ }
+ }
+ });
+ mainList.setAdapter(listAdapter);
+ final String autoText = "✔ 自动关闭";
+ final String shutText = "✘ 自动关闭";
+ // 自定义头部右边文本并设置点击事件
+ topBar.setRightText(shutText, new TopBar.OnTopClickListener() {
+ @Override
+ public void onClick(View view) {
+ String getText = ((TextView) view).getText().toString();
+ if (getText.equals(autoText)) {
+ topBar.setRightText(shutText); // 更新文本
+ listAdapter.setAutoClose(false); // 取消自动关闭
+ } else {
+ topBar.setRightText(autoText); // 更新文本
+ listAdapter.setAutoClose(true); // 设置自动关闭
+ }
+ }
+ });
+ }
+
+ private interface OnItemClick {
+ void onClick(SwipeDrawer swipeDrawer, int position, int id);
+ }
+
+ private class ListAdapter extends ArrayAdapter implements View.OnClickListener {
+ private int layout;
+ private LayoutInflater inflater;
+ private List list;
+ private OnItemClick onItemClick = null;
+ private boolean autoClose = false;
+
+ // 创建 DrawerHolder 对象,非自动关闭的情况保存 item 状态使用
+ private DrawerHolder drawerHolder = new DrawerHolder();
+
+ private ListAdapter(Context context, int resource, List objects) {
+ super(context, resource, objects);
+ layout = resource;
+ inflater = LayoutInflater.from(context);
+ list = objects;
+ }
+
+ private void setOnItemClick(OnItemClick click) {
+ onItemClick = click;
+ }
+
+ private void setAutoClose(boolean bool) {
+ autoClose = bool;
+ drawerHolder.clearHolder(); // 清除已保存状态并关闭所有已打开 item
+ notifyDataSetChanged(); // 更新 list
+ }
+
+ @Override
+ public void onClick(View view) {
+ int id = view.getId();
+ int position = (int) view.getTag();
+ SwipeDrawer swipeDrawer = SwipeDrawer.getParentDrawer(view);
+ if (swipeDrawer == null) return;
+ if (onItemClick != null) { // 点击事件回调
+ onItemClick.onClick(swipeDrawer, position, id);
+ }
+ }
+
+ @NonNull
+ public View getView(int position, View convertView, @NonNull ViewGroup parent) {
+ View view;
+ ViewHolder viewHolder;
+ if (convertView == null) {
+ view = inflater.inflate(layout, null);
+ viewHolder = new ViewHolder();
+ viewHolder.title = view.findViewById(R.id.item_title);
+ viewHolder.itemMain = view.findViewById(R.id.itemMain);
+ viewHolder.itemDing = view.findViewById(R.id.itemDing);
+ viewHolder.itemDel = view.findViewById(R.id.itemDel);
+ viewHolder.itemClose = view.findViewById(R.id.itemClose);
+ viewHolder.itemMain.setOnClickListener(this);
+ viewHolder.itemDing.setOnClickListener(this);
+ viewHolder.itemDel.setOnClickListener(this);
+ viewHolder.itemClose.setOnClickListener(this);
+ view.setTag(viewHolder);
+ } else {
+ view = convertView;
+ viewHolder = (ViewHolder) view.getTag();
+ }
+ SwipeDrawer swipeDrawer = ((SwipeDrawer) view);
+ swipeDrawer.setAutoClose(autoClose); // 设置是否自动关闭
+ viewHolder.itemMain.setTag(position);
+ viewHolder.itemDing.setTag(position);
+ viewHolder.itemDel.setTag(position);
+ viewHolder.itemClose.setTag(position);
+ viewHolder.title.setText(list.get(position));
+
+ // bindHolder 的第一个参数传递 item 的 SwipeDrawer 布局
+ // bindHolder 的第二个参数传递唯一对象
+ drawerHolder.bindHolder(swipeDrawer, list.get(position));
+ return view;
+ }
+
+ private class ViewHolder {
+ View itemMain;
+ View itemDing;
+ View itemDel;
+ View itemClose;
+ TextView title;
+ }
+ }
+
+}
diff --git a/app/src/main/java/cn/leaqi/drawerapp/Demo4Activity.java b/app/src/main/java/cn/leaqi/drawerapp/Demo4Activity.java
new file mode 100644
index 0000000..db64a6c
--- /dev/null
+++ b/app/src/main/java/cn/leaqi/drawerapp/Demo4Activity.java
@@ -0,0 +1,70 @@
+package cn.leaqi.drawerapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+
+import cn.leaqi.drawerapp.Utils.Common;
+import cn.leaqi.drawerapp.Views.TopBar;
+import cn.leaqi.drawer.SwipeDrawer;
+import cn.leaqi.drawer.OnDrawerState;
+
+public class Demo4Activity extends Activity {
+
+ TopBar topBar = null;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_demo4);
+ topBar = new TopBar(this); // 头部操作类
+ topBar.setTitle("ScrollView"); // 头部标题
+ topBar.showLeftBack(); // 显示头部返回按钮
+ AppInit();
+ }
+
+ public void AppInit() {
+ final SwipeDrawer mainDrawer = findViewById(R.id.mainDrawer);
+ final View gesture = findViewById(R.id.gesture); // 方向引导布局
+
+ // 设置头部右边图标并设置点击事件
+ topBar.showRight(R.mipmap.icon_menu, new TopBar.OnTopClickListener() {
+ @Override
+ public void onClick(View view) {
+ mainDrawer.toggleDrawer(SwipeDrawer.DIRECTION_RIGHT); // 点击打开或关闭Right方向
+ }
+ });
+
+ // 监听 SwipeDrawer 状态
+ mainDrawer.setOnDrawerState(new OnDrawerState() {
+ @Override
+ public void onStart(int type) { // 拖拽开始
+ Common.animHide(gesture, 200); // 隐藏方向引导
+ }
+ @Override
+ public void onMove(int type, float progress) { }
+ @Override
+ public void onOpen(int type) { // 打开
+ if (type == SwipeDrawer.DIRECTION_RIGHT) { // 打开了Right方向
+ topBar.setRightIcon(R.mipmap.icon_close); // 设置头部右边图标
+ }
+ }
+ @Override
+ public void onClose(int type) { // 关闭
+ Common.animShow(gesture, 200); // 显示方向引导
+ if (type == SwipeDrawer.DIRECTION_RIGHT) { // 关闭了Right方向
+ topBar.setRightIcon(R.mipmap.icon_menu); // 设置头部右边图标
+ }
+ }
+ @Override
+ public void onCancel(int type) { // 取消操作
+ if (mainDrawer.getShow()) { // 判断是否打开
+ Common.animHide(gesture, 200); // 隐藏方向引导
+ } else {
+ Common.animShow(gesture, 200); // 显示方向引导
+ }
+ }
+ });
+ }
+
+}
diff --git a/app/src/main/java/cn/leaqi/drawerapp/Demo5Activity.java b/app/src/main/java/cn/leaqi/drawerapp/Demo5Activity.java
new file mode 100644
index 0000000..bafd6cb
--- /dev/null
+++ b/app/src/main/java/cn/leaqi/drawerapp/Demo5Activity.java
@@ -0,0 +1,126 @@
+package cn.leaqi.drawerapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.viewpager.widget.PagerAdapter;
+import androidx.viewpager.widget.ViewPager;
+
+import com.google.android.material.bottomnavigation.BottomNavigationView;
+import cn.leaqi.drawerapp.Views.TopBar;
+import cn.leaqi.drawer.SwipeDrawer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Demo5Activity extends Activity {
+
+ TopBar topBar = null;
+ SwipeDrawer mainDrawer = null;
+ ViewPager mainView = null;
+ BottomNavigationView menuView = null;
+ List viewList = null;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_demo5);
+ topBar = new TopBar(this); // 头部操作类
+ topBar.setTitle("ViewPager"); // 头部标题
+ topBar.showLeftBack(); // 显示头部返回按钮
+ mainDrawer = findViewById(R.id.mainDrawer);
+ mainView = findViewById(R.id.mainView);
+ menuView = findViewById(R.id.menuView);
+ viewList = new ArrayList<>();
+ AppInit();
+ }
+
+ private void AppInit() {
+ showPage(0);
+
+ createPage(1);
+ createPage(2);
+ createPage(3);
+ createPage(4);
+
+ mainView.setAdapter(new ListPageAdapter(viewList));
+ // Page切换监听
+ mainView.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
+ @Override
+ public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { }
+ @Override
+ public void onPageSelected(int position) {
+ menuView.getMenu().getItem(position).setChecked(true); // 选中导航菜单
+ showPage(position); // 更新文本
+ }
+ @Override
+ public void onPageScrollStateChanged(int state) { }
+ });
+ // 导航菜单点击监听
+ menuView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
+ @Override
+ public boolean onNavigationItemSelected(@NonNull MenuItem item) {
+ if (mainDrawer.getShow()) { // 如果最外层 SwipeDrawer 是打开状态
+ mainDrawer.closeDrawer(); // 关闭
+ }
+ mainView.setCurrentItem(item.getOrder()); // Page切换
+ return true;
+ }
+ });
+ }
+
+ // 创建Page
+ private void createPage(int position) {
+ View page = LayoutInflater.from(this).inflate(R.layout.view_page, null);
+ TextView mainView = page.findViewById(R.id.Main);
+ TextView topView = page.findViewById(R.id.Top);
+ TextView bottomView = page.findViewById(R.id.Bottom);
+ mainView.setText(("ViewPager\n\nPage" + position));
+ topView.setText(("ViewPager\n\nPage" + position + " - Top"));
+ bottomView.setText(("ViewPager\n\nPage" + position + " - Bottom"));
+ viewList.add(page);
+ menuView.getMenu().add(0, position - 1, position - 1,"Page" + position).setIcon(R.drawable.menu_item);
+ }
+
+ // 更新头部文本
+ private void showPage(int position) {
+ topBar.setRightText("Page" + (position + 1));
+ }
+
+ private class ListPageAdapter extends PagerAdapter {
+ List list;
+
+ public ListPageAdapter(List l) {
+ list = l;
+ }
+
+ @Override
+ public int getCount() {
+ return list.size();
+ }
+
+ @Override
+ public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
+ return view == object;
+ }
+
+ @Override
+ public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
+ container.removeView(list.get(position));
+ }
+
+ @NonNull
+ @Override
+ public Object instantiateItem(@NonNull ViewGroup container, int position) {
+ container.addView(list.get(position));
+ return list.get(position);
+ }
+ }
+
+}
diff --git a/app/src/main/java/cn/leaqi/drawerapp/Demo6Activity.java b/app/src/main/java/cn/leaqi/drawerapp/Demo6Activity.java
new file mode 100644
index 0000000..d807e8d
--- /dev/null
+++ b/app/src/main/java/cn/leaqi/drawerapp/Demo6Activity.java
@@ -0,0 +1,20 @@
+package cn.leaqi.drawerapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+import cn.leaqi.drawerapp.Views.TopBar;
+
+public class Demo6Activity extends Activity {
+
+ TopBar topBar = null;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_demo6);
+ topBar = new TopBar(this); // 头部操作类
+ topBar.setTitle("多层嵌套"); // 头部标题
+ topBar.showLeftBack(); // 显示头部返回按钮
+ }
+}
diff --git a/app/src/main/java/cn/leaqi/drawerapp/Demo7Activity.java b/app/src/main/java/cn/leaqi/drawerapp/Demo7Activity.java
new file mode 100644
index 0000000..f5dfe24
--- /dev/null
+++ b/app/src/main/java/cn/leaqi/drawerapp/Demo7Activity.java
@@ -0,0 +1,86 @@
+package cn.leaqi.drawerapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.View;
+
+import cn.leaqi.drawerapp.Views.TopBar;
+import cn.leaqi.drawerapp.Views.UserInfo;
+import cn.leaqi.drawerapp.Views.UserMenu;
+import cn.leaqi.drawer.SwipeDrawer;
+import cn.leaqi.drawer.OnDrawerState;
+
+public class Demo7Activity extends Activity {
+
+ TopBar topBar = null;
+ SwipeDrawer rootDrawer = null;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_demo7);
+ rootDrawer = findViewById(R.id.rootDrawer);
+ topBar = new TopBar(this); // 头部操作类
+ topBar.setTitle("边缘拖拽"); // 头部标题
+ new UserMenu(this); // 左侧边栏用户菜单操作类
+ new UserInfo(this); // 右侧边栏用户菜单操作类
+ AppInit();
+ }
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ if (keyCode == KeyEvent.KEYCODE_BACK) { // 监听返回键
+ if (rootDrawer.getShow()) { // 如果是打开状态
+ rootDrawer.closeDrawer(); // 关闭
+ return true; // 拦截
+ }
+ }
+ return super.onKeyDown(keyCode, event);
+ }
+
+ // 设置头部左边图标并设置点击事件
+ private void AppInit() {
+ topBar.showLeft(R.mipmap.icon_menu, new TopBar.OnTopClickListener() {
+ @Override
+ public void onClick(View view) {
+ rootDrawer.toggleDrawer(SwipeDrawer.DIRECTION_LEFT); // 点击打开或关闭Left方向
+ }
+ });
+ // 设置头部右边图标并设置点击事件
+ topBar.showRight(R.mipmap.icon_menu, new TopBar.OnTopClickListener() {
+ @Override
+ public void onClick(View view) {
+ rootDrawer.toggleDrawer(SwipeDrawer.DIRECTION_RIGHT); // 点击打开或关闭Right方向
+ }
+ });
+
+ // 监听 SwipeDrawer 状态
+ rootDrawer.setOnDrawerState(new OnDrawerState() {
+ @Override
+ public void onStart(int type) { }
+ @Override
+ public void onMove(int type, float progress) { }
+ @Override
+ public void onOpen(int type) { // 打开
+ if (type == SwipeDrawer.DIRECTION_LEFT) { // 打开了Left方向
+ topBar.setLeftIcon(R.mipmap.icon_close); // 设置头部左边图标
+ }else if (type == SwipeDrawer.DIRECTION_RIGHT) { // 打开了Right方向
+ topBar.setRightIcon(R.mipmap.icon_close); // 设置头部右边图标
+ }
+ }
+ @Override
+ public void onClose(int type) { // 关闭
+ if (type == SwipeDrawer.DIRECTION_LEFT) { // 关闭了Left方向
+ topBar.setLeftIcon(R.mipmap.icon_menu); // 设置头部左边图标
+ }else if (type == SwipeDrawer.DIRECTION_RIGHT) { // 关闭了Right方向
+ topBar.setRightIcon(R.mipmap.icon_menu); // 设置头部右边图标
+ }
+ }
+ @Override
+ public void onCancel(int type) { }
+ });
+
+ }
+
+}
diff --git a/app/src/main/java/cn/leaqi/drawerapp/Demo8Activity.java b/app/src/main/java/cn/leaqi/drawerapp/Demo8Activity.java
new file mode 100644
index 0000000..4215b62
--- /dev/null
+++ b/app/src/main/java/cn/leaqi/drawerapp/Demo8Activity.java
@@ -0,0 +1,97 @@
+package cn.leaqi.drawerapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.GridView;
+import android.widget.SeekBar;
+
+import cn.leaqi.drawerapp.Utils.Common;
+import cn.leaqi.drawerapp.Views.TopBar;
+import cn.leaqi.drawer.SwipeDrawer;
+
+public class Demo8Activity extends Activity {
+ TopBar topBar = null;
+ SwipeDrawer rootDrawer = null;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_demo8);
+ rootDrawer = findViewById(R.id.rootDrawer);
+ topBar = new TopBar(this); // 头部操作类
+ topBar.setTitle("底部弹出"); // 头部标题
+ topBar.setRightText("滑动到底部或者点击➜"); // 显示头部右边文本
+ AppInit();
+ ListData();
+ }
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ if (keyCode == KeyEvent.KEYCODE_BACK) { // 监听返回键
+ if (rootDrawer.getShow()) { // 如果是打开状态
+ rootDrawer.closeDrawer(); // 关闭
+ return true; // 拦截
+ }
+ }
+ return super.onKeyDown(keyCode, event);
+ }
+
+ private void AppInit() {
+ final View bottomLayout = findViewById(R.id.bottomLayout);
+ final int bottomTop = bottomLayout.getPaddingTop(); // 获取顶部距离
+ final SeekBar seekBar = findViewById(R.id.seekBar);
+ final View close = findViewById(R.id.close); // 关闭按钮
+
+ // 设置头部右边图标并设置点击事件
+ topBar.showRight(R.mipmap.icon_menu, new TopBar.OnTopClickListener() {
+ @Override
+ public void onClick(View view) {
+ rootDrawer.toggleDrawer(SwipeDrawer.DIRECTION_BOTTOM); // 点击打开或关闭Bottom方向
+ }
+ });
+
+ seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
+ bottomLayout.setPadding(0, bottomTop + i,0 , 0); // 设置顶部距离
+ }
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) { }
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) { }
+ });
+
+ // 关闭按钮点击事件
+ close.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ if (rootDrawer.getShow()) {
+ rootDrawer.closeDrawer(); // 关闭
+ }
+ }
+ });
+ }
+
+ /**
+ * 给 GridView 填充数据
+ */
+ private void ListData() {
+ final GridView gridView = findViewById(R.id.gridView);
+ final String[] dataList = {"视频","问答","漫画","财经","娱乐","科技","国际","军事","直播","情感","租赁","装修","音乐","航空","股票","NBA","短视频","房产","数码","手机","游戏","历史","电影","星座","旅游","图片","教育","育儿","文学","明星","科普","综艺","天气","美容","服饰","影视","美食","健康","搞笑","体育","预约","养生","时尚","公益","汽车","文化","艺术","金融","网游","电竞","商业","中超"};
+ ArrayAdapter adapter = new ArrayAdapter<>(this, R.layout.btn_item, dataList);
+ gridView.setAdapter(adapter);
+
+ gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> adapterView, View view, int i, long l) {
+ Common.showToast(dataList[i]);
+ }
+ });
+
+ }
+
+}
diff --git a/app/src/main/java/cn/leaqi/drawerapp/Demo9Activity.java b/app/src/main/java/cn/leaqi/drawerapp/Demo9Activity.java
new file mode 100644
index 0000000..639b86f
--- /dev/null
+++ b/app/src/main/java/cn/leaqi/drawerapp/Demo9Activity.java
@@ -0,0 +1,133 @@
+package cn.leaqi.drawerapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.GridView;
+import android.widget.TextView;
+
+import cn.leaqi.drawerapp.Utils.Common;
+import cn.leaqi.drawerapp.Views.TopBar;
+import cn.leaqi.drawer.SwipeDrawer;
+import cn.leaqi.drawer.OnDrawerState;
+
+public class Demo9Activity extends Activity {
+ TopBar topBar = null;
+ SwipeDrawer rootDrawer = null;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_demo9);
+ rootDrawer = findViewById(R.id.rootDrawer);
+ topBar = new TopBar(this); // 头部操作类
+ topBar.setTitle("顶部弹出"); // 头部标题
+ AppInit();
+ ListData();
+ }
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ if (keyCode == KeyEvent.KEYCODE_BACK) { // 监听返回键
+ if (rootDrawer.getShow()) { // 如果是打开状态
+ rootDrawer.closeDrawer(); // 关闭
+ return true; // 拦截
+ }
+ }
+ return super.onKeyDown(keyCode, event);
+ }
+
+ private void AppInit() {
+ final View mask = findViewById(R.id.mask); // 自定义主布局遮罩
+ final View topMask = findViewById(R.id.topMask); // 自定义Top布局遮罩
+ final GridView gridView = findViewById(R.id.gridView); // Top布局GridView
+ final View topLayout = findViewById(R.id.topLayout);
+ topLayout.post(new Runnable() {
+ @Override
+ public void run() {
+ // 更新高度
+ ViewGroup.LayoutParams getLp = topLayout.getLayoutParams();
+ getLp.height = rootDrawer.getMeasuredHeight() - topBar.getHeight();
+ topLayout.setLayoutParams(getLp);
+ rootDrawer.requestLayout();
+ }
+ });
+
+ // 设置头部右边图标并设置点击事件
+ topBar.showRight(R.mipmap.icon_menu, new TopBar.OnTopClickListener() {
+ @Override
+ public void onClick(View view) {
+ rootDrawer.toggleDrawer(SwipeDrawer.DIRECTION_TOP); // 点击打开或关闭Top方向
+ }
+ });
+
+ // 监听 SwipeDrawer 状态
+ rootDrawer.setOnDrawerState(new OnDrawerState() {
+ private boolean radiusBar = false;
+ @Override
+ public void onStart(int type) { }
+ @Override
+ public void onMove(int type, float progress) { // 移动时
+ mask.setAlpha(progress); // 根据打开进度设置主布局遮罩透明度
+ topMask.setAlpha(1 - progress); // 根据打开进度设置Top布局遮罩透明度
+ gridView.setAlpha(progress); // 根据打开进度设置 GridView 透明度
+ // 根据打开进度设置 GridView 的缩放
+ gridView.setScaleX(progress);
+ gridView.setScaleY(progress);
+ // 根据打开进度设置头部透明度
+ topBar.setBarAlpha(rootDrawer.getShow() ? progress * 0.7f : 1 - progress);
+ // 处理头部圆角
+ if (!rootDrawer.getShow()) {
+ if (progress == 0) {
+ topBar.normalBar();
+ radiusBar = false;
+ } else {
+ if (!radiusBar) {
+ topBar.radiusBar();
+ radiusBar = true;
+ }
+ }
+ }
+ }
+ @Override
+ public void onOpen(int type) { // 打开
+ if (type == SwipeDrawer.DIRECTION_TOP) { // 打开了Top方向
+ topBar.setRightIcon(R.mipmap.icon_close); // 设置头部右边图标
+ topBar.radiusBar();
+ radiusBar = true;
+ }
+ }
+ @Override
+ public void onClose(int type) { // 关闭
+ if (type == SwipeDrawer.DIRECTION_TOP) { // 关闭了Top方向
+ topBar.setRightIcon(R.mipmap.icon_menu); // 设置头部右边图标
+ }
+ }
+ @Override
+ public void onCancel(int type) { }
+ });
+ }
+
+ /**
+ * 给 GridView 填充数据
+ */
+ private void ListData() {
+ final GridView gridView = findViewById(R.id.gridView);
+ final String[] dataList = {"视频","问答","漫画","财经","娱乐","科技","国际","军事","直播","情感","租赁","装修","音乐","航空","股票","NBA","短视频","房产","数码","手机","游戏","历史","电影","星座","旅游","图片","教育","育儿","文学","明星","科普","综艺","天气","美容","服饰","影视","美食","健康","搞笑","体育","预约","养生","时尚","公益","汽车","文化","艺术","金融","网游","电竞","商业","中超"};
+ ArrayAdapter adapter = new ArrayAdapter<>(this, R.layout.btn_item, dataList);
+ gridView.setAdapter(adapter);
+
+ gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> adapterView, View view, int i, long l) {
+ Common.showToast(dataList[i]);
+ }
+ });
+
+ }
+
+}
diff --git a/app/src/main/java/cn/leaqi/drawerapp/MainActivity.java b/app/src/main/java/cn/leaqi/drawerapp/MainActivity.java
new file mode 100644
index 0000000..bb1e23b
--- /dev/null
+++ b/app/src/main/java/cn/leaqi/drawerapp/MainActivity.java
@@ -0,0 +1,249 @@
+package cn.leaqi.drawerapp;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Color;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.GridView;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+
+import cn.leaqi.drawer.AnimThread;
+import cn.leaqi.drawerapp.Utils.Cache;
+import cn.leaqi.drawerapp.Utils.Common;
+import cn.leaqi.drawerapp.Views.TopBar;
+import cn.leaqi.drawerapp.Views.UserInfo;
+import cn.leaqi.drawerapp.Views.UserMenu;
+import cn.leaqi.drawer.SwipeDrawer;
+import cn.leaqi.drawer.OnDrawerState;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class MainActivity extends Activity {
+
+ TopBar topBar = null;
+ SwipeDrawer rootDrawer = null;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ topBar = new TopBar(this); // 头部操作类
+ rootDrawer = findViewById(R.id.rootDrawer);
+ new UserMenu(this); // 左侧边栏用户菜单操作类
+ new UserInfo(this); // 右侧边栏用户菜单操作类
+ AppInit();
+ ListData();
+ Cache.clearCache();
+ }
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ if (keyCode == KeyEvent.KEYCODE_BACK) { // 监听返回键
+ if (rootDrawer.getShow()) { // 如果是打开状态
+ rootDrawer.closeDrawer(); // 关闭
+ return true; // 拦截
+ }
+ }
+ return super.onKeyDown(keyCode, event);
+ }
+
+ public void AppInit() {
+ final View mask = findViewById(R.id.mask); // 自定义遮罩
+ final TextView modeDrawer = findViewById(R.id.modeDrawer); // 抽屉模式按钮
+ final TextView modeCover = findViewById(R.id.modeCover); // 覆盖模式按钮
+ final TextView modeFixed = findViewById(R.id.modeFixed); // 固定模式按钮
+
+ modeDrawer.setSelected(true); // 默认选中抽屉模式按钮
+ View.OnClickListener onClickListener = new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ int isSet = -1;
+ if (view == modeDrawer && rootDrawer.getMode() != SwipeDrawer.MODE_DRAWER) { // 被点击的是 抽屉模式按钮 且当前状态非抽屉模式
+ rootDrawer.setMode(SwipeDrawer.MODE_DRAWER); // 设置模式为抽屉模式
+ isSet = rootDrawer.getMode() == SwipeDrawer.MODE_DRAWER ? 1 : 0; // 判断是否设置成功
+ } else if (view == modeCover && rootDrawer.getMode() != SwipeDrawer.MODE_COVER) { // 被点击的是 覆盖模式按钮 且当前状态非覆盖模式
+ rootDrawer.setMode(SwipeDrawer.MODE_COVER); // 设置模式为覆盖模式
+ isSet = rootDrawer.getMode() == SwipeDrawer.MODE_COVER ? 1 : 0; // 判断是否设置成功
+ } else if (view == modeFixed && rootDrawer.getMode() != SwipeDrawer.MODE_FIXED) { // 被点击的是 固定模式按钮 且当前状态非固定模式
+ rootDrawer.setMode(SwipeDrawer.MODE_FIXED); // 设置模式为固定模式
+ isSet = rootDrawer.getMode() == SwipeDrawer.MODE_FIXED ? 1 : 0; // 判断是否设置成功
+ }
+ if (isSet == 1) { // 设置成功
+ // 更新选中按钮
+ modeFixed.setSelected(view == modeFixed);
+ modeCover.setSelected(view == modeCover);
+ modeDrawer.setSelected(view == modeDrawer);
+ Common.showToast("切换成功");
+ } else if (isSet == 0) {
+ Common.showToast("切换失败");
+ }
+ }
+ };
+ // 绑定按钮点击事件
+ modeDrawer.setOnClickListener(onClickListener);
+ modeCover.setOnClickListener(onClickListener);
+ modeFixed.setOnClickListener(onClickListener);
+
+ // 设置头部左边图标并设置点击事件
+ topBar.showLeft(R.mipmap.icon_menu, new TopBar.OnTopClickListener() {
+ @Override
+ public void onClick(View view) {
+ rootDrawer.toggleDrawer(SwipeDrawer.DIRECTION_LEFT); // 点击打开或关闭Left方向
+ }
+ });
+ // 设置头部右边图标并设置点击事件
+ topBar.showRight(R.mipmap.icon_menu, new TopBar.OnTopClickListener() {
+ @Override
+ public void onClick(View view) {
+ rootDrawer.toggleDrawer(SwipeDrawer.DIRECTION_RIGHT); // 点击打开或关闭Right方向
+ }
+ });
+
+ // 监听 SwipeDrawer 状态
+ rootDrawer.setOnDrawerState(new OnDrawerState() {
+ @Override
+ public void onStart(int type) { }
+ @Override
+ public void onMove(int type, float progress) {
+ mask.setAlpha(progress); // 根据打开进度设置遮罩透明度
+ if (rootDrawer.getMode() == SwipeDrawer.MODE_DRAWER && type == SwipeDrawer.DIRECTION_LEFT) { // 模式为 抽屉模式,且操作的是left方向
+ progress *= 0.15; // 给进度打个折
+ rootDrawer.setMainScale(1 - progress); // 根据打开进度缩放主布局
+ }
+ }
+ @Override
+ public void onOpen(int type) { // 打开
+ if (type == SwipeDrawer.DIRECTION_LEFT) { // 打开了Left方向
+ topBar.setLeftIcon(R.mipmap.icon_close); // 设置头部左边图标
+ }else if (type == SwipeDrawer.DIRECTION_RIGHT) { // 打开了Right方向
+ topBar.setRightIcon(R.mipmap.icon_close); // 设置头部右边图标
+ }
+ }
+ @Override
+ public void onClose(int type) { // 关闭
+ if (type == SwipeDrawer.DIRECTION_LEFT) { // 关闭了Left方向
+ topBar.setLeftIcon(R.mipmap.icon_menu); // 设置头部左边图标
+ }else if (type == SwipeDrawer.DIRECTION_RIGHT) { // 关闭了Right方向
+ topBar.setRightIcon(R.mipmap.icon_menu); // 设置头部右边图标
+ }
+ }
+ @Override
+ public void onCancel(int type) { }
+ });
+
+ }
+
+ /**
+ * 给 GridView 填充数据
+ */
+ private void ListData() {
+ final GridView mainList = findViewById(R.id.mainList);
+ final List listData = new ArrayList(){{
+ add(new BtnBean("ListView", "Demo1", "#3F51B5"));
+ add(new BtnBean("RecyclerView", "Demo2", "#059C8E"));
+ add(new BtnBean("GridView", "Demo3", "#A8BB00"));
+ add(new BtnBean("ScrollView", "Demo4", "#FF5722"));
+ add(new BtnBean("ViewPager", "Demo5", "#0DAC14"));
+ add(new BtnBean("多层嵌套", "Demo6", "#B328CA"));
+ add(new BtnBean("边缘拖拽", "Demo7", "#E91E63"));
+ add(new BtnBean("底部弹出", "Demo8", "#FF9800"));
+ add(new BtnBean("顶部弹出", "Demo9", "#4D12F7"));
+ add(new BtnBean("短视频布局", "Demo10", "#161722"));
+ add(new BtnBean("ListView 下拉刷新", "Demo11", "#23BB5B"));
+ add(new BtnBean("RecyclerView 下拉刷新", "Demo12", "#AE4DD1"));
+ add(new BtnBean("GridView 下拉刷新", "Demo13", "#447CCF"));
+ add(new BtnBean("ScrollView 下拉刷新", "Demo14", "#20B1AC"));
+ }};
+ final ListAdapter listAdapter = new ListAdapter(this, R.layout.list_btn, listData);
+ mainList.setAdapter(listAdapter);
+ }
+
+ private class BtnBean {
+ String text; // 显示文本
+ String link; // 打开链接
+ int color; // 背景颜色
+ BtnBean(String t, String l, String c) {
+ text = t;
+ link = l;
+ color = Color.parseColor(c);
+ }
+ }
+
+ private class ListAdapter extends ArrayAdapter implements View.OnClickListener {
+ private int layout;
+ private LayoutInflater inflater;
+ private List list;
+ private int TagString = R.attr.TagString;
+
+ private ListAdapter(Context context, int resource, List objects) {
+ super(context, resource, objects);
+ layout = resource;
+ inflater = LayoutInflater.from(context);
+ list = objects;
+ }
+
+ @Override
+ public void onClick(View view) {
+ String link = (String) view.getTag(TagString);
+ openActivity(link);
+ }
+
+ @NonNull
+ public View getView(int position, View convertView, @NonNull ViewGroup parent) {
+ View view;
+ ViewHolder viewHolder;
+ if (convertView == null) {
+ view = inflater.inflate(layout, null);
+ viewHolder = new ViewHolder();
+ viewHolder.btnLeft = view.findViewById(R.id.btnLeft);
+ viewHolder.btnRight = view.findViewById(R.id.btnRight);
+ viewHolder.btnTop = view.findViewById(R.id.btnTop);
+ viewHolder.btnBottom = view.findViewById(R.id.btnBottom);
+ viewHolder.btnText = view.findViewById(R.id.btnText);
+ view.setTag(viewHolder);
+ view.setOnClickListener(this);
+ } else {
+ view = convertView;
+ viewHolder = (ViewHolder) view.getTag();
+ }
+ BtnBean item = list.get(position);
+ viewHolder.btnLeft.setText(item.link);
+ viewHolder.btnRight.setText(item.link);
+ viewHolder.btnTop.setText(item.link);
+ viewHolder.btnBottom.setText(item.link);
+ viewHolder.btnText.setText(item.text);
+ viewHolder.btnText.setBackgroundColor(item.color);
+ view.setTag(TagString, item.link);
+ return view;
+ }
+
+ private class ViewHolder {
+ TextView btnLeft;
+ TextView btnRight;
+ TextView btnTop;
+ TextView btnBottom;
+ TextView btnText;
+ }
+ }
+
+ /**
+ * 打开 Activity
+ * @param link 链接
+ */
+ public void openActivity(String link) {
+ Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("drawer://leaqi.cn/" + link));
+ MainActivity.this.startActivity(intent);
+ }
+
+}
diff --git a/app/src/main/java/cn/leaqi/drawerapp/Utils/AppData.java b/app/src/main/java/cn/leaqi/drawerapp/Utils/AppData.java
new file mode 100644
index 0000000..aef54d3
--- /dev/null
+++ b/app/src/main/java/cn/leaqi/drawerapp/Utils/AppData.java
@@ -0,0 +1,19 @@
+package cn.leaqi.drawerapp.Utils;
+
+import android.app.Application;
+import android.content.Context;
+
+public class AppData extends Application {
+
+ private static Context context;
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ context = getApplicationContext();
+ }
+
+ public static Context getContext(){
+ return context;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/cn/leaqi/drawerapp/Utils/Cache.java b/app/src/main/java/cn/leaqi/drawerapp/Utils/Cache.java
new file mode 100644
index 0000000..f03f5cb
--- /dev/null
+++ b/app/src/main/java/cn/leaqi/drawerapp/Utils/Cache.java
@@ -0,0 +1,118 @@
+package cn.leaqi.drawerapp.Utils;
+
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.widget.ImageView;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.net.URLEncoder;
+
+public class Cache {
+
+ /**
+ * 清除缓存目录
+ */
+ public static void clearCache() {
+ try {
+ delFolder(new File(getCachePath()));
+ delFolder(AppData.getContext().getCacheDir());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 删除目录
+ * @param dir 路径
+ * @return 是否成功
+ */
+ private static boolean delFolder(File dir) {
+ boolean isOk = true;
+ try {
+ if (dir != null) {
+ if(dir.isDirectory()) {
+ String[] list = dir.list();
+ if (list != null) {
+ for (String item : list) {
+ if (!delFolder(new File(dir, item))) {
+ return false;
+ }
+ }
+ }
+ }
+ isOk = dir.delete();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return isOk;
+ }
+
+ /**
+ * 获取缓存路径
+ * @return 返回路径
+ */
+ public static String getCachePath(){
+ boolean isPath;
+ File setPath = new File(AppData.getContext().getFilesDir(), "data");
+ if (!setPath.exists()) {
+ isPath = setPath.mkdirs();
+ }else{
+ isPath = true;
+ }
+ return (isPath ? setPath : AppData.getContext().getCacheDir()).toString();
+ }
+
+ /**
+ * 获取缓存文件
+ * @param name 文件名
+ * @return 返回文件路径
+ */
+ public static File getCacheFile(String name){
+ try {
+ name = URLEncoder.encode(name, "UTF-8");
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return new File(getCachePath() + "/" + name + ".Q");
+ }
+
+ /**
+ * 创建文件
+ * @param file 文件路径
+ * @param bitmap 内容
+ * @return 是否成功
+ */
+ public static boolean fileWrite(File file, Bitmap bitmap){
+ try {
+ BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(file));
+ bitmap.compress(Bitmap.CompressFormat.JPEG, 80, stream);
+ stream.flush();
+ return file.exists();
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ /**
+ * 显示缓存图片
+ * @param img Image
+ * @param file 文件
+ */
+ public static boolean showImage(ImageView img, File file){
+ try {
+ if(file.exists()) {
+ img.setImageURI(Uri.fromFile(file));
+ return true;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+}
+
diff --git a/app/src/main/java/cn/leaqi/drawerapp/Utils/Common.java b/app/src/main/java/cn/leaqi/drawerapp/Utils/Common.java
new file mode 100644
index 0000000..123a8e0
--- /dev/null
+++ b/app/src/main/java/cn/leaqi/drawerapp/Utils/Common.java
@@ -0,0 +1,326 @@
+package cn.leaqi.drawerapp.Utils;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.net.Uri;
+import android.view.View;
+import android.view.animation.AlphaAnimation;
+import android.view.animation.Animation;
+import android.view.animation.AnimationSet;
+import android.view.animation.CycleInterpolator;
+import android.view.animation.LinearInterpolator;
+import android.view.animation.RotateAnimation;
+import android.view.animation.ScaleAnimation;
+import android.view.animation.TranslateAnimation;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.ImageView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Random;
+
+public class Common {
+
+ /**
+ * dp转px
+ * @param context 上下文
+ * @param dpValue dp
+ * @return px
+ */
+ public static int dipToPx(Context context, float dpValue) {
+ final float scale = context.getResources().getDisplayMetrics().density;
+ return (int) (dpValue * scale + 0.5f);
+ }
+
+ /**
+ * px转dp
+ * @param context 上下文
+ * @param pxValue px
+ * @return dp
+ */
+ public static int pxToDip(Context context, float pxValue) {
+ final float scale = context.getResources().getDisplayMetrics().density;
+ return (int) (pxValue / scale + 0.5f);
+ }
+
+ /**
+ * 设置随机背景颜色,随机值越低颜色越深
+ * @param view View
+ */
+ public static void setRndBg(View view){
+ Random random = new Random();
+ int color = Color.rgb(random.nextInt(180), random.nextInt(180), random.nextInt(180));
+ view.setBackgroundColor(color);
+ }
+
+ /**
+ * 设置随机文本颜色,随机值越低颜色越深
+ * @param view TextView
+ */
+ public static void setRndColor(TextView view){
+ Random random = new Random();
+ int color = Color.rgb(random.nextInt(180), random.nextInt(180), random.nextInt(180));
+ view.setTextColor(color);
+ }
+
+ /**
+ * 显示动画
+ * @param view View
+ * @param ms 动画毫秒
+ */
+ public static void animShow(View view, int ms){
+ if(view.getVisibility() == View.VISIBLE) return;
+ AlphaAnimation animation = new AlphaAnimation(0f, 1f);
+ animation.setDuration(ms);
+ view.clearAnimation();
+ view.startAnimation(animation);
+ view.setVisibility(View.VISIBLE);
+ }
+
+ /**
+ * 隐藏动画
+ * @param view View
+ * @param ms 动画毫秒
+ */
+ public static void animHide(View view, int ms){
+ if(view.getVisibility() == View.GONE) return;
+ AlphaAnimation animation = new AlphaAnimation(1f, 0f);
+ animation.setDuration(ms);
+ view.clearAnimation();
+ view.startAnimation(animation);
+ view.setVisibility(View.GONE);
+ }
+
+ /**
+ * 显示隐藏动画
+ * @param view View
+ * @param ms 动画毫秒
+ */
+ public static void scaleHide(final View view, final int ms){
+ ScaleAnimation scale = new ScaleAnimation(0.5f, 1f, 0.5f, 1f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
+ scale.setDuration(ms);
+ view.clearAnimation();
+ view.startAnimation(scale);
+ view.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ ScaleAnimation scale = new ScaleAnimation(1f, 0.5f, 1f, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
+ scale.setDuration(ms);
+ scale.setAnimationListener(new Animation.AnimationListener() {
+ @Override
+ public void onAnimationStart(Animation animation) {
+
+ }
+ @Override
+ public void onAnimationEnd(Animation animation) {
+ view.setVisibility(View.GONE);
+ }
+ @Override
+ public void onAnimationRepeat(Animation animation) {
+
+ }
+ });
+ view.clearAnimation();
+ view.startAnimation(scale);
+ }
+ },ms + 1500);
+ }
+
+ /**
+ * 设置旋转动画
+ * @param view View
+ * @param ms 动画毫秒
+ */
+ public static void animRotate(View view, int ms){
+ Animation animation = new RotateAnimation(
+ 0f, 360,
+ Animation.RELATIVE_TO_SELF, 0.5f,
+ Animation.RELATIVE_TO_SELF, 0.5f
+ );
+ animation.setInterpolator(new LinearInterpolator());
+ animation.setRepeatMode(Animation.RESTART);
+ animation.setDuration(ms);
+ animation.setRepeatCount(-1);
+ animation.setFillAfter(true);
+ view.clearAnimation();
+ view.startAnimation(animation);
+ }
+
+ /**
+ * 设置平移动画
+ * @param view View
+ * @param ms 动画毫秒
+ */
+ public static void animTranslate(View view, float fromX, float toX, float fromY, float toY, int ms){
+ Animation animation = new TranslateAnimation(
+ Animation.RELATIVE_TO_SELF, fromX,
+ Animation.RELATIVE_TO_SELF, toX,
+ Animation.RELATIVE_TO_SELF, fromY,
+ Animation.RELATIVE_TO_SELF, toY
+ );
+ animation.setInterpolator(new LinearInterpolator());
+ animation.setRepeatMode(Animation.RESTART);
+ animation.setDuration(ms);
+ animation.setRepeatCount(-1);
+ animation.setFillAfter(true);
+ view.clearAnimation();
+ view.startAnimation(animation);
+ }
+
+ /**
+ * 抖动动画
+ * @param view View
+ * @param to 偏移量
+ * @param cycles 次数
+ * @param ms 动画毫秒
+ */
+ public static void animShake(View view, float to, int cycles, int ms) {
+ RotateAnimation rotateAnim = new RotateAnimation(0, to, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
+ rotateAnim.setInterpolator(new CycleInterpolator(cycles));
+ rotateAnim.setRepeatCount(-1);
+ rotateAnim.setDuration(ms);
+ view.clearAnimation();
+ view.startAnimation(rotateAnim);
+ }
+
+ /**
+ * 动画
+ * @param view View
+ * @param ms 动画毫秒
+ */
+ public static void animScale(View view, int ms){
+ AnimationSet animSet = new AnimationSet(false);
+ ScaleAnimation scale = new ScaleAnimation(0f, 1f, 0f, 1f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
+ RotateAnimation rotate = new RotateAnimation(0f, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
+ AlphaAnimation alpha = new AlphaAnimation(0f, 1f);
+ animSet.addAnimation(scale);
+ animSet.addAnimation(rotate);
+ animSet.addAnimation(alpha);
+ animSet.setDuration(ms);
+ animSet.setFillAfter(true);
+ view.clearAnimation();
+ view.startAnimation(animSet);
+ }
+
+ /**
+ * 弹出Toast
+ * @param text 显示文本
+ */
+ public static void showToast(String text) {
+ Toast.makeText(AppData.getContext(), text, Toast.LENGTH_SHORT).show();
+ }
+
+ /**
+ * 模拟按键
+ * @param keyCode keyCode
+ */
+ public static void sendKeyCode(int keyCode) {
+ try {
+ String keyCommand = "input keyevent " + keyCode;
+ Runtime.getRuntime().exec(keyCommand);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 收起软键盘
+ * @param context 上下文
+ */
+ public static void hideInput(Context context) {
+ try {
+ InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
+ if (imm != null && imm.isActive()) {
+ imm.hideSoftInputFromWindow(((Activity) context).getWindow().getDecorView().getWindowToken(), 0);
+ }
+ }
+ catch (Exception e){
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 格式化数字
+ * @param num 数字
+ * @return w
+ */
+ public static String ParseNum(int num) {
+ try {
+ int setScale = 0;
+ float setNum = num;
+ String setExt = "";
+ if (setNum > 10000) {
+ setScale = 2;
+ setNum = setNum / 10000;
+ setExt = "w";
+ }
+ if (setScale > 0) {
+ BigDecimal bigDecimal = new BigDecimal(setNum);
+ return bigDecimal.setScale(setScale, BigDecimal.ROUND_HALF_UP).doubleValue() + setExt;
+ } else {
+ return String.valueOf(num);
+ }
+ }catch (Exception e){
+ return String.valueOf(num);
+ }
+ }
+
+ /**
+ * 加载网络图片并缓存
+ * @param img ImageView
+ * @param url 图片地址
+ */
+ public static void setHttpImage(final ImageView img, final String url) {
+ setHttpImage(img, url, -1);
+ }
+
+ /**
+ * 加载网络图片并缓存
+ * @param img ImageView
+ * @param url 图片地址
+ * @param resId // 默认图片
+ */
+ public static void setHttpImage(final ImageView img, final String url, final int resId) {
+ final File cacheFile = Cache.getCacheFile(url);
+ if (Cache.showImage(img, cacheFile)) return;
+ if (resId != -1) {
+ img.setImageResource(resId);
+ }
+ if (url.length() == 0) return;
+ new Thread(new Runnable(){
+ @Override
+ public void run() {
+ try {
+ URL imgUrl = new URL(url);
+ HttpURLConnection http = (HttpURLConnection) imgUrl.openConnection();
+ http.setDoInput(true);
+ http.connect();
+ InputStream stream = http.getInputStream();
+ final Bitmap bitmap = BitmapFactory.decodeStream(stream);
+ img.post(new Runnable() {
+ @Override
+ public void run() {
+ img.setImageBitmap(bitmap);
+ }
+ });
+ Cache.fileWrite(cacheFile, bitmap);
+ stream.close();
+ } catch (Exception e) {
+ //System.out.println("setHttpImage : " + url);
+ e.printStackTrace();
+ }
+ }
+ }).start();
+ }
+
+}
diff --git a/app/src/main/java/cn/leaqi/drawerapp/Utils/Config.java b/app/src/main/java/cn/leaqi/drawerapp/Utils/Config.java
new file mode 100644
index 0000000..7409e1e
--- /dev/null
+++ b/app/src/main/java/cn/leaqi/drawerapp/Utils/Config.java
@@ -0,0 +1,260 @@
+package cn.leaqi.drawerapp.Utils;
+
+import android.util.SparseArray;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+public class Config {
+
+ // 用户数据
+ public static SparseArray UserList = new SparseArray(){{
+ put(1, new UserBean(1, "微笑,向前行", "https://p.ssl.qhimg.com/t01f5b748f60e62c1b4.jpg" ,"https://p3.ssl.qhimgs1.com/dr/578_864_/t01e752a6a89da01e13.jpg" ,"湖北武汉大学" ,18 , 1,"要开学了,又有新生要来军训了,该准备西瓜了…"));
+ put(2, new UserBean(2, "奔雷拳", "https://p.ssl.qhimg.com/t01c1c5570e3dbb0425.jpg" ,"https://p0.ssl.qhimgs1.com/dr/578_384_/t01be93565b295f6f2a.jpg" ,"湖北武汉" ,20 , 1,"眼睛别乱看,看我就行,这么帅的大帅哥站在你们面前都不知道看,一帮子傻孩子!"));
+ put(3, new UserBean(3, "努力奔向目标", "https://p.ssl.qhimg.com/t01447ac7de787f8fba.jpg" ,"https://p3.ssl.qhimgs1.com/dr/578_384_/t0118d9c58168abac5d.jpg" ,"内蒙呼和浩特" , 2,30 ,"小心点啊同学们,我这个人轻易不出手,出手必伤人,伤人必见血,见血必死人!"));
+ put(4, new UserBean(4, "未来丶为我们而来", "https://p.ssl.qhimg.com/t01f3e5713b8d1df758.jpg" ,"https://p1.ssl.qhimgs1.com/dr/578_384_/t014581243af77e697b.jpg" ,"山西太原" , 2,36 ,"求晴天,求高温,求四十度求,暴晒求,没风,我们苦点没关系;一定要让高一的学弟学妹们,有个良好的军训环境。"));
+ put(5, new UserBean(5, "剑舞天涯", "https://p.ssl.qhimg.com/t010a3c59594ee46c1c.jpg" ,"https://p1.ssl.qhimgs1.com/dr/578_432_/t014353b3af6d1a9f87.jpg" ,"山西朔州" ,41 , 2,"站军姿时,某教官看到其他方阵有人晕倒,于是转过身对他方阵的人说:我们这儿的人不许倒下啊!倒下了我就当没看到,踩着他过去……众人无语。"));
+ put(6, new UserBean(6, "少女总统", "https://p.ssl.qhimg.com/t01c99f6e988f439ff2.jpg" ,"https://p5.ssl.qhimgs1.com/dr/578_670_/t01b223399f42c6b305.jpg" ,"广东深圳" ,22 , 2,"又有一大批“包青天”准备进入中学的大门。"));
+ put(7, new UserBean(7, "遇见就不再错过", "https://p.ssl.qhimg.com/t01b078a864fbdd6676.jpg" ,"https://p2.ssl.qhimgs1.com/dr/578_384_/t01115afe13160b8d28.jpg" ,"广东广州" ,23 , 2,"You have no idea how I’m feeling so shut up."));
+ put(8, new UserBean(8, "女人你给力吗", "https://p.ssl.qhimg.com/t015198455bf5f8b610.jpg" ,"https://p0.ssl.qhimgs1.com/dr/578_432_/t011e61455d215da766.jpg" ,"福建厦门" ,35 , 2,"你以为放手可以成全我的幸福,可你不知道我最大的幸福就是和你手牵手。"));
+ put(9, new UserBean(9, "一生都得酷", "https://p.ssl.qhimg.com/t01227f53f9ed7daea7.jpg" ,"https://p1.ssl.qhimgs1.com/dr/578_386_/t015189a3a4f35210fb.jpg" ,"福建福州" ,32 , 2,"青春如同奔流的江河,一点一滴的流淌着。"));
+ put(10, new UserBean(10, "我绝版了i", "https://p.ssl.qhimg.com/t01b9f72e02098beb90.jpg" ,"https://p2.ssl.qhimgs1.com/dr/578_774_/t015822699eef49a5cc.jpg" ,"北京朝阳" ,18 , 2,"个女人都是被种种牵绊舒服在滚滚红尘里,以哀伤的心,慢慢独到年华老去,终此一生。"));
+ put(11, new UserBean(11, "拿稳我心你称王", "https://p.ssl.qhimg.com/t01aca9887854891929.jpg" ,"https://p3.ssl.qhimgs1.com/dr/578_382_/t01f5e0987e89922aa9.jpg" ,"湖北襄阳" ,19 , 2,"I didn't stop loving you.I just decided not to show my love."));
+ put(12, new UserBean(12, "仗剑倚青天つ", "https://p.ssl.qhimg.com/t01fd7fe000944649c6.jpg" ,"https://p5.ssl.qhimgs1.com/dr/578_386_/t01b4f15741b4b7aa15.jpg" ,"湖北天门" ,22 , 2,"这个社会什么都可以是假的,但是,我唯一不能容忍的就是:钱的假的。"));
+ put(13, new UserBean(13, "一生酷到底━═", "https://p.ssl.qhimg.com/t01942c71ff242289d9.jpg" ,"https://p5.ssl.qhimgs1.com/dr/578_578_/t016177097bcba1bcd5.jpg" ,"湖北宜昌" ,23 , 1,"心总是在最痛时,复苏;爱总是在最深时,落下帷幕。"));
+ put(14, new UserBean(14, "宇宙第一帅胚", "https://p.ssl.qhimg.com/t01a797c1e165ea9f14.jpg" ,"https://p5.ssl.qhimgs1.com/dr/578_384_/t0169791ab581437fef.jpg" ,"湖南长沙" ,24 , 1,"挤公交是包含散打、瑜珈、柔道、平衡木等多种体育和健身项目于一体的综合性运动。"));
+ put(15, new UserBean(15, "帅飞一条街", "https://p.ssl.qhimg.com/t01ecc074986ad1a0ba.jpg" ,"https://p1.ssl.qhimgs1.com/dr/578_432_/t017cfb90896b2f775b.jpg" ,"湖南岳阳" ,26 , 1,"原来,很多时候,最让人疼痛的,是孤独。"));
+ put(16, new UserBean(16, "战神灵魂", "https://p.ssl.qhimg.com/t01a2f82c9aa97a63f4.jpg" ,"https://p0.ssl.qhimgs1.com/dr/578_384_/t01dedde1abb87fe64a.jpg" ,"武汉轻工大学" ,28 , 0,"女生应该骄傲的活着,而不是卑微的恋爱。"));
+ put(17, new UserBean(17, "从头酷到脚", "https://p.ssl.qhimg.com/t017d10751189aca021.jpg" ,"https://p3.ssl.qhimgs1.com/dr/578_384_/t01fb0e60ff70513e0d.jpg" ,"湖北工业大学" ,21 , 2,"I'll smile before all people look at you, performance."));
+ put(18, new UserBean(18, "傲视之巅", "https://p.ssl.qhimg.com/t0112a220bdb5fc5292.jpg" ,"https://p0.ssl.qhimgs1.com/dr/578_384_/t01d0160895cfa7e296.jpg" ,"湖北经济学院" ,31 , 0,"回忆千丝万缕,思念缱倦流年,昨日种种,红叶黄花,一恍如烟霞。"));
+ put(19, new UserBean(19, "馭電追風雨", "https://p.ssl.qhimg.com/t0197152db76690b5a9.jpg" ,"https://p3.ssl.qhimgs1.com/dr/578_384_/t014749d906dcd5fad3.jpg" ,"上海交通大学" ,32 , 2,"喝白开水的人,不一定很纯。"));
+ put(20, new UserBean(20, "酷到失控", "https://p.ssl.qhimg.com/t01f1c6faf2bebc07d2.jpg" ,"https://p0.ssl.qhimgs1.com/dr/578_384_/t018a8aab5a54da7fb4.jpg" ,"中国科学技术大学" ,55 , 0,"感情是没有公式,没有原则没有道理可循的,可是人们至死都还在执著与追求。"));
+ put(21, new UserBean(21, "┌;饕餮噬天", "https://p.ssl.qhimg.com/t01020f0617455b8995.jpg" ,"https://p3.ssl.qhimgs1.com/dr/578_384_/t01a617f89cbc438eb9.jpg" ,"哈尔滨工业大学" ,54 , 1,"Love makes you hold on to things you wouldn’t have been able to."));
+ put(22, new UserBean(22, "一秒メ速杀", "https://p.ssl.qhimg.com/t012d3983a0169afa90.jpg" ,"https://p0.ssl.qhimgs1.com/dr/578_868_/t0185dead6ea9dfd14e.jpg" ,"北京航空航天大学" ,46 , 0,"擦干眼泪,抬起头,莪依然拥有最坚强的笑容。"));
+ put(23, new UserBean(23, "哥丶曾用C车称霸", "https://p.ssl.qhimg.com/t019928cb519504a8c5.jpg" ,"https://p5.ssl.qhimgs1.com/dr/578_864_/t01a881b34f659f4315.jpg" ,"河南信阳" ,37 , 2,"夏天就是不好,穷的时候我连西北风都没有喝。"));
+ put(24, new UserBean(24, "去爱去疯去执着", "https://p.ssl.qhimg.com/t01a3225285cda30314.jpg" ,"https://p5.ssl.qhimgs1.com/dr/578_432_/t018c9d28095cb10e85.jpg" ,"河南漯河" ,45 , 0,"所有的失敗,與失去自己的失敗比起來,更是微不足道。"));
+ put(25, new UserBean(25, "酒神", "https://p.ssl.qhimg.com/t01666b511f61006aa2.jpg" ,"https://p0.ssl.qhimgs1.com/dr/578_770_/t016b28f08d3007d974.jpg" ,"广西桂林" ,66 , 0,"她的忧伤,只为一些在颓废中荒废的年华。"));
+ put(26, new UserBean(26, "哥↖超神了", "https://p.ssl.qhimg.com/t0168cd944ae26436ed.jpg" ,"https://p5.ssl.qhimgs1.com/dr/578_384_/t01d5c1d61d72247ff5.jpg" ,"广西阳朔" ,43 , 0,"有些人永远不会被遗忘,有些人永远只是代替品。"));
+ put(27, new UserBean(27, "嗜血飞龙", "https://p.ssl.qhimg.com/t01be3b242d22d34c6e.jpg" ,"https://p2.ssl.qhimgs1.com/dr/578_384_/t0180dbeb7b2d466dec.jpg" ,"贵州贵阳" ,22 , 2,"爱情也许会随着季节的变迁而褪去,但友谊会为你全年守侯。"));
+ put(28, new UserBean(28, "霹雳无敌", "https://p.ssl.qhimg.com/t010e57ddd763c3e814.jpg" ,"https://p1.ssl.qhimgs1.com/dr/578_374_/t0180efa16d4d1cba57.jpg" ,"四川成都" ,28 , 0,"感情是没有公式,没有原则没有道理可循的,可是人们至死都还在执著与追求。"));
+ put(29, new UserBean(29, "独撑全场", "https://p.ssl.qhimg.com/t016b0e3d5920ce25f1.jpg" ,"https://p0.ssl.qhimgs1.com/dr/578_384_/t011b5790b23c936276.jpg" ,"浙江杭州" ,33 , 2,"怎样的一个冬天,我看见烟火幸福满天。又怎样的一个冬天,冷得让我泪流满面。"));
+ put(30, new UserBean(30, "不朽神王", "https://p.ssl.qhimg.com/t017081c67288d79538.jpg" ,"https://p2.ssl.qhimgs1.com/dr/578_384_/t01e552cd0ad2e87e52.jpg" ,"安徽合肥" ,26 , 0,"我这人不懂音乐,所以时而不靠谱,时而不着调。"));
+ }};
+
+ // 视频数据
+ public static SparseArray VideoList = new SparseArray(){{
+ put(1, new VideoBean(1, "https://p26.douyinpic.com/tos-cn-p-0015/52a44cd0f20f4e47a02fc024b352abd0_1622205519~tplv-dy-360p.jpeg", "超级鸡马体验超高难度地狱模式,大黄崩溃了", "https://aweme.snssdk.com/aweme/v1/play/?video_id=v0300fg10000c2oe863c77u6arm00r8g&ratio=720p&line=0"));
+ put(2, new VideoBean(2, "https://p3.douyinpic.com/tos-cn-p-0015/f21cca9009db49fa8673231708170553_1622116507~tplv-dy-360p.jpeg", "超级鸡马基友互坑时刻,失去信心的大黄", "https://aweme.snssdk.com/aweme/v1/play/?video_id=v0200fg10000c2noh33c77u7rldvc80g&ratio=720p&line=0"));
+ put(3, new VideoBean(3, "https://p3.douyinpic.com/tos-cn-p-0015/c0cb9f67fb7943a597324859f3c6a247_1622992747~tplv-dy-360p.jpeg", "迷你世界无限套娃合西瓜,伙伴捣乱抢生意,那我走?", "https://aweme.snssdk.com/aweme/v1/play/?video_id=v0300fg10000c2ueejbc77u55imc2kh0&ratio=720p&line=0"));
+ put(4, new VideoBean(4, "https://p9.douyinpic.com/tos-cn-p-0015/d35df6920e304e1d89bc2da2a8542a63_1622992741~tplv-dy-360p.jpeg", "荒野求生出发雪山城堡,媳妇公主现身,名副其实三剑客", "https://aweme.snssdk.com/aweme/v1/play/?video_id=v0300fg10000c2ueefjc77u7pgi7d2l0&ratio=720p&line=0"));
+ put(5, new VideoBean(5, "https://p26.douyinpic.com/tos-cn-p-0015/8b44de38f0af413cad0309407d9bbb5a_1622910908~tplv-dy-360p.jpeg", "只只大冒险勇闯冰雪天敌,让我们荡起双桨,多米差点被红烧", "https://aweme.snssdk.com/aweme/v1/play/?video_id=v0300fg10000c2tqfcbc77u7pghl11f0&ratio=720p&line=0"));
+ put(6, new VideoBean(6, "https://p3.douyinpic.com/tos-cn-p-0015/d8b27728ee7c4307a0da0e5375cb6847_1622802859~tplv-dy-360p.jpeg", "迷你世界生存到极致就像开挂狼堡大升级!火柴盒秒变大别墅", "https://aweme.snssdk.com/aweme/v1/play/?video_id=v0300fg10000c2t037bc77u99amfcrcg&ratio=720p&line=0"));
+ put(7, new VideoBean(7, "https://p9.douyinpic.com/tos-cn-p-0015/f5ffbfac5855435db282a48c21ad86ef_1622802766~tplv-dy-360p.jpeg", "迷你世界流沙来了快建房,建造基岩房,善心大发搭救伙伴?", "https://aweme.snssdk.com/aweme/v1/play/?video_id=v0200fg10000c2t02frc77ue9k8it51g&ratio=720p&line=0"));
+ put(8, new VideoBean(8, "https://p26.douyinpic.com/tos-cn-p-0015/bc3b441d79634ed2be97bee37cccf0c5_1622740457~tplv-dy-360p.jpeg", "方舟生存进化神奇宝贝61水晶洞穴对抗死亡蠕虫,寻获团结神器", "https://aweme.snssdk.com/aweme/v1/play/?video_id=v0300fg10000c2sgro3c77u6ark8buf0&ratio=720p&line=0"));
+ put(9, new VideoBean(9, "https://p11.douyinpic.com/tos-cn-p-0015/b4af2f96eba441cda73390c395c11a9e_1610528747~tplv-dy-360p.jpeg", "2021年值得入住的民宿,有生之年一定要去“睡”一次!", "https://aweme.snssdk.com/aweme/v1/play/?video_id=v0300fbd0000bvvbf74f27p33ot7scog&ratio=720p&line=0"));
+ put(10, new VideoBean(10, "https://p26.douyinpic.com/tos-cn-p-0015/5c135e0e11b24fb0a68753f3d687dea9_1597227392~tplv-dy-360p.jpeg", "国内最美的热气球景点,你们去过吗?", "https://aweme.snssdk.com/aweme/v1/play/?video_id=v0200ffa0000bsps2f19dds8ickgdepg&ratio=720p&line=0"));
+ put(11, new VideoBean(11, "https://p26.douyinpic.com/tos-cn-p-0015/c21f7fd21d64487da8aa42dce6a03a7f_1597137139~tplv-dy-360p.jpeg", "每个月最适合旅行你过的地方?你真的去对啦吗!", "https://aweme.snssdk.com/aweme/v1/play/?video_id=v0200f710000bsp60uhultt2lbn69dm0&ratio=720p&line=0"));
+ put(12, new VideoBean(12, "https://p3.douyinpic.com/tos-cn-p-0015/321d3fe11da14debaa027f06be10c23c_1596453366~tplv-dy-360p.jpeg", "没有去过香格里拉,怎知世界的纯净,云南最值得打卡的地方!", "https://aweme.snssdk.com/aweme/v1/play/?video_id=v0200f540000bsjv3pn66jan1d2adivg&ratio=720p&line=0"));
+ put(13, new VideoBean(13, "https://p11.douyinpic.com/tos-cn-p-0015/422abdf7c362450c8f7c9cb1e960d296_1602583642~tplv-dy-360p.jpeg", "西双版纳4天3晚游才人均不到一千?这份攻略你可要收好了!", "https://aweme.snssdk.com/aweme/v1/play/?video_id=v0300f050000bu2nku3ircaev3kmjkbg&ratio=720p&line=0"));
+ put(14, new VideoBean(14, "https://p5-ipv6.douyinpic.com/tos-cn-p-0015/be19f7ffbb484918bc887eeabc998884_1610510314~tplv-dy-360p.jpeg", "有种冰雪童话,叫冬天的哈尔滨!", "https://aweme.snssdk.com/aweme/v1/play/?video_id=v0300fe90000bvv6pvnbjpufrvum2u00&ratio=720p&line=0"));
+ put(15, new VideoBean(15, "https://p5-ipv6.douyinpic.com/tos-cn-p-0015/1a99e8fd03bc460caf84aa907114fb1b_1621522703~tplv-dy-360p.jpeg", "iPad Pro 2021款12.9英寸黑白颜色对比。", "https://aweme.snssdk.com/aweme/v1/play/?video_id=v0300fg10000c2j7h4l0296d5d3stmeg&ratio=720p&line=0"));
+ put(16, new VideoBean(16, "https://p3.douyinpic.com/tos-cn-p-0015/1ef8c86241794397bab1dc2636829f28_1610682052~tplv-dy-360p.jpeg", "想要主动降噪与好音质,2021年适合iPhone的真无线蓝牙耳机怎么选?", "https://aweme.snssdk.com/aweme/v1/play/?video_id=v0300f620000c00grqvh77phu82ph2vg&ratio=720p&line=0"));
+ put(17, new VideoBean(17, "https://p9.douyinpic.com/tos-cn-p-0015/6947ee2833d64c759781347bb9493b51_1621682660~tplv-dy-360p.jpeg", "首个进入太空的生物,为什么要选择一只流浪狗呢?", "https://aweme.snssdk.com/aweme/v1/play/?video_id=v0d00fg10000c2kejkjfgt7pa5plj1v0&ratio=720p&line=0"));
+ put(18, new VideoBean(18, "https://p29.douyinpic.com/tos-cn-p-0015/b9f343aca10d42a3b3f2812d844975e6_1621508159~tplv-dy-360p.jpeg", "同样是鲤鱼,为什么黄河鲤鱼更贵呢?", "https://aweme.snssdk.com/aweme/v1/play/?video_id=v0d00fg10000c2j40anc4lr2q92q4khg&ratio=720p&line=0"));
+ put(19, new VideoBean(19, "https://p9.douyinpic.com/tos-cn-p-0015/88478c2b62ef4a9698646c1498db03ce_1621338097~tplv-dy-360p.jpeg", "肉被切开后,为什么表面会跳动呢?", "https://aweme.snssdk.com/aweme/v1/play/?video_id=v0300fg10000c2hqfo56j906d0kh5mtg&ratio=720p&line=0"));
+ put(20, new VideoBean(20, "https://p3.douyinpic.com/tos-cn-p-0015/282e28eca8764b1ca63f2d047d83c0bf_1620819728~tplv-dy-360p.jpeg", "为什么椰子里面会有水呢?", "https://aweme.snssdk.com/aweme/v1/play/?video_id=v0d00fg10000c2drtt8gk4jgd7f6iv70&ratio=720p&line=0"));
+ put(21, new VideoBean(21, "https://p3.douyinpic.com/tos-cn-p-0015/a3b08e5aafba4fb68dec2787c3106d66_1620644241~tplv-dy-360p.jpeg", "为什么工人要往水泥里加白糖呢?", "https://aweme.snssdk.com/aweme/v1/play/?video_id=v0300fg10000c2ch2offq9lkha32kbhg&ratio=720p&line=0"));
+ put(22, new VideoBean(22, "https://p3.douyinpic.com/tos-cn-p-0015/27c47da4df52490c8cb7a88e87e3c1a1_1621074960~tplv-dy-360p.jpeg", "科学家为什么不敢把火星土壤带回地球呢?", "https://aweme.snssdk.com/aweme/v1/play/?video_id=v0300fg10000c2fq7akpeg7h5b65tt7g&ratio=720p&line=0"));
+ put(23, new VideoBean(23, "https://p9.douyinpic.com/tos-cn-p-0015/d0fa69ee574a484890c21a9319d17945_1621335837~tplv-dy-360p.jpeg", "有气囊的鼻托你见过吗?", "https://aweme.snssdk.com/aweme/v1/play/?video_id=v0d00fg10000c2hpt2pd3u0ebthcfs00&ratio=720p&line=0"));
+ put(24, new VideoBean(24, "https://p3.douyinpic.com/tos-cn-p-0015/feb6883763e14f70a0c1fd72db8bb0a1_1578713534~tplv-dy-360p.jpeg", "我做的红酒雪梨,每次上桌不到1分钟就被抢光,思虑再三,决定把方法发出来,希望学会的能给我个❤️", "https://aweme.snssdk.com/aweme/v1/play/?video_id=v0200f3b0000bock3dfff77e7cs0sg20&ratio=720p&line=0"));
+ put(25, new VideoBean(25, "https://p9.douyinpic.com/tos-cn-p-0015/ebe5f77db8ec4be2a543d0a4930940cc_1619255418~tplv-dy-360p.jpeg", "的新吃法!真的太好吃了!全麦欧包更适合做主食哦!", "https://aweme.snssdk.com/aweme/v1/play/?video_id=v0d00fg10000c21u0m6e1f8bno2t4g0g&ratio=720p&line=0"));
+ put(26, new VideoBean(26, "https://p26.douyinpic.com/tos-cn-p-0015/4194debff77a46809f820df7aa576945_1618909651~tplv-dy-360p.jpeg", "月旨期放心吃,吃肉肉掉肉肉", "https://aweme.snssdk.com/aweme/v1/play/?video_id=v0300fg10000c1v9jih8v0llc8ll1nl0&ratio=720p&line=0"));
+ put(27, new VideoBean(27, "https://p5-ipv6.douyinpic.com/tos-cn-p-0015/5af33941f597475e9384484699b5384c_1618734474~tplv-dy-360p.jpeg", "用茶代替水做出来的红烧肉,肥而不腻,隔壁老王都说好吃!", "https://aweme.snssdk.com/aweme/v1/play/?video_id=v0300fg10000c1tuqn7764jl2usnm9vg&ratio=720p&line=0"));
+ put(28, new VideoBean(28, "https://p5-ipv6.douyinpic.com/29b0a000063e8b0c4b4b5~tplv-dy-360p.jpeg", "塞尔达传说来到王城遗址,塞尔达公主为我举行授勋仪式", "https://aweme.snssdk.com/aweme/v1/play/?video_id=v0300f2a0000bkg294tj482rnh8bi410&ratio=720p&line=0"));
+ put(29, new VideoBean(29, "https://p26.douyinpic.com/29428000b866180a60e1c~tplv-dy-360p.jpeg", "塞尔达传说用火把点燃哈特诺之塔,我得到了四大部落的位置", "https://aweme.snssdk.com/aweme/v1/play/?video_id=v0300f880000bke1osdmuq8m6dopcfg0&ratio=720p&line=0"));
+ put(30, new VideoBean(30, "https://p3.douyinpic.com/27451000a879e0cd3b3d3~tplv-dy-360p.jpeg", "翼龙历险记打败会喷火的龙皇后,5只小翼龙宝宝出生了", "https://aweme.snssdk.com/aweme/v1/play/?video_id=v0300fb70000bk1gdqmt2ulrrokagfg0&ratio=720p&line=0"));
+ }};
+
+ // 音乐数据
+ public static SparseArray MusicList = new SparseArray(){{
+ put(1, new MusicBean(1,"https://p26.douyinpic.com/aweme/200x200/tos-cn-v-2774c002/258d5c278eb0418ea2ea362c21403e27.jpeg", "孤勇者 - 陈奕迅"));
+ put(2, new MusicBean(2,"https://p26.douyinpic.com/aweme/200x200/tos-cn-v-2774c002/78085574025c4d3cb66009647c379492.jpeg", "Shadow of the Sun - Max Elto"));
+ put(3, new MusicBean(3,"https://p6.douyinpic.com/aweme/200x200/tos-cn-v-2774c002/756143d75cb04a6e8d280538d9fcbe73.jpeg", "守护着我的光 - 李巍V仔"));
+ put(4, new MusicBean(4,"https://p9.douyinpic.com/aweme/200x200/tos-cn-v-2774c002/b7528a0aa0164f2aadfe332b2e54ca76.jpeg", "WAVE(Prod by 张杰峻) - 花欲燃"));
+ put(5, new MusicBean(5,"https://p26.douyinpic.com/aweme/200x200/tos-cn-v-2774c002/5614d4be2fe5475faebad7865050df83.jpeg", "陪你度过漫长岁月 - 张钰琪"));
+ put(6, new MusicBean(6,"https://p11.douyinpic.com/aweme/200x200/tos-cn-v-2774c002/cbac750dc48b4e8e8f9a88ce8813e49e.jpeg", "哪里都是你(DJR7版) - DJR7"));
+ put(7, new MusicBean(7,"https://p6.douyinpic.com/aweme/200x200/tos-cn-v-2774c002/6267a87bdc7044949f59eeb624600606.jpeg", "It's a Beautiful Day - Evan McHugh"));
+ put(8, new MusicBean(8,"https://p9.douyinpic.com/aweme/200x200/tos-cn-v-2774c002/d67d7f6ff98644b58718a6757147b4af.jpeg", "人世间(电视剧《人世间》主题曲) - 雷佳"));
+ put(9, new MusicBean(9,"https://p6.douyinpic.com/aweme/200x200/tos-cn-v-2774c002/08d50473149248ec9d29419e88fe9fc0.jpeg", "爱丫爱丫 - By2"));
+ put(10, new MusicBean(10,"https://p26.douyinpic.com/aweme/200x200/tos-cn-v-2774c002/2757047296424a679cca6c017ec1eba0.jpeg", "在草地上肆意奔跑(片段) - 傅如乔"));
+ put(11, new MusicBean(11,"https://p26.douyinpic.com/aweme/200x200/tos-cn-v-2774c002/23960b32a6b149e3b336b4ecd433246f.jpeg", "落在生命里的光 - 尹昔眠"));
+ put(12, new MusicBean(12,"https://p6.douyinpic.com/aweme/200x200/tos-cn-v-2774c002/869bd0664feb47e8aa256d090a06d8b6.jpeg", "渐暖片段1 - 时代少年团"));
+ put(13, new MusicBean(13,"https://p26.douyinpic.com/aweme/200x200/tos-cn-v-2774c002/c44420cfb0d64f6b9516a0b9c41bd49a.jpeg", "行于水 (剪辑版) - 万妮达Vinida Weng"));
+ put(14, new MusicBean(14,"https://p3.douyinpic.com/aweme/200x200/tos-cn-v-2774c002/70d2e6e3921b42f68265dcd02ecc0b3d.jpeg", "裹着心的光 30s - 林俊杰"));
+ put(15, new MusicBean(15,"https://p9.douyinpic.com/aweme/200x200/tos-cn-v-2774c002/3d3cb370ddb24e95b54ab9bd58c40872.jpeg", "Something Just Like This - Bely Basarte"));
+ put(16, new MusicBean(16,"https://p3.douyinpic.com/aweme/200x200/tos-cn-v-2774c002/984c581341be494ab12e9195d8b9dd60.jpeg", "张碧晨《光的方向》(剪辑版) - 张碧晨"));
+ put(17, new MusicBean(17,"https://p11.douyinpic.com/aweme/200x200/tos-cn-v-2774c002/77790e0f66f64fb88934bf022f34c1dc.jpeg", "致00后的预防针 - 王以诺"));
+ put(18, new MusicBean(18,"https://p3.douyinpic.com/aweme/200x200/tos-cn-v-2774c002/7677e49b6a734b3bb2db8cc357351f5c.jpeg", "雪龙吟(剪辑版) - 张杰"));
+ put(19, new MusicBean(19,"https://p3.douyinpic.com/aweme/200x200/tos-cn-v-2774c002/b4c665dbf7234ebfa59e1cec6a5d9dbc.jpeg", "我们的爱 - 曹雨航"));
+ put(20, new MusicBean(20,"https://p9.douyinpic.com/aweme/200x200/tos-cn-v-2774c002/c8db6cd7a66b402f854bb547b757def0.jpeg", "老茧-剪辑版 - 简弘亦"));
+ put(21, new MusicBean(21,"https://p6.douyinpic.com/aweme/200x200/tos-cn-v-2774c002/cf8b3f3801924f049da1db34286572aa.jpeg", "Beautiful - INTO1-米卡"));
+ put(22, new MusicBean(22,"https://p3.douyinpic.com/aweme/200x200/tos-cn-v-2774c002/1cc8823cd51e4ee4b06b5ec65616afeb.jpeg", "天若有情 ((电视剧「锦绣未央」主题曲) - A-Lin"));
+ put(23, new MusicBean(23,"https://p3.douyinpic.com/aweme/200x200/tos-cn-v-2774c002/cd7d189e43cb4c59ac081a60571220ec.jpeg", "DO WHATEVER想做就做(剪辑版) - 卡西恩Cacien"));
+ put(24, new MusicBean(24,"https://p26.douyinpic.com/aweme/200x200/tos-cn-v-2774c002/62756bbdce8d46c9be06cac90813425e.jpeg", "平凡的一天 - 毛不易"));
+ put(25, new MusicBean(25,"https://p9.douyinpic.com/aweme/200x200/tos-cn-v-2774c002/cd0510692553442b80ca8006d6f326cd.jpeg", "我们啊(男版)片段2 - 三块木头"));
+ put(26, new MusicBean(26,"https://p26.douyinpic.com/aweme/200x200/tos-cn-v-2774c002/02011d6377e64bfcb35820795c6560cf.jpeg", "剑魂_鱼多余完整版已上线 - 鱼多余"));
+ put(27, new MusicBean(27,"https://p3.douyinpic.com/aweme/200x200/tos-cn-v-2774c002/c5dfad8371c54cd69986c9dc7a4bb325.jpeg", "最好的都给你(剪辑版) - 余佳运"));
+ put(28, new MusicBean(28,"https://p11.douyinpic.com/aweme/200x200/tos-cn-v-2774c002/1f5f7b1b48f0427fab2d28cfe9e3c009.jpeg", "微风吹(剪辑版) - 李润祺"));
+ put(29, new MusicBean(29,"https://p3.douyinpic.com/aweme/200x200/tos-cn-v-2774c002/5064ec1dc0d845419fea14ce792bed70.jpeg", "Celebrity - IU"));
+ put(30, new MusicBean(30,"https://p3.douyinpic.com/aweme/200x200/tos-cn-v-2774c002/23960b32a6b149e3b336b4ecd433246f.jpeg", "落在生命里的光 - 尹昔眠"));
+ }};
+
+ // 评论数据
+ public static SparseArray CommentList = new SparseArray(){{
+ put(1, new CommentBean(1, UserList.get(1), "超级鸡马体验超高难度地狱模式,大黄崩溃了"));
+ put(2, new CommentBean(2, UserList.get(2), "超级鸡马基友互坑时刻,失去信心的大黄"));
+ put(3, new CommentBean(3, UserList.get(3), "迷你世界无限套娃合西瓜,伙伴捣乱抢生意,那我走?"));
+ put(4, new CommentBean(4, UserList.get(4), "荒野求生出发雪山城堡,媳妇公主现身,名副其实三剑客"));
+ put(5, new CommentBean(5, UserList.get(5), "只只大冒险勇闯冰雪天敌,让我们荡起双桨,多米差点被红烧"));
+ put(6, new CommentBean(6, UserList.get(6), "迷你世界生存到极致就像开挂狼堡大升级!火柴盒秒变大别墅"));
+ put(7, new CommentBean(7, UserList.get(7), "迷你世界流沙来了快建房,建造基岩房,善心大发搭救伙伴?"));
+ put(8, new CommentBean(8, UserList.get(8), "方舟生存进化神奇宝贝61水晶洞穴对抗死亡蠕虫,寻获团结神器"));
+ put(9, new CommentBean(9, UserList.get(9), "2021年值得入住的民宿,有生之年一定要去“睡”一次!"));
+ put(10, new CommentBean(10, UserList.get(10), "国内最美的热气球景点,你们去过吗?"));
+ put(11, new CommentBean(11, UserList.get(11), "每个月最适合旅行你过的地方?你真的去对啦吗!"));
+ put(12, new CommentBean(12, UserList.get(12), "没有去过香格里拉,怎知世界的纯净,云南最值得打卡的地方!"));
+ put(13, new CommentBean(13, UserList.get(13), "西双版纳4天3晚游才人均不到一千?这份攻略你可要收好了!"));
+ put(14, new CommentBean(14, UserList.get(14), "有种冰雪童话,叫冬天的哈尔滨!"));
+ put(15, new CommentBean(15, UserList.get(15), "iPad Pro 2021款12.9英寸黑白颜色对比。"));
+ put(16, new CommentBean(16, UserList.get(16), "想要主动降噪与好音质,2021年适合iPhone的真无线蓝牙耳机怎么选?"));
+ put(17, new CommentBean(17, UserList.get(17), "首个进入太空的生物,为什么要选择一只流浪狗呢?"));
+ put(18, new CommentBean(18, UserList.get(18), "同样是鲤鱼,为什么黄河鲤鱼更贵呢?"));
+ put(19, new CommentBean(19, UserList.get(19), "肉被切开后,为什么表面会跳动呢?"));
+ put(20, new CommentBean(20, UserList.get(20), "为什么椰子里面会有水呢?"));
+ put(21, new CommentBean(21, UserList.get(21), "为什么工人要往水泥里加白糖呢?"));
+ put(22, new CommentBean(22, UserList.get(22), "科学家为什么不敢把火星土壤带回地球呢?"));
+ put(23, new CommentBean(23, UserList.get(23), "有气囊的鼻托你见过吗?"));
+ put(24, new CommentBean(24, UserList.get(24), "我做的红酒雪梨,每次上桌不到1分钟就被抢光,思虑再三,决定把方法发出来,希望学会的能给我个❤️"));
+ put(25, new CommentBean(25, UserList.get(25), "的新吃法!真的太好吃了!全麦欧包更适合做主食哦!"));
+ put(26, new CommentBean(26, UserList.get(26), "月旨期放心吃,吃肉肉掉肉肉"));
+ put(27, new CommentBean(27, UserList.get(27), "用茶代替水做出来的红烧肉,肥而不腻,隔壁老王都说好吃!"));
+ put(28, new CommentBean(28, UserList.get(28), "塞尔达传说来到王城遗址,塞尔达公主为我举行授勋仪式"));
+ put(29, new CommentBean(29, UserList.get(29), "塞尔达传说用火把点燃哈特诺之塔,我得到了四大部落的位置"));
+ put(30, new CommentBean(30, UserList.get(30), "翼龙历险记打败会喷火的龙皇后,5只小翼龙宝宝出生了"));
+ }};
+
+ // 随机用户视频
+ public static SparseArray> UserVideo = new SparseArray>(){{
+ Random rand = new Random();
+ for(int i = 0; i < UserList.size(); i++) {
+ int key = UserList.keyAt(i);
+ List list = new ArrayList<>();
+ int getI = rand.nextInt(10);
+ int getS = rand.nextInt(20) + 10;
+ for(int o = getI; o < getS; o++) {
+ list.add(VideoList.get(VideoList.keyAt(o)));
+ }
+ put(key, list);
+ }
+ }};
+
+ public static class UserBean {
+ public int id;
+ public String name;
+ public String icon;
+ public String bg;
+ public String city;
+ public int age;
+ public int sex;
+ public String text;
+ public int praise;
+ public int follow;
+ public int fans;
+ public boolean isFollow = false;
+ UserBean(int id, String name, String icon, String bg, String city, int age, int sex, String text) {
+ Random rand = new Random();
+ this.id = id;
+ this.name = name;
+ this.icon = icon;
+ this.bg = bg;
+ this.city = city;
+ this.age = age;
+ this.sex = sex;
+ this.text = text;
+ praise = rand.nextInt(100000);
+ follow = rand.nextInt(100000);
+ fans = rand.nextInt(100000);
+ }
+ public String getPraise() {
+ return Common.ParseNum(praise);
+ }
+ public String getFollow() {
+ return Common.ParseNum(follow);
+ }
+ public String getFans() {
+ return Common.ParseNum(fans);
+ }
+ }
+
+ public static class VideoBean {
+ public int id;
+ public String img;
+ public String text;
+ public String src;
+ public int favCount;
+ public int sayCount;
+ public int shareCount;
+ public boolean isFav = false;
+ VideoBean(int id, String img, String text, String src) {
+ Random rand = new Random();
+ this.id = id;
+ this.img = img;
+ this.text = text;
+ this.src = src;
+ favCount = rand.nextInt(100000);
+ sayCount = rand.nextInt(100000);
+ shareCount = rand.nextInt(100000);
+ }
+ public String getFavCount() {
+ return Common.ParseNum(favCount);
+ }
+ public String getSayCount() {
+ return Common.ParseNum(sayCount);
+ }
+ public String getShareCount() {
+ return Common.ParseNum(shareCount);
+ }
+ }
+
+ public static class MusicBean {
+ public int id;
+ public String icon;
+ public String text;
+ MusicBean(int id, String icon, String text) {
+ this.id = id;
+ this.icon = icon;
+ this.text = text;
+ }
+ }
+
+ public static class CommentBean {
+ public int id;
+ public UserBean user;
+ public String text;
+ public String time;
+ public int favCount;
+ CommentBean(int id, UserBean user, String text) {
+ Random rand = new Random();
+ this.id = id;
+ this.user = user;
+ this.text = text;
+ this.time = (rand.nextInt(59) + 1) + (rand.nextInt(2) == 0 ? "小时" : "分钟") + "前";
+ favCount = rand.nextInt(100000);
+ }
+ public String getFavCount() {
+ return Common.ParseNum(favCount);
+ }
+ }
+
+}
diff --git a/app/src/main/java/cn/leaqi/drawerapp/Views/MarqueView.java b/app/src/main/java/cn/leaqi/drawerapp/Views/MarqueView.java
new file mode 100644
index 0000000..57dbd47
--- /dev/null
+++ b/app/src/main/java/cn/leaqi/drawerapp/Views/MarqueView.java
@@ -0,0 +1,45 @@
+package cn.leaqi.drawerapp.Views;
+
+import android.content.Context;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+
+import androidx.appcompat.widget.AppCompatTextView;
+
+/**
+ * TextView 文本滚动
+ */
+public class MarqueView extends AppCompatTextView {
+
+ private boolean isFocused = false;
+
+ public MarqueView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ Init();
+ }
+
+ public MarqueView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ Init();
+ }
+
+ public MarqueView(Context context) {
+ super(context);
+ Init();
+ }
+
+ public void Init() {
+ setSingleLine(true);
+ setEllipsize(TextUtils.TruncateAt.MARQUEE);
+ }
+
+ public void setFocused(boolean focused) {
+ isFocused = focused;
+ requestLayout();
+ }
+
+ @Override
+ public boolean isFocused() {
+ return isFocused;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/cn/leaqi/drawerapp/Views/NewGridView.java b/app/src/main/java/cn/leaqi/drawerapp/Views/NewGridView.java
new file mode 100644
index 0000000..1c98f2c
--- /dev/null
+++ b/app/src/main/java/cn/leaqi/drawerapp/Views/NewGridView.java
@@ -0,0 +1,30 @@
+package cn.leaqi.drawerapp.Views;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.GridView;
+
+/**
+ * GridView 嵌套滚动
+ */
+public class NewGridView extends GridView {
+
+ public NewGridView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public NewGridView(Context context) {
+ super(context);
+ }
+
+ public NewGridView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ @Override
+ public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
+ super.onMeasure(widthMeasureSpec, expandSpec);
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/cn/leaqi/drawerapp/Views/RadiusImage.java b/app/src/main/java/cn/leaqi/drawerapp/Views/RadiusImage.java
new file mode 100644
index 0000000..4030d5e
--- /dev/null
+++ b/app/src/main/java/cn/leaqi/drawerapp/Views/RadiusImage.java
@@ -0,0 +1,126 @@
+package cn.leaqi.drawerapp.Views;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.RectF;
+import android.util.AttributeSet;
+
+import androidx.appcompat.widget.AppCompatImageView;
+
+import cn.leaqi.drawerapp.R;
+
+/**
+ * ImageView 图片圆角
+ */
+public class RadiusImage extends AppCompatImageView {
+
+ private int leftTopRadius = 0;
+ private int rightTopRadius = 0;
+ private int rightBottomRadius = 0;
+ private int leftBottomRadius = 0;
+
+ private Paint paint;
+ private Paint paint2;
+
+ public RadiusImage(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ init(context, attrs);
+ }
+
+ public RadiusImage(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(context, attrs);
+ }
+
+ public RadiusImage(Context context) {
+ super(context);
+ init(context, null);
+ }
+
+ private void init(Context context, AttributeSet attrs) {
+ if (attrs != null) {
+ final TypedArray attrArr = context.obtainStyledAttributes(attrs, R.styleable.RadiusImage);
+ int allRadius = attrArr.getDimensionPixelSize(R.styleable.RadiusImage_radius, 0);
+ if(allRadius > 0){
+ leftTopRadius = allRadius;
+ rightTopRadius = allRadius;
+ leftBottomRadius = allRadius;
+ rightBottomRadius = allRadius;
+ }
+ attrArr.recycle();
+ }
+
+ paint = new Paint();
+ paint.setColor(Color.WHITE);
+ paint.setAntiAlias(true);
+ paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
+
+ paint2 = new Paint();
+ paint2.setXfermode(null);
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ try {
+ Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
+ Canvas canvas2 = new Canvas(bitmap);
+ super.draw(canvas2);
+ if(leftTopRadius > 0)drawLeftTop(canvas2);
+ if(rightTopRadius > 0)drawRightTop(canvas2);
+ if(leftBottomRadius > 0)drawLeftBottom(canvas2);
+ if(rightBottomRadius > 0)drawRightBottom(canvas2);
+ canvas.drawBitmap(bitmap, 0, 0, paint2);
+ bitmap.recycle();
+ } catch (IllegalArgumentException e){
+ e.printStackTrace();
+ }
+ }
+
+ private void drawLeftTop(Canvas canvas) {
+ Path path = new Path();
+ path.moveTo(0, leftTopRadius);
+ path.lineTo(0, 0);
+ path.lineTo(leftTopRadius, 0);
+ path.arcTo(new RectF(0, 0, leftTopRadius * 2, leftTopRadius * 2), -90, -90);
+ path.close();
+ canvas.drawPath(path, paint);
+ }
+
+ private void drawRightTop(Canvas canvas) {
+ Path path = new Path();
+ path.moveTo(getWidth(), rightTopRadius);
+ path.lineTo(getWidth(), 0);
+ path.lineTo(getWidth() - rightTopRadius, 0);
+ path.arcTo(new RectF(getWidth() - rightTopRadius * 2, 0, getWidth(), rightTopRadius * 2), -90, 90);
+ path.close();
+ canvas.drawPath(path, paint);
+ }
+
+ private void drawLeftBottom(Canvas canvas) {
+ Path path = new Path();
+ path.moveTo(0, getHeight() - leftBottomRadius);
+ path.lineTo(0, getHeight());
+ path.lineTo(leftBottomRadius, getHeight());
+ path.arcTo(new RectF(0, getHeight() - leftBottomRadius * 2, leftBottomRadius * 2, getHeight()), 90, 90);
+ path.close();
+ canvas.drawPath(path, paint);
+ }
+
+ private void drawRightBottom(Canvas canvas) {
+ Path path = new Path();
+ path.moveTo(getWidth() - rightBottomRadius, getHeight());
+ path.lineTo(getWidth(), getHeight());
+ path.lineTo(getWidth(), getHeight() - rightBottomRadius);
+ path.arcTo(new RectF(getWidth() - rightBottomRadius * 2, getHeight() - rightBottomRadius * 2, getWidth(), getHeight()), -0, 90);
+ path.close();
+ canvas.drawPath(path, paint);
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/cn/leaqi/drawerapp/Views/TopBar.java b/app/src/main/java/cn/leaqi/drawerapp/Views/TopBar.java
new file mode 100644
index 0000000..ddee7a3
--- /dev/null
+++ b/app/src/main/java/cn/leaqi/drawerapp/Views/TopBar.java
@@ -0,0 +1,225 @@
+package cn.leaqi.drawerapp.Views;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Color;
+import android.os.Build;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.TextView;
+
+import cn.leaqi.drawerapp.R;
+import cn.leaqi.drawerapp.Utils.Common;
+
+/**
+ * 布局头部处理类
+ */
+public class TopBar {
+ private Context mContext;
+ private Activity mActivity;
+
+ private int statusHeight = 0;
+ private View topBar;
+ private View topStatus;
+ private View topHead;
+ private TextView topText;
+ private View topLeft;
+ private View topRight;
+ private View topLeftIcon;
+ private View topRightIcon;
+ private TextView topRightText;
+
+ public interface OnTopClickListener{
+ void onClick(View view);
+ }
+
+ public TopBar(Context context) {
+ mContext = context;
+ mActivity = ((Activity)mContext);
+ topBar = mActivity.findViewById(R.id.top_bar);
+ topStatus = mActivity.findViewById(R.id.top_status);
+ topHead = mActivity.findViewById(R.id.top_head);
+ topText = mActivity.findViewById(R.id.top_text);
+ topLeft = mActivity.findViewById(R.id.top_left);
+ topRight = mActivity.findViewById(R.id.top_right);
+ topLeftIcon = mActivity.findViewById(R.id.top_left_icon);
+ topRightIcon = mActivity.findViewById(R.id.top_right_icon);
+ topRightText = mActivity.findViewById(R.id.top_right_text);
+ setStatusBar(true);
+ }
+
+ public TopBar(Context context, boolean isStatus) {
+ mContext = context;
+ mActivity = ((Activity)mContext);
+ if (isStatus) {
+ topStatus = mActivity.findViewById(R.id.top_status);
+ }
+ setStatusBar(isStatus);
+ }
+
+ private void setStatusBar(boolean isStatus){
+ try {
+ Window window = mActivity.getWindow();
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ setStatusTop(isStatus);
+ window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
+ window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
+ window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
+ window.setStatusBarColor(Color.TRANSPARENT);
+ }else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ setStatusTop(isStatus);
+ window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
+ window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void setNavigationBar() {
+ Window window = mActivity.getWindow();
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ window.setNavigationBarColor(Color.BLACK);
+ }
+ }
+
+ private void setStatusTop(boolean isStatus){
+ try {
+ int resourceId = mContext.getResources().getIdentifier("status_bar_height", "dimen", "android");
+ if (resourceId > 0) {
+ statusHeight = mContext.getResources().getDimensionPixelSize(resourceId);
+ }
+ if (statusHeight == 0) {
+ statusHeight = Common.dipToPx(mContext, 25);
+ }
+ //System.out.println("StatusHeight : " + statusHeight + " - SDK_INT : " + Build.VERSION.SDK_INT);
+ if (isStatus && topStatus != null) {
+ ViewGroup.LayoutParams params = topStatus.getLayoutParams();
+ params.height = statusHeight;
+ topStatus.setLayoutParams(params);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void setTitle(String title){
+ topText.setText(title);
+ }
+
+ public void setLeftIcon(int image) {
+ setLeftIcon(image, true);
+ }
+
+ public void setLeftIcon(int image, boolean isAnim) {
+ topLeftIcon.setBackgroundResource(image);
+ if (isAnim) Common.animScale(topLeftIcon, 200);
+ }
+
+ public void setRightIcon(int image) {
+ setRightIcon(image, true);
+ }
+
+ public void setRightIcon(int image, boolean isAnim) {
+ topRightIcon.setBackgroundResource(image);
+ if (isAnim) Common.animScale(topRightIcon, 200);
+ }
+
+ public void showLeft(int image, final OnTopClickListener listener){
+ setLeftIcon(image, false);
+ if (topLeft.getVisibility() == View.GONE) {
+ topLeft.setVisibility(View.VISIBLE);
+ }
+ if(listener != null){
+ topLeft.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ listener.onClick(view);
+ }
+ });
+ }
+ }
+
+ public void showRight(int image, final OnTopClickListener listener){
+ setRightIcon(image, false);
+ if (topRight.getVisibility() == View.GONE) {
+ topRight.setVisibility(View.VISIBLE);
+ }
+ if(listener != null){
+ topRight.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ listener.onClick(view);
+ }
+ });
+ }
+ }
+
+ public void setRightText(String text){
+ setRightText(text, null);
+ }
+
+ public void setRightText(String text, final OnTopClickListener listener){
+ if (topRightText.getVisibility() == View.GONE) {
+ topRightText.setVisibility(View.VISIBLE);
+ }
+ topRightText.setText(text);
+ if(listener != null){
+ topRightText.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ listener.onClick(view);
+ }
+ });
+ }
+ }
+
+ public void showLeftBack() {
+ showLeft(R.mipmap.icon_back, new TopBar.OnTopClickListener() {
+ @Override
+ public void onClick(View view) {
+ mActivity.finish();
+ }
+ });
+ }
+
+ public void radiusBar() {
+ topHead.setBackgroundResource(R.drawable.radius_status);
+ if (topStatus.getVisibility() == View.VISIBLE) {
+ topStatus.setVisibility(View.INVISIBLE);
+ }
+ }
+
+ public void normalBar() {
+ topHead.setBackgroundResource(R.color.colorPrimary);
+ if (topStatus.getVisibility() == View.INVISIBLE) {
+ topStatus.setVisibility(View.VISIBLE);
+ }
+ }
+
+ public void setBarAlpha(float alpha) {
+ topBar.setAlpha(alpha);
+ }
+
+ public int getWidth() {
+ return topBar.getMeasuredWidth();
+ }
+
+ public int getHeight() {
+ return topBar.getMeasuredHeight();
+ }
+
+ public int getStatusHeight() {
+ return statusHeight;
+ }
+
+ public View getTopLeftIcon() {
+ return topLeftIcon;
+ }
+
+ public View getTopRightIcon() {
+ return topRightIcon;
+ }
+}
diff --git a/app/src/main/java/cn/leaqi/drawerapp/Views/TouchView.java b/app/src/main/java/cn/leaqi/drawerapp/Views/TouchView.java
new file mode 100644
index 0000000..dcac269
--- /dev/null
+++ b/app/src/main/java/cn/leaqi/drawerapp/Views/TouchView.java
@@ -0,0 +1,54 @@
+package cn.leaqi.drawerapp.Views;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.widget.LinearLayout;
+
+/**
+ * 布局触摸缩小
+ */
+public class TouchView extends LinearLayout {
+
+ public TouchView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ init(context, attrs);
+ }
+
+ public TouchView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(context, attrs);
+ }
+
+ public TouchView(Context context) {
+ super(context);
+ init(context, null);
+ }
+
+ private void init(Context context, AttributeSet attrs) {
+ setClickable(true);
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+ setScaleX(0.8f);
+ setScaleY(0.8f);
+ return true;
+ }
+ return super.onInterceptTouchEvent(ev);
+ }
+
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ switch (ev.getAction()) {
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ setScaleX(1f);
+ setScaleY(1f);
+ }
+ return super.onTouchEvent(ev);
+ }
+
+}
diff --git a/app/src/main/java/cn/leaqi/drawerapp/Views/UserComment.java b/app/src/main/java/cn/leaqi/drawerapp/Views/UserComment.java
new file mode 100644
index 0000000..9f8c304
--- /dev/null
+++ b/app/src/main/java/cn/leaqi/drawerapp/Views/UserComment.java
@@ -0,0 +1,251 @@
+package cn.leaqi.drawerapp.Views;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.Rect;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import cn.leaqi.drawerapp.R;
+import cn.leaqi.drawerapp.Utils.Common;
+import cn.leaqi.drawerapp.Utils.Config;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+
+/**
+ * 视频布局用户评论类
+ */
+public class UserComment implements View.OnClickListener {
+ private Context mContext;
+ private RecyclerView mainList;
+ private ListAdapter listAdapter;
+ private List listData = new ArrayList<>();
+
+ private View parent;
+ private View itemSend;
+ private View sendIcon;
+ private EditText sendVal;
+ private View sendAt;
+ private View sendBq;
+ private View sendSubmit;
+
+ private int keyboardHeight = 0;
+
+ public UserComment(Context context, View view) {
+ mContext = context;
+ parent = view;
+ mainList = parent.findViewById(R.id.itemComment);
+ itemSend = parent.findViewById(R.id.itemSend);
+ sendIcon = parent.findViewById(R.id.send_icon);
+ sendVal = parent.findViewById(R.id.send_val);
+ sendAt = parent.findViewById(R.id.send_at);
+ sendBq = parent.findViewById(R.id.send_bq);
+ sendSubmit = parent.findViewById(R.id.send_submit);
+ sendIcon.setOnClickListener(this);
+ sendAt.setOnClickListener(this);
+ sendBq.setOnClickListener(this);
+ sendSubmit.setOnClickListener(this);
+ AppInit();
+ }
+
+ @Override
+ public void onClick(View view) {
+ if (view == sendIcon) {
+ Common.showToast("拍视频");
+ } else if (view == sendAt) {
+ Common.showToast("艾特");
+ } else if (view == sendBq) {
+ Common.showToast("表情");
+ } else if (view == sendSubmit) {
+ // 发布评论
+ final String getVal = sendVal.getText().toString();
+ if (getVal.length() > 0) {
+ Common.showToast("发布成功");
+ Common.hideInput(mContext);
+ sendVal.setText("");
+ listData.add(0, new ItemBean(getVal));
+ listAdapter.notifyItemInserted(0);
+ mainList.scrollToPosition(0);
+ }
+ }
+ }
+
+ private void AppInit() {
+ listAdapter = new ListAdapter(mContext, R.layout.comment_item, listData);
+ mainList.setLayoutManager(new LinearLayoutManager(mContext));
+ mainList.setAdapter(listAdapter);
+
+ sendVal.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { }
+ @Override
+ public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { }
+ @Override
+ public void afterTextChanged(Editable editable) {
+ if (editable.toString().length() > 0) {
+ sendSubmit.setVisibility(View.VISIBLE);
+ } else {
+ sendSubmit.setVisibility(View.GONE);
+ }
+ }
+ });
+
+ parent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener(){
+ @Override
+ public void onGlobalLayout() {
+ Rect rect = new Rect();
+ parent.getWindowVisibleDisplayFrame(rect);
+ int getHeight = parent.getHeight() - rect.bottom;
+ if (keyboardHeight != getHeight) {
+ keyboardHeight = getHeight;
+ RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) itemSend.getLayoutParams();
+ lp.bottomMargin = getHeight;
+ itemSend.setLayoutParams(lp);
+ }
+ }
+ });
+ }
+
+ public void setData() {
+ for (int i = 1; i < Config.CommentList.size() + 1; i++) {
+ Config.CommentBean item = Config.CommentList.get(i);
+ listData.add(new ItemBean(item.user.icon, item.user.name, item.text, item.time, item.favCount));
+ }
+ Collections.shuffle(listData);
+ listAdapter.notifyDataSetChanged();
+ }
+
+ private class ItemBean {
+ int src = -1;
+ String icon;
+ String name;
+ String text;
+ String time;
+ int dig;
+ boolean isDig = false;
+
+ private ItemBean(String i, String n, String s, String t, int d) {
+ icon = i;
+ name = n;
+ text = s;
+ time = t;
+ dig = d;
+ }
+
+ private ItemBean(String t) {
+ src = R.mipmap.icon;
+ name = "我";
+ text = t;
+ time = "刚刚";
+ dig = 0;
+ }
+
+ private String getDigParse() {
+ return Common.ParseNum(dig);
+ }
+ }
+
+ private class ListAdapter extends RecyclerView.Adapter {
+ private int layout;
+ private LayoutInflater inflater;
+ private List list;
+
+
+ private ListAdapter(Context context, int resource, List objects) {
+ layout = resource;
+ inflater = LayoutInflater.from(context);
+ list = objects;
+ }
+
+ @NonNull
+ @Override
+ public ListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ View addView = inflater.inflate(layout, parent, false);
+ return new ListViewHolder(addView);
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull ListViewHolder holder, int position) {
+ ItemBean item = list.get(position);
+ if (item.src != -1) {
+ // 新增的评论使用默认头像
+ holder.itemIcon.setImageResource(item.src);
+ } else {
+ // 加载评论用户头像
+ Common.setHttpImage(holder.itemIcon, item.icon, R.mipmap.icon_user);
+ }
+ holder.itemTitle.setText(item.name); // 用户名称
+ holder.itemText.setText(item.text); // 评论内容
+ holder.itemTime.setText(item.time); // 评论时间
+ // 评论点赞
+ holder.itemDigIcon.setImageResource(item.isDig ? R.mipmap.icon_dig_cur : R.mipmap.icon_dig_def);
+ holder.itemDigNum.setVisibility(item.dig == 0 ? View.GONE : View.VISIBLE);
+ holder.itemDigNum.setTextColor(Color.parseColor(item.isDig ? "#FC2E5D" : "#888888"));
+ holder.itemDigNum.setText(item.getDigParse());
+ }
+
+ @Override
+ public int getItemCount() {
+ return list.size();
+ }
+
+ private class ListViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
+ ImageView itemIcon;
+ TextView itemTitle;
+ TextView itemText;
+ TextView itemTime;
+ View itemDigBox;
+ ImageView itemDigIcon;
+ TextView itemDigNum;
+
+ private ListViewHolder(View view) {
+ super(view);
+ itemIcon = view.findViewById(R.id.item_icon);
+ itemTitle = view.findViewById(R.id.item_title);
+ itemText = view.findViewById(R.id.item_text);
+ itemTime = view.findViewById(R.id.item_time);
+ itemDigBox = view.findViewById(R.id.item_dig_box);
+ itemDigIcon = view.findViewById(R.id.item_dig_icon);
+ itemDigNum = view.findViewById(R.id.item_dig_num);
+ itemIcon.setOnClickListener(this);
+ itemTitle.setOnClickListener(this);
+ itemDigBox.setOnClickListener(this);
+ }
+
+ @Override
+ public void onClick(View view) {
+ int position = getAdapterPosition();
+ ItemBean item = list.get(position);
+ if (view == itemIcon || view == itemTitle) {
+ Common.showToast(item.name);
+ } else if (view == itemDigBox) {
+ // 点击评论点赞
+ item.isDig = !item.isDig;
+ item.dig = item.isDig ? item.dig + 1 : item.dig - 1;
+ itemDigIcon.setImageResource(item.isDig ? R.mipmap.icon_dig_cur : R.mipmap.icon_dig_def);
+ itemDigNum.setVisibility(item.dig == 0 ? View.GONE : View.VISIBLE);
+ itemDigNum.setTextColor(Color.parseColor(item.isDig ? "#FC2E5D" : "#888888"));
+ itemDigNum.setText(item.getDigParse());
+ }
+ }
+
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/cn/leaqi/drawerapp/Views/UserHome.java b/app/src/main/java/cn/leaqi/drawerapp/Views/UserHome.java
new file mode 100644
index 0000000..23b8f5e
--- /dev/null
+++ b/app/src/main/java/cn/leaqi/drawerapp/Views/UserHome.java
@@ -0,0 +1,265 @@
+package cn.leaqi.drawerapp.Views;
+
+import android.app.Activity;
+import android.content.Context;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.GridView;
+import android.widget.ImageView;
+import android.widget.ScrollView;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+
+import com.google.android.material.tabs.TabLayout;
+import cn.leaqi.drawerapp.R;
+import cn.leaqi.drawerapp.Utils.Common;
+import cn.leaqi.drawerapp.Utils.Config;
+import cn.leaqi.drawer.SwipeDrawer;
+import cn.leaqi.drawer.OnDrawerState;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 视频布局用户主页类
+ */
+public class UserHome implements View.OnClickListener {
+ private Context mContext;
+ private Activity mActivity;
+ private SwipeDrawer homeDrawer;
+ private SwipeDrawer infoDrawer;
+ private TabLayout homeTab;
+ private ScrollView homeScroll;
+ private ImageView homeBg;
+ private ImageView homeIcon;
+ private TextView homeName;
+ private TextView homeId;
+ private TextView homeText;
+ private TextView homeAge;
+ private ImageView homeSex;
+ private TextView homeCity;
+ private TextView numPraise;
+ private TextView numFollow;
+ private TextView numFans;
+ private View homeFollow;
+ private View homeCancel;
+
+ private List tabList = new ArrayList(){{
+ add("作品");
+ add("喜欢");
+ }};
+
+ private List listData = new ArrayList<>();
+ private ListAdapter listAdapter = null;
+
+ private Config.UserBean userInfo;
+
+ public UserHome(Context context) {
+ mContext = context;
+ mActivity = ((Activity)mContext);
+ homeDrawer = mActivity.findViewById(R.id.homeDrawer);
+ infoDrawer = mActivity.findViewById(R.id.infoDrawer);
+ homeTab = mActivity.findViewById(R.id.homeTab);
+ homeScroll = mActivity.findViewById(R.id.homeScroll);
+ homeBg = mActivity.findViewById(R.id.homeBg);
+ homeIcon = mActivity.findViewById(R.id.homeIcon);
+ homeName = mActivity.findViewById(R.id.homeName);
+ homeId = mActivity.findViewById(R.id.homeId);
+ homeText = mActivity.findViewById(R.id.homeText);
+ homeAge = mActivity.findViewById(R.id.homeAge);
+ homeSex = mActivity.findViewById(R.id.homeSex);
+ homeCity = mActivity.findViewById(R.id.homeCity);
+ numPraise = mActivity.findViewById(R.id.numPraise);
+ numFollow = mActivity.findViewById(R.id.numFollow);
+ numFans = mActivity.findViewById(R.id.numFans);
+ homeFollow = mActivity.findViewById(R.id.homeFollow);
+ homeCancel = mActivity.findViewById(R.id.homeCancel);
+ AppInit();
+ ListData();
+ }
+
+ @Override
+ public void onClick(View view) {
+ int getId = view.getId();
+ switch (getId) {
+ case R.id.homeBack : // 点击左上角返回
+ Common.sendKeyCode(KeyEvent.KEYCODE_BACK);
+ break;
+ case R.id.homeSet : // 点击右上角设置
+ homeDrawer.openDrawer(SwipeDrawer.DIRECTION_BOTTOM);
+ break;
+ case R.id.homeClose : // 点击设置面板关闭按钮
+ homeDrawer.closeDrawer();
+ break;
+ case R.id.homeFollow : // 点击关注
+ if (userInfo != null) {
+ userInfo.isFollow = true;
+ homeCancel.setVisibility(View.VISIBLE);
+ homeFollow.setVisibility(View.GONE);
+ Common.showToast("已关注");
+ }
+ break;
+ case R.id.homeCancel : // 点击取消关注
+ if (userInfo != null) {
+ userInfo.isFollow = false;
+ homeCancel.setVisibility(View.GONE);
+ homeFollow.setVisibility(View.VISIBLE);
+ Common.showToast("取消关注");
+ }
+ break;
+ case R.id.homeShare : // 点击设置面板分享
+ Common.showToast("分享");
+ homeDrawer.closeDrawer();
+ break;
+ case R.id.homeMsg : // 点击设置面板聊天
+ Common.showToast("聊天");
+ homeDrawer.closeDrawer();
+ break;
+ case R.id.homeWarn : // 点击设置面板举报
+ Common.showToast("举报");
+ homeDrawer.closeDrawer();
+ break;
+ case R.id.homeBlack : // 点击设置面板举报
+ Common.showToast("拉黑");
+ homeDrawer.closeDrawer();
+ break;
+ }
+ }
+
+ private void AppInit() {
+ final View homeBg = mActivity.findViewById(R.id.homeBg);
+ final View homeBack = mActivity.findViewById(R.id.homeBack);
+ final View homeSet = mActivity.findViewById(R.id.homeSet);
+ final View homeClose = mActivity.findViewById(R.id.homeClose);
+ final View homeShare = mActivity.findViewById(R.id.homeShare);
+ final View homeMsg = mActivity.findViewById(R.id.homeMsg);
+ final View homeWarn = mActivity.findViewById(R.id.homeWarn);
+ final View homeBlack = mActivity.findViewById(R.id.homeBlack);
+ homeFollow.setOnClickListener(this);
+ homeCancel.setOnClickListener(this);
+ homeBack.setOnClickListener(this);
+ homeSet.setOnClickListener(this);
+ homeClose.setOnClickListener(this);
+ homeShare.setOnClickListener(this);
+ homeMsg.setOnClickListener(this);
+ homeWarn.setOnClickListener(this);
+ homeBlack.setOnClickListener(this);
+ createTab();
+
+ infoDrawer.setOnDrawerState(new OnDrawerState() {
+ @Override
+ public void onStart(int type) { }
+ @Override
+ public void onMove(int type, float progress) {
+ // 主页顶部下拉背景放大缩小
+ progress *= 0.5;
+ homeBg.setScaleX(1 + progress);
+ homeBg.setScaleY(1 + progress);
+ }
+ @Override
+ public void onOpen(int type) { }
+ @Override
+ public void onClose(int type) { }
+ @Override
+ public void onCancel(int type) { }
+ });
+ }
+
+ // 更新主页数据
+ public void upHome(Config.UserBean info) {
+ homeCancel.setVisibility(info.isFollow ? View.VISIBLE : View.GONE);
+ homeFollow.setVisibility(info.isFollow ? View.GONE : View.VISIBLE);
+ if (userInfo != info) {
+ userInfo = info;
+ homeScroll.scrollTo(0, 0); // scroll 回到顶部
+ homeName.setText(userInfo.name); // 用户名称
+ homeId.setText(("账号: " + (100000 + userInfo.id))); // 用户ID
+ homeText.setText(userInfo.text); // 用户简介
+ homeAge.setText((userInfo.age + "岁")); // 用户年龄
+ homeCity.setText(userInfo.city); // 用户城市
+ numPraise.setText(userInfo.getPraise()); // 获赞数量
+ numFollow.setText(userInfo.getFollow()); // 关注数量
+ numFans.setText(userInfo.getFans()); // 粉丝数量
+ homeTab.getTabAt(0).select();
+ // 设置用户性别图标
+ if (userInfo.sex > 0) {
+ homeSex.setVisibility(View.VISIBLE);
+ homeSex.setImageResource(userInfo.sex == 1 ? R.mipmap.sex_1 : R.mipmap.sex_2);
+ } else {
+ homeSex.setVisibility(View.GONE);
+ }
+ Common.setHttpImage(homeBg, userInfo.bg); // 用户主页背景图
+ Common.setHttpImage(homeIcon, userInfo.icon, R.mipmap.icon_user); // 用户头像
+ SetList();
+ }
+ }
+
+ private void createTab() {
+ for (int i = 0; i < tabList.size(); i++) {
+ homeTab.addTab(homeTab.newTab().setText(tabList.get(i)));
+ }
+ homeTab.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
+ @Override
+ public void onTabSelected(TabLayout.Tab tab) { }
+ @Override
+ public void onTabUnselected(TabLayout.Tab tab) { }
+ @Override
+ public void onTabReselected(TabLayout.Tab tab) { }
+ });
+ }
+
+ private void SetList() {
+ listData.clear();
+ listData.addAll(Config.UserVideo.get(userInfo.id));
+ homeTab.getTabAt(0).setText(tabList.get(0) + (listData.size() > 0 ? " " + listData.size() : ""));
+ listAdapter.notifyDataSetChanged();
+ }
+
+ private void ListData() {
+ final GridView homeGrid = mActivity.findViewById(R.id.homeGrid);
+ listAdapter = new ListAdapter(mActivity, R.layout.home_item, listData);
+ homeGrid.setAdapter(listAdapter);
+ }
+
+ private class ListAdapter extends ArrayAdapter{
+ private int layout;
+ private LayoutInflater inflater;
+ private List list;
+
+ private ListAdapter(Context context, int resource, List objects) {
+ super(context, resource, objects);
+ layout = resource;
+ inflater = LayoutInflater.from(context);
+ list = objects;
+ }
+ @NonNull
+ public View getView(int position, View convertView, @NonNull ViewGroup parent) {
+ View view;
+ ViewHolder viewHolder;
+ if (convertView == null) {
+ view = inflater.inflate(layout, null);
+ viewHolder = new ViewHolder();
+ viewHolder.itemImg = view.findViewById(R.id.itemImg);
+ viewHolder.title = view.findViewById(R.id.itemTitle);
+ view.setTag(viewHolder);
+ } else {
+ view = convertView;
+ viewHolder = (ViewHolder) view.getTag();
+ }
+ Config.VideoBean item = list.get(position);
+ viewHolder.title.setText(item.getFavCount());
+ Common.setHttpImage(viewHolder.itemImg, item.img);
+ return view;
+ }
+
+ private class ViewHolder {
+ ImageView itemImg;
+ TextView title;
+ }
+ }
+
+}
diff --git a/app/src/main/java/cn/leaqi/drawerapp/Views/UserInfo.java b/app/src/main/java/cn/leaqi/drawerapp/Views/UserInfo.java
new file mode 100644
index 0000000..cbe2317
--- /dev/null
+++ b/app/src/main/java/cn/leaqi/drawerapp/Views/UserInfo.java
@@ -0,0 +1,76 @@
+package cn.leaqi.drawerapp.Views;
+
+import android.app.Activity;
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+
+import cn.leaqi.drawerapp.R;
+import cn.leaqi.drawerapp.Utils.Common;
+import cn.leaqi.drawer.SwipeDrawer;
+import cn.leaqi.drawer.OnDrawerState;
+
+/**
+ * 右侧边栏用户菜单操作类
+ */
+public class UserInfo implements View.OnClickListener {
+ private Context mContext;
+ private Activity mActivity;
+
+
+ public UserInfo(Context context) {
+ mContext = context;
+ mActivity = ((Activity)mContext);
+ AppInit();
+ }
+
+ private void AppInit() {
+ final SwipeDrawer userInfo = mActivity.findViewById(R.id.userInfo);
+ final View infoTopIcon = mActivity.findViewById(R.id.infoTopIcon);
+ final View infoTopTitle = mActivity.findViewById(R.id.infoTopTitle);
+ final ViewGroup listItem1 = mActivity.findViewById(R.id.listItem1);
+ final ViewGroup listItem2 = mActivity.findViewById(R.id.listItem2);
+ final ViewGroup listItem3 = mActivity.findViewById(R.id.listItem3);
+
+ userInfo.setOnDrawerState(new OnDrawerState() {
+ @Override
+ public void onStart(int type) { }
+ @Override
+ public void onMove(int type, float progress) {
+ if (type == SwipeDrawer.DIRECTION_TOP) {
+ infoTopIcon.setRotation(progress * 360);
+ progress *= 0.2;
+ infoTopIcon.setScaleX(1 + progress);
+ infoTopIcon.setScaleY(1 + progress);
+ infoTopTitle.setScaleX(1 + progress);
+ infoTopTitle.setScaleY(1 + progress);
+ }
+ }
+ @Override
+ public void onOpen(int type) { }
+ @Override
+ public void onClose(int type) { }
+ @Override
+ public void onCancel(int type) { }
+ });
+
+ for (int i = 0; i < listItem1.getChildCount(); i++) {
+ View view = listItem1.getChildAt(i);
+ view.setOnClickListener(this);
+ }
+ for (int i = 0; i < listItem2.getChildCount(); i++) {
+ View view = listItem2.getChildAt(i);
+ view.setOnClickListener(this);
+ }
+ for (int i = 0; i < listItem3.getChildCount(); i++) {
+ View view = listItem3.getChildAt(i);
+ view.setOnClickListener(this);
+ }
+ }
+
+ @Override
+ public void onClick(View view) {
+ String getText = (String) view.getTag();
+ Common.showToast(getText);
+ }
+}
diff --git a/app/src/main/java/cn/leaqi/drawerapp/Views/UserMenu.java b/app/src/main/java/cn/leaqi/drawerapp/Views/UserMenu.java
new file mode 100644
index 0000000..fe5b613
--- /dev/null
+++ b/app/src/main/java/cn/leaqi/drawerapp/Views/UserMenu.java
@@ -0,0 +1,39 @@
+package cn.leaqi.drawerapp.Views;
+
+import android.app.Activity;
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+
+import cn.leaqi.drawerapp.R;
+import cn.leaqi.drawerapp.Utils.Common;
+
+/**
+ * 左侧边栏用户菜单操作类
+ */
+public class UserMenu implements View.OnClickListener {
+ private Context mContext;
+ private Activity mActivity;
+
+
+ public UserMenu(Context context) {
+ mContext = context;
+ mActivity = ((Activity)mContext);
+ AppInit();
+ }
+
+ private void AppInit() {
+ final ViewGroup listItem = mActivity.findViewById(R.id.listItem);
+
+ for (int i = 0; i < listItem.getChildCount(); i++) {
+ View view = listItem.getChildAt(i);
+ view.setOnClickListener(this);
+ }
+ }
+
+ @Override
+ public void onClick(View view) {
+ String getText = (String) view.getTag();
+ Common.showToast(getText);
+ }
+}
diff --git a/app/src/main/java/cn/leaqi/drawerapp/Views/UserShare.java b/app/src/main/java/cn/leaqi/drawerapp/Views/UserShare.java
new file mode 100644
index 0000000..a05ead8
--- /dev/null
+++ b/app/src/main/java/cn/leaqi/drawerapp/Views/UserShare.java
@@ -0,0 +1,46 @@
+package cn.leaqi.drawerapp.Views;
+
+import android.app.Activity;
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+
+import cn.leaqi.drawerapp.R;
+import cn.leaqi.drawerapp.Utils.Common;
+import cn.leaqi.drawer.SwipeDrawer;
+
+/**
+ * 视频布局用户分享类
+ */
+public class UserShare implements View.OnClickListener {
+ private Context mContext;
+ private Activity mActivity;
+ private SwipeDrawer rootDrawer;
+
+ public UserShare(Context context) {
+ mContext = context;
+ mActivity = ((Activity)mContext);
+ rootDrawer = mActivity.findViewById(R.id.rootDrawer);
+ AppInit();
+ }
+
+ private void AppInit() {
+ final ViewGroup shareBox1 = mActivity.findViewById(R.id.shareBox1);
+ final ViewGroup shareBox2 = mActivity.findViewById(R.id.shareBox2);
+ for (int i = 0; i < shareBox1.getChildCount(); i++) {
+ View view = shareBox1.getChildAt(i);
+ view.setOnClickListener(this);
+ }
+ for (int i = 0; i < shareBox2.getChildCount(); i++) {
+ View view = shareBox2.getChildAt(i);
+ view.setOnClickListener(this);
+ }
+ }
+
+ @Override
+ public void onClick(View view) {
+ String getText = (String) view.getTag();
+ Common.showToast(getText);
+ rootDrawer.closeDrawer();
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/cn/leaqi/drawerapp/Views/VideoPlay.java b/app/src/main/java/cn/leaqi/drawerapp/Views/VideoPlay.java
new file mode 100644
index 0000000..9db618b
--- /dev/null
+++ b/app/src/main/java/cn/leaqi/drawerapp/Views/VideoPlay.java
@@ -0,0 +1,324 @@
+package cn.leaqi.drawerapp.Views;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.media.MediaPlayer;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.animation.AlphaAnimation;
+import android.view.animation.Animation;
+import android.view.animation.AnimationSet;
+import android.view.animation.ScaleAnimation;
+import android.widget.SeekBar;
+import android.widget.VideoView;
+
+import cn.leaqi.drawerapp.R;
+import cn.leaqi.drawer.SwipeDrawer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 自定义VideoView视频播放器
+ */
+public class VideoPlay extends VideoView implements MediaPlayer.OnErrorListener,View.OnClickListener {
+
+ private static final List lastPlay = new ArrayList<>();
+
+ private boolean init = false;
+ private boolean drag = false;
+
+ private boolean isPlay = false;
+
+ private int loadId = -1;
+ private int playId = -1;
+ private int pauseId = -1;
+ private int seekId = -1;
+ private View loadView = null;
+ private View playView = null;
+ private View pauseView = null;
+ private SeekBar seekView = null;
+ private OnPlayState onPlayState = null;
+
+ public interface OnPlayState {
+ void onStart(VideoPlay view);
+ void onPlay(VideoPlay view);
+ void onStop(VideoPlay view);
+ void onError(VideoPlay view);
+ }
+
+ public VideoPlay(Context context) {
+ super(context);
+ Init(context, null);
+ }
+
+ public VideoPlay(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ Init(context, attrs);
+ }
+
+ public VideoPlay(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ Init(context, attrs);
+ }
+
+ private void Init(Context context, AttributeSet attrs) {
+ if (attrs != null) {
+ final TypedArray attrArr = context.obtainStyledAttributes(attrs, R.styleable.VideoPlay);
+ playId = attrArr.getResourceId(R.styleable.VideoPlay_playId, playId);
+ pauseId = attrArr.getResourceId(R.styleable.VideoPlay_pauseId, pauseId);
+ seekId = attrArr.getResourceId(R.styleable.VideoPlay_seekId, seekId);
+ loadId = attrArr.getResourceId(R.styleable.VideoPlay_loadId, loadId);
+ attrArr.recycle();
+ }
+ setOnErrorListener(this);
+ setOnClickListener(this);
+ setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
+ @Override
+ public void onPrepared(MediaPlayer mediaPlayer) {
+ isPlay = true;
+ loadAnim(false);
+ if (onPlayState != null) onPlayState.onPlay(VideoPlay.this);
+ }
+ });
+ setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
+ @Override
+ public void onCompletion(MediaPlayer mediaPlayer) {
+ mediaPlayer.start();
+ mediaPlayer.setLooping(true);
+ }
+ });
+ }
+
+ public void setOnPlayState(OnPlayState call) {
+ onPlayState = call;
+ }
+
+ private void upProgress() {
+ final int duration = getDuration();
+ if (seekView != null) {
+ seekView.setMax(duration);
+ new Thread() {
+ @Override
+ public void run() {
+ try {
+ while (isPlaying() && !drag) {
+ /*int current = getCurrentPosition();
+ int progress = Math.round(((float) current / duration) * 100);
+ System.out.println("current : " + current + " - " + progress);*/
+ seekView.post(new Runnable() {
+ @Override
+ public void run() {
+ if (drag) return;
+ seekView.setProgress(getCurrentPosition());
+ }
+ });
+ sleep(500);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }.start();
+ }
+ }
+
+ private void upViews(boolean play) {
+ if (play) {
+ if(playView != null) playView.setVisibility(GONE);
+ if(pauseView != null) pauseView.setVisibility(VISIBLE);
+ } else {
+ if(playView != null) playView.setVisibility(VISIBLE);
+ if(pauseView != null) pauseView.setVisibility(GONE);
+ }
+ }
+
+ private void loadAnim(boolean bool) {
+ if (loadView != null) {
+ if (bool) {
+ ScaleAnimation scale = new ScaleAnimation(0.3f, 1f, 1f, 1f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
+ scale.setRepeatCount(-1);
+ AlphaAnimation alpha = new AlphaAnimation(1f, 0.3f);
+ alpha.setRepeatCount(-1);
+ AnimationSet anim = new AnimationSet(true);
+ anim.addAnimation(scale);
+ anim.addAnimation(alpha);
+ anim.setDuration(300);
+ loadView.startAnimation(anim);
+ loadView.setVisibility(VISIBLE);
+ } else {
+ loadView.clearAnimation();
+ loadView.setVisibility(GONE);
+ }
+ }
+ if (seekView != null) {
+ if (bool) {
+ seekView.setVisibility(GONE);
+ } else {
+ seekView.setVisibility(VISIBLE);
+ }
+ }
+ }
+
+ public static void setViewAlpha(float alpha) {
+ if (lastPlay.size() > 0) {
+ for (VideoPlay view : lastPlay) {
+ if (view.seekView != null) {
+ view.seekView.setAlpha(alpha);
+ }
+ if (view.playView != null) {
+ view.playView.setAlpha(alpha);
+ }
+ if (view.pauseView != null) {
+ view.pauseView.setAlpha(alpha);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void start() {
+ if (lastPlay.indexOf(this) == -1) lastPlay.add(this);
+ super.start();
+ upProgress();
+ upViews(true);
+ if (isPlay) {
+ if (onPlayState != null) onPlayState.onPlay(this);
+ } else {
+ loadAnim(true);
+ if (onPlayState != null) onPlayState.onStart(this);
+ }
+ }
+
+ @Override
+ public void pause() {
+ super.pause();
+ upViews(false);
+ if (onPlayState != null) onPlayState.onStop(this);
+ }
+
+ @Override
+ public void resume() {
+ if (lastPlay.indexOf(this) == -1) lastPlay.add(this);
+ super.resume();
+ upProgress();
+ upViews(true);
+ if (onPlayState != null) onPlayState.onPlay(this);
+ }
+
+ @Override
+ public void stopPlayback() {
+ super.stopPlayback();
+ }
+
+ @Override
+ public void onClick(View view) {
+ if (view == pauseView) {
+ if (isPlaying()) {
+ pause();
+ }
+ } else if (view == playView) {
+ start();
+ }
+ }
+
+ @Override
+ public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
+ System.out.println("MediaPlayer : " + mediaPlayer + " - " + i + " - " + i1);
+ if (onPlayState != null) onPlayState.onPlay(this);
+ return true;
+ }
+
+ /*@Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ int width = getDefaultSize(0, widthMeasureSpec);
+ int height = getDefaultSize(0, heightMeasureSpec);
+ setMeasuredDimension(width, height);
+ }*/
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+ if (!init) {
+ View parent = (View) getParent();
+ if (parent != null) {
+ View view;
+ if (playId != -1) {
+ view = parent.findViewById(playId);
+ if (view != null) {
+ playView = view;
+ playView.setOnClickListener(this);
+ }
+ }
+ if (pauseId != -1) {
+ view = parent.findViewById(pauseId);
+ if (view != null) {
+ pauseView = view;
+ pauseView.setVisibility(VISIBLE);
+ pauseView.setOnClickListener(this);
+ }
+ }
+ if (loadId != -1) {
+ view = parent.findViewById(loadId);
+ if (view != null) {
+ loadView = view;
+ loadAnim(true);
+ }
+ }
+ if (seekId != -1) {
+ view = parent.findViewById(seekId);
+ if (view instanceof SeekBar) {
+ seekView = (SeekBar) view;
+ seekView.setVisibility(GONE);
+ seekView.setOnTouchListener(new OnTouchListener() {
+ @Override
+ public boolean onTouch(View view, MotionEvent ev) {
+ switch (ev.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ SwipeDrawer.setAllIntercept(true);
+ break;
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ SwipeDrawer.setAllIntercept(false);
+ break;
+ }
+ return false;
+ }
+ });
+ seekView.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
+ if (b) {
+ seekTo(i);
+ }
+ }
+
+ @Override
+ public void onStartTrackingTouch(final SeekBar seekBar) {
+ drag = true;
+ seekBar.setScaleX(2f);
+ seekBar.setScaleY(2f);
+ }
+
+ @Override
+ public void onStopTrackingTouch(final SeekBar seekBar) {
+ drag = false;
+ seekBar.setScaleX(1f);
+ seekBar.setScaleY(1f);
+ upProgress();
+ }
+ });
+ }
+ }
+ }
+ init = true;
+ }
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ if (lastPlay.indexOf(this) >= 0) lastPlay.remove(this);
+ super.onDetachedFromWindow();
+ }
+}
diff --git a/app/src/main/res/drawable/fixed_btn_select.xml b/app/src/main/res/drawable/fixed_btn_select.xml
new file mode 100644
index 0000000..75cbc94
--- /dev/null
+++ b/app/src/main/res/drawable/fixed_btn_select.xml
@@ -0,0 +1,15 @@
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/load_anim.xml b/app/src/main/res/drawable/load_anim.xml
new file mode 100644
index 0000000..e38c550
--- /dev/null
+++ b/app/src/main/res/drawable/load_anim.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/menu_color.xml b/app/src/main/res/drawable/menu_color.xml
new file mode 100644
index 0000000..2c47d58
--- /dev/null
+++ b/app/src/main/res/drawable/menu_color.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/app/src/main/res/drawable/menu_item.xml b/app/src/main/res/drawable/menu_item.xml
new file mode 100644
index 0000000..ac5bd31
--- /dev/null
+++ b/app/src/main/res/drawable/menu_item.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/radius_add.xml b/app/src/main/res/drawable/radius_add.xml
new file mode 100644
index 0000000..92c90b0
--- /dev/null
+++ b/app/src/main/res/drawable/radius_add.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/radius_bg.xml b/app/src/main/res/drawable/radius_bg.xml
new file mode 100644
index 0000000..326ee22
--- /dev/null
+++ b/app/src/main/res/drawable/radius_bg.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/radius_bg_top.xml b/app/src/main/res/drawable/radius_bg_top.xml
new file mode 100644
index 0000000..446199a
--- /dev/null
+++ b/app/src/main/res/drawable/radius_bg_top.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/radius_border.xml b/app/src/main/res/drawable/radius_border.xml
new file mode 100644
index 0000000..f24702e
--- /dev/null
+++ b/app/src/main/res/drawable/radius_border.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/radius_cancel.xml b/app/src/main/res/drawable/radius_cancel.xml
new file mode 100644
index 0000000..afc71bc
--- /dev/null
+++ b/app/src/main/res/drawable/radius_cancel.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/radius_follow.xml b/app/src/main/res/drawable/radius_follow.xml
new file mode 100644
index 0000000..7c8faee
--- /dev/null
+++ b/app/src/main/res/drawable/radius_follow.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/radius_grey_top.xml b/app/src/main/res/drawable/radius_grey_top.xml
new file mode 100644
index 0000000..c8bb726
--- /dev/null
+++ b/app/src/main/res/drawable/radius_grey_top.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/radius_grid_item.xml b/app/src/main/res/drawable/radius_grid_item.xml
new file mode 100644
index 0000000..2ef741c
--- /dev/null
+++ b/app/src/main/res/drawable/radius_grid_item.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/radius_icon.xml b/app/src/main/res/drawable/radius_icon.xml
new file mode 100644
index 0000000..c951946
--- /dev/null
+++ b/app/src/main/res/drawable/radius_icon.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/radius_so.xml b/app/src/main/res/drawable/radius_so.xml
new file mode 100644
index 0000000..c2bed9c
--- /dev/null
+++ b/app/src/main/res/drawable/radius_so.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/radius_status.xml b/app/src/main/res/drawable/radius_status.xml
new file mode 100644
index 0000000..63b1ad3
--- /dev/null
+++ b/app/src/main/res/drawable/radius_status.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/radius_tags.xml b/app/src/main/res/drawable/radius_tags.xml
new file mode 100644
index 0000000..fc05e64
--- /dev/null
+++ b/app/src/main/res/drawable/radius_tags.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/radius_value.xml b/app/src/main/res/drawable/radius_value.xml
new file mode 100644
index 0000000..b6c92f1
--- /dev/null
+++ b/app/src/main/res/drawable/radius_value.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/radius_white.xml b/app/src/main/res/drawable/radius_white.xml
new file mode 100644
index 0000000..e5cd0b6
--- /dev/null
+++ b/app/src/main/res/drawable/radius_white.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/radius_white_top.xml b/app/src/main/res/drawable/radius_white_top.xml
new file mode 100644
index 0000000..73df44b
--- /dev/null
+++ b/app/src/main/res/drawable/radius_white_top.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/seek_layer.xml b/app/src/main/res/drawable/seek_layer.xml
new file mode 100644
index 0000000..1d21b2d
--- /dev/null
+++ b/app/src/main/res/drawable/seek_layer.xml
@@ -0,0 +1,17 @@
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/seek_thumb.xml b/app/src/main/res/drawable/seek_thumb.xml
new file mode 100644
index 0000000..c4b8b45
--- /dev/null
+++ b/app/src/main/res/drawable/seek_thumb.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/seek_video_layer.xml b/app/src/main/res/drawable/seek_video_layer.xml
new file mode 100644
index 0000000..45f5e6a
--- /dev/null
+++ b/app/src/main/res/drawable/seek_video_layer.xml
@@ -0,0 +1,15 @@
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/seek_video_thumb.xml b/app/src/main/res/drawable/seek_video_thumb.xml
new file mode 100644
index 0000000..8f2b258
--- /dev/null
+++ b/app/src/main/res/drawable/seek_video_thumb.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_demo1.xml b/app/src/main/res/layout/activity_demo1.xml
new file mode 100644
index 0000000..2d3fe7d
--- /dev/null
+++ b/app/src/main/res/layout/activity_demo1.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_demo10.xml b/app/src/main/res/layout/activity_demo10.xml
new file mode 100644
index 0000000..e29ed26
--- /dev/null
+++ b/app/src/main/res/layout/activity_demo10.xml
@@ -0,0 +1,158 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_demo11.xml b/app/src/main/res/layout/activity_demo11.xml
new file mode 100644
index 0000000..9e84ff7
--- /dev/null
+++ b/app/src/main/res/layout/activity_demo11.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_demo12.xml b/app/src/main/res/layout/activity_demo12.xml
new file mode 100644
index 0000000..5725660
--- /dev/null
+++ b/app/src/main/res/layout/activity_demo12.xml
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_demo13.xml b/app/src/main/res/layout/activity_demo13.xml
new file mode 100644
index 0000000..250ef23
--- /dev/null
+++ b/app/src/main/res/layout/activity_demo13.xml
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_demo14.xml b/app/src/main/res/layout/activity_demo14.xml
new file mode 100644
index 0000000..073d3bb
--- /dev/null
+++ b/app/src/main/res/layout/activity_demo14.xml
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_demo2.xml b/app/src/main/res/layout/activity_demo2.xml
new file mode 100644
index 0000000..5aaf11f
--- /dev/null
+++ b/app/src/main/res/layout/activity_demo2.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_demo3.xml b/app/src/main/res/layout/activity_demo3.xml
new file mode 100644
index 0000000..8a34a1c
--- /dev/null
+++ b/app/src/main/res/layout/activity_demo3.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_demo4.xml b/app/src/main/res/layout/activity_demo4.xml
new file mode 100644
index 0000000..843a54e
--- /dev/null
+++ b/app/src/main/res/layout/activity_demo4.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_demo5.xml b/app/src/main/res/layout/activity_demo5.xml
new file mode 100644
index 0000000..942d2ae
--- /dev/null
+++ b/app/src/main/res/layout/activity_demo5.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_demo6.xml b/app/src/main/res/layout/activity_demo6.xml
new file mode 100644
index 0000000..8d98d26
--- /dev/null
+++ b/app/src/main/res/layout/activity_demo6.xml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_demo7.xml b/app/src/main/res/layout/activity_demo7.xml
new file mode 100644
index 0000000..3b50530
--- /dev/null
+++ b/app/src/main/res/layout/activity_demo7.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_demo8.xml b/app/src/main/res/layout/activity_demo8.xml
new file mode 100644
index 0000000..4994f92
--- /dev/null
+++ b/app/src/main/res/layout/activity_demo8.xml
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_demo9.xml b/app/src/main/res/layout/activity_demo9.xml
new file mode 100644
index 0000000..548eda5
--- /dev/null
+++ b/app/src/main/res/layout/activity_demo9.xml
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..d9fd19f
--- /dev/null
+++ b/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/btn_item.xml b/app/src/main/res/layout/btn_item.xml
new file mode 100644
index 0000000..196a9b6
--- /dev/null
+++ b/app/src/main/res/layout/btn_item.xml
@@ -0,0 +1,9 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/comment_item.xml b/app/src/main/res/layout/comment_item.xml
new file mode 100644
index 0000000..385b30b
--- /dev/null
+++ b/app/src/main/res/layout/comment_item.xml
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/grid_item.xml b/app/src/main/res/layout/grid_item.xml
new file mode 100644
index 0000000..55b48a2
--- /dev/null
+++ b/app/src/main/res/layout/grid_item.xml
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/grid_text.xml b/app/src/main/res/layout/grid_text.xml
new file mode 100644
index 0000000..b2abf34
--- /dev/null
+++ b/app/src/main/res/layout/grid_text.xml
@@ -0,0 +1,17 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/home_item.xml b/app/src/main/res/layout/home_item.xml
new file mode 100644
index 0000000..5e0d6fe
--- /dev/null
+++ b/app/src/main/res/layout/home_item.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/home_tab_item.xml b/app/src/main/res/layout/home_tab_item.xml
new file mode 100644
index 0000000..a748b83
--- /dev/null
+++ b/app/src/main/res/layout/home_tab_item.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_so.xml b/app/src/main/res/layout/item_so.xml
new file mode 100644
index 0000000..cc9662c
--- /dev/null
+++ b/app/src/main/res/layout/item_so.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/list_btn.xml b/app/src/main/res/layout/list_btn.xml
new file mode 100644
index 0000000..fc2d542
--- /dev/null
+++ b/app/src/main/res/layout/list_btn.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/list_icon.xml b/app/src/main/res/layout/list_icon.xml
new file mode 100644
index 0000000..b881313
--- /dev/null
+++ b/app/src/main/res/layout/list_icon.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/list_item.xml b/app/src/main/res/layout/list_item.xml
new file mode 100644
index 0000000..be21c79
--- /dev/null
+++ b/app/src/main/res/layout/list_item.xml
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/main_load.xml b/app/src/main/res/layout/main_load.xml
new file mode 100644
index 0000000..c6418ba
--- /dev/null
+++ b/app/src/main/res/layout/main_load.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/tab_item.xml b/app/src/main/res/layout/tab_item.xml
new file mode 100644
index 0000000..9191e1b
--- /dev/null
+++ b/app/src/main/res/layout/tab_item.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/top_bar.xml b/app/src/main/res/layout/top_bar.xml
new file mode 100644
index 0000000..5ff730f
--- /dev/null
+++ b/app/src/main/res/layout/top_bar.xml
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/user_comment.xml b/app/src/main/res/layout/user_comment.xml
new file mode 100644
index 0000000..3077f70
--- /dev/null
+++ b/app/src/main/res/layout/user_comment.xml
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/user_home.xml b/app/src/main/res/layout/user_home.xml
new file mode 100644
index 0000000..1589afe
--- /dev/null
+++ b/app/src/main/res/layout/user_home.xml
@@ -0,0 +1,255 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/user_info.xml b/app/src/main/res/layout/user_info.xml
new file mode 100644
index 0000000..b49736f
--- /dev/null
+++ b/app/src/main/res/layout/user_info.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/user_list.xml b/app/src/main/res/layout/user_list.xml
new file mode 100644
index 0000000..786c140
--- /dev/null
+++ b/app/src/main/res/layout/user_list.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/user_menu.xml b/app/src/main/res/layout/user_menu.xml
new file mode 100644
index 0000000..45794fc
--- /dev/null
+++ b/app/src/main/res/layout/user_menu.xml
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/user_share.xml b/app/src/main/res/layout/user_share.xml
new file mode 100644
index 0000000..20aff6f
--- /dev/null
+++ b/app/src/main/res/layout/user_share.xml
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/video_item.xml b/app/src/main/res/layout/video_item.xml
new file mode 100644
index 0000000..a4e819e
--- /dev/null
+++ b/app/src/main/res/layout/video_item.xml
@@ -0,0 +1,197 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/video_page.xml b/app/src/main/res/layout/video_page.xml
new file mode 100644
index 0000000..d9a7656
--- /dev/null
+++ b/app/src/main/res/layout/video_page.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/view_page.xml b/app/src/main/res/layout/view_page.xml
new file mode 100644
index 0000000..18ebc75
--- /dev/null
+++ b/app/src/main/res/layout/view_page.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-xhdpi/bg.jpg b/app/src/main/res/mipmap-xhdpi/bg.jpg
new file mode 100644
index 0000000..c970cc5
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/bg.jpg differ
diff --git a/app/src/main/res/mipmap-xhdpi/cover_load.png b/app/src/main/res/mipmap-xhdpi/cover_load.png
new file mode 100644
index 0000000..206e0df
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/cover_load.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/cover_more.png b/app/src/main/res/mipmap-xhdpi/cover_more.png
new file mode 100644
index 0000000..b406f49
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/cover_more.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/follow_add.png b/app/src/main/res/mipmap-xhdpi/follow_add.png
new file mode 100644
index 0000000..a8250d1
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/follow_add.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/follow_ok.png b/app/src/main/res/mipmap-xhdpi/follow_ok.png
new file mode 100644
index 0000000..bc9ced8
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/follow_ok.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/home_black.png b/app/src/main/res/mipmap-xhdpi/home_black.png
new file mode 100644
index 0000000..dcf6637
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/home_black.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/home_msg.png b/app/src/main/res/mipmap-xhdpi/home_msg.png
new file mode 100644
index 0000000..781943d
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/home_msg.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/home_share.png b/app/src/main/res/mipmap-xhdpi/home_share.png
new file mode 100644
index 0000000..23dcce9
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/home_share.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/home_warn.png b/app/src/main/res/mipmap-xhdpi/home_warn.png
new file mode 100644
index 0000000..a03d5ca
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/home_warn.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon.png b/app/src/main/res/mipmap-xhdpi/icon.png
new file mode 100644
index 0000000..fc374f6
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_add.png b/app/src/main/res/mipmap-xhdpi/icon_add.png
new file mode 100644
index 0000000..72a0241
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_add.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_back.png b/app/src/main/res/mipmap-xhdpi/icon_back.png
new file mode 100644
index 0000000..d3a7fa0
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_back.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_bhcs.png b/app/src/main/res/mipmap-xhdpi/icon_bhcs.png
new file mode 100644
index 0000000..5fac9eb
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_bhcs.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_bhcs_1.png b/app/src/main/res/mipmap-xhdpi/icon_bhcs_1.png
new file mode 100644
index 0000000..733154c
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_bhcs_1.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_bottom.png b/app/src/main/res/mipmap-xhdpi/icon_bottom.png
new file mode 100644
index 0000000..228a15e
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_bottom.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_bottom_black.png b/app/src/main/res/mipmap-xhdpi/icon_bottom_black.png
new file mode 100644
index 0000000..3d2fa46
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_bottom_black.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_close.png b/app/src/main/res/mipmap-xhdpi/icon_close.png
new file mode 100644
index 0000000..5508b6e
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_close.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_close_black.png b/app/src/main/res/mipmap-xhdpi/icon_close_black.png
new file mode 100644
index 0000000..c1cae39
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_close_black.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_close_white.png b/app/src/main/res/mipmap-xhdpi/icon_close_white.png
new file mode 100644
index 0000000..4e3973a
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_close_white.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_complete.png b/app/src/main/res/mipmap-xhdpi/icon_complete.png
new file mode 100644
index 0000000..11239fe
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_complete.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_cwtd.png b/app/src/main/res/mipmap-xhdpi/icon_cwtd.png
new file mode 100644
index 0000000..ac6655a
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_cwtd.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_cwtd_1.png b/app/src/main/res/mipmap-xhdpi/icon_cwtd_1.png
new file mode 100644
index 0000000..20e07f6
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_cwtd_1.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_dig_cur.png b/app/src/main/res/mipmap-xhdpi/icon_dig_cur.png
new file mode 100644
index 0000000..ed60bf3
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_dig_cur.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_dig_def.png b/app/src/main/res/mipmap-xhdpi/icon_dig_def.png
new file mode 100644
index 0000000..2e6ae3d
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_dig_def.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_down.png b/app/src/main/res/mipmap-xhdpi/icon_down.png
new file mode 100644
index 0000000..885b7c1
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_down.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_ewm.png b/app/src/main/res/mipmap-xhdpi/icon_ewm.png
new file mode 100644
index 0000000..631e280
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_ewm.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_fav.png b/app/src/main/res/mipmap-xhdpi/icon_fav.png
new file mode 100644
index 0000000..70a5a67
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_fav.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_fav_cur.png b/app/src/main/res/mipmap-xhdpi/icon_fav_cur.png
new file mode 100644
index 0000000..3945e86
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_fav_cur.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_hqly.png b/app/src/main/res/mipmap-xhdpi/icon_hqly.png
new file mode 100644
index 0000000..5637824
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_hqly.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_hqly_1.png b/app/src/main/res/mipmap-xhdpi/icon_hqly_1.png
new file mode 100644
index 0000000..7830f86
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_hqly_1.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_hssy.png b/app/src/main/res/mipmap-xhdpi/icon_hssy.png
new file mode 100644
index 0000000..645aa49
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_hssy.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_hssy_1.png b/app/src/main/res/mipmap-xhdpi/icon_hssy_1.png
new file mode 100644
index 0000000..0b90030
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_hssy_1.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_jdyd.png b/app/src/main/res/mipmap-xhdpi/icon_jdyd.png
new file mode 100644
index 0000000..72efb9a
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_jdyd.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_jdyd_1.png b/app/src/main/res/mipmap-xhdpi/icon_jdyd_1.png
new file mode 100644
index 0000000..9a7840a
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_jdyd_1.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_jzfw.png b/app/src/main/res/mipmap-xhdpi/icon_jzfw.png
new file mode 100644
index 0000000..efc66b4
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_jzfw.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_jzfw_1.png b/app/src/main/res/mipmap-xhdpi/icon_jzfw_1.png
new file mode 100644
index 0000000..e308ed2
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_jzfw_1.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_left.png b/app/src/main/res/mipmap-xhdpi/icon_left.png
new file mode 100644
index 0000000..2ce8b9b
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_left.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_left_black.png b/app/src/main/res/mipmap-xhdpi/icon_left_black.png
new file mode 100644
index 0000000..1374851
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_left_black.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_load.png b/app/src/main/res/mipmap-xhdpi/icon_load.png
new file mode 100644
index 0000000..d43e548
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_load.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_lrmr.png b/app/src/main/res/mipmap-xhdpi/icon_lrmr.png
new file mode 100644
index 0000000..29a6a16
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_lrmr.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_lrmr_1.png b/app/src/main/res/mipmap-xhdpi/icon_lrmr_1.png
new file mode 100644
index 0000000..5a90ddb
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_lrmr_1.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_machine.png b/app/src/main/res/mipmap-xhdpi/icon_machine.png
new file mode 100644
index 0000000..6207709
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_machine.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_menu.png b/app/src/main/res/mipmap-xhdpi/icon_menu.png
new file mode 100644
index 0000000..bbf1f55
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_menu.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_more.png b/app/src/main/res/mipmap-xhdpi/icon_more.png
new file mode 100644
index 0000000..7470dcc
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_more.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_music.png b/app/src/main/res/mipmap-xhdpi/icon_music.png
new file mode 100644
index 0000000..cc3e4d9
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_music.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_note.png b/app/src/main/res/mipmap-xhdpi/icon_note.png
new file mode 100644
index 0000000..c14a93f
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_note.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_over.png b/app/src/main/res/mipmap-xhdpi/icon_over.png
new file mode 100644
index 0000000..ef86da5
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_over.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_play.png b/app/src/main/res/mipmap-xhdpi/icon_play.png
new file mode 100644
index 0000000..232d81d
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_play.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_re.png b/app/src/main/res/mipmap-xhdpi/icon_re.png
new file mode 100644
index 0000000..71e0206
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_re.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_read.png b/app/src/main/res/mipmap-xhdpi/icon_read.png
new file mode 100644
index 0000000..35accf1
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_read.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_right.png b/app/src/main/res/mipmap-xhdpi/icon_right.png
new file mode 100644
index 0000000..e58896c
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_right.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_right_black.png b/app/src/main/res/mipmap-xhdpi/icon_right_black.png
new file mode 100644
index 0000000..0492410
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_right_black.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_say.png b/app/src/main/res/mipmap-xhdpi/icon_say.png
new file mode 100644
index 0000000..8b8d47b
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_say.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_search.png b/app/src/main/res/mipmap-xhdpi/icon_search.png
new file mode 100644
index 0000000..83d4b80
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_search.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_set.png b/app/src/main/res/mipmap-xhdpi/icon_set.png
new file mode 100644
index 0000000..654e5fa
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_set.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_share.png b/app/src/main/res/mipmap-xhdpi/icon_share.png
new file mode 100644
index 0000000..6151fbd
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_share.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_sjhc.png b/app/src/main/res/mipmap-xhdpi/icon_sjhc.png
new file mode 100644
index 0000000..7ce1b7e
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_sjhc.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_sjhc_1.png b/app/src/main/res/mipmap-xhdpi/icon_sjhc_1.png
new file mode 100644
index 0000000..5aad576
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_sjhc_1.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_so.png b/app/src/main/res/mipmap-xhdpi/icon_so.png
new file mode 100644
index 0000000..678b0d6
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_so.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_top.png b/app/src/main/res/mipmap-xhdpi/icon_top.png
new file mode 100644
index 0000000..8208e92
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_top.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_top_black.png b/app/src/main/res/mipmap-xhdpi/icon_top_black.png
new file mode 100644
index 0000000..5e49257
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_top_black.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_up.png b/app/src/main/res/mipmap-xhdpi/icon_up.png
new file mode 100644
index 0000000..1422f20
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_up.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_user.png b/app/src/main/res/mipmap-xhdpi/icon_user.png
new file mode 100644
index 0000000..83fd016
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_user.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_xin.png b/app/src/main/res/mipmap-xhdpi/icon_xin.png
new file mode 100644
index 0000000..61e784b
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_xin.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/load_1.png b/app/src/main/res/mipmap-xhdpi/load_1.png
new file mode 100644
index 0000000..7405707
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/load_1.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/load_10.png b/app/src/main/res/mipmap-xhdpi/load_10.png
new file mode 100644
index 0000000..0d8cc49
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/load_10.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/load_11.png b/app/src/main/res/mipmap-xhdpi/load_11.png
new file mode 100644
index 0000000..3c9bacf
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/load_11.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/load_12.png b/app/src/main/res/mipmap-xhdpi/load_12.png
new file mode 100644
index 0000000..553d1d7
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/load_12.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/load_13.png b/app/src/main/res/mipmap-xhdpi/load_13.png
new file mode 100644
index 0000000..8889550
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/load_13.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/load_14.png b/app/src/main/res/mipmap-xhdpi/load_14.png
new file mode 100644
index 0000000..3177520
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/load_14.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/load_15.png b/app/src/main/res/mipmap-xhdpi/load_15.png
new file mode 100644
index 0000000..6c9e3cd
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/load_15.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/load_16.png b/app/src/main/res/mipmap-xhdpi/load_16.png
new file mode 100644
index 0000000..efee392
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/load_16.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/load_17.png b/app/src/main/res/mipmap-xhdpi/load_17.png
new file mode 100644
index 0000000..90f68af
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/load_17.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/load_18.png b/app/src/main/res/mipmap-xhdpi/load_18.png
new file mode 100644
index 0000000..59e5477
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/load_18.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/load_19.png b/app/src/main/res/mipmap-xhdpi/load_19.png
new file mode 100644
index 0000000..2f3548c
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/load_19.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/load_2.png b/app/src/main/res/mipmap-xhdpi/load_2.png
new file mode 100644
index 0000000..544f0f3
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/load_2.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/load_20.png b/app/src/main/res/mipmap-xhdpi/load_20.png
new file mode 100644
index 0000000..c458462
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/load_20.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/load_21.png b/app/src/main/res/mipmap-xhdpi/load_21.png
new file mode 100644
index 0000000..db694be
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/load_21.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/load_22.png b/app/src/main/res/mipmap-xhdpi/load_22.png
new file mode 100644
index 0000000..b8f47ff
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/load_22.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/load_3.png b/app/src/main/res/mipmap-xhdpi/load_3.png
new file mode 100644
index 0000000..837ea6c
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/load_3.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/load_4.png b/app/src/main/res/mipmap-xhdpi/load_4.png
new file mode 100644
index 0000000..dee22af
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/load_4.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/load_5.png b/app/src/main/res/mipmap-xhdpi/load_5.png
new file mode 100644
index 0000000..54362c9
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/load_5.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/load_6.png b/app/src/main/res/mipmap-xhdpi/load_6.png
new file mode 100644
index 0000000..499e8f8
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/load_6.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/load_7.png b/app/src/main/res/mipmap-xhdpi/load_7.png
new file mode 100644
index 0000000..7653416
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/load_7.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/load_8.png b/app/src/main/res/mipmap-xhdpi/load_8.png
new file mode 100644
index 0000000..bf67caf
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/load_8.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/load_9.png b/app/src/main/res/mipmap-xhdpi/load_9.png
new file mode 100644
index 0000000..4ae02f0
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/load_9.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/pull_back.png b/app/src/main/res/mipmap-xhdpi/pull_back.png
new file mode 100644
index 0000000..3894de0
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/pull_back.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/pull_rider.png b/app/src/main/res/mipmap-xhdpi/pull_rider.png
new file mode 100644
index 0000000..bb21c7b
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/pull_rider.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/pull_sun.png b/app/src/main/res/mipmap-xhdpi/pull_sun.png
new file mode 100644
index 0000000..6b2efe9
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/pull_sun.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/pull_wheel.png b/app/src/main/res/mipmap-xhdpi/pull_wheel.png
new file mode 100644
index 0000000..6c81438
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/pull_wheel.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/radius_back.png b/app/src/main/res/mipmap-xhdpi/radius_back.png
new file mode 100644
index 0000000..7d3ebf7
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/radius_back.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/radius_set.png b/app/src/main/res/mipmap-xhdpi/radius_set.png
new file mode 100644
index 0000000..162db62
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/radius_set.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/seek_cur.png b/app/src/main/res/mipmap-xhdpi/seek_cur.png
new file mode 100644
index 0000000..b5847e3
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/seek_cur.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/seek_def.png b/app/src/main/res/mipmap-xhdpi/seek_def.png
new file mode 100644
index 0000000..321585d
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/seek_def.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/seek_video_cur.png b/app/src/main/res/mipmap-xhdpi/seek_video_cur.png
new file mode 100644
index 0000000..1e37dec
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/seek_video_cur.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/seek_video_def.png b/app/src/main/res/mipmap-xhdpi/seek_video_def.png
new file mode 100644
index 0000000..cc1563a
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/seek_video_def.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/send_at.png b/app/src/main/res/mipmap-xhdpi/send_at.png
new file mode 100644
index 0000000..1ed84da
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/send_at.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/send_bq.png b/app/src/main/res/mipmap-xhdpi/send_bq.png
new file mode 100644
index 0000000..53e110e
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/send_bq.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/send_icon.png b/app/src/main/res/mipmap-xhdpi/send_icon.png
new file mode 100644
index 0000000..aa77aab
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/send_icon.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/send_submit.png b/app/src/main/res/mipmap-xhdpi/send_submit.png
new file mode 100644
index 0000000..ef6dd6d
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/send_submit.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/sex_1.png b/app/src/main/res/mipmap-xhdpi/sex_1.png
new file mode 100644
index 0000000..d397ed0
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/sex_1.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/sex_2.png b/app/src/main/res/mipmap-xhdpi/sex_2.png
new file mode 100644
index 0000000..1902bc4
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/sex_2.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/share_and.png b/app/src/main/res/mipmap-xhdpi/share_and.png
new file mode 100644
index 0000000..bc53892
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/share_and.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/share_code.png b/app/src/main/res/mipmap-xhdpi/share_code.png
new file mode 100644
index 0000000..56601e6
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/share_code.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/share_down.png b/app/src/main/res/mipmap-xhdpi/share_down.png
new file mode 100644
index 0000000..1ce4c70
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/share_down.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/share_edit.png b/app/src/main/res/mipmap-xhdpi/share_edit.png
new file mode 100644
index 0000000..6045729
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/share_edit.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/share_link.png b/app/src/main/res/mipmap-xhdpi/share_link.png
new file mode 100644
index 0000000..1951777
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/share_link.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/share_no.png b/app/src/main/res/mipmap-xhdpi/share_no.png
new file mode 100644
index 0000000..0013071
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/share_no.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/share_pyq.png b/app/src/main/res/mipmap-xhdpi/share_pyq.png
new file mode 100644
index 0000000..1136570
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/share_pyq.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/share_qq.png b/app/src/main/res/mipmap-xhdpi/share_qq.png
new file mode 100644
index 0000000..0da6733
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/share_qq.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/share_qz.png b/app/src/main/res/mipmap-xhdpi/share_qz.png
new file mode 100644
index 0000000..e963c44
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/share_qz.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/share_relay.png b/app/src/main/res/mipmap-xhdpi/share_relay.png
new file mode 100644
index 0000000..d164807
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/share_relay.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/share_send.png b/app/src/main/res/mipmap-xhdpi/share_send.png
new file mode 100644
index 0000000..d254041
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/share_send.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/share_wb.png b/app/src/main/res/mipmap-xhdpi/share_wb.png
new file mode 100644
index 0000000..c8a5e62
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/share_wb.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/share_wran.png b/app/src/main/res/mipmap-xhdpi/share_wran.png
new file mode 100644
index 0000000..da9f75d
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/share_wran.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/share_wx.png b/app/src/main/res/mipmap-xhdpi/share_wx.png
new file mode 100644
index 0000000..94810fc
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/share_wx.png differ
diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml
new file mode 100644
index 0000000..f8613e7
--- /dev/null
+++ b/app/src/main/res/values/attrs.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..8731fcb
--- /dev/null
+++ b/app/src/main/res/values/colors.xml
@@ -0,0 +1,9 @@
+
+
+ #00acf1
+ #049AD6
+ #E91E4D
+ #161722
+ #555555
+ #999999
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..ac4a533
--- /dev/null
+++ b/app/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ DrawerApp
+
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..01ba5cb
--- /dev/null
+++ b/app/src/main/res/values/styles.xml
@@ -0,0 +1,399 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/xml/network_security_config.xml b/app/src/main/res/xml/network_security_config.xml
new file mode 100644
index 0000000..dca93c0
--- /dev/null
+++ b/app/src/main/res/xml/network_security_config.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..18f2562
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,23 @@
+
+buildscript {
+ repositories {
+ google()
+ mavenCentral()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:3.5.2'
+ classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
+ }
+}
+
+allprojects {
+ repositories {
+ google()
+ mavenCentral()
+ maven { url "https://jitpack.io" }
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/drawer/build.gradle b/drawer/build.gradle
new file mode 100644
index 0000000..6bb1aa4
--- /dev/null
+++ b/drawer/build.gradle
@@ -0,0 +1,23 @@
+apply plugin: 'com.android.library'
+apply plugin: 'com.github.dcendents.android-maven'
+group='com.github.Leaqi'
+version='1.0'
+
+android {
+ compileSdkVersion 29
+ buildToolsVersion "29.0.3"
+
+ defaultConfig {
+ minSdkVersion 14
+ targetSdkVersion 29
+ versionCode 1
+ versionName version
+ consumerProguardFiles 'consumer-rules.pro'
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+}
\ No newline at end of file
diff --git a/drawer/consumer-rules.pro b/drawer/consumer-rules.pro
new file mode 100644
index 0000000..e69de29
diff --git a/drawer/proguard-rules.pro b/drawer/proguard-rules.pro
new file mode 100644
index 0000000..f1b4245
--- /dev/null
+++ b/drawer/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/drawer/src/main/AndroidManifest.xml b/drawer/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..1ab2970
--- /dev/null
+++ b/drawer/src/main/AndroidManifest.xml
@@ -0,0 +1 @@
+
diff --git a/drawer/src/main/java/cn/leaqi/drawer/AnimThread.java b/drawer/src/main/java/cn/leaqi/drawer/AnimThread.java
new file mode 100644
index 0000000..a439be1
--- /dev/null
+++ b/drawer/src/main/java/cn/leaqi/drawer/AnimThread.java
@@ -0,0 +1,126 @@
+/*
+ Copyright 2022 Leaqi
+
+ 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 cn.leaqi.drawer;
+
+import android.view.animation.AccelerateDecelerateInterpolator;
+import android.view.animation.Interpolator;
+
+/**
+ * AnimThread by animation processing class
+ * Created by Leaqi.
+ * Github: https://github.com/Leaqi
+ */
+public class AnimThread extends Thread {
+
+ private static int FPS = 100;
+
+ private int setDuration;
+ private boolean isStop = false;
+ private boolean isEnd = false;
+ private boolean isAlive = true;
+
+ private Interpolator animInterpolator;
+
+ public AnimThread(int duration, Interpolator interpolator) {
+ setDuration = duration;
+ animInterpolator = interpolator == null ? new AccelerateDecelerateInterpolator() : interpolator;
+ onInit();
+ start();
+ }
+
+ protected void onInit() {}
+
+ protected void onEnd() {}
+
+ protected void onUpdate(float value) {}
+
+ public void setStop() {
+ isStop = true;
+ }
+
+ public void setEnd() {
+ isEnd = true;
+ }
+
+ public void setAlive() {
+ isAlive = false;
+ }
+
+ public static void setFPS(int num) {
+ FPS = num;
+ }
+
+ public boolean getStop() {
+ return isStop;
+ }
+
+ public boolean getEnd() {
+ return isEnd;
+ }
+
+ public boolean getAlive() {
+ return isAlive;
+ }
+
+ public static int getFPS() {
+ return FPS;
+ }
+
+ public float getInterpolation(float t) {
+ if (animInterpolator != null) {
+ return animInterpolator.getInterpolation(t);
+ } else {
+ return t;
+ }
+ }
+
+ @Override
+ public void run() {
+ if (setDuration > 0) {
+ int sSleep = Math.round(1000 / FPS);
+ int iNum = 0;
+ float eNum = ((float) setDuration / 1000) * FPS;
+ float value = 0;
+ while (iNum < eNum) {
+ if (isEnd) break;
+ if (isStop) return;
+ try {
+ Thread.sleep(sSleep);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ value = getInterpolation(iNum / eNum);
+ onUpdate(value);
+ iNum++;
+ }
+ if (value < 1) {
+ onUpdate(1);
+ }
+ } else {
+ onUpdate(1);
+ }
+ onEnd();
+ }
+
+ public static boolean isThread(AnimThread thread) {
+ if (thread != null) {
+ return thread.getAlive() || thread.isAlive();
+ } else {
+ return false;
+ }
+ }
+
+}
diff --git a/drawer/src/main/java/cn/leaqi/drawer/DrawerHolder.java b/drawer/src/main/java/cn/leaqi/drawer/DrawerHolder.java
new file mode 100644
index 0000000..5f19fca
--- /dev/null
+++ b/drawer/src/main/java/cn/leaqi/drawer/DrawerHolder.java
@@ -0,0 +1,116 @@
+/*
+ Copyright 2022 Leaqi
+
+ 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 cn.leaqi.drawer;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * The function of DrawerHolder is to save the state of SwipeDrawer
+ * Created by Leaqi.
+ * Github: https://github.com/Leaqi
+ */
+public class DrawerHolder implements OnDrawerSwitch {
+
+ private Map listView = Collections.synchronizedMap(new HashMap());
+ private Map