Compare commits

..

No commits in common. "main" and "medicine" have entirely different histories.

1482 changed files with 2829940 additions and 37 deletions

41
.gitignore vendored
View File

@ -1,35 +1,6 @@
# ---> Android
# Gradle files
.gradle/
build/
# Local configuration file (sdk path, etc)
local.properties
# Log/OS Files
*.log
# Android Studio generated files and folders
captures/
.externalNativeBuild/
.cxx/
*.apk
output.json
# IntelliJ
*.iml
.idea/
misc.xml
deploymentTargetDropDown.xml
render.experimental.xml
# Keystore files
*.jks
*.keystore
# Google Services (e.g. APIs or Firebase)
google-services.json
# Android Profiling
*.hprof
/build
/gradle
caches
.idea
wrapper
/zhuike/release

View File

@ -0,0 +1 @@
#Mon Dec 12 23:14:59 CST 2016

View File

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="WizardSettings">
<option name="children">
<map>
<entry key="imageWizard">
<value>
<PersistentState />
</value>
</entry>
<entry key="vectorWizard">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="vectorAssetStep">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="clipartAsset">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="url" value="jar:file:/D:/Program%20Files/Android/Android%20Studio/plugins/android/lib/android.jar!/images/material_design_icons/action/ic_feedback_black_24dp.xml" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
<option name="values">
<map>
<entry key="color" value="ffffff" />
<entry key="outputName" value="ic_feedback_black_24dp" />
<entry key="sourceFile" value="C:\Users\wm" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</component>
</project>

View File

@ -0,0 +1,12 @@
<component name="libraryTable">
<library name="Gradle: android.arch.core:runtime:1.1.1@aar" external-system-id="GRADLE">
<CLASSES>
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/9998df719cfe7769cf2116a029db41eb/runtime-1.1.1/AndroidManifest.xml" />
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/9998df719cfe7769cf2116a029db41eb/runtime-1.1.1/jars/classes.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/android.arch.core/runtime/1.1.1/25df553df10af32bede9dd768a2d15299543d84/runtime-1.1.1-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,12 @@
<component name="libraryTable">
<library name="Gradle: android.arch.lifecycle:livedata:1.1.1@aar" external-system-id="GRADLE">
<CLASSES>
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/3b4d1627b74edb955dc2b172f543a439/livedata-1.1.1/AndroidManifest.xml" />
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/3b4d1627b74edb955dc2b172f543a439/livedata-1.1.1/jars/classes.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/android.arch.lifecycle/livedata/1.1.1/bf27acaa4953c98cd519756ed7b7caacf94407d4/livedata-1.1.1-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,12 @@
<component name="libraryTable">
<library name="Gradle: android.arch.lifecycle:livedata-core:1.1.1@aar" external-system-id="GRADLE">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/142bc8fa9d0f8aea450b230db58064f6/livedata-core-1.1.1/jars/classes.jar!/" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/142bc8fa9d0f8aea450b230db58064f6/livedata-core-1.1.1/AndroidManifest.xml" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/android.arch.lifecycle/livedata-core/1.1.1/c38818e006ea7a408c05e3090364332d46494ef/livedata-core-1.1.1-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,12 @@
<component name="libraryTable">
<library name="Gradle: android.arch.lifecycle:runtime:1.1.1@aar" external-system-id="GRADLE">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/c273fd5482f711c674e1e33078e800bd/runtime-1.1.1/jars/classes.jar!/" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/c273fd5482f711c674e1e33078e800bd/runtime-1.1.1/AndroidManifest.xml" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/android.arch.lifecycle/runtime/1.1.1/8e4214221b3797b863dc9998d16abb4af043e784/runtime-1.1.1-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,12 @@
<component name="libraryTable">
<library name="Gradle: android.arch.lifecycle:viewmodel:1.1.1@aar" external-system-id="GRADLE">
<CLASSES>
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/cb7dd7624a4e48ab7eef500ac270ec45/viewmodel-1.1.1/AndroidManifest.xml" />
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/cb7dd7624a4e48ab7eef500ac270ec45/viewmodel-1.1.1/jars/classes.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/android.arch.lifecycle/viewmodel/1.1.1/d1cc8e805317f171be63c68341f499acda7e42d6/viewmodel-1.1.1-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="Gradle: com.android.support:animated-vector-drawable:28.0.0@aar" external-system-id="GRADLE">
<CLASSES>
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/ce0bc6c0ba910628d730fa0dee6b8470/animated-vector-drawable-28.0.0/AndroidManifest.xml" />
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/ce0bc6c0ba910628d730fa0dee6b8470/animated-vector-drawable-28.0.0/jars/classes.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,14 @@
<component name="libraryTable">
<library name="Gradle: com.android.support:appcompat-v7:28.0.0@aar" external-system-id="GRADLE">
<ANNOTATIONS>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/43a056e8e1abc4dff482f7ba71806374/appcompat-v7-28.0.0/annotations.zip!/" />
</ANNOTATIONS>
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/43a056e8e1abc4dff482f7ba71806374/appcompat-v7-28.0.0/jars/classes.jar!/" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/43a056e8e1abc4dff482f7ba71806374/appcompat-v7-28.0.0/AndroidManifest.xml" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/43a056e8e1abc4dff482f7ba71806374/appcompat-v7-28.0.0/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="Gradle: com.android.support:asynclayoutinflater:28.0.0@aar" external-system-id="GRADLE">
<CLASSES>
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/70517e14c4b230786481abe3dc955417/asynclayoutinflater-28.0.0/AndroidManifest.xml" />
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/70517e14c4b230786481abe3dc955417/asynclayoutinflater-28.0.0/jars/classes.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,11 @@
<component name="libraryTable">
<library name="Gradle: com.android.support:cardview-v7:28.0.0@aar" external-system-id="GRADLE">
<CLASSES>
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/9f5d1fd5fdd344c196572d15e858880e/cardview-v7-28.0.0/res" />
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/9f5d1fd5fdd344c196572d15e858880e/cardview-v7-28.0.0/jars/classes.jar!/" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/9f5d1fd5fdd344c196572d15e858880e/cardview-v7-28.0.0/AndroidManifest.xml" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,11 @@
<component name="libraryTable">
<library name="Gradle: com.android.support.constraint:constraint-layout:1.1.3@aar" external-system-id="GRADLE">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/5b7bf93e0f8053ae00e85352f83a4186/constraint-layout-1.1.3/jars/classes.jar!/" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/5b7bf93e0f8053ae00e85352f83a4186/constraint-layout-1.1.3/res" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/5b7bf93e0f8053ae00e85352f83a4186/constraint-layout-1.1.3/AndroidManifest.xml" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,14 @@
<component name="libraryTable">
<library name="Gradle: com.android.support:coordinatorlayout:28.0.0@aar" external-system-id="GRADLE">
<ANNOTATIONS>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/cc389bc1f11c296ea06e8c6705804f7e/coordinatorlayout-28.0.0/annotations.zip!/" />
</ANNOTATIONS>
<CLASSES>
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/cc389bc1f11c296ea06e8c6705804f7e/coordinatorlayout-28.0.0/AndroidManifest.xml" />
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/cc389bc1f11c296ea06e8c6705804f7e/coordinatorlayout-28.0.0/jars/classes.jar!/" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/cc389bc1f11c296ea06e8c6705804f7e/coordinatorlayout-28.0.0/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="Gradle: com.android.support:cursoradapter:28.0.0@aar" external-system-id="GRADLE">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/02309bb5ec38fc8522fc324bb53ad5cb/cursoradapter-28.0.0/jars/classes.jar!/" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/02309bb5ec38fc8522fc324bb53ad5cb/cursoradapter-28.0.0/AndroidManifest.xml" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="Gradle: com.android.support:customview:28.0.0@aar" external-system-id="GRADLE">
<CLASSES>
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/4c9619195032b444b439296d0f6ffb95/customview-28.0.0/AndroidManifest.xml" />
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/4c9619195032b444b439296d0f6ffb95/customview-28.0.0/jars/classes.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,14 @@
<component name="libraryTable">
<library name="Gradle: com.android.support:design:28.0.0@aar" external-system-id="GRADLE">
<ANNOTATIONS>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/d7d4f3582e5b79d22421953532359be5/design-28.0.0/annotations.zip!/" />
</ANNOTATIONS>
<CLASSES>
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/d7d4f3582e5b79d22421953532359be5/design-28.0.0/res" />
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/d7d4f3582e5b79d22421953532359be5/design-28.0.0/jars/classes.jar!/" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/d7d4f3582e5b79d22421953532359be5/design-28.0.0/AndroidManifest.xml" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="Gradle: com.android.support:documentfile:28.0.0@aar" external-system-id="GRADLE">
<CLASSES>
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/f755063c375a935d59a5f1339651e62e/documentfile-28.0.0/AndroidManifest.xml" />
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/f755063c375a935d59a5f1339651e62e/documentfile-28.0.0/jars/classes.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Gradle: com.android.support:drawerlayout:28.0.0@aar" external-system-id="GRADLE">
<ANNOTATIONS>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/906e72cb6b2a2068ad150344cd2281eb/drawerlayout-28.0.0/annotations.zip!/" />
</ANNOTATIONS>
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/906e72cb6b2a2068ad150344cd2281eb/drawerlayout-28.0.0/jars/classes.jar!/" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/906e72cb6b2a2068ad150344cd2281eb/drawerlayout-28.0.0/AndroidManifest.xml" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="Gradle: com.android.support:interpolator:28.0.0@aar" external-system-id="GRADLE">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/37678cad1a370a7c0f06f2887f158f40/interpolator-28.0.0/jars/classes.jar!/" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/37678cad1a370a7c0f06f2887f158f40/interpolator-28.0.0/AndroidManifest.xml" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="Gradle: com.android.support:loader:28.0.0@aar" external-system-id="GRADLE">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/36a78670f0a5619cd5f8fd1a5c14e869/loader-28.0.0/jars/classes.jar!/" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/36a78670f0a5619cd5f8fd1a5c14e869/loader-28.0.0/AndroidManifest.xml" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="Gradle: com.android.support:localbroadcastmanager:28.0.0@aar" external-system-id="GRADLE">
<CLASSES>
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/7372ba5d776bde24b3c538b3ef56508e/localbroadcastmanager-28.0.0/AndroidManifest.xml" />
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/7372ba5d776bde24b3c538b3ef56508e/localbroadcastmanager-28.0.0/jars/classes.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Gradle: com.android.support:print:28.0.0@aar" external-system-id="GRADLE">
<ANNOTATIONS>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/f469d85215fe7cbba8e984751c3da810/print-28.0.0/annotations.zip!/" />
</ANNOTATIONS>
<CLASSES>
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/f469d85215fe7cbba8e984751c3da810/print-28.0.0/AndroidManifest.xml" />
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/f469d85215fe7cbba8e984751c3da810/print-28.0.0/jars/classes.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,14 @@
<component name="libraryTable">
<library name="Gradle: com.android.support:recyclerview-v7:28.0.0@aar" external-system-id="GRADLE">
<ANNOTATIONS>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/0f9c9fe40a240b8da55e7f2e763081a6/recyclerview-v7-28.0.0/annotations.zip!/" />
</ANNOTATIONS>
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/0f9c9fe40a240b8da55e7f2e763081a6/recyclerview-v7-28.0.0/jars/classes.jar!/" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/0f9c9fe40a240b8da55e7f2e763081a6/recyclerview-v7-28.0.0/res" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/0f9c9fe40a240b8da55e7f2e763081a6/recyclerview-v7-28.0.0/AndroidManifest.xml" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="Gradle: com.android.support:slidingpanelayout:28.0.0@aar" external-system-id="GRADLE">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/9e72e6eac7e3c9ac5692baa9dc946ddc/slidingpanelayout-28.0.0/jars/classes.jar!/" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/9e72e6eac7e3c9ac5692baa9dc946ddc/slidingpanelayout-28.0.0/AndroidManifest.xml" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,14 @@
<component name="libraryTable">
<library name="Gradle: com.android.support:support-compat:28.0.0@aar" external-system-id="GRADLE">
<ANNOTATIONS>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/48a53f71b3f6afbc0776ad29d9c64e19/support-compat-28.0.0/annotations.zip!/" />
</ANNOTATIONS>
<CLASSES>
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/48a53f71b3f6afbc0776ad29d9c64e19/support-compat-28.0.0/res" />
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/48a53f71b3f6afbc0776ad29d9c64e19/support-compat-28.0.0/jars/classes.jar!/" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/48a53f71b3f6afbc0776ad29d9c64e19/support-compat-28.0.0/AndroidManifest.xml" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="Gradle: com.android.support:support-core-ui:28.0.0@aar" external-system-id="GRADLE">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/b930089b52491710e9ec87d12afb293e/support-core-ui-28.0.0/jars/classes.jar!/" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/b930089b52491710e9ec87d12afb293e/support-core-ui-28.0.0/AndroidManifest.xml" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="Gradle: com.android.support:support-core-utils:28.0.0@aar" external-system-id="GRADLE">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/a87da87b0aaf2b51ef846785b1e5f962/support-core-utils-28.0.0/jars/classes.jar!/" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/a87da87b0aaf2b51ef846785b1e5f962/support-core-utils-28.0.0/AndroidManifest.xml" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Gradle: com.android.support:support-fragment:28.0.0@aar" external-system-id="GRADLE">
<ANNOTATIONS>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/1a4c8aa7d5a0eed80b973de001dc442c/support-fragment-28.0.0/annotations.zip!/" />
</ANNOTATIONS>
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/1a4c8aa7d5a0eed80b973de001dc442c/support-fragment-28.0.0/jars/classes.jar!/" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/1a4c8aa7d5a0eed80b973de001dc442c/support-fragment-28.0.0/AndroidManifest.xml" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,14 @@
<component name="libraryTable">
<library name="Gradle: com.android.support:support-media-compat:28.0.0@aar" external-system-id="GRADLE">
<ANNOTATIONS>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/57a36daf7befb6df84518d0c42361719/support-media-compat-28.0.0/annotations.zip!/" />
</ANNOTATIONS>
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/57a36daf7befb6df84518d0c42361719/support-media-compat-28.0.0/jars/classes.jar!/" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/57a36daf7befb6df84518d0c42361719/support-media-compat-28.0.0/AndroidManifest.xml" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/57a36daf7befb6df84518d0c42361719/support-media-compat-28.0.0/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="Gradle: com.android.support:support-v4:28.0.0@aar" external-system-id="GRADLE">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/14df0b94c2fe3a4847e1ec69893810c2/support-v4-28.0.0/jars/classes.jar!/" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/14df0b94c2fe3a4847e1ec69893810c2/support-v4-28.0.0/AndroidManifest.xml" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="Gradle: com.android.support:support-vector-drawable:28.0.0@aar" external-system-id="GRADLE">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/4a2987f78d4a69b363df9edaf245f443/support-vector-drawable-28.0.0/jars/classes.jar!/" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/4a2987f78d4a69b363df9edaf245f443/support-vector-drawable-28.0.0/AndroidManifest.xml" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Gradle: com.android.support:swiperefreshlayout:28.0.0@aar" external-system-id="GRADLE">
<ANNOTATIONS>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/8693cd07b9d3424279c0b90b1e669016/swiperefreshlayout-28.0.0/annotations.zip!/" />
</ANNOTATIONS>
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/8693cd07b9d3424279c0b90b1e669016/swiperefreshlayout-28.0.0/jars/classes.jar!/" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/8693cd07b9d3424279c0b90b1e669016/swiperefreshlayout-28.0.0/AndroidManifest.xml" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,14 @@
<component name="libraryTable">
<library name="Gradle: com.android.support:transition:28.0.0@aar" external-system-id="GRADLE">
<ANNOTATIONS>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/a127590709832facb297d0ea7736f005/transition-28.0.0/annotations.zip!/" />
</ANNOTATIONS>
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/a127590709832facb297d0ea7736f005/transition-28.0.0/jars/classes.jar!/" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/a127590709832facb297d0ea7736f005/transition-28.0.0/res" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/a127590709832facb297d0ea7736f005/transition-28.0.0/AndroidManifest.xml" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="Gradle: com.android.support:versionedparcelable:28.0.0@aar" external-system-id="GRADLE">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/92dec29e650c4e0ac0103f64078175f1/versionedparcelable-28.0.0/jars/classes.jar!/" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/92dec29e650c4e0ac0103f64078175f1/versionedparcelable-28.0.0/AndroidManifest.xml" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="Gradle: com.android.support:viewpager:28.0.0@aar" external-system-id="GRADLE">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/1cab75f978e25ba5b2062e19cc30cc7c/viewpager-28.0.0/jars/classes.jar!/" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/1cab75f978e25ba5b2062e19cc30cc7c/viewpager-28.0.0/AndroidManifest.xml" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,15 @@
<component name="libraryTable">
<library name="Gradle: com.astuetz:pagerslidingtabstrip:1.0.1@aar" external-system-id="GRADLE">
<CLASSES>
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/9a65bf875b1486d582d553a1f172d422/pagerslidingtabstrip-1.0.1/AndroidManifest.xml" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/9a65bf875b1486d582d553a1f172d422/pagerslidingtabstrip-1.0.1/res" />
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/9a65bf875b1486d582d553a1f172d422/pagerslidingtabstrip-1.0.1/jars/classes.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.astuetz/pagerslidingtabstrip/1.0.1/95949acd77afb68778e883b4dc56f037bf88f219/pagerslidingtabstrip-1.0.1-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.astuetz/pagerslidingtabstrip/1.0.1/6a34a8358416eecbbfe6fa3a54b95d8afd4b0b39/pagerslidingtabstrip-1.0.1-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,15 @@
<component name="libraryTable">
<library name="Gradle: com.flyco.tablayout:FlycoTabLayout_Lib:2.1.2@aar" external-system-id="GRADLE">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/e9fc11de6797d7e09cceeada229e22df/FlycoTabLayout_Lib-2.1.2/jars/classes.jar!/" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/e9fc11de6797d7e09cceeada229e22df/FlycoTabLayout_Lib-2.1.2/res" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/e9fc11de6797d7e09cceeada229e22df/FlycoTabLayout_Lib-2.1.2/AndroidManifest.xml" />
</CLASSES>
<JAVADOC>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.flyco.tablayout/FlycoTabLayout_Lib/2.1.2/37d5ba1c7e12670bc1da7def1d3722614e03561f/FlycoTabLayout_Lib-2.1.2-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.flyco.tablayout/FlycoTabLayout_Lib/2.1.2/431eceecfe6b4044d8e075971d9f25018f12e876/FlycoTabLayout_Lib-2.1.2-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="Gradle: com.google.android.gms:play-services-audience:16.0.0@aar" external-system-id="GRADLE">
<CLASSES>
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/4fe418b1bea0deefd1fac920bfd48397/play-services-audience-16.0.0/AndroidManifest.xml" />
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/4fe418b1bea0deefd1fac920bfd48397/play-services-audience-16.0.0/jars/classes.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,11 @@
<component name="libraryTable">
<library name="Gradle: com.google.android.gms:play-services-base:16.0.1@aar" external-system-id="GRADLE">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/a05e41b094cdde5032791c9859ef90f8/play-services-base-16.0.1/jars/classes.jar!/" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/a05e41b094cdde5032791c9859ef90f8/play-services-base-16.0.1/res" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/a05e41b094cdde5032791c9859ef90f8/play-services-base-16.0.1/AndroidManifest.xml" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,11 @@
<component name="libraryTable">
<library name="Gradle: com.google.android.gms:play-services-basement:16.0.1@aar" external-system-id="GRADLE">
<CLASSES>
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/f79734fc9b54e5f31f156f2cbfec475b/play-services-basement-16.0.1/res" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/f79734fc9b54e5f31f156f2cbfec475b/play-services-basement-16.0.1/AndroidManifest.xml" />
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/f79734fc9b54e5f31f156f2cbfec475b/play-services-basement-16.0.1/jars/classes.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,11 @@
<component name="libraryTable">
<library name="Gradle: com.google.android.gms:play-services-plus:16.0.0@aar" external-system-id="GRADLE">
<CLASSES>
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/b5c536a6345cdf3d4e52f4f5bf3ac190/play-services-plus-16.0.0/AndroidManifest.xml" />
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/b5c536a6345cdf3d4e52f4f5bf3ac190/play-services-plus-16.0.0/jars/classes.jar!/" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/b5c536a6345cdf3d4e52f4f5bf3ac190/play-services-plus-16.0.0/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="Gradle: com.google.android.gms:play-services-tasks:16.0.1@aar" external-system-id="GRADLE">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/d7b9d36bd06ba17f065d57ee796eb5c6/play-services-tasks-16.0.1/jars/classes.jar!/" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/d7b9d36bd06ba17f065d57ee796eb5c6/play-services-tasks-16.0.1/AndroidManifest.xml" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,14 @@
<component name="libraryTable">
<library name="Gradle: com.jakewharton:butterknife:9.0.0@aar" external-system-id="GRADLE">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/2ac14506a4e0af8012d64e29c53f212c/butterknife-9.0.0/jars/classes.jar!/" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/2ac14506a4e0af8012d64e29c53f212c/butterknife-9.0.0/AndroidManifest.xml" />
</CLASSES>
<JAVADOC>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.jakewharton/butterknife/9.0.0/905cc58569caf8a949f943d1ecd022ff8a401faa/butterknife-9.0.0-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.jakewharton/butterknife/9.0.0/487ec437fd0313b4a4f5f2069f90a92698ecca90/butterknife-9.0.0-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,14 @@
<component name="libraryTable">
<library name="Gradle: com.jakewharton:butterknife-runtime:9.0.0@aar" external-system-id="GRADLE">
<CLASSES>
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/9ba002aa52d0d21d6ba6868591ebc270/butterknife-runtime-9.0.0/AndroidManifest.xml" />
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/9ba002aa52d0d21d6ba6868591ebc270/butterknife-runtime-9.0.0/jars/classes.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.jakewharton/butterknife-runtime/9.0.0/39ea68f6fcd783603c7d5dc36263aa191d5a84e5/butterknife-runtime-9.0.0-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.jakewharton/butterknife-runtime/9.0.0/94e78411c5db9cae9baf741ea83c5a64701a851a/butterknife-runtime-9.0.0-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Gradle: com.youth.banner:banner:1.4.10@aar" external-system-id="GRADLE">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/707167e459cbe8d3285fb5a9cbe67283/banner-1.4.10/jars/classes.jar!/" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/707167e459cbe8d3285fb5a9cbe67283/banner-1.4.10/res" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/707167e459cbe8d3285fb5a9cbe67283/banner-1.4.10/AndroidManifest.xml" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.youth.banner/banner/1.4.10/eae835ac9b7ca690031f2b42fbcc88edab66ce5f/banner-1.4.10-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Gradle: org.litepal.android:core:3.0.0@aar" external-system-id="GRADLE">
<CLASSES>
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/521f2f8ba0b54fb19ca133417ec367c0/core-3.0.0/res" />
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/521f2f8ba0b54fb19ca133417ec367c0/core-3.0.0/jars/classes.jar!/" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/521f2f8ba0b54fb19ca133417ec367c0/core-3.0.0/AndroidManifest.xml" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.litepal.android/core/3.0.0/aee6bfbad95aadfd0903570b5d110eb3d02921ca/core-3.0.0-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Gradle: org.litepal.android:java:3.0.0@aar" external-system-id="GRADLE">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/1125c1f52a1baa61f7d83c1f1d16d547/java-3.0.0/jars/classes.jar!/" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/1125c1f52a1baa61f7d83c1f1d16d547/java-3.0.0/AndroidManifest.xml" />
<root url="file://$USER_HOME$/.gradle/caches/transforms-2/files-2.1/1125c1f52a1baa61f7d83c1f1d16d547/java-3.0.0/res" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.litepal.android/java/3.0.0/494ed8ebec335809cec8e1b782b6cd0267ee59c2/java-3.0.0-sources.jar!/" />
</SOURCES>
</library>
</component>

13
.idea/misc.xml Normal file
View File

@ -0,0 +1,13 @@
<project version="4">
<component name="CMakeSettings">
<configurations>
<configuration PROFILE_NAME="Debug" CONFIG_NAME="Debug" />
</configurations>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="corretto-1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

View File

@ -1,2 +0,0 @@
# pda

78
build.gradle Normal file
View File

@ -0,0 +1,78 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
// aliyun maven
maven { url 'https://maven.aliyun.com/repository/public' }
// gradle-plugin
maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
// google()
maven { url 'https://maven.aliyun.com/repository/google' }
// jcenter()
maven { url 'https://maven.aliyun.com/repository/jcenter' }
// central()
maven { url 'https://maven.aliyun.com/repository/central' }
// google()
// jcenter()
maven { url 'https://dl.bintray.com/umsdk/release' }
maven {
url "https://jitpack.io"
}
// maven {
// name 'Sonatype SNAPSHOTs'
// url 'https://oss.sonatype.org/content/repositories/snapshots/'
// }
// maven { url "https://jitpack.io" }
}
dependencies {
classpath 'com.android.tools.build:gradle:4.2.2'
//classpath 'com.jakewharton:butterknife-gradle-plugin:9.0.0'
classpath 'com.jakewharton:butterknife-gradle-plugin:9.0.0'
// classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
}
}
allprojects {
// gradle.projectsEvaluated {
// tasks.withType(JavaCompile) {
// options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
// }
// }
repositories {
// aliyun maven
maven { url 'https://maven.aliyun.com/repository/public' }
// gradle-plugin
maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
// google()
maven { url 'https://maven.aliyun.com/repository/google' }
// jcenter()
maven { url 'https://maven.aliyun.com/repository/jcenter' }
// central()
maven { url 'https://maven.aliyun.com/repository/central' }
// google()
// jcenter()
/* maven {
url "https://raw.githubusercontent.com/umeng/mvn-repo-umeng/master/repository"
}*/
maven { url 'https://jitpack.io' }
maven { url 'https://dl.bintray.com/umsdk/release' }
flatDir {
dirs 'libs'
}
// maven {
// name 'Sonatype SNAPSHOTs'
// url 'https://oss.sonatype.org/content/repositories/snapshots/'
// }
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
//tasks.withType(JavaCompile) {
// options.encoding = "GBK"
//}

2
gradle.properties Normal file
View File

@ -0,0 +1,2 @@
android.enableR8=false
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8

160
gradlew vendored Normal file
View File

@ -0,0 +1,160 @@
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

90
gradlew.bat vendored Normal file
View File

@ -0,0 +1,90 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

187
import-summary.txt Normal file
View File

@ -0,0 +1,187 @@
ECLIPSE ANDROID PROJECT IMPORT SUMMARY
======================================
Manifest Merging:
-----------------
Your project uses libraries that provide manifests, and your Eclipse
project did not explicitly turn on manifest merging. In Android Gradle
projects, manifests are always merged (meaning that contents from your
libraries' manifests will be merged into the app manifest. If you had
manually copied contents from library manifests into your app manifest
you may need to remove these for the app to build correctly.
Ignored Files:
--------------
The following files were *not* copied into the new Gradle project; you
should evaluate whether these are still needed in your project and if
so manually move them:
From listviewlibrary:
* .DS_Store
* .gitignore
* ant.properties
* build.xml
* pom.xml
* proguard-project.txt
From qy:
* .DS_Store
* .gitignore
* app.txt
* ic_launcher-web.png
* icon_bstart.png
* lib/
* lib/achartengine-1.1.0.jar
* lib/android-support-v4.jar
* lib/android-support-v7-gridlayout.jar
* lib/armeabi-v7a/
* lib/armeabi-v7a/libconceal.so
* lib/gen/
* lib/gen/android/
* lib/gen/android/support/
* lib/gen/android/support/v7/
* lib/gen/android/support/v7/gridlayout/
* lib/gen/android/support/v7/gridlayout/R.java
* lib/gen/com/
* lib/gen/com/mobeta/
* lib/gen/com/mobeta/android/
* lib/gen/com/mobeta/android/dslv/
* lib/gen/com/mobeta/android/dslv/R.java
* lib/gen/com/qiyou/
* lib/gen/com/qiyou/mb/
* lib/gen/com/qiyou/mb/android/
* lib/gen/com/qiyou/mb/android/BuildConfig.java
* lib/gen/com/qiyou/mb/android/R.java
* lib/gson-2.2.4-javadoc.jar
* lib/gson-2.2.4.jar
* lib/x86/
* lib/x86/libconceal.so
* log4j-1.2.16.jar
* log4j.properties
* proguard-project.txt
* proguard.cfg.bak
* proguard/
* proguard/dump.txt
* proguard/mapping.txt
* proguard/seeds.txt
* proguard/usage.txt
* rem.txt
* version.xml
Replaced Jars with Dependencies:
--------------------------------
The importer recognized the following .jar files as third party
libraries and replaced them with Gradle dependencies instead. This has
the advantage that more explicit version information is known, and the
libraries can be updated automatically. However, it is possible that
the .jar file in your project was of an older version than the
dependency we picked, which could render the project not compileable.
You can disable the jar replacement in the import wizard and try again:
android-support-v4.jar => com.android.support:support-v4:20.+
android-support-v7-gridlayout.jar => com.android.support:gridlayout-v7:20.+
Replaced Libraries with Dependencies:
-------------------------------------
The importer recognized the following library projects as third party
libraries and replaced them with Gradle dependencies instead. This has
the advantage that more explicit version information is known, and the
libraries can be updated automatically. However, it is possible that
the source files in your project were of an older version than the
dependency we picked, which could render the project not compileable.
You can disable the library replacement in the import wizard and try
again:
android-support-v7-gridlayout => [com.android.support:gridlayout-v7:20.+]
Moved Files:
------------
Android Gradle projects use a different directory structure than ADT
Eclipse projects. Here's how the projects were restructured:
In listviewlibrary:
* AndroidManifest.xml => listviewlibrary/src/main/AndroidManifest.xml
* assets/ => listviewlibrary/src/main/assets
* res/ => listviewlibrary/src/main/res/
* src/ => listviewlibrary/src/main/java/
In qy:
* AndroidManifest.xml => qy/src/main/AndroidManifest.xml
* assets/ => qy/src/main/assets
* libs/BaiduLBS_Android.jar => qy/libs/BaiduLBS_Android.jar
* libs/SocialSDK_QQZone_1.jar => qy/libs/SocialSDK_QQZone_1.jar
* libs/SocialSDK_QQZone_2.jar => qy/libs/SocialSDK_QQZone_2.jar
* libs/SocialSDK_QQZone_3.jar => qy/libs/SocialSDK_QQZone_3.jar
* libs/SocialSDK_Sina.jar => qy/libs/SocialSDK_Sina.jar
* libs/SocialSDK_WeiXin_1.jar => qy/libs/SocialSDK_WeiXin_1.jar
* libs/SocialSDK_WeiXin_2.jar => qy/libs/SocialSDK_WeiXin_2.jar
* libs/SocialSDK_tencentWB_1.jar => qy/libs/SocialSDK_tencentWB_1.jar
* libs/SocialSDK_tencentWB_2.jar => qy/libs/SocialSDK_tencentWB_2.jar
* libs/SocialSDK_tencentWB_3.jar => qy/libs/SocialSDK_tencentWB_3.jar
* libs/SpeechApi.jar => qy/libs/SpeechApi.jar
* libs/achartengine-1.1.0.jar => qy/libs/achartengine-1.1.0.jar
* libs/android-async-http-1.4.6.jar => qy/libs/android-async-http-1.4.6.jar
* libs/armeabi/libBaiduMapSDK_base_v3_7_1.so => qy/src/main/jniLibs/armeabi/libBaiduMapSDK_base_v3_7_1.so
* libs/armeabi/libBaiduMapSDK_cloud_v3_7_1.so => qy/src/main/jniLibs/armeabi/libBaiduMapSDK_cloud_v3_7_1.so
* libs/armeabi/libBaiduMapSDK_map_v3_7_1.so => qy/src/main/jniLibs/armeabi/libBaiduMapSDK_map_v3_7_1.so
* libs/armeabi/libBaiduMapSDK_radar_v3_7_1.so => qy/src/main/jniLibs/armeabi/libBaiduMapSDK_radar_v3_7_1.so
* libs/armeabi/libBaiduMapSDK_search_v3_7_1.so => qy/src/main/jniLibs/armeabi/libBaiduMapSDK_search_v3_7_1.so
* libs/armeabi/libbspatch.so => qy/src/main/jniLibs/armeabi/libbspatch.so
* libs/armeabi/libconceal.so => qy/src/main/jniLibs/armeabi/libconceal.so
* libs/armeabi/liblocSDK6a.so => qy/src/main/jniLibs/armeabi/liblocSDK6a.so
* libs/armeabi/libvi_voslib.so => qy/src/main/jniLibs/armeabi/libvi_voslib.so
* libs/conceal_android.jar => qy/libs/conceal_android.jar
* libs/httpmime-4.1.3.jar => qy/libs/httpmime-4.1.3.jar
* libs/libconceal.jar => qy/libs/libconceal.jar
* libs/locSDK_6.13.jar => qy/libs/locSDK_6.13.jar
* libs/nineoldandroids-2.4.0.jar => qy/libs/nineoldandroids-2.4.0.jar
* libs/swipelistview-1.0-20130701.103547-12-jar-with-dependencies.jar => qy/libs/swipelistview-1.0-20130701.103547-12-jar-with-dependencies.jar
* libs/umeng-analytics-v6.0.3.jar => qy/libs/umeng-analytics-v6.0.3.jar
* libs/umeng-update-v2.6.0.1.jar => qy/libs/umeng-update-v2.6.0.1.jar
* libs/umeng_social_sdk.jar => qy/libs/umeng_social_sdk.jar
* libs/universal-image-loader-1.9.2.jar => qy/libs/universal-image-loader-1.9.2.jar
* libs/utdid4all-1.0.4.jar => qy/libs/utdid4all-1.0.4.jar
* lint.xml => qy/lint.xml
* proguard.cfg => qy/proguard.cfg
* res/ => qy/src/main/res/
* src/ => qy/src/main/java/
* src/.DS_Store => qy/src/main/resources/.DS_Store
* src/com/.DS_Store => qy/src/main/resources/com/.DS_Store
* src/com/baidu/mapapi/overlayutil/package.html => qy/src/main/resources/com/baidu/mapapi/overlayutil/package.html
* src/com/qiyou/.DS_Store => qy/src/main/resources/com/qiyou/.DS_Store
* src/com/qiyou/mb/.DS_Store => qy/src/main/resources/com/qiyou/mb/.DS_Store
* src/com/qiyou/mb/android/.DS_Store => qy/src/main/resources/com/qiyou/mb/android/.DS_Store
* src/com/qiyou/mb/android/beans/.gitignore => qy/src/main/resources/com/qiyou/mb/android/beans/.gitignore
* src/com/qiyou/mb/android/ui/.DS_Store => qy/src/main/resources/com/qiyou/mb/android/ui/.DS_Store
* src/com/qiyou/mb/android/ui/fragments/.gitignore => qy/src/main/resources/com/qiyou/mb/android/ui/fragments/.gitignore
* src/com/qiyou/mb/android/ui/fragments/STAT_test_dd => qy/src/main/resources/com/qiyou/mb/android/ui/fragments/STAT_test_dd
* src/org/.DS_Store => qy/src/main/resources/org/.DS_Store
* /Volumes/workingspace/android/workspace/testQy/res/ => qy/src/androidTest/res/
* /Volumes/workingspace/android/workspace/testQy/src/ => qy/src/androidTest/java/
Missing Android Support Repository:
-----------------------------------
Some useful libraries, such as the Android Support Library, are
installed from a special Maven repository, which should be installed
via the SDK manager.
It looks like this library is missing from your SDK installation at:
/Volumes/workingspace/android/adt-bundle-mac-x86_64-20140702/sdk
To install it, open the SDK manager, and in the Extras category,
select "Android Support Repository". You may also want to install the
"Google Repository" if you want to use libraries like Google Play
Services.
Next Steps:
-----------
You can now build the project. The Gradle project needs network
connectivity to download dependencies.
Bugs:
-----
If for some reason your project does not build, and you determine that
it is due to a bug or limitation of the Eclipse to Gradle importer,
please file a bug at http://b.android.com with category
Component-Tools.
(This import summary is for your information only, and can be deleted
after import once you are satisfied with the results.)

1
listviewlibrary/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build

View File

@ -0,0 +1,22 @@
apply plugin: 'com.android.library'
android {
compileSdkVersion 26
buildToolsVersion "28.0.3"
defaultConfig {
minSdkVersion 15
targetSdkVersion 26
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
}
dependencies {
api 'com.android.support:support-v4:26.1.0'
}

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mobeta.android.dslv"
android:versionCode="4"
android:versionName="0.6.1">
<!-- uses-sdk android:targetSdkVersion="22"
android:minSdkVersion="8" / -->
</manifest>

View File

@ -0,0 +1,468 @@
package com.mobeta.android.dslv;
import android.graphics.Point;
import android.view.GestureDetector;
import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.AdapterView;
/**
* Class that starts and stops item drags on a {@link DragSortListView}
* based on touch gestures. This class also inherits from
* {@link SimpleFloatViewManager}, which provides basic float View
* creation.
*
* An instance of this class is meant to be passed to the methods
* {@link DragSortListView#setTouchListener()} and
* {@link DragSortListView#setFloatViewManager()} of your
* {@link DragSortListView} instance.
*/
public class DragSortController extends SimpleFloatViewManager implements View.OnTouchListener, GestureDetector.OnGestureListener {
/**
* Drag init mode enum.
*/
public static final int ON_DOWN = 0;
public static final int ON_DRAG = 1;
public static final int ON_LONG_PRESS = 2;
private int mDragInitMode = ON_DOWN;
private boolean mSortEnabled = true;
/**
* Remove mode enum.
*/
public static final int CLICK_REMOVE = 0;
public static final int FLING_REMOVE = 1;
/**
* The current remove mode.
*/
private int mRemoveMode;
private boolean mRemoveEnabled = false;
private boolean mIsRemoving = false;
private GestureDetector mDetector;
private GestureDetector mFlingRemoveDetector;
private int mTouchSlop;
public static final int MISS = -1;
private int mHitPos = MISS;
private int mFlingHitPos = MISS;
private int mClickRemoveHitPos = MISS;
private int[] mTempLoc = new int[2];
private int mItemX;
private int mItemY;
private int mCurrX;
private int mCurrY;
private boolean mDragging = false;
private float mFlingSpeed = 500f;
private int mDragHandleId;
private int mClickRemoveId;
private int mFlingHandleId;
private boolean mCanDrag;
private DragSortListView mDslv;
private int mPositionX;
/**
* Calls {@link #DragSortController(DragSortListView, int)} with a
* 0 drag handle id, FLING_RIGHT_REMOVE remove mode,
* and ON_DOWN drag init. By default, sorting is enabled, and
* removal is disabled.
*
* @param dslv The DSLV instance
*/
public DragSortController(DragSortListView dslv) {
this(dslv, 0, ON_DOWN, FLING_REMOVE);
}
public DragSortController(DragSortListView dslv, int dragHandleId, int dragInitMode, int removeMode) {
this(dslv, dragHandleId, dragInitMode, removeMode, 0);
}
public DragSortController(DragSortListView dslv, int dragHandleId, int dragInitMode, int removeMode, int clickRemoveId) {
this(dslv, dragHandleId, dragInitMode, removeMode, clickRemoveId, 0);
}
/**
* By default, sorting is enabled, and removal is disabled.
*
* @param dslv The DSLV instance
* @param dragHandleId The resource id of the View that represents
* the drag handle in a list item.
*/
public DragSortController(DragSortListView dslv, int dragHandleId, int dragInitMode,
int removeMode, int clickRemoveId, int flingHandleId) {
super(dslv);
mDslv = dslv;
mDetector = new GestureDetector(dslv.getContext(), this);
mFlingRemoveDetector = new GestureDetector(dslv.getContext(), mFlingRemoveListener);
mFlingRemoveDetector.setIsLongpressEnabled(false);
mTouchSlop = ViewConfiguration.get(dslv.getContext()).getScaledTouchSlop();
mDragHandleId = dragHandleId;
mClickRemoveId = clickRemoveId;
mFlingHandleId = flingHandleId;
setRemoveMode(removeMode);
setDragInitMode(dragInitMode);
}
public int getDragInitMode() {
return mDragInitMode;
}
/**
* Set how a drag is initiated. Needs to be one of
* {@link ON_DOWN}, {@link ON_DRAG}, or {@link ON_LONG_PRESS}.
*
* @param mode The drag init mode.
*/
public void setDragInitMode(int mode) {
mDragInitMode = mode;
}
/**
* Enable/Disable list item sorting. Disabling is useful if only item
* removal is desired. Prevents drags in the vertical direction.
*
* @param enabled Set <code>true</code> to enable list
* item sorting.
*/
public void setSortEnabled(boolean enabled) {
mSortEnabled = enabled;
}
public boolean isSortEnabled() {
return mSortEnabled;
}
/**
* One of {@link CLICK_REMOVE}, {@link FLING_RIGHT_REMOVE},
* {@link FLING_LEFT_REMOVE},
* {@link SLIDE_RIGHT_REMOVE}, or {@link SLIDE_LEFT_REMOVE}.
*/
public void setRemoveMode(int mode) {
mRemoveMode = mode;
}
public int getRemoveMode() {
return mRemoveMode;
}
/**
* Enable/Disable item removal without affecting remove mode.
*/
public void setRemoveEnabled(boolean enabled) {
mRemoveEnabled = enabled;
}
public boolean isRemoveEnabled() {
return mRemoveEnabled;
}
/**
* Set the resource id for the View that represents the drag
* handle in a list item.
*
* @param id An android resource id.
*/
public void setDragHandleId(int id) {
mDragHandleId = id;
}
/**
* Set the resource id for the View that represents the fling
* handle in a list item.
*
* @param id An android resource id.
*/
public void setFlingHandleId(int id) {
mFlingHandleId = id;
}
/**
* Set the resource id for the View that represents click
* removal button.
*
* @param id An android resource id.
*/
public void setClickRemoveId(int id) {
mClickRemoveId = id;
}
/**
* Sets flags to restrict certain motions of the floating View
* based on DragSortController settings (such as remove mode).
* Starts the drag on the DragSortListView.
*
* @param position The list item position (includes headers).
* @param deltaX Touch x-coord minus left edge of floating View.
* @param deltaY Touch y-coord minus top edge of floating View.
*
* @return True if drag started, false otherwise.
*/
public boolean startDrag(int position, int deltaX, int deltaY) {
int dragFlags = 0;
if (mSortEnabled && !mIsRemoving) {
dragFlags |= DragSortListView.DRAG_POS_Y | DragSortListView.DRAG_NEG_Y;
}
if (mRemoveEnabled && mIsRemoving) {
dragFlags |= DragSortListView.DRAG_POS_X;
dragFlags |= DragSortListView.DRAG_NEG_X;
}
mDragging = mDslv.startDrag(position - mDslv.getHeaderViewsCount(), dragFlags, deltaX,
deltaY);
return mDragging;
}
@Override
public boolean onTouch(View v, MotionEvent ev) {
if (!mDslv.isDragEnabled() || mDslv.listViewIntercepted()) {
return false;
}
mDetector.onTouchEvent(ev);
if (mRemoveEnabled && mDragging && mRemoveMode == FLING_REMOVE) {
mFlingRemoveDetector.onTouchEvent(ev);
}
int action = ev.getAction() & MotionEvent.ACTION_MASK;
switch (action) {
case MotionEvent.ACTION_DOWN:
mCurrX = (int) ev.getX();
mCurrY = (int) ev.getY();
break;
case MotionEvent.ACTION_UP:
if (mRemoveEnabled && mIsRemoving) {
int x = mPositionX >= 0 ? mPositionX : -mPositionX;
int removePoint = mDslv.getWidth() / 2;
if (x > removePoint) {
mDslv.stopDragWithVelocity(true, 0);
}
}
case MotionEvent.ACTION_CANCEL:
mIsRemoving = false;
mDragging = false;
break;
}
return false;
}
/**
* Overrides to provide fading when slide removal is enabled.
*/
@Override
public void onDragFloatView(View floatView, Point position, Point touch) {
if (mRemoveEnabled && mIsRemoving) {
mPositionX = position.x;
}
}
/**
* Get the position to start dragging based on the ACTION_DOWN
* MotionEvent. This function simply calls
* {@link #dragHandleHitPosition(MotionEvent)}. Override
* to change drag handle behavior;
* this function is called internally when an ACTION_DOWN
* event is detected.
*
* @param ev The ACTION_DOWN MotionEvent.
*
* @return The list position to drag if a drag-init gesture is
* detected; MISS if unsuccessful.
*/
public int startDragPosition(MotionEvent ev) {
return dragHandleHitPosition(ev);
}
public int startFlingPosition(MotionEvent ev) {
return mRemoveMode == FLING_REMOVE ? flingHandleHitPosition(ev) : MISS;
}
/**
* Checks for the touch of an item's drag handle (specified by
* {@link #setDragHandleId(int)}), and returns that item's position
* if a drag handle touch was detected.
*
* @param ev The ACTION_DOWN MotionEvent.
* @return The list position of the item whose drag handle was
* touched; MISS if unsuccessful.
*/
public int dragHandleHitPosition(MotionEvent ev) {
return viewIdHitPosition(ev, mDragHandleId);
}
public int flingHandleHitPosition(MotionEvent ev) {
return viewIdHitPosition(ev, mFlingHandleId);
}
public int viewIdHitPosition(MotionEvent ev, int id) {
final int x = (int) ev.getX();
final int y = (int) ev.getY();
int touchPos = mDslv.pointToPosition(x, y); // includes headers/footers
final int numHeaders = mDslv.getHeaderViewsCount();
final int numFooters = mDslv.getFooterViewsCount();
final int count = mDslv.getCount();
// Log.d("mobeta", "touch down on position " + itemnum);
// We're only interested if the touch was on an
// item that's not a header or footer.
if (touchPos != AdapterView.INVALID_POSITION && touchPos >= numHeaders
&& touchPos < (count - numFooters)) {
final View item = mDslv.getChildAt(touchPos - mDslv.getFirstVisiblePosition());
final int rawX = (int) ev.getRawX();
final int rawY = (int) ev.getRawY();
View dragBox = id == 0 ? item : (View) item.findViewById(id);
if (dragBox != null) {
dragBox.getLocationOnScreen(mTempLoc);
if (rawX > mTempLoc[0] && rawY > mTempLoc[1] &&
rawX < mTempLoc[0] + dragBox.getWidth() &&
rawY < mTempLoc[1] + dragBox.getHeight()) {
mItemX = item.getLeft();
mItemY = item.getTop();
return touchPos;
}
}
}
return MISS;
}
@Override
public boolean onDown(MotionEvent ev) {
if (mRemoveEnabled && mRemoveMode == CLICK_REMOVE) {
mClickRemoveHitPos = viewIdHitPosition(ev, mClickRemoveId);
}
mHitPos = startDragPosition(ev);
if (mHitPos != MISS && mDragInitMode == ON_DOWN) {
startDrag(mHitPos, (int) ev.getX() - mItemX, (int) ev.getY() - mItemY);
}
mIsRemoving = false;
mCanDrag = true;
mPositionX = 0;
mFlingHitPos = startFlingPosition(ev);
return true;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
final int x1 = (int) e1.getX();
final int y1 = (int) e1.getY();
final int x2 = (int) e2.getX();
final int y2 = (int) e2.getY();
final int deltaX = x2 - mItemX;
final int deltaY = y2 - mItemY;
if (mCanDrag && !mDragging && (mHitPos != MISS || mFlingHitPos != MISS)) {
if (mHitPos != MISS) {
if (mDragInitMode == ON_DRAG && Math.abs(y2 - y1) > mTouchSlop && mSortEnabled) {
startDrag(mHitPos, deltaX, deltaY);
}
else if (mDragInitMode != ON_DOWN && Math.abs(x2 - x1) > mTouchSlop && mRemoveEnabled)
{
mIsRemoving = true;
startDrag(mFlingHitPos, deltaX, deltaY);
}
} else if (mFlingHitPos != MISS) {
if (Math.abs(x2 - x1) > mTouchSlop && mRemoveEnabled) {
mIsRemoving = true;
startDrag(mFlingHitPos, deltaX, deltaY);
} else if (Math.abs(y2 - y1) > mTouchSlop) {
mCanDrag = false; // if started to scroll the list then
// don't allow sorting nor fling-removing
}
}
}
// return whatever
return false;
}
@Override
public void onLongPress(MotionEvent e) {
// Log.d("mobeta", "lift listener long pressed");
if (mHitPos != MISS && mDragInitMode == ON_LONG_PRESS) {
mDslv.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
startDrag(mHitPos, mCurrX - mItemX, mCurrY - mItemY);
}
}
// complete the OnGestureListener interface
@Override
public final boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return false;
}
// complete the OnGestureListener interface
@Override
public boolean onSingleTapUp(MotionEvent ev) {
if (mRemoveEnabled && mRemoveMode == CLICK_REMOVE) {
if (mClickRemoveHitPos != MISS) {
mDslv.removeItem(mClickRemoveHitPos - mDslv.getHeaderViewsCount());
}
}
return true;
}
// complete the OnGestureListener interface
@Override
public void onShowPress(MotionEvent ev) {
// do nothing
}
private GestureDetector.OnGestureListener mFlingRemoveListener =
new GestureDetector.SimpleOnGestureListener() {
@Override
public final boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
// Log.d("mobeta", "on fling remove called");
if (mRemoveEnabled && mIsRemoving) {
int w = mDslv.getWidth();
int minPos = w / 5;
if (velocityX > mFlingSpeed) {
if (mPositionX > -minPos) {
mDslv.stopDragWithVelocity(true, velocityX);
}
} else if (velocityX < -mFlingSpeed) {
if (mPositionX < minPos) {
mDslv.stopDragWithVelocity(true, velocityX);
}
}
mIsRemoving = false;
}
return false;
}
};
}

View File

@ -0,0 +1,241 @@
package com.mobeta.android.dslv;
import java.util.ArrayList;
import android.content.Context;
import android.database.Cursor;
import android.util.SparseIntArray;
import android.view.View;
import android.view.ViewGroup;
import android.support.v4.widget.CursorAdapter;
/**
* A subclass of {@link android.widget.CursorAdapter} that provides
* reordering of the elements in the Cursor based on completed
* drag-sort operations. The reordering is a simple mapping of
* list positions into Cursor positions (the Cursor is unchanged).
* To persist changes made by drag-sorts, one can retrieve the
* mapping with the {@link #getCursorPositions()} method, which
* returns the reordered list of Cursor positions.
*
* An instance of this class is passed
* to {@link DragSortListView#setAdapter(ListAdapter)} and, since
* this class implements the {@link DragSortListView.DragSortListener}
* interface, it is automatically set as the DragSortListener for
* the DragSortListView instance.
*/
public abstract class DragSortCursorAdapter extends CursorAdapter implements DragSortListView.DragSortListener {
public static final int REMOVED = -1;
/**
* Key is ListView position, value is Cursor position
*/
private SparseIntArray mListMapping = new SparseIntArray();
private ArrayList<Integer> mRemovedCursorPositions = new ArrayList<Integer>();
public DragSortCursorAdapter(Context context, Cursor c) {
super(context, c);
}
public DragSortCursorAdapter(Context context, Cursor c, boolean autoRequery) {
super(context, c, autoRequery);
}
public DragSortCursorAdapter(Context context, Cursor c, int flags) {
super(context, c, flags);
}
/**
* Swaps Cursor and clears list-Cursor mapping.
*
* @see android.widget.CursorAdapter#swapCursor(android.database.Cursor)
*/
@Override
public Cursor swapCursor(Cursor newCursor) {
Cursor old = super.swapCursor(newCursor);
resetMappings();
return old;
}
/**
* Changes Cursor and clears list-Cursor mapping.
*
* @see android.widget.CursorAdapter#changeCursor(android.database.Cursor)
*/
@Override
public void changeCursor(Cursor cursor) {
super.changeCursor(cursor);
resetMappings();
}
/**
* Resets list-cursor mapping.
*/
public void reset() {
resetMappings();
notifyDataSetChanged();
}
private void resetMappings() {
mListMapping.clear();
mRemovedCursorPositions.clear();
}
@Override
public Object getItem(int position) {
return super.getItem(mListMapping.get(position, position));
}
@Override
public long getItemId(int position) {
return super.getItemId(mListMapping.get(position, position));
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
return super.getDropDownView(mListMapping.get(position, position), convertView, parent);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return super.getView(mListMapping.get(position, position), convertView, parent);
}
/**
* On drop, this updates the mapping between Cursor positions
* and ListView positions. The Cursor is unchanged. Retrieve
* the current mapping with {@link getCursorPositions()}.
*
* @see DragSortListView.DropListener#drop(int, int)
*/
@Override
public void drop(int from, int to) {
if (from != to) {
int cursorFrom = mListMapping.get(from, from);
if (from > to) {
for (int i = from; i > to; --i) {
mListMapping.put(i, mListMapping.get(i - 1, i - 1));
}
} else {
for (int i = from; i < to; ++i) {
mListMapping.put(i, mListMapping.get(i + 1, i + 1));
}
}
mListMapping.put(to, cursorFrom);
cleanMapping();
notifyDataSetChanged();
}
}
/**
* On remove, this updates the mapping between Cursor positions
* and ListView positions. The Cursor is unchanged. Retrieve
* the current mapping with {@link getCursorPositions()}.
*
* @see DragSortListView.RemoveListener#remove(int)
*/
@Override
public void remove(int which) {
int cursorPos = mListMapping.get(which, which);
if (!mRemovedCursorPositions.contains(cursorPos)) {
mRemovedCursorPositions.add(cursorPos);
}
int newCount = getCount();
for (int i = which; i < newCount; ++i) {
mListMapping.put(i, mListMapping.get(i + 1, i + 1));
}
mListMapping.delete(newCount);
cleanMapping();
notifyDataSetChanged();
}
/**
* Does nothing. Just completes DragSortListener interface.
*/
@Override
public void drag(int from, int to) {
// do nothing
}
/**
* Remove unnecessary mappings from sparse array.
*/
private void cleanMapping() {
ArrayList<Integer> toRemove = new ArrayList<Integer>();
int size = mListMapping.size();
for (int i = 0; i < size; ++i) {
if (mListMapping.keyAt(i) == mListMapping.valueAt(i)) {
toRemove.add(mListMapping.keyAt(i));
}
}
size = toRemove.size();
for (int i = 0; i < size; ++i) {
mListMapping.delete(toRemove.get(i));
}
}
@Override
public int getCount() {
return super.getCount() - mRemovedCursorPositions.size();
}
/**
* Get the Cursor position mapped to by the provided list position
* (given all previously handled drag-sort
* operations).
*
* @param position List position
*
* @return The mapped-to Cursor position
*/
public int getCursorPosition(int position) {
return mListMapping.get(position, position);
}
/**
* Get the current order of Cursor positions presented by the
* list.
*/
public ArrayList<Integer> getCursorPositions() {
ArrayList<Integer> result = new ArrayList<Integer>();
for (int i = 0; i < getCount(); ++i) {
result.add(mListMapping.get(i, i));
}
return result;
}
/**
* Get the list position mapped to by the provided Cursor position.
* If the provided Cursor position has been removed by a drag-sort,
* this returns {@link #REMOVED}.
*
* @param cursorPosition A Cursor position
* @return The mapped-to list position or REMOVED
*/
public int getListPosition(int cursorPosition) {
if (mRemovedCursorPositions.contains(cursorPosition)) {
return REMOVED;
}
int index = mListMapping.indexOfValue(cursorPosition);
if (index < 0) {
return cursorPosition;
} else {
return mListMapping.keyAt(index);
}
}
}

View File

@ -0,0 +1,100 @@
package com.mobeta.android.dslv;
import android.content.Context;
import android.view.Gravity;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.util.Log;
/**
* Lightweight ViewGroup that wraps list items obtained from user's
* ListAdapter. ItemView expects a single child that has a definite
* height (i.e. the child's layout height is not MATCH_PARENT).
* The width of
* ItemView will always match the width of its child (that is,
* the width MeasureSpec given to ItemView is passed directly
* to the child, and the ItemView measured width is set to the
* child's measured width). The height of ItemView can be anything;
* the
*
*
* The purpose of this class is to optimize slide
* shuffle animations.
*/
public class DragSortItemView extends ViewGroup {
private int mGravity = Gravity.TOP;
public DragSortItemView(Context context) {
super(context);
// always init with standard ListView layout params
setLayoutParams(new AbsListView.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
//setClipChildren(true);
}
public void setGravity(int gravity) {
mGravity = gravity;
}
public int getGravity() {
return mGravity;
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
final View child = getChildAt(0);
if (child == null) {
return;
}
if (mGravity == Gravity.TOP) {
child.layout(0, 0, getMeasuredWidth(), child.getMeasuredHeight());
} else {
child.layout(0, getMeasuredHeight() - child.getMeasuredHeight(), getMeasuredWidth(), getMeasuredHeight());
}
}
/**
*
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int height = MeasureSpec.getSize(heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
final View child = getChildAt(0);
if (child == null) {
setMeasuredDimension(0, width);
return;
}
if (child.isLayoutRequested()) {
// Always let child be as tall as it wants.
measureChild(child, widthMeasureSpec,
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
}
if (heightMode == MeasureSpec.UNSPECIFIED) {
ViewGroup.LayoutParams lp = getLayoutParams();
if (lp.height > 0) {
height = lp.height;
} else {
height = child.getMeasuredHeight();
}
}
setMeasuredDimension(width, height);
}
}

View File

@ -0,0 +1,55 @@
package com.mobeta.android.dslv;
import android.content.Context;
import android.view.Gravity;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.Checkable;
import android.util.Log;
/**
* Lightweight ViewGroup that wraps list items obtained from user's
* ListAdapter. ItemView expects a single child that has a definite
* height (i.e. the child's layout height is not MATCH_PARENT).
* The width of
* ItemView will always match the width of its child (that is,
* the width MeasureSpec given to ItemView is passed directly
* to the child, and the ItemView measured width is set to the
* child's measured width). The height of ItemView can be anything;
* the
*
*
* The purpose of this class is to optimize slide
* shuffle animations.
*/
public class DragSortItemViewCheckable extends DragSortItemView implements Checkable {
public DragSortItemViewCheckable(Context context) {
super(context);
}
@Override
public boolean isChecked() {
View child = getChildAt(0);
if (child instanceof Checkable)
return ((Checkable) child).isChecked();
else
return false;
}
@Override
public void setChecked(boolean checked) {
View child = getChildAt(0);
if (child instanceof Checkable)
((Checkable) child).setChecked(checked);
}
@Override
public void toggle() {
View child = getChildAt(0);
if (child instanceof Checkable)
((Checkable) child).toggle();
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,133 @@
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mobeta.android.dslv;
import android.content.Context;
import android.database.Cursor;
import android.view.View;
import android.view.ViewGroup;
import android.view.LayoutInflater;
// taken from v4 rev. 10 ResourceCursorAdapter.java
/**
* Static library support version of the framework's {@link android.widget.ResourceCursorAdapter}.
* Used to write apps that run on platforms prior to Android 3.0. When running
* on Android 3.0 or above, this implementation is still used; it does not try
* to switch to the framework's implementation. See the framework SDK
* documentation for a class overview.
*/
public abstract class ResourceDragSortCursorAdapter extends DragSortCursorAdapter {
private int mLayout;
private int mDropDownLayout;
private LayoutInflater mInflater;
/**
* Constructor the enables auto-requery.
*
* @deprecated This option is discouraged, as it results in Cursor queries
* being performed on the application's UI thread and thus can cause poor
* responsiveness or even Application Not Responding errors. As an alternative,
* use {@link android.app.LoaderManager} with a {@link android.content.CursorLoader}.
*
* @param context The context where the ListView associated with this adapter is running
* @param layout resource identifier of a layout file that defines the views
* for this list item. Unless you override them later, this will
* define both the item views and the drop down views.
*/
@Deprecated
public ResourceDragSortCursorAdapter(Context context, int layout, Cursor c) {
super(context, c);
mLayout = mDropDownLayout = layout;
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
/**
* Constructor with default behavior as per
* {@link CursorAdapter#CursorAdapter(Context, Cursor, boolean)}; it is recommended
* you not use this, but instead {@link #ResourceCursorAdapter(Context, int, Cursor, int)}.
* When using this constructor, {@link #FLAG_REGISTER_CONTENT_OBSERVER}
* will always be set.
*
* @param context The context where the ListView associated with this adapter is running
* @param layout resource identifier of a layout file that defines the views
* for this list item. Unless you override them later, this will
* define both the item views and the drop down views.
* @param c The cursor from which to get the data.
* @param autoRequery If true the adapter will call requery() on the
* cursor whenever it changes so the most recent
* data is always displayed. Using true here is discouraged.
*/
public ResourceDragSortCursorAdapter(Context context, int layout, Cursor c, boolean autoRequery) {
super(context, c, autoRequery);
mLayout = mDropDownLayout = layout;
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
/**
* Standard constructor.
*
* @param context The context where the ListView associated with this adapter is running
* @param layout Resource identifier of a layout file that defines the views
* for this list item. Unless you override them later, this will
* define both the item views and the drop down views.
* @param c The cursor from which to get the data.
* @param flags Flags used to determine the behavior of the adapter,
* as per {@link CursorAdapter#CursorAdapter(Context, Cursor, int)}.
*/
public ResourceDragSortCursorAdapter(Context context, int layout, Cursor c, int flags) {
super(context, c, flags);
mLayout = mDropDownLayout = layout;
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
/**
* Inflates view(s) from the specified XML file.
*
* @see android.widget.CursorAdapter#newView(android.content.Context,
* android.database.Cursor, ViewGroup)
*/
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return mInflater.inflate(mLayout, parent, false);
}
@Override
public View newDropDownView(Context context, Cursor cursor, ViewGroup parent) {
return mInflater.inflate(mDropDownLayout, parent, false);
}
/**
* <p>Sets the layout resource of the item views.</p>
*
* @param layout the layout resources used to create item views
*/
public void setViewResource(int layout) {
mLayout = layout;
}
/**
* <p>Sets the layout resource of the drop down views.</p>
*
* @param dropDownLayout the layout resources used to create drop down views
*/
public void setDropDownViewResource(int dropDownLayout) {
mDropDownLayout = dropDownLayout;
}
}

View File

@ -0,0 +1,422 @@
/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mobeta.android.dslv;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.view.View;
import android.widget.TextView;
import android.widget.ImageView;
// taken from sdk/sources/android-16/android/widget/SimpleCursorAdapter.java
/**
* An easy adapter to map columns from a cursor to TextViews or ImageViews
* defined in an XML file. You can specify which columns you want, which
* views you want to display the columns, and the XML file that defines
* the appearance of these views.
*
* Binding occurs in two phases. First, if a
* {@link android.widget.SimpleCursorAdapter.ViewBinder} is available,
* {@link ViewBinder#setViewValue(android.view.View, android.database.Cursor, int)}
* is invoked. If the returned value is true, binding has occured. If the
* returned value is false and the view to bind is a TextView,
* {@link #setViewText(TextView, String)} is invoked. If the returned value
* is false and the view to bind is an ImageView,
* {@link #setViewImage(ImageView, String)} is invoked. If no appropriate
* binding can be found, an {@link IllegalStateException} is thrown.
*
* If this adapter is used with filtering, for instance in an
* {@link android.widget.AutoCompleteTextView}, you can use the
* {@link android.widget.SimpleCursorAdapter.CursorToStringConverter} and the
* {@link android.widget.FilterQueryProvider} interfaces
* to get control over the filtering process. You can refer to
* {@link #convertToString(android.database.Cursor)} and
* {@link #runQueryOnBackgroundThread(CharSequence)} for more information.
*/
public class SimpleDragSortCursorAdapter extends ResourceDragSortCursorAdapter {
/**
* A list of columns containing the data to bind to the UI.
* This field should be made private, so it is hidden from the SDK.
* {@hide}
*/
protected int[] mFrom;
/**
* A list of View ids representing the views to which the data must be bound.
* This field should be made private, so it is hidden from the SDK.
* {@hide}
*/
protected int[] mTo;
private int mStringConversionColumn = -1;
private CursorToStringConverter mCursorToStringConverter;
private ViewBinder mViewBinder;
String[] mOriginalFrom;
/**
* Constructor the enables auto-requery.
*
* @deprecated This option is discouraged, as it results in Cursor queries
* being performed on the application's UI thread and thus can cause poor
* responsiveness or even Application Not Responding errors. As an alternative,
* use {@link android.app.LoaderManager} with a {@link android.content.CursorLoader}.
*/
@Deprecated
public SimpleDragSortCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
super(context, layout, c);
mTo = to;
mOriginalFrom = from;
findColumns(c, from);
}
/**
* Standard constructor.
*
* @param context The context where the ListView associated with this
* SimpleListItemFactory is running
* @param layout resource identifier of a layout file that defines the views
* for this list item. The layout file should include at least
* those named views defined in "to"
* @param c The database cursor. Can be null if the cursor is not available yet.
* @param from A list of column names representing the data to bind to the UI. Can be null
* if the cursor is not available yet.
* @param to The views that should display column in the "from" parameter.
* These should all be TextViews. The first N views in this list
* are given the values of the first N columns in the from
* parameter. Can be null if the cursor is not available yet.
* @param flags Flags used to determine the behavior of the adapter,
* as per {@link CursorAdapter#CursorAdapter(Context, Cursor, int)}.
*/
public SimpleDragSortCursorAdapter(Context context, int layout,
Cursor c, String[] from, int[] to, int flags) {
super(context, layout, c, flags);
mTo = to;
mOriginalFrom = from;
findColumns(c, from);
}
/**
* Binds all of the field names passed into the "to" parameter of the
* constructor with their corresponding cursor columns as specified in the
* "from" parameter.
*
* Binding occurs in two phases. First, if a
* {@link android.widget.SimpleCursorAdapter.ViewBinder} is available,
* {@link ViewBinder#setViewValue(android.view.View, android.database.Cursor, int)}
* is invoked. If the returned value is true, binding has occured. If the
* returned value is false and the view to bind is a TextView,
* {@link #setViewText(TextView, String)} is invoked. If the returned value is
* false and the view to bind is an ImageView,
* {@link #setViewImage(ImageView, String)} is invoked. If no appropriate
* binding can be found, an {@link IllegalStateException} is thrown.
*
* @throws IllegalStateException if binding cannot occur
*
* @see android.widget.CursorAdapter#bindView(android.view.View,
* android.content.Context, android.database.Cursor)
* @see #getViewBinder()
* @see #setViewBinder(android.widget.SimpleCursorAdapter.ViewBinder)
* @see #setViewImage(ImageView, String)
* @see #setViewText(TextView, String)
*/
@Override
public void bindView(View view, Context context, Cursor cursor) {
final ViewBinder binder = mViewBinder;
final int count = mTo.length;
final int[] from = mFrom;
final int[] to = mTo;
for (int i = 0; i < count; i++) {
final View v = view.findViewById(to[i]);
if (v != null) {
boolean bound = false;
if (binder != null) {
bound = binder.setViewValue(v, cursor, from[i]);
}
if (!bound) {
String text = cursor.getString(from[i]);
if (text == null) {
text = "";
}
if (v instanceof TextView) {
setViewText((TextView) v, text);
} else if (v instanceof ImageView) {
setViewImage((ImageView) v, text);
} else {
throw new IllegalStateException(v.getClass().getName() + " is not a " +
" view that can be bounds by this SimpleCursorAdapter");
}
}
}
}
}
/**
* Returns the {@link ViewBinder} used to bind data to views.
*
* @return a ViewBinder or null if the binder does not exist
*
* @see #bindView(android.view.View, android.content.Context, android.database.Cursor)
* @see #setViewBinder(android.widget.SimpleCursorAdapter.ViewBinder)
*/
public ViewBinder getViewBinder() {
return mViewBinder;
}
/**
* Sets the binder used to bind data to views.
*
* @param viewBinder the binder used to bind data to views, can be null to
* remove the existing binder
*
* @see #bindView(android.view.View, android.content.Context, android.database.Cursor)
* @see #getViewBinder()
*/
public void setViewBinder(ViewBinder viewBinder) {
mViewBinder = viewBinder;
}
/**
* Called by bindView() to set the image for an ImageView but only if
* there is no existing ViewBinder or if the existing ViewBinder cannot
* handle binding to an ImageView.
*
* By default, the value will be treated as an image resource. If the
* value cannot be used as an image resource, the value is used as an
* image Uri.
*
* Intended to be overridden by Adapters that need to filter strings
* retrieved from the database.
*
* @param v ImageView to receive an image
* @param value the value retrieved from the cursor
*/
public void setViewImage(ImageView v, String value) {
try {
v.setImageResource(Integer.parseInt(value));
} catch (NumberFormatException nfe) {
v.setImageURI(Uri.parse(value));
}
}
/**
* Called by bindView() to set the text for a TextView but only if
* there is no existing ViewBinder or if the existing ViewBinder cannot
* handle binding to a TextView.
*
* Intended to be overridden by Adapters that need to filter strings
* retrieved from the database.
*
* @param v TextView to receive text
* @param text the text to be set for the TextView
*/
public void setViewText(TextView v, String text) {
v.setText(text);
}
/**
* Return the index of the column used to get a String representation
* of the Cursor.
*
* @return a valid index in the current Cursor or -1
*
* @see android.widget.CursorAdapter#convertToString(android.database.Cursor)
* @see #setStringConversionColumn(int)
* @see #setCursorToStringConverter(android.widget.SimpleCursorAdapter.CursorToStringConverter)
* @see #getCursorToStringConverter()
*/
public int getStringConversionColumn() {
return mStringConversionColumn;
}
/**
* Defines the index of the column in the Cursor used to get a String
* representation of that Cursor. The column is used to convert the
* Cursor to a String only when the current CursorToStringConverter
* is null.
*
* @param stringConversionColumn a valid index in the current Cursor or -1 to use the default
* conversion mechanism
*
* @see android.widget.CursorAdapter#convertToString(android.database.Cursor)
* @see #getStringConversionColumn()
* @see #setCursorToStringConverter(android.widget.SimpleCursorAdapter.CursorToStringConverter)
* @see #getCursorToStringConverter()
*/
public void setStringConversionColumn(int stringConversionColumn) {
mStringConversionColumn = stringConversionColumn;
}
/**
* Returns the converter used to convert the filtering Cursor
* into a String.
*
* @return null if the converter does not exist or an instance of
* {@link android.widget.SimpleCursorAdapter.CursorToStringConverter}
*
* @see #setCursorToStringConverter(android.widget.SimpleCursorAdapter.CursorToStringConverter)
* @see #getStringConversionColumn()
* @see #setStringConversionColumn(int)
* @see android.widget.CursorAdapter#convertToString(android.database.Cursor)
*/
public CursorToStringConverter getCursorToStringConverter() {
return mCursorToStringConverter;
}
/**
* Sets the converter used to convert the filtering Cursor
* into a String.
*
* @param cursorToStringConverter the Cursor to String converter, or
* null to remove the converter
*
* @see #setCursorToStringConverter(android.widget.SimpleCursorAdapter.CursorToStringConverter)
* @see #getStringConversionColumn()
* @see #setStringConversionColumn(int)
* @see android.widget.CursorAdapter#convertToString(android.database.Cursor)
*/
public void setCursorToStringConverter(CursorToStringConverter cursorToStringConverter) {
mCursorToStringConverter = cursorToStringConverter;
}
/**
* Returns a CharSequence representation of the specified Cursor as defined
* by the current CursorToStringConverter. If no CursorToStringConverter
* has been set, the String conversion column is used instead. If the
* conversion column is -1, the returned String is empty if the cursor
* is null or Cursor.toString().
*
* @param cursor the Cursor to convert to a CharSequence
*
* @return a non-null CharSequence representing the cursor
*/
@Override
public CharSequence convertToString(Cursor cursor) {
if (mCursorToStringConverter != null) {
return mCursorToStringConverter.convertToString(cursor);
} else if (mStringConversionColumn > -1) {
return cursor.getString(mStringConversionColumn);
}
return super.convertToString(cursor);
}
/**
* Create a map from an array of strings to an array of column-id integers in cursor c.
* If c is null, the array will be discarded.
*
* @param c the cursor to find the columns from
* @param from the Strings naming the columns of interest
*/
private void findColumns(Cursor c, String[] from) {
if (c != null) {
int i;
int count = from.length;
if (mFrom == null || mFrom.length != count) {
mFrom = new int[count];
}
for (i = 0; i < count; i++) {
mFrom[i] = c.getColumnIndexOrThrow(from[i]);
}
} else {
mFrom = null;
}
}
@Override
public Cursor swapCursor(Cursor c) {
// super.swapCursor() will notify observers before we have
// a valid mapping, make sure we have a mapping before this
// happens
findColumns(c, mOriginalFrom);
return super.swapCursor(c);
}
/**
* Change the cursor and change the column-to-view mappings at the same time.
*
* @param c The database cursor. Can be null if the cursor is not available yet.
* @param from A list of column names representing the data to bind to the UI. Can be null
* if the cursor is not available yet.
* @param to The views that should display column in the "from" parameter.
* These should all be TextViews. The first N views in this list
* are given the values of the first N columns in the from
* parameter. Can be null if the cursor is not available yet.
*/
public void changeCursorAndColumns(Cursor c, String[] from, int[] to) {
mOriginalFrom = from;
mTo = to;
// super.changeCursor() will notify observers before we have
// a valid mapping, make sure we have a mapping before this
// happens
findColumns(c, mOriginalFrom);
super.changeCursor(c);
}
/**
* This class can be used by external clients of SimpleCursorAdapter
* to bind values fom the Cursor to views.
*
* You should use this class to bind values from the Cursor to views
* that are not directly supported by SimpleCursorAdapter or to
* change the way binding occurs for views supported by
* SimpleCursorAdapter.
*
* @see SimpleCursorAdapter#bindView(android.view.View, android.content.Context, android.database.Cursor)
* @see SimpleCursorAdapter#setViewImage(ImageView, String)
* @see SimpleCursorAdapter#setViewText(TextView, String)
*/
public static interface ViewBinder {
/**
* Binds the Cursor column defined by the specified index to the specified view.
*
* When binding is handled by this ViewBinder, this method must return true.
* If this method returns false, SimpleCursorAdapter will attempts to handle
* the binding on its own.
*
* @param view the view to bind the data to
* @param cursor the cursor to get the data from
* @param columnIndex the column at which the data can be found in the cursor
*
* @return true if the data was bound to the view, false otherwise
*/
boolean setViewValue(View view, Cursor cursor, int columnIndex);
}
/**
* This class can be used by external clients of SimpleCursorAdapter
* to define how the Cursor should be converted to a String.
*
* @see android.widget.CursorAdapter#convertToString(android.database.Cursor)
*/
public static interface CursorToStringConverter {
/**
* Returns a CharSequence representing the specified Cursor.
*
* @param cursor the cursor for which a CharSequence representation
* is requested
*
* @return a non-null CharSequence representing the cursor
*/
CharSequence convertToString(Cursor cursor);
}
}

View File

@ -0,0 +1,89 @@
package com.mobeta.android.dslv;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.Color;
import android.widget.ListView;
import android.widget.ImageView;
import android.view.View;
import android.view.ViewGroup;
import android.util.Log;
/**
* Simple implementation of the FloatViewManager class. Uses list
* items as they appear in the ListView to create the floating View.
*/
public class SimpleFloatViewManager implements DragSortListView.FloatViewManager {
private Bitmap mFloatBitmap;
private ImageView mImageView;
private int mFloatBGColor = Color.BLACK;
private ListView mListView;
public SimpleFloatViewManager(ListView lv) {
mListView = lv;
}
public void setBackgroundColor(int color) {
mFloatBGColor = color;
}
/**
* This simple implementation creates a Bitmap copy of the
* list item currently shown at ListView <code>position</code>.
*/
@Override
public View onCreateFloatView(int position) {
// Guaranteed that this will not be null? I think so. Nope, got
// a NullPointerException once...
View v = mListView.getChildAt(position + mListView.getHeaderViewsCount() - mListView.getFirstVisiblePosition());
if (v == null) {
return null;
}
v.setPressed(false);
// Create a copy of the drawing cache so that it does not get
// recycled by the framework when the list tries to clean up memory
//v.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
v.setDrawingCacheEnabled(true);
mFloatBitmap = Bitmap.createBitmap(v.getDrawingCache());
v.setDrawingCacheEnabled(false);
if (mImageView == null) {
mImageView = new ImageView(mListView.getContext());
}
mImageView.setBackgroundColor(mFloatBGColor);
mImageView.setPadding(0, 0, 0, 0);
mImageView.setImageBitmap(mFloatBitmap);
mImageView.setLayoutParams(new ViewGroup.LayoutParams(v.getWidth(), v.getHeight()));
return mImageView;
}
/**
* This does nothing
*/
@Override
public void onDragFloatView(View floatView, Point position, Point touch) {
// do nothing
}
/**
* Removes the Bitmap from the ImageView created in
* onCreateFloatView() and tells the system to recycle it.
*/
@Override
public void onDestroyFloatView(View floatView) {
((ImageView) floatView).setImageDrawable(null);
mFloatBitmap.recycle();
mFloatBitmap = null;
}
}

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="DragSortListView">
<attr name="collapsed_height" format="dimension" />
<attr name="drag_scroll_start" format="float" />
<attr name="max_drag_scroll_speed" format="float" />
<attr name="float_background_color" format="color" />
<attr name="remove_mode">
<enum name="clickRemove" value="0" />
<enum name="flingRemove" value="1" />
</attr>
<attr name="track_drag_sort" format="boolean"/>
<attr name="float_alpha" format="float"/>
<attr name="slide_shuffle_speed" format="float"/>
<attr name="remove_animation_duration" format="integer"/>
<attr name="drop_animation_duration" format="integer"/>
<attr name="drag_enabled" format="boolean" />
<attr name="sort_enabled" format="boolean" />
<attr name="remove_enabled" format="boolean" />
<attr name="drag_start_mode">
<enum name="onDown" value="0" />
<enum name="onMove" value="1" />
<enum name="onLongPress" value="2"/>
</attr>
<attr name="drag_handle_id" format="integer" />
<attr name="fling_handle_id" format="integer" />
<attr name="click_remove_id" format="integer" />
<attr name="use_default_controller" format="boolean" />
</declare-styleable>
</resources>

8
local.properties Normal file
View File

@ -0,0 +1,8 @@
## This file must *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
#Sun Jun 30 00:00:45 CST 2019
sdk.dir=D\:\\android\\sdk

3
settings.gradle Normal file
View File

@ -0,0 +1,3 @@
//include ':listviewlibrary', ':PushSDK', ':i7lvsvrs', ':zhuike', ':q'y, ':app'
//include ':zhuike', ':testapp' //, ':app', ':appNet'
include ':zhuike'

1
zhuike/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build

1
zhuike/.svn/entries Normal file
View File

@ -0,0 +1 @@
12

1
zhuike/.svn/format Normal file
View File

@ -0,0 +1 @@
12

View File

@ -0,0 +1,264 @@
package com.novelbook.android.dialog;
import android.content.Context;
import android.graphics.drawable.BitmapDrawable;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import com.novelbook.android.utils.Config;
import com.novelbook.android.R;
import com.novelbook.android.view.BookPageWidget;
import java.text.DecimalFormat;
public class ReadSettingDialog implements BaseDialog,View.OnClickListener {
ImageButton btn_return;
ImageButton btn_ight;
ImageButton btn_listener_book;
TextView tv_pre;
SeekBar sb_progress;
TextView tv_next;
TextView tv_directory;
TextView tv_dayornight;
TextView tv_setting;
TextView tv_Progress;
RelativeLayout rl_Progress;
private PopupWindow mPopupWindow,mPopupWindowTop;
private BookPageWidget mBookPageWidget;
private View view,viewTop;
private SettingListener mSettingListener;
private Context mContext;
private Config config;
private Boolean mDayOrNight;
public ReadSettingDialog(BookPageWidget bookPageWidget) {
this.mBookPageWidget = bookPageWidget;
mContext = bookPageWidget.getContext();
LayoutInflater layoutInflater = (LayoutInflater) bookPageWidget.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = layoutInflater.inflate(R.layout.zdialog_read_setting, null);
viewTop = layoutInflater.inflate(R.layout.zdialog_read_setting_top, null);
btn_return = (ImageButton) viewTop.findViewById(R.id.btn_return);
btn_ight = (ImageButton) viewTop.findViewById(R.id.btn_light);
btn_listener_book = (ImageButton) viewTop.findViewById(R.id.btn_listener_book);
tv_pre = (TextView) view.findViewById(R.id.tv_pre);
sb_progress = (SeekBar) view.findViewById(R.id.sb_progress);
tv_next = (TextView) view.findViewById(R.id.tv_next);
tv_directory = (TextView) view.findViewById(R.id.tv_directory);
tv_dayornight = (TextView) view.findViewById(R.id.tv_dayornight);
tv_setting = (TextView) view.findViewById(R.id.tv_setting);
tv_Progress = (TextView) view.findViewById(R.id.tv_progress);
rl_Progress = (RelativeLayout) view.findViewById(R.id.rl_progress);
btn_return.setOnClickListener(this);
btn_ight.setOnClickListener(this);
btn_listener_book.setOnClickListener(this);
tv_pre.setOnClickListener(this);
sb_progress.setOnClickListener(this);
tv_next.setOnClickListener(this);
tv_directory.setOnClickListener(this);
tv_dayornight.setOnClickListener(this);
tv_setting.setOnClickListener(this);
tv_Progress.setOnClickListener(this);
rl_Progress.setOnClickListener(this);
mPopupWindow = new PopupWindow(view, ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
mPopupWindowTop = new PopupWindow(viewTop, ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
mPopupWindow.setOutsideTouchable(true);
mPopupWindow.setBackgroundDrawable(new BitmapDrawable());
mPopupWindow.setOutsideTouchable(true);
mPopupWindow.setFocusable(true);// menu菜单获得焦点 如果没有获得焦点menu菜单中的控件事件无法响应
mPopupWindow.update();
mPopupWindowTop.setOutsideTouchable(true);
mPopupWindowTop.setBackgroundDrawable(new BitmapDrawable());
mPopupWindowTop.setOutsideTouchable(true);
mPopupWindowTop.setFocusable(true);// menu菜单获得焦点 如果没有获得焦点menu菜单中的控件事件无法响应
mPopupWindowTop.update();
view.setOnTouchListener(new View.OnTouchListener()// 需要设置点击之后取消popupview即使点击外面也可以捕获事件
{
public boolean onTouch(View v, MotionEvent event)
{
if (isShow())
{
dismiss();
}
return false;
}
});
config = Config.getInstance();
sb_progress.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
float pro;
// 触发操作,拖动
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
pro = (float) (progress / 10000.0);
showProgress(pro);
}
// 表示进度条刚开始拖动,开始拖动时候触发的操作
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
// 停止拖动时候
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
if (mSettingListener != null){
mSettingListener.changeProgress(pro);
}
}
});
initDayOrNight();
}
public void initDayOrNight(){
mDayOrNight = config.getDayOrNight();
if (mDayOrNight){
tv_dayornight.setText(mContext.getResources().getString(R.string.read_setting_day));
}else{
tv_dayornight.setText(mContext.getResources().getString(R.string.read_setting_night));
}
}
//改变显示模式
public void changeDayOrNight(){
if (mDayOrNight){
mDayOrNight = false;
tv_dayornight.setText(mContext.getResources().getString(R.string.read_setting_night));
}else{
mDayOrNight = true;
tv_dayornight.setText(mContext.getResources().getString(R.string.read_setting_day));
}
config.setDayOrNight(mDayOrNight);
if (mSettingListener != null) {
mSettingListener.dayorNight(mDayOrNight);
}
}
//显示书本进度
public void showProgress(float progress){
if (rl_Progress.getVisibility() != View.VISIBLE) {
rl_Progress.setVisibility(View.VISIBLE);
}
setProgress(progress);
}
//隐藏书本进度
public void hideProgress(){
rl_Progress.setVisibility(View.GONE);
}
@Override
public void show() {
hideProgress();
mPopupWindowTop.showAtLocation(mBookPageWidget, Gravity.TOP, 0, 0);
mPopupWindow.showAtLocation(mBookPageWidget, Gravity.BOTTOM, 0, 0);
}
private void setProgress(float progress){
DecimalFormat decimalFormat=new DecimalFormat("00.00");//构造方法的字符格式这里如果小数不足2位,会以0补足.
String p=decimalFormat.format(progress * 100.0);//format 返回的是字符串
tv_Progress.setText(p + "%");
}
public void setSeekBarProgress(float progress){
sb_progress.setProgress((int) (progress * 10000));
}
@Override
public void dismiss() {
mPopupWindowTop.dismiss();
mPopupWindow.dismiss();
}
@Override
public Boolean isShow() {
return mPopupWindow.isShowing() || mPopupWindowTop.isShowing();
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_return:
if (mSettingListener != null) {
mSettingListener.back();
}
break;
case R.id.btn_light:
break;
case R.id.btn_listener_book:
break;
case R.id.tv_pre:
if (mSettingListener != null) {
mSettingListener.pre();
}
break;
case R.id.sb_progress:
break;
case R.id.tv_next:
if (mSettingListener != null) {
mSettingListener.next();
}
break;
case R.id.tv_directory:
if (mSettingListener != null) {
mSettingListener.directory();
}
break;
case R.id.tv_dayornight:
changeDayOrNight();
break;
case R.id.tv_setting:
if (mSettingListener != null) {
mSettingListener.setting();
}
break;
}
}
public void setSettingListener(SettingListener settingListener) {
this.mSettingListener = settingListener;
}
public interface SettingListener {
void back();
void pre();
void dismiss();
void next();
void directory();
void dayorNight(Boolean isNight);
void setting();
void changeProgress(float progress);
}
}

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="Gradle: com.packetzoom:pz-okhttp3-interceptor:3.2.43@aar">
<CLASSES>
<root url="file://$USER_HOME$/.gradle/caches/transforms-1/files-1.1/pz-okhttp3-interceptor-3.2.43.aar/d3dede00ee90d31b0f32cd372a35eab6/res" />
<root url="jar://$USER_HOME$/.gradle/caches/transforms-1/files-1.1/pz-okhttp3-interceptor-3.2.43.aar/d3dede00ee90d31b0f32cd372a35eab6/jars/classes.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,462 @@
package com.novelbook.android.utils;
import android.content.Context;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;
import com.novelbook.android.db.Novel;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
public class Fileutil {
public static String name ;
public static int folderNum = 0;
/**
* 计算目录大小
*
* @param dir
* @return
*/
public static long getDirSize(File dir) {
if (dir == null) {
return 0;
}
// 不是目录
if (!dir.isDirectory()) {
return 0;
}
long dirSize = 0;
File[] files = dir.listFiles();
for (File file : files) {
if (file.isFile()) {
dirSize += file.length();
} else if (file.isDirectory()) {
// dirSize += file.length();
// 递归调用
dirSize += getDirSize(file);
}
}
return dirSize;
}
/**
* 转换文件大小
*
* @param fileS
* @return B/KB/MB/GB
*/
public static String formatFileSize(long fileS) {
if (fileS == 0) {
return "0.00B";
}
DecimalFormat dFormat = new DecimalFormat("#.00");
String fileSizeString = "";
if (fileS < 1024) {
fileSizeString = dFormat.format((double) fileS) + "B";
} else if (fileS < 1048576) {
fileSizeString = dFormat.format((double) fileS / 1024) + "KB";
} else if (fileS < 1073741824) {
fileSizeString = dFormat.format((double) fileS / 1048576) + "MB";
} else {
fileSizeString = dFormat.format((double) fileS / 1073741824) + "GB";
}
return fileSizeString;
}
/**
* 文件目录地址
*
* @return
*/
public static String fileDirectory(String dirPath, String fileName) {
String filePath = "";
String storageState = Environment.getExternalStorageState();
if (storageState.equals(Environment.MEDIA_MOUNTED)) {
filePath = Environment.getExternalStorageDirectory()
.getAbsolutePath() + dirPath;
File file = new File(filePath);
if (!file.exists()) {
// 建立一个新的目录
file.mkdirs();
}
filePath = filePath + fileName;
}
return filePath;
}
/**
* 获取文件目录
*
* @return
*/
public static File getDirectoryFile(String dirPath) {
String storageState = Environment.getExternalStorageState();
File file = null;
if (storageState.equals(Environment.MEDIA_MOUNTED)) {
String filePath = Environment.getExternalStorageDirectory()
.getAbsolutePath() + dirPath;
file = new File(filePath);
if (!file.exists()) {
// 建立一个新的目录
file.mkdirs();
}
}
return file;
}
/**
* 检查文件后缀
*
* @param checkItsEnd
* @param fileEndings
* @return
*/
private static boolean checkEndsWithInStringArray(String checkItsEnd,
String[] fileEndings) {
for (String aEnd : fileEndings) {
if (checkItsEnd.endsWith(aEnd))
return true;
}
return false;
}
/**
* 根据不同的后缀打开不同的文件
*
* @param fileName
*/
/** public static void openFile(Context context, String fileName, File file) {
Intent intent;
if (checkEndsWithInStringArray(fileName, context.getResources()
.getStringArray(R.array.fileEndingImage))) {
intent = OpenFiles.getImageFileIntent(file);
context.startActivity(intent);
} else if (checkEndsWithInStringArray(fileName, context.getResources()
.getStringArray(R.array.fileEndingWebText))) {
intent = OpenFiles.getHtmlFileIntent(file);
context.startActivity(intent);
} else if (checkEndsWithInStringArray(fileName, context.getResources()
.getStringArray(R.array.fileEndingPackage))) {
intent = OpenFiles.getApkFileIntent(file);
context.startActivity(intent);
} else if (checkEndsWithInStringArray(fileName, context.getResources()
.getStringArray(R.array.fileEndingAudio))) {
intent = OpenFiles.getAudioFileIntent(file);
context.startActivity(intent);
} else if (checkEndsWithInStringArray(fileName, context.getResources()
.getStringArray(R.array.fileEndingVideo))) {
intent = OpenFiles.getVideoFileIntent(file);
context.startActivity(intent);
} else if (checkEndsWithInStringArray(fileName, context.getResources()
.getStringArray(R.array.fileEndingText))) {
intent = OpenFiles.getTextFileIntent(file);
context.startActivity(intent);
} else if (checkEndsWithInStringArray(fileName, context.getResources()
.getStringArray(R.array.fileEndingPdf))) {
intent = OpenFiles.getPdfFileIntent(file);
context.startActivity(intent);
} else if (checkEndsWithInStringArray(fileName, context.getResources()
.getStringArray(R.array.fileEndingWord))) {
intent = OpenFiles.getWordFileIntent(file);
context.startActivity(intent);
} else if (checkEndsWithInStringArray(fileName, context.getResources()
.getStringArray(R.array.fileEndingExcel))) {
intent = OpenFiles.getExcelFileIntent(file);
context.startActivity(intent);
} else if (checkEndsWithInStringArray(fileName, context.getResources()
.getStringArray(R.array.fileEndingPPT))) {
intent = OpenFiles.getPPTFileIntent(file);
context.startActivity(intent);
} else {
Toast.makeText(context, "打开文件错误", Toast.LENGTH_SHORT).show();
}
} */
/**
* 根据不同的后缀imageView设置不同的值
*
* @param fileName
*/
/** public static void setImage(Context context, String fileName,
ImageView imageView) {
if (checkEndsWithInStringArray(fileName, context.getResources()
.getStringArray(R.array.fileEndingImage))) {
imageView.setImageResource(R.drawable.file_icon_picture);
} else if (checkEndsWithInStringArray(fileName, context.getResources()
.getStringArray(R.array.fileEndingWebText))) {
imageView.setImageResource(R.drawable.file_icon_txt);
} else if (checkEndsWithInStringArray(fileName, context.getResources()
.getStringArray(R.array.fileEndingPackage))) {
imageView.setImageResource(R.drawable.file_icon_rar);
} else if (checkEndsWithInStringArray(fileName, context.getResources()
.getStringArray(R.array.fileEndingAudio))) {
imageView.setImageResource(R.drawable.file_icon_mp3);
} else if (checkEndsWithInStringArray(fileName, context.getResources()
.getStringArray(R.array.fileEndingVideo))) {
imageView.setImageResource(R.drawable.file_icon_video);
} else if (checkEndsWithInStringArray(fileName, context.getResources()
.getStringArray(R.array.fileEndingText))) {
imageView.setImageResource(R.drawable.file_icon_txt);
} else if (checkEndsWithInStringArray(fileName, context.getResources()
.getStringArray(R.array.fileEndingPdf))) {
imageView.setImageResource(R.drawable.file_icon_pdf);
} else if (checkEndsWithInStringArray(fileName, context.getResources()
.getStringArray(R.array.fileEndingWord))) {
imageView.setImageResource(R.drawable.file_icon_office);
} else if (checkEndsWithInStringArray(fileName, context.getResources()
.getStringArray(R.array.fileEndingExcel))) {
imageView.setImageResource(R.drawable.file_icon_office);
} else if (checkEndsWithInStringArray(fileName, context.getResources()
.getStringArray(R.array.fileEndingPPT))) {
imageView.setImageResource(R.drawable.file_icon_office);
} else {
imageView.setImageResource(R.drawable.file);
}
} */
/**
*
* 返回本地文件列表
*
* @param //本地文件夹路径
*/
public static List<File> getFileListByPath( String path) {
Novel bookList = new Novel();
int fileNum = 0 ;
File dir = new File(path);
List<File> folderList = new ArrayList<File>();
List<File> fileList = new ArrayList<File>();
// 获取指定盘符下的所有文件列表。listFiles可以获得指定路径下的所有文件以数组方式返回
File[] files = dir.listFiles();
// 如果该目录下面为空,则该目录的此方法执行
if (files == null) {
return folderList;
}
// 通过循环将所遍历所有文件
for (int i = 0; i < files.length; i++) {
if (!files[i].isHidden()) {
if (files[i].isDirectory()) {
folderList.add(files[i]);
folderNum++;
}
if (files[i].isFile()) {
if (files[i].toString().contains(".txt")) { //txt".equals(extName)
fileList.add(files[i]);
// name = files[i].toString();
// FileActivity.paths.add(files[i].toString());
}
}
}
Log.d("Fileutil", folderNum + "");
}
folderList.addAll(fileList);
return folderList;
}
public static int getFileNum (List<File> list) {
File file;
int num = 0;
for (int i = 0 ; i<list.size(); i++) {
file = list.get(i);
if (file.isFile()){
num++;
}
}
return num;
}
/**
* 复制一个目录及其子目录、文件到另外一个目录
*
* @param src
* @param dest
* @throws IOException
*/
public static void copyFolder(File src, File dest) {
if (src.isDirectory()) {
if (!dest.exists()) {
dest.mkdir();
}
String files[] = src.list();
for (String file : files) {
File srcFile = new File(src, file);
File destFile = new File(dest, file);
// 递归复制
copyFolder(srcFile, destFile);
}
} else {
InputStream in;
OutputStream out;
try {
in = new FileInputStream(src);
out = new FileOutputStream(dest);
byte[] buffer = new byte[1024];
int length;
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
in.close();
out.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* @param src
* 源文件路径
* @param name
* 源文件名字
* @param dest
* 目标目录
*/
public static void copyFile(File src, String name, File dest) {
File file = new File(dest, name);
InputStream inputStream = null;
OutputStream outputStream = null;
try {
inputStream = new FileInputStream(src);
outputStream = new FileOutputStream(file);
byte[] b = new byte[1024];
int len = 0;
while ((len = inputStream.read(b)) != -1) {
outputStream.write(b, 0, len);
}
outputStream.close();
inputStream.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 创建目录或文件
*/
public static void createDirorFile(String path, String name, Context context,int check) {
File file = new File(path + File.separator + name);
if (check==0) {// 如果为文件
try {
file.createNewFile();
Toast.makeText(context, "创建文件成功", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Toast.makeText(context, "创建文件失败", Toast.LENGTH_SHORT).show();
}
} else if(check==1){
// 创建目录
if (file.mkdirs()) {
Toast.makeText(context, "创建目录成功", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "创建目录失败", Toast.LENGTH_SHORT).show();
}
}
}
/**
* 删除一个目录
*/
public static void deleteDir(File dir) {
if (dir == null || !dir.exists() || !dir.isDirectory()) {
return;
}
for (File file : dir.listFiles()) {
if (file.isFile())
file.delete(); // 删除所有文件
else if (file.isDirectory())
deleteDir(file); // 递规的方式删除文件夹
}
dir.delete();
}
/**
* @param fromDir
* 这个为源目录
* @param fromPath
* 这个为源目录的上一级路径
* @param toName
* 要修改的名字
*/
public static boolean renameFile(File fromDir, String fromPath,
String toName) {
File tempFile = new File(fromPath + File.separator + toName);
if (tempFile.exists()) {
return false;
} else {
return fromDir.renameTo(tempFile);
}
}
/** 去掉文件扩展名
*
*
* */
public static String getFileNameNoEx (String filename) {
if ((filename != null) && (filename.length() > 0)) {
int dot = filename.lastIndexOf('.');
if ((dot >-1) && (dot < (filename.length()))) {
return filename.substring(0, dot);
}
}
return filename;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="Gradle: com.android.support:documentfile:28.0.0@aar">
<CLASSES>
<root url="file://$USER_HOME$/.gradle/caches/transforms-1/files-1.1/documentfile-28.0.0.aar/bd8a84573a14077e3418642e1bf16f95/res" />
<root url="jar://$USER_HOME$/.gradle/caches/transforms-1/files-1.1/documentfile-28.0.0.aar/bd8a84573a14077e3418642e1bf16f95/jars/classes.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,401 @@
package com.novelbook.android.Fragments;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import com.novelbook.android.R;
import com.novelbook.android.db.Novel;
import com.novelbook.android.netsubscribe.BookSubscribe;
import com.novelbook.android.netutils.OnSuccessAndFaultListener;
import com.novelbook.android.netutils.OnSuccessAndFaultSub;
import com.novelbook.android.utils.Constants;
import com.novelbook.android.utils.GsonUtil;
import com.novelbook.android.utils.OnItemClickListener;
import com.novelbook.android.adapter.BookListAdapter;
import com.umeng.analytics.MobclickAgent;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
import butterknife.BindView;
public class Fragment_booklist extends BasicFragment {
public static final String TAG = Fragment_booklist.class.getSimpleName();
private static final String EXTR_CATE ="cate" ;
private static final String EXTR_PROGRESS ="progress" ;
private static final String EXTR_SEARCH ="search";
private static final String EXTR_FN ="fn" ;
private static final String EXTR_BANGDAN ="bangdan" ;
private static final String EXTR_HISTORY ="history" ;
private static final String EXTR_CID ="cid" ;
private BookListAdapter mAdapter;
// private BookListAdapter mAdapter;
private List mData;;
private List mMoreData;
private String cate;
private int progress,cid;
private String keyWord ,fn,bangdan,history;
private int listItem =R.layout.recycle_list_item_horizon;
//private int pageNo=1;
private int totalCount;
// private int pageCount;
@BindView(R.id.rvBooklist)
RecyclerView mRecyclerView;
@SuppressLint("ValidFragment")
public Fragment_booklist(String cate, int progress) {
this.cate =cate;
this.progress = progress;
}
public Fragment_booklist() {
// Required empty public constructor
}
public static Fragment_booklist newInstance(int cid,String bangdan) {
Fragment_booklist fragment = new Fragment_booklist();
Bundle args = new Bundle();
args.putInt(EXTR_CID,cid);
args.putString(EXTR_BANGDAN,bangdan);
fragment.setArguments(args);
return fragment;
}
public static Fragment_booklist newInstance(String fn,String bangdan) {
Fragment_booklist fragment = new Fragment_booklist();
Bundle args = new Bundle();
args.putString(EXTR_FN,fn);
args.putString(EXTR_BANGDAN,bangdan);
fragment.setArguments(args);
return fragment;
}
public static Fragment_booklist newInstance(String noveType,int progress) {
Fragment_booklist fragment = new Fragment_booklist();
Bundle args = new Bundle();
args.putString(EXTR_CATE,noveType);
args.putInt(EXTR_PROGRESS, progress);
fragment.setArguments(args);
return fragment;
}
public static Fragment_booklist search(String keyWord) {
Fragment_booklist fragment = new Fragment_booklist();
Bundle args = new Bundle();
args.putString(EXTR_SEARCH,keyWord);
fragment.setArguments(args);
return fragment;
}
public static Fragment_booklist history() {
Fragment_booklist fragment = new Fragment_booklist();
Bundle args = new Bundle();
args.putString(EXTR_HISTORY,EXTR_HISTORY);
fragment.setArguments(args);
return fragment;
}
protected void processArguments(){
if (getArguments() != null) {
Bundle bundle = getArguments() ;
bangdan =bundle.getString(EXTR_BANGDAN);
fn= bundle.getString(EXTR_FN);
cid =bundle.getInt(EXTR_CID);
if(!TextUtils.isEmpty((fn))){
return;
}
cate = bundle.getString(EXTR_CATE);
progress = bundle.getInt(EXTR_PROGRESS);
keyWord =bundle.getString(EXTR_SEARCH);
history =bundle.getString(EXTR_HISTORY);
if(!TextUtils.isEmpty(history)){
listItem =R.layout.recycle_list_item_history;
}
}
}
int lastPageNo =0;
@Override
protected void fillData() {
if(mRecyclerView.getAdapter()==null) {
mRecyclerView.setLayoutManager(new LinearLayoutManager(activity));
mRecyclerView.setAdapter(mAdapter);
}
if(mMoreData!=null) {
if(mMoreData.size()>0) {
pageNo++;
}
int status =getPageCount()>= pageNo ? BookListAdapter.PULLUP_LOAD_MORE : BookListAdapter.NO_LOAD_MORE;
// mAdapter.setPercent(pageNo/pageCount);
mAdapter.AddFooterItem(mMoreData);
mAdapter.changeMoreStatus(status);
mMoreData.clear();
}
}
@Override
protected int getLayoutRes() {
return R.layout.fragment_fragment_booklist;
}
@Override
public void initData() {
if(pageNo>1){
if(lastPageNo ==pageNo){
return;
}
}
lastPageNo = pageNo;
// int pn = pageNo;
if(pageNo==1) {
if (mData != null) { //下拉刷新
mData = new ArrayList<Novel>();
mAdapter.setData(mData);
// loadListAd(mAdapter,1,false);
} else {
initialDataAdapter();
}
}
/* if(mAdapter!=null){
mAdapter.changeMoreStatus(BookListAdapter.LOADING_MORE);
}*/
mMoreData =null;
OnSuccessAndFaultListener successAndFaultListener = new OnSuccessAndFaultListener() {
@Override
public void onSuccess(String result) {
// mFirstPage= gson.fromJson(result, FirstPage.class);
try {
JSONObject jsonObject = new JSONObject(result);
setPageCount(jsonObject.getInt("pageCount")); ;
mMoreData = GsonUtil. parserJsonArray(jsonObject,Constants.BLOCK_TITLE_NOVELS);
if(mMoreData.size()>0){
loadListAd(mAdapter,1,mData.size()>0);
}
} catch (Exception e) {
e.printStackTrace(); Log.e(TAG, "onSuccess: 解析失败",e );
}
handler.sendEmptyMessage(1);
}
@Override
public void onFault(String errorMsg) {
//失败
Log.d(TAG, "error on get firstpage: " + errorMsg);
handler.sendEmptyMessage(1);
}
};
showProgressDialog(false,"正在加载...");
Log.d(TAG,String.format("fn is %s",fn) );
if(!TextUtils.isEmpty(bangdan) && (cid >0 || !TextUtils.isEmpty(fn))){ //榜单
// showProgressDialog(true, "正在加载榜单");
mAdapter.setShowTop(true);
BookSubscribe.getPaihangBangList(Constants.SEX,pageNo,cid,new OnSuccessAndFaultSub(new OnSuccessAndFaultListener() {
@Override
public void onSuccess(String result) {
try {
JSONObject jsonObject = new JSONObject(result);
String resultstr = jsonObject.getString("rank") ;
setPageCount(jsonObject.getJSONObject("rank").getInt("pageCount")); ;
mMoreData = GsonUtil. parserJsonArray(resultstr,Constants.BLOCK_TITLE_NOVELS);
Log.d(TAG, "排行榜详细 onSuccess: pageCount " + getPageCount());
if(mMoreData.size()>0){
loadListAd(mAdapter,1,mData.size()>0);
}
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "onSuccess: 解析失败",e );
}
handler.sendEmptyMessage(1);
}
@Override
public void onFault(String errorMsg) {
//失败
Log.d(TAG, "error on get firstpage: " + errorMsg);
handler.sendEmptyMessage(1);
}
}, getActivity()));
}else if(!TextUtils.isEmpty(fn)){ //首页 更多
mAdapter.setShowTop(true);
// showProgressDialog(true, "正在加载更多");
BookSubscribe.getNovelPaihang(fn,Constants.SEX,new OnSuccessAndFaultSub(successAndFaultListener, getActivity()));
}
else if(!TextUtils.isEmpty((cate))) { //分类
mAdapter.setShowTop(true);
// showProgressDialog(true, "正在加载分类");
BookSubscribe.getCateNovelList(cate, pageNo, Constants.SEX, progress, new OnSuccessAndFaultSub(successAndFaultListener, getActivity()));
}else if(!TextUtils.isEmpty(keyWord)){ //搜索
// showProgressDialog(true, "正在加载搜索");
// mAdapter.setShowTop(true);
BookSubscribe.getSearchNovelList( keyWord,pageNo, Constants.SEX, new OnSuccessAndFaultSub(successAndFaultListener, getActivity()));
}else if(!TextUtils.isEmpty(history)){
loadHistory();
}else{
handler.sendEmptyMessage(1);
}
}
private void initialDataAdapter() {
mData = new ArrayList<Novel>();
mAdapter = new BookListAdapter(activity, mData, listItem, new OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
if(mData.get(position) instanceof Novel)
showBookDetail((Novel)mData.get(position));
// openBook(mData.get(position),mAdapter);
}
@Override
public void onItemLongClick(View view, int position) {
// initDialog(position);
// mAdapter.removeData(position);
}
@Override
public void onLinearOutClick(View view, int position, int llId) {
Toast.makeText(activity, "book " + position + " clicked",
Toast.LENGTH_SHORT).show();
}
});
mAdapter.setShowFootView(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(activity));
mRecyclerView.setAdapter(mAdapter);
}
@Override
public void initViews(){
//mRecyclerView
//lv_catalogue.setFastScrollStyle(R.style.FastScrollTheme); //不起作用
initLoadMoreListener();
}
//----------------绑定列表
void initialBookList() {
}
@Override
public void setFTag() {
}
private void initLoadMoreListener() {
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
int lastVisibleItem ;
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
Log.d(TAG, String.format("onScrollStateChanged , state %s ,lastVisibleitem %s ,getItemCount %s,pageno %s ,getPageCount() %s",
newState==RecyclerView.SCROLL_STATE_IDLE,lastVisibleItem,mAdapter.getItemCount(),pageNo,getPageCount()));
//判断RecyclerView的状态 是空闲时同时是最后一个可见的ITEM时才加载
if(newState==RecyclerView.SCROLL_STATE_IDLE&&lastVisibleItem+1==mAdapter.getItemCount()){
if(pageNo <= getPageCount()) {
//设置正在加载更多
mAdapter.changeMoreStatus(mAdapter.LOADING_MORE);
//改为网络请求
initData();
}else{
mAdapter.changeMoreStatus(mAdapter.NO_LOAD_MORE);
}
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
//最后一个可见的ITEM
lastVisibleItem=layoutManager.findLastVisibleItemPosition();
}
});
}
void loadHistory(){
initialDataAdapter();
new Thread() {
@Override
public void run() {
super.run();
mMoreData = Novel.getNovelsHistory();
setPageCount(1);
//
handler.sendEmptyMessage(1);
if(mMoreData!=null && mMoreData.size()>5) {
loadListAd(mAdapter, 1, mData.size() > 0);
}
}
}.start();
}
boolean isFirstLoad =true;
@Override
public void onResume(){
super.onResume();
// pageNo=1;
if(!TextUtils.isEmpty(history)){
if(isFirstLoad) {
isFirstLoad=false;
}else{
initData();
}
}
MobclickAgent.onPageStart(TAG);
}
@Override
public void onPause(){
super.onPause();
MobclickAgent.onPageEnd(TAG);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 975 B

View File

@ -0,0 +1,348 @@
package com.novelbook.android.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.support.annotation.ColorRes;
import android.support.annotation.DrawableRes;
import android.util.AttributeSet;
import android.widget.ImageView;
import com.novelbook.android.R;
/**
* 流程控制的比较严谨比如setup函数的使用
* updateShaderMatrix保证图片损失度最小和始终绘制图片正中央的那部分
* 作者思路是画圆用渲染器位图填充而不是把Bitmap重绘切割成一个圆形图片。
*/
public class CircleImageView extends ImageView {
//缩放类型
private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP;
private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;
private static final int COLORDRAWABLE_DIMENSION = 2;
// 默认边界宽度
private static final int DEFAULT_BORDER_WIDTH = 0;
// 默认边界颜色
private static final int DEFAULT_BORDER_COLOR = Color.BLACK;
private static final boolean DEFAULT_BORDER_OVERLAY = false;
private final RectF mDrawableRect = new RectF();
private final RectF mBorderRect = new RectF();
private final Matrix mShaderMatrix = new Matrix();
//这个画笔最重要的是关联了mBitmapShader 使canvas在执行的时候可以切割原图片(mBitmapShader是关联了原图的bitmap的)
private final Paint mBitmapPaint = new Paint();
//这个描边则与本身的原图bitmap没有任何关联
private final Paint mBorderPaint = new Paint();
//这里定义了 圆形边缘的默认宽度和颜色
private int mBorderColor = DEFAULT_BORDER_COLOR;
private int mBorderWidth = DEFAULT_BORDER_WIDTH;
private Bitmap mBitmap;
private BitmapShader mBitmapShader; // 位图渲染
private int mBitmapWidth; // 位图宽度
private int mBitmapHeight; // 位图高度
private float mDrawableRadius;// 图片半径
private float mBorderRadius;// 带边框的的图片半径
private ColorFilter mColorFilter;
//初始false
private boolean mReady;
private boolean mSetupPending;
private boolean mBorderOverlay;
//构造函数
public CircleImageView(Context context) {
super(context);
init();
}
//构造函数
public CircleImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
/**
* 构造函数
*/
public CircleImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
//通过obtainStyledAttributes 获得一组值赋给 TypedArray数组 , 这一组值来自于res/values/attrs.xml中的name="CircleImageView"的declare-styleable中。
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0);
//通过TypedArray提供的一系列方法getXXXX取得我们在xml里定义的参数值
// 获取边界的宽度
mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_border_width, DEFAULT_BORDER_WIDTH);
// 获取边界的颜色
mBorderColor = a.getColor(R.styleable.CircleImageView_border_color, DEFAULT_BORDER_COLOR);
mBorderOverlay = DEFAULT_BORDER_OVERLAY;
//调用 recycle() 回收TypedArray,以便后面重用
a.recycle();
System.out.println("CircleImageView -- 构造函数");
init();
}
/**
* 作用就是保证第一次执行setup函数里下面代码要在构造函数执行完毕时调用
*/
private void init() {
//在这里ScaleType被强制设定为CENTER_CROP就是将图片水平垂直居中进行缩放。
super.setScaleType(SCALE_TYPE);
mReady = true;
if (mSetupPending) {
setup();
mSetupPending = false;
}
}
@Override
public ScaleType getScaleType() {
return SCALE_TYPE;
}
/**
* 这里明确指出 此种imageview 只支持CENTER_CROP 这一种属性
*
* @param scaleType
*/
@Override
public void setScaleType(ScaleType scaleType) {
if (scaleType != SCALE_TYPE) {
throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType));
}
}
@Override
public void setAdjustViewBounds(boolean adjustViewBounds) {
if (adjustViewBounds) {
throw new IllegalArgumentException("adjustViewBounds not supported.");
}
}
@Override
protected void onDraw(Canvas canvas) {
//如果图片不存在就不画
if (getDrawable() == null) {
return;
}
//绘制内圆形 图片 画笔为mBitmapPaint
canvas.drawCircle(getWidth() / 2, getHeight() / 2, mDrawableRadius, mBitmapPaint);
//如果圆形边缘的宽度不为0 我们还要绘制带边界的外圆形 边界画笔为mBorderPaint
if (mBorderWidth != 0) {
canvas.drawCircle(getWidth() / 2, getHeight() / 2, mBorderRadius, mBorderPaint);
}
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
setup();
}
public int getBorderColor() {
return mBorderColor;
}
public void setBorderColor(int borderColor) {
if (borderColor == mBorderColor) {
return;
}
mBorderColor = borderColor;
mBorderPaint.setColor(mBorderColor);
invalidate();
}
public void setBorderColorResource(@ColorRes int borderColorRes) {
setBorderColor(getContext().getResources().getColor(borderColorRes));
}
public int getBorderWidth() {
return mBorderWidth;
}
public void setBorderWidth(int borderWidth) {
if (borderWidth == mBorderWidth) {
return;
}
mBorderWidth = borderWidth;
setup();
}
public boolean isBorderOverlay() {
return mBorderOverlay;
}
public void setBorderOverlay(boolean borderOverlay) {
if (borderOverlay == mBorderOverlay) {
return;
}
mBorderOverlay = borderOverlay;
setup();
}
/**
* 以下四个函数都是
* 复写ImageView的setImageXxx()方法
* 注意这个函数先于构造函数调用之前调用
* @param bm
*/
@Override
public void setImageBitmap(Bitmap bm) {
super.setImageBitmap(bm);
mBitmap = bm;
setup();
}
@Override
public void setImageDrawable(Drawable drawable) {
super.setImageDrawable(drawable);
mBitmap = getBitmapFromDrawable(drawable);
System.out.println("setImageDrawable -- setup");
setup();
}
@Override
public void setImageResource(@DrawableRes int resId) {
super.setImageResource(resId);
mBitmap = getBitmapFromDrawable(getDrawable());
setup();
}
@Override
public void setImageURI(Uri uri) {
super.setImageURI(uri);
mBitmap = getBitmapFromDrawable(getDrawable());
setup();
}
@Override
public void setColorFilter(ColorFilter cf) {
if (cf == mColorFilter) {
return;
}
mColorFilter = cf;
mBitmapPaint.setColorFilter(mColorFilter);
invalidate();
}
/**
* Drawable转Bitmap
* @param drawable
* @return
*/
private Bitmap getBitmapFromDrawable(Drawable drawable) {
if (drawable == null) {
return null;
}
if (drawable instanceof BitmapDrawable) {
//通常来说 我们的代码就是执行到这里就返回了。返回的就是我们最原始的bitmap
return ((BitmapDrawable) drawable).getBitmap();
}
try {
Bitmap bitmap;
if (drawable instanceof ColorDrawable) {
bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG);
} else {
bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG);
}
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
} catch (OutOfMemoryError e) {
return null;
}
}
/**
* 这个函数很关键,进行图片画笔边界画笔(Paint)一些重绘参数初始化:
* 构建渲染器BitmapShader用Bitmap来填充绘制区域,设置样式以及内外圆半径计算等,
* 以及调用updateShaderMatrix()函数和 invalidate()函数;
*/
private void setup() {
//因为mReady默认值为false,所以第一次进这个函数的时候if语句为真进入括号体内
//设置mSetupPending为true然后直接返回后面的代码并没有执行。
if (!mReady) {
mSetupPending = true;
return;
}
//防止空指针异常
if (mBitmap == null) {
return;
}
// 构建渲染器用mBitmap位图来填充绘制区域 ,参数值代表如果图片太小的话 就直接拉伸
mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
// 设置图片画笔反锯齿
mBitmapPaint.setAntiAlias(true);
// 设置图片画笔渲染器
mBitmapPaint.setShader(mBitmapShader);
// 设置边界画笔样式
mBorderPaint.setStyle(Paint.Style.STROKE);//设画笔为空心
mBorderPaint.setAntiAlias(true);
mBorderPaint.setColor(mBorderColor); //画笔颜色
mBorderPaint.setStrokeWidth(mBorderWidth);//画笔边界宽度
//这个地方是取的原图片的宽高
mBitmapHeight = mBitmap.getHeight();
mBitmapWidth = mBitmap.getWidth();
// 设置含边界显示区域取的是CircleImageView的布局实际大小为方形查看xml也就是160dp(240px) getWidth得到是某个view的实际尺寸
mBorderRect.set(0, 0, getWidth(), getHeight());
//计算 圆形带边界部分外圆的最小半径取mBorderRect的宽高减去一个边缘大小的一半的较小值这个地方我比较纳闷为什么求外圆半径需要先减去一个边缘大小
mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2, (mBorderRect.width() - mBorderWidth) / 2);
// 初始图片显示区域为mBorderRectCircleImageView的布局实际大小
mDrawableRect.set(mBorderRect);
if (!mBorderOverlay) {
//demo里始终执行
//通过inset方法 使得图片显示的区域从mBorderRect大小上下左右内移边界的宽度形成区域查看xml边界宽度为2dp3px,所以方形边长为就是160-4=156dp(234px)
mDrawableRect.inset(mBorderWidth, mBorderWidth);
}
//这里计算的是内圆的最小半径,也即去除边界宽度的半径
mDrawableRadius = Math.min(mDrawableRect.height() / 2, mDrawableRect.width() / 2);
//设置渲染器的变换矩阵也即是mBitmap用何种缩放形式填充
updateShaderMatrix();
//手动触发ondraw()函数 完成最终的绘制
invalidate();
}
/**
* 这个函数为设置BitmapShader的Matrix参数设置最小缩放比例平移参数。
* 作用:保证图片损失度最小和始终绘制图片正中央的那部分
*/
private void updateShaderMatrix() {
float scale;
float dx = 0;
float dy = 0;
mShaderMatrix.set(null);
// 这里不好理解 这个不等式也就是(mBitmapWidth / mDrawableRect.width()) > (mBitmapHeight / mDrawableRect.height())
//取最小的缩放比例
if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) {
//y轴缩放 x轴平移 使得图片的y轴方向的边的尺寸缩放到图片显示区域mDrawableRect一样
scale = mDrawableRect.height() / (float) mBitmapHeight;
dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;
} else {
//x轴缩放 y轴平移 使得图片的x轴方向的边的尺寸缩放到图片显示区域mDrawableRect一样
scale = mDrawableRect.width() / (float) mBitmapWidth;
dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;
}
// shaeder的变换矩阵我们这里主要用于放大或者缩小。
mShaderMatrix.setScale(scale, scale);
// 平移
mShaderMatrix.postTranslate((int) (dx + 0.5f) + mDrawableRect.left, (int) (dy + 0.5f) + mDrawableRect.top);
// 设置变换矩阵
mBitmapShader.setLocalMatrix(mShaderMatrix);
}
}

View File

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Main2Activity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ToolBarTheme.AppBarOverlay">
<!--android:layout_height="?attr/actionBarSize"-->
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
style="@style/Toolbar"
android:layout_width="match_parent"
android:layout_height="@dimen/toolbarHeight"
android:background="?attr/colorPrimary"
app:popupTheme="@style/ToolBarTheme.PopupOverlay" >
<TextView
android:id="@+id/toolbarTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:gravity="center"
android:text="我是标题"
android:textSize="18sp"
android:layout_weight="1"
android:visibility="visible"
android:textColor="@color/white"
/>
<!-- <android.support.v7.widget.AppCompatSpinner
android:id="@+id/sexSelect"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="50dp"
style="@style/common_spinner"
app:theme="@style/common_spinner"
android:popupTheme="@style/common_spinner"
android:entries="@array/sex"
android:layout_gravity="left|center_vertical"
android:layout_weight="0"
android:visibility="gone"
/>-->
<RadioGroup
android:id="@+id/rgSex"
style="@style/radioGroup"
android:layout_gravity="center_horizontal"
>
<RadioButton
android:id="@+id/radioButtonBoy"
android:text="男生"
style="@style/radioButton"
android:checked="true"
/>
<RadioButton
android:id="@+id/radioButtonGirl"
android:text="女生"
style="@style/radioButton"
/>
</RadioGroup>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<include layout="@layout/realcontent" />
</LinearLayout>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|start"
android:layout_margin="@dimen/fab_margin"
android:visibility="gone"
app:srcCompat="@android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>

View File

@ -0,0 +1,75 @@
package com.novelbook.android.AD.toutiao;
/*import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import com.bytedance.sdk.openadsdk.TTAdConfig;
import com.bytedance.sdk.openadsdk.TTAdConstant;
import com.bytedance.sdk.openadsdk.TTAdManager;
import com.bytedance.sdk.openadsdk.TTAdSdk;
import com.novelbook.android.BuildConfig;
import com.novelbook.android.utils.Constants;
import static com.novelbook.android.bean.AdSetting.getAppID;*/
import android.content.Context;
/**
* 可以用一个单例来保存TTAdManager实例在需要初始化sdk的时候调用
*/
public class TTAdManagerHolder {
//step1:接入网盟广告sdk的初始化操作详情见接入文档和穿山甲平台说明
private static void doInit(Context context) {
/* if (!sInit) {
TTAdSdk.init(context, buildConfig(context));
sInit = true;
}*/
}
public static void init(Context context) {
/* if( Constants.AD_SETTING.isShowAdsense() &&
!TextUtils.isEmpty(getAppID(Constants.AD_TOUTIAO)) ) {
doInit(context);
}*/
}
/*
private static boolean sInit;
public static TTAdManager get() {
if (!sInit) {
throw new RuntimeException("TTAdSdk is not init, please check.");
}
return TTAdSdk.getAdManager();
}
public static void init(Context context) {
if( Constants.AD_SETTING.isShowAdsense() &&
!TextUtils.isEmpty(getAppID(Constants.AD_TOUTIAO)) ) {
doInit(context);
}
}
private static TTAdConfig buildConfig(Context context) {
Log.d("adinit", "buildConfig:Constants.SEX= "+Constants.SEX );
return new TTAdConfig.Builder()
.appId(getAppID(Constants.AD_TOUTIAO))
.useTextureView(false) //使用TextureView控件播放视频,默认为SurfaceView,当有SurfaceView冲突的场景可以使用TextureView
.appName("如意小说")
.titleBarTheme(TTAdConstant.TITLE_BAR_THEME_DARK)
.allowShowNotify(true) //是否允许sdk展示通知栏提示
.allowShowPageWhenScreenLock(true) //是否在锁屏场景支持展示广告落地页
// .debug(true) //测试阶段打开,可以通过日志排查问题,上线时去除该调用
.directDownloadNetworkType(TTAdConstant.NETWORK_STATE_WIFI, TTAdConstant.NETWORK_STATE_4G) //允许直接下载的网络状态集合
.supportMultiProcess(false) //是否支持多进程true支持
.gender(Constants.SEX==1 ? TTAdConstant.GENDER_MALE : TTAdConstant.GENDER_FEMALE) // TTAdConstant.GENDER_UNKNOWN)
// .age(20) //TODO: 年龄收集
.build();
}*/
public static void initOnSexChange(Context context){
// buildConfig(context);
}
}

View File

@ -0,0 +1,53 @@
package com.novelbook.android.utils;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
public class BitmapUtil {
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
/** final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
} */
final int heightRatio = Math.round((float) height / (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
// 选择宽和高中最小的比率作为inSampleSize的值这样可以保证最终图片的宽和高
// 一定都不会大于等于目标的宽和高。
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
}

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@ -0,0 +1,421 @@
package com.novelbook.android.Fragments;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import com.novelbook.android.R;
import com.novelbook.android.db.Novel;
import com.novelbook.android.netsubscribe.BookSubscribe;
import com.novelbook.android.netutils.OnSuccessAndFaultListener;
import com.novelbook.android.netutils.OnSuccessAndFaultSub;
import com.novelbook.android.utils.Constants;
import com.novelbook.android.utils.GsonUtil;
import com.novelbook.android.utils.OnItemClickListener;
import com.novelbook.android.adapter.BookListAdapter;
import com.umeng.analytics.MobclickAgent;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
import butterknife.BindView;
public class Fragment_booklist extends BasicFragment {
public static final String TAG = Fragment_booklist.class.getSimpleName();
private static final String EXTR_CATE ="cate" ;
private static final String EXTR_PROGRESS ="progress" ;
private static final String EXTR_SEARCH ="search";
private static final String EXTR_FN ="fn" ;
private static final String EXTR_BANGDAN ="bangdan" ;
private static final String EXTR_HISTORY ="history" ;
private static final String EXTR_CID ="cid" ;
private BookListAdapter mAdapter;
// private BookListAdapter mAdapter;
private List mData;;
private List mMoreData;
private String cate;
private int progress,cid;
private String keyWord ,fn,bangdan,history;
private int listItem =R.layout.recycle_list_item_horizon;
//private int pageNo=1;
private int totalCount;
// private int pageCount;
@BindView(R.id.rvBooklist)
RecyclerView mRecyclerView;
@SuppressLint("ValidFragment")
public Fragment_booklist(String cate, int progress) {
this.cate =cate;
this.progress = progress;
}
public Fragment_booklist() {
// Required empty public constructor
}
public static Fragment_booklist newInstance(int cid,String bangdan) {
Fragment_booklist fragment = new Fragment_booklist();
Bundle args = new Bundle();
args.putInt(EXTR_CID,cid);
args.putString(EXTR_BANGDAN,bangdan);
fragment.setArguments(args);
return fragment;
}
public static Fragment_booklist newInstance(String fn,String bangdan) {
Fragment_booklist fragment = new Fragment_booklist();
Bundle args = new Bundle();
args.putString(EXTR_FN,fn);
args.putString(EXTR_BANGDAN,bangdan);
fragment.setArguments(args);
return fragment;
}
public static Fragment_booklist newInstance(String noveType,int progress) {
Fragment_booklist fragment = new Fragment_booklist();
Bundle args = new Bundle();
args.putString(EXTR_CATE,noveType);
args.putInt(EXTR_PROGRESS, progress);
fragment.setArguments(args);
return fragment;
}
public static Fragment_booklist search(String keyWord) {
Fragment_booklist fragment = new Fragment_booklist();
Bundle args = new Bundle();
args.putString(EXTR_SEARCH,keyWord);
fragment.setArguments(args);
return fragment;
}
public static Fragment_booklist history() {
Fragment_booklist fragment = new Fragment_booklist();
Bundle args = new Bundle();
args.putString(EXTR_HISTORY,EXTR_HISTORY);
fragment.setArguments(args);
return fragment;
}
protected void processArguments(){
if (getArguments() != null) {
Bundle bundle = getArguments() ;
bangdan =bundle.getString(EXTR_BANGDAN);
fn= bundle.getString(EXTR_FN);
cid =bundle.getInt(EXTR_CID);
if(!TextUtils.isEmpty((fn))){
return;
}
cate = bundle.getString(EXTR_CATE);
progress = bundle.getInt(EXTR_PROGRESS);
keyWord =bundle.getString(EXTR_SEARCH);
history =bundle.getString(EXTR_HISTORY);
if(!TextUtils.isEmpty(history)){
listItem =R.layout.recycle_list_item_history;
}
}
}
int lastPageNo =0;
@Override
protected void fillData() {
if(mRecyclerView.getAdapter()==null) {
mRecyclerView.setLayoutManager(new LinearLayoutManager(activity));
mRecyclerView.setAdapter(mAdapter);
}
if(mMoreData!=null) {
if(mMoreData.size()>0) {
pageNo++;
}
int status =getPageCount()>= pageNo ? BookListAdapter.PULLUP_LOAD_MORE : BookListAdapter.NO_LOAD_MORE;
// mAdapter.setPercent(pageNo/pageCount);
mAdapter.AddFooterItem(mMoreData);
mAdapter.changeMoreStatus(status);
mMoreData.clear();
}
}
@Override
protected int getLayoutRes() {
return R.layout.fragment_fragment_booklist;
}
@Override
public void initData() {
if(pageNo>1){
if(lastPageNo ==pageNo){
return;
}
}
lastPageNo = pageNo;
// int pn = pageNo;
if(pageNo==1) {
noveIds = new ArrayList<Integer>();
if (mData != null) { //下拉刷新
mData = new ArrayList<Novel>();
mAdapter.setData(mData);
// loadListAd(mAdapter,1,false);
} else {
initialDataAdapter();
}
}
/* if(mAdapter!=null){
mAdapter.changeMoreStatus(BookListAdapter.LOADING_MORE);
}*/
mMoreData =null;
OnSuccessAndFaultListener successAndFaultListener = new OnSuccessAndFaultListener() {
@Override
public void onSuccess(String result) {
// mFirstPage= gson.fromJson(result, FirstPage.class);
try {
JSONObject jsonObject = new JSONObject(result);
setPageCount(jsonObject.getInt("pageCount")); ;
List<Novel> list = GsonUtil. parserJsonArray(jsonObject,Constants.BLOCK_TITLE_NOVELS);
mMoreData =new ArrayList<Novel>();
for(Novel novel :list){
if(!noveIds.contains(novel.getNovelId())){
mMoreData.add(novel);
noveIds.add(novel.getNovelId());
}
}
if(mMoreData.size()>0){
loadListAd(mAdapter,1,mData.size()>0);
}
} catch (Exception e) {
e.printStackTrace(); Log.e(TAG, "onSuccess: 解析失败",e );
}
handler.sendEmptyMessage(1);
}
@Override
public void onFault(String errorMsg) {
//失败
Log.d(TAG, "error on get firstpage: " + errorMsg);
handler.sendEmptyMessage(1);
}
};
showProgressDialog(false,"正在加载...");
Log.d(TAG,String.format("fn is %s",fn) );
if(!TextUtils.isEmpty(bangdan) && (cid >0 || !TextUtils.isEmpty(fn))){ //榜单
// showProgressDialog(true, "正在加载榜单");
mAdapter.setShowTop(true);
BookSubscribe.getPaihangBangList(Constants.SEX,pageNo,cid,new OnSuccessAndFaultSub(new OnSuccessAndFaultListener() {
@Override
public void onSuccess(String result) {
try {
JSONObject jsonObject = new JSONObject(result);
String resultstr = jsonObject.getString("rank") ;
setPageCount(jsonObject.getJSONObject("rank").getInt("pageCount")); ;
List<Novel> list = GsonUtil. parserJsonArray(resultstr,Constants.BLOCK_TITLE_NOVELS);
mMoreData =new ArrayList<Novel>();
for(Novel novel :list){
if(!noveIds.contains(novel.getNovelId())){
mMoreData.add(novel);
noveIds.add(novel.getNovelId());
}
}
Log.d(TAG, "排行榜详细 onSuccess: pageCount " + getPageCount());
if(mMoreData.size()>0){
loadListAd(mAdapter,1,mData.size()>0);
}
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "onSuccess: 解析失败",e );
}
Log.d(TAG, "progress: progress to hide");
handler.sendEmptyMessage(1);
}
@Override
public void onFault(String errorMsg) {
//失败
Log.d(TAG, "error on get firstpage: " + errorMsg);
handler.sendEmptyMessage(1);
}
}, getActivity()));
}else if(!TextUtils.isEmpty(fn)){ //首页 更多
mAdapter.setShowTop(true);
// showProgressDialog(true, "正在加载更多");
BookSubscribe.getNovelPaihang(fn,pageNo,Constants.SEX,new OnSuccessAndFaultSub(successAndFaultListener, getActivity()));
}
else if(!TextUtils.isEmpty((cate))) { //分类
mAdapter.setShowTop(true);
// showProgressDialog(true, "正在加载分类");
BookSubscribe.getCateNovelList(cate, pageNo, Constants.SEX, progress, new OnSuccessAndFaultSub(successAndFaultListener, getActivity()));
}else if(!TextUtils.isEmpty(keyWord)){ //搜索
// showProgressDialog(true, "正在加载搜索");
// mAdapter.setShowTop(true);
BookSubscribe.getSearchNovelList( keyWord,pageNo, Constants.SEX, new OnSuccessAndFaultSub(successAndFaultListener, getActivity()));
}else if(!TextUtils.isEmpty(history)){
loadHistory();
}else{
handler.sendEmptyMessage(1);
}
}
private void initialDataAdapter() {
mData = new ArrayList<Novel>();
mAdapter = new BookListAdapter(activity, mData, listItem, new OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
if(mData.get(position) instanceof Novel)
showBookDetail((Novel)mData.get(position));
// openBook(mData.get(position),mAdapter);
}
@Override
public void onItemLongClick(View view, int position) {
// initDialog(position);
// mAdapter.removeData(position);
}
@Override
public void onLinearOutClick(View view, int position, int llId) {
Toast.makeText(activity, "book " + position + " clicked",
Toast.LENGTH_SHORT).show();
}
});
mAdapter.setShowFootView(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(activity));
mRecyclerView.setAdapter(mAdapter);
}
@Override
public void initViews(){
//mRecyclerView
//lv_catalogue.setFastScrollStyle(R.style.FastScrollTheme); //不起作用
initLoadMoreListener();
}
//----------------绑定列表
void initialBookList() {
}
@Override
public void setFTag() {
}
private void initLoadMoreListener() {
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
int lastVisibleItem ;
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
Log.d(TAG, String.format("onScrollStateChanged , state %s ,lastVisibleitem %s ,getItemCount %s,pageno %s ,getPageCount() %s",
newState==RecyclerView.SCROLL_STATE_IDLE,lastVisibleItem,mAdapter.getItemCount(),pageNo,getPageCount()));
//判断RecyclerView的状态 是空闲时同时是最后一个可见的ITEM时才加载
if(newState==RecyclerView.SCROLL_STATE_IDLE&&lastVisibleItem+1==mAdapter.getItemCount()){
if(pageNo <= getPageCount()) {
//设置正在加载更多
mAdapter.changeMoreStatus(mAdapter.LOADING_MORE);
//改为网络请求
initData();
}else{
mAdapter.changeMoreStatus(mAdapter.NO_LOAD_MORE);
}
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
//最后一个可见的ITEM
lastVisibleItem=layoutManager.findLastVisibleItemPosition();
}
});
}
void loadHistory(){
initialDataAdapter();
new Thread() {
@Override
public void run() {
super.run();
mMoreData = Novel.getNovelsHistory();
setPageCount(1);
//
handler.sendEmptyMessage(1);
if(mMoreData!=null && mMoreData.size()>5) {
loadListAd(mAdapter, 1, mData.size() > 0);
}
}
}.start();
}
boolean isFirstLoad =true;
@Override
public void onResume(){
super.onResume();
// pageNo=1;
if(!TextUtils.isEmpty(history)){
if(isFirstLoad) {
isFirstLoad=false;
}else{
initData();
}
}
MobclickAgent.onPageStart(TAG);
}
@Override
public void onPause(){
super.onPause();
MobclickAgent.onPageEnd(TAG);
}
}

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 边框颜色值 -->
<item>
<shape>
<solid android:color="#9c9c9c" />
</shape>
</item>
<!-- 主体背景颜色值 -->
<item android:bottom="1dp"> <!--设置只有底部有边框-->
<shape>
<solid android:color="#ffffff" />
</shape>
</item>
</layer-list>

View File

@ -0,0 +1,12 @@
<component name="libraryTable">
<library name="Gradle: com.android.support.test:monitor:1.0.2@aar">
<CLASSES>
<root url="file://$USER_HOME$/.gradle/caches/transforms-1/files-1.1/monitor-1.0.2.aar/f9313d309242cd0979a51392ae691413/res" />
<root url="jar://$USER_HOME$/.gradle/caches/transforms-1/files-1.1/monitor-1.0.2.aar/f9313d309242cd0979a51392ae691413/jars/classes.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.support.test/monitor/1.0.2/5764301056100b445e9ba31df7d1b554a55450f6/monitor-1.0.2-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,91 @@
package com.novelbook.android.utils;
import com.novelbook.android.R;
import com.novelbook.android.bean.AdSetting;
import com.novelbook.android.bean.ProgressType;
import java.util.ArrayList;
import java.util.List;
public class Constants {
public static final String BLOCK_TITLE_NOVELS = "ns";
public static final String HOT_KEYS = "keywords";
public static final int NOVEL_SPAN_CNT =3 ; //grid columns
public static final int MAXAGE_MAX =60*60*24*28; //28 天 ;
public static final int MAXAGE_MULU = 60*60*24*7*2; //2周;;
public static final String VERSION_ADDRESS ="version.xml";
public static int APP_START_COUNT_4AD =0 ;
public static int APP_START_COUNT =0 ;
public static int SHELF_ORDER =0 ;
public static AdSetting AD_SETTING;
public static final int AD_TENCENT_QQ =1;
public static final int AD_MOB =2;
public static final int AD_TOUTIAO =3;
public static final int AD_BANNER_TOP =1;
public static final int AD_BANNER_BOTTOM =2;
public static boolean AD_BACKGROUND_TRANSPARENT =true ;
public static boolean PRE_LOAD_CHAPT = false;
public static int SCREEN_HEIGHT_PIX =1920 ;
public static int SCREEN_WIDTH_PIX = 1080;
public static String DECLARE ="";
public static boolean SHOW_NOVEL_CHAPTER_URL =false;
/* public static boolean SHOWAD =false ;
public static int AD_NATIVE_BANNER_SOURCE = 1 ; //1:tencent,2:toutiao
public static int AD_BANNER_SOURCE = 2 ; //1:tencent,2:toutiao
public static int AD_UNIFIED_RECYCLE_SOURCE = 2 ; //1:tencent,2:toutiao
public static int AD_SPLASH_SOURCE = 1 ; //1:tencent,2:toutiao
public static int AD_SOURCE =1 ; //1:tencent,2:toutiao
public static long AD_SPLASH_INVTERVAL = 5*60*1000;//间隔5分钟
public static int AD_SPLASH_PAGES = 15;
public static int AD_CHAPT_TOP_BANNER_PER_PAGE_COUNT=0; //每几页show topbanner
public static int AD_CHAPT_NATIVE_BANNER_PER_PAGE_COUNT=0; //每几页show nativebanner
public static int AD_CHAPTER_BANNER_POSITION =1;//1 top 2 bottom
public static int AD_CHAPTER_BANNER_KEEP_PAGES =20;//1 top 2 bottom
public static boolean AD_SHOW_CHAPT_END_BANNER =true;*/
public static int ONE_DP_SIZE =1;
public static long LAST_G = 0;//主目录API上次访问时间
public static long MAXAGE_G = 3600;//主目录API上次访问时间
public static String[] HOT_KEYS_VALUE = {};
public static int SEX=1; //1 男2女
public static String A_Regex = "<a[^>]+href[\\s]*=[\\s]*['\"]?([^'\"]+)['\"\\s]?[^>]*>([^<]+)<"; //TODO: 从服务器更新
public static List<String> lstProperties =null;
public static List<String> lstSex =null;
public static List<String> lstNt=null;
//public static List<Progress> lstProgress=null;
public static String[] lstProgress={"连载中","已完本","新书"};
public static List<ProgressType> lstProgressType=null;
public static int retryCnt =5;
public static int muluRetryCnt =5;
// public static List<String> lstProgress=null;
public static boolean showDialogOnUi =true;
public static boolean showDialogOnUiPage =false;
public static String announcement ="免责声明:阅读内容均来自互联网,本软件仅提供转码服务";
public static String email ="";
public static int minVersion =0;
public static int version =0;
public static int serverVersion =0;
public static String updateUrl="http://xiaoshuofenxiang.com/version.xml";;
public static final String BAD_CHAR =" ";//not blank,don't edit
public final static int MAX_PAGE_CNT =10;//最多加载的页数
public final static int MAX_SLEEP_4_CHAPT_DOWNLOAD =15000;//最多等待时间10s
public final static int MAX_SHELF_CNT =100;
public static final String REPORT_NEW_UPDATE ="HasNewUpdate"; //其它源有新章节
public static final String REPORT_REX_CHAPTER_CONTENT_ERROR ="EmptyText";//章节内容解析错误
public static final String REPORT_REX_MULU_ERROR ="NovelNotFound";//目录获取错误 ,或书不存在
public static List<String> REPORT_HIS = new ArrayList<String>();
}

View File

@ -0,0 +1,119 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="0dp"
android:layout_weight="1"
android:background="@drawable/item_selector"
android:clickable="true"
android:gravity="center"
android:orientation="vertical"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/imageView"
style="@style/NovelImage.horizon"
android:src="@drawable/googleg_standard_color_18" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="top"
android:orientation="vertical"
>
<TextView
android:id="@+id/title"
style="@style/TextViewNovelTitle.horizon"
android:text="ddd " />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:orientation="horizontal">
<TextView
android:id="@+id/category"
style="@style/TextViewNovelType"
android:text=" " />
<TextView
android:id="@+id/tvNovelStatus"
style="@style/TextViewNovelType.Status"
android:layout_marginLeft="10dp"
android:text=" "
/>
<TextView
android:id="@+id/author"
style="@style/TextViewNovelAuthor"
android:text=" " />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="0dp"
android:layout_marginTop="2dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tvLastRead"
style="@style/TextViewNovelType"
android:layout_marginStart="10dp"
android:text=" "
android:textColor="@color/common_google_signin_btn_text_light" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="0dp"
android:layout_marginTop="4dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tvProgress"
style="@style/TextViewNovelType"
android:text=" "
android:textColor="@color/common_google_signin_btn_text_light" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="0dp"
android:layout_marginTop="2dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tvReadtime"
style="@style/TextViewNovelType"
android:layout_marginLeft="10dp"
android:text=" "
android:textColor="@color/common_google_signin_btn_text_light" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout style="@style/llGraySplit.2dp.gray" />
</LinearLayout>

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More