期末大作业

master
tangjiefeng 2 years ago
parent aec645b6d6
commit e42d3f6ba6

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="11" />
</component>
</project>

@ -0,0 +1,414 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DBNavigator.Project.DataEditorManager">
<record-view-column-sorting-type value="BY_INDEX" />
<value-preview-text-wrapping value="true" />
<value-preview-pinned value="false" />
</component>
<component name="DBNavigator.Project.DatabaseEditorStateManager">
<last-used-providers />
</component>
<component name="DBNavigator.Project.DatabaseFileManager">
<open-files />
</component>
<component name="DBNavigator.Project.Settings">
<connections />
<browser-settings>
<general>
<display-mode value="TABBED" />
<navigation-history-size value="100" />
<show-object-details value="false" />
</general>
<filters>
<object-type-filter>
<object-type name="SCHEMA" enabled="true" />
<object-type name="USER" enabled="true" />
<object-type name="ROLE" enabled="true" />
<object-type name="PRIVILEGE" enabled="true" />
<object-type name="CHARSET" enabled="true" />
<object-type name="TABLE" enabled="true" />
<object-type name="VIEW" enabled="true" />
<object-type name="MATERIALIZED_VIEW" enabled="true" />
<object-type name="NESTED_TABLE" enabled="true" />
<object-type name="COLUMN" enabled="true" />
<object-type name="INDEX" enabled="true" />
<object-type name="CONSTRAINT" enabled="true" />
<object-type name="DATASET_TRIGGER" enabled="true" />
<object-type name="DATABASE_TRIGGER" enabled="true" />
<object-type name="SYNONYM" enabled="true" />
<object-type name="SEQUENCE" enabled="true" />
<object-type name="PROCEDURE" enabled="true" />
<object-type name="FUNCTION" enabled="true" />
<object-type name="PACKAGE" enabled="true" />
<object-type name="TYPE" enabled="true" />
<object-type name="TYPE_ATTRIBUTE" enabled="true" />
<object-type name="ARGUMENT" enabled="true" />
<object-type name="DIMENSION" enabled="true" />
<object-type name="CLUSTER" enabled="true" />
<object-type name="DBLINK" enabled="true" />
</object-type-filter>
</filters>
<sorting>
<object-type name="COLUMN" sorting-type="NAME" />
<object-type name="FUNCTION" sorting-type="NAME" />
<object-type name="PROCEDURE" sorting-type="NAME" />
<object-type name="ARGUMENT" sorting-type="POSITION" />
<object-type name="TYPE ATTRIBUTE" sorting-type="POSITION" />
</sorting>
<default-editors>
<object-type name="VIEW" editor-type="SELECTION" />
<object-type name="PACKAGE" editor-type="SELECTION" />
<object-type name="TYPE" editor-type="SELECTION" />
</default-editors>
</browser-settings>
<navigation-settings>
<lookup-filters>
<lookup-objects>
<object-type name="SCHEMA" enabled="true" />
<object-type name="USER" enabled="false" />
<object-type name="ROLE" enabled="false" />
<object-type name="PRIVILEGE" enabled="false" />
<object-type name="CHARSET" enabled="false" />
<object-type name="TABLE" enabled="true" />
<object-type name="VIEW" enabled="true" />
<object-type name="MATERIALIZED VIEW" enabled="true" />
<object-type name="INDEX" enabled="true" />
<object-type name="CONSTRAINT" enabled="true" />
<object-type name="DATASET TRIGGER" enabled="true" />
<object-type name="DATABASE TRIGGER" enabled="true" />
<object-type name="SYNONYM" enabled="false" />
<object-type name="SEQUENCE" enabled="true" />
<object-type name="PROCEDURE" enabled="true" />
<object-type name="FUNCTION" enabled="true" />
<object-type name="PACKAGE" enabled="true" />
<object-type name="TYPE" enabled="true" />
<object-type name="DIMENSION" enabled="false" />
<object-type name="CLUSTER" enabled="false" />
<object-type name="DBLINK" enabled="true" />
</lookup-objects>
<force-database-load value="false" />
<prompt-connection-selection value="true" />
<prompt-schema-selection value="true" />
</lookup-filters>
</navigation-settings>
<dataset-grid-settings>
<general>
<enable-zooming value="true" />
<enable-column-tooltip value="true" />
</general>
<sorting>
<nulls-first value="true" />
<max-sorting-columns value="4" />
</sorting>
<audit-columns>
<column-names value="" />
<visible value="true" />
<editable value="false" />
</audit-columns>
</dataset-grid-settings>
<dataset-editor-settings>
<text-editor-popup>
<active value="false" />
<active-if-empty value="false" />
<data-length-threshold value="100" />
<popup-delay value="1000" />
</text-editor-popup>
<values-actions-popup>
<show-popup-button value="true" />
<element-count-threshold value="1000" />
<data-length-threshold value="250" />
</values-actions-popup>
<general>
<fetch-block-size value="100" />
<fetch-timeout value="30" />
<trim-whitespaces value="true" />
<convert-empty-strings-to-null value="true" />
<select-content-on-cell-edit value="true" />
<large-value-preview-active value="true" />
</general>
<filters>
<prompt-filter-dialog value="true" />
<default-filter-type value="BASIC" />
</filters>
<qualified-text-editor text-length-threshold="300">
<content-types>
<content-type name="Text" enabled="true" />
<content-type name="Properties" enabled="true" />
<content-type name="XML" enabled="true" />
<content-type name="DTD" enabled="true" />
<content-type name="HTML" enabled="true" />
<content-type name="XHTML" enabled="true" />
<content-type name="Java" enabled="true" />
<content-type name="SQL" enabled="true" />
<content-type name="PL/SQL" enabled="true" />
<content-type name="JSON" enabled="true" />
<content-type name="JSON5" enabled="true" />
<content-type name="Groovy" enabled="true" />
<content-type name="AIDL" enabled="true" />
<content-type name="YAML" enabled="true" />
<content-type name="Manifest" enabled="true" />
</content-types>
</qualified-text-editor>
<record-navigation>
<navigation-target value="VIEWER" />
</record-navigation>
</dataset-editor-settings>
<code-editor-settings>
<general>
<show-object-navigation-gutter value="false" />
<show-spec-declaration-navigation-gutter value="true" />
<enable-spellchecking value="true" />
<enable-reference-spellchecking value="false" />
</general>
<confirmations>
<save-changes value="false" />
<revert-changes value="true" />
</confirmations>
</code-editor-settings>
<code-completion-settings>
<filters>
<basic-filter>
<filter-element type="RESERVED_WORD" id="keyword" selected="true" />
<filter-element type="RESERVED_WORD" id="function" selected="true" />
<filter-element type="RESERVED_WORD" id="parameter" selected="true" />
<filter-element type="RESERVED_WORD" id="datatype" selected="true" />
<filter-element type="RESERVED_WORD" id="exception" selected="true" />
<filter-element type="OBJECT" id="schema" selected="true" />
<filter-element type="OBJECT" id="role" selected="true" />
<filter-element type="OBJECT" id="user" selected="true" />
<filter-element type="OBJECT" id="privilege" selected="true" />
<user-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="false" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</user-schema>
<public-schema>
<filter-element type="OBJECT" id="table" selected="false" />
<filter-element type="OBJECT" id="view" selected="false" />
<filter-element type="OBJECT" id="materialized view" selected="false" />
<filter-element type="OBJECT" id="index" selected="false" />
<filter-element type="OBJECT" id="constraint" selected="false" />
<filter-element type="OBJECT" id="trigger" selected="false" />
<filter-element type="OBJECT" id="synonym" selected="false" />
<filter-element type="OBJECT" id="sequence" selected="false" />
<filter-element type="OBJECT" id="procedure" selected="false" />
<filter-element type="OBJECT" id="function" selected="false" />
<filter-element type="OBJECT" id="package" selected="false" />
<filter-element type="OBJECT" id="type" selected="false" />
<filter-element type="OBJECT" id="dimension" selected="false" />
<filter-element type="OBJECT" id="cluster" selected="false" />
<filter-element type="OBJECT" id="dblink" selected="false" />
</public-schema>
<any-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="true" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</any-schema>
</basic-filter>
<extended-filter>
<filter-element type="RESERVED_WORD" id="keyword" selected="true" />
<filter-element type="RESERVED_WORD" id="function" selected="true" />
<filter-element type="RESERVED_WORD" id="parameter" selected="true" />
<filter-element type="RESERVED_WORD" id="datatype" selected="true" />
<filter-element type="RESERVED_WORD" id="exception" selected="true" />
<filter-element type="OBJECT" id="schema" selected="true" />
<filter-element type="OBJECT" id="user" selected="true" />
<filter-element type="OBJECT" id="role" selected="true" />
<filter-element type="OBJECT" id="privilege" selected="true" />
<user-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="true" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</user-schema>
<public-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="true" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</public-schema>
<any-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="true" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</any-schema>
</extended-filter>
</filters>
<sorting enabled="true">
<sorting-element type="RESERVED_WORD" id="keyword" />
<sorting-element type="RESERVED_WORD" id="datatype" />
<sorting-element type="OBJECT" id="column" />
<sorting-element type="OBJECT" id="table" />
<sorting-element type="OBJECT" id="view" />
<sorting-element type="OBJECT" id="materialized view" />
<sorting-element type="OBJECT" id="index" />
<sorting-element type="OBJECT" id="constraint" />
<sorting-element type="OBJECT" id="trigger" />
<sorting-element type="OBJECT" id="synonym" />
<sorting-element type="OBJECT" id="sequence" />
<sorting-element type="OBJECT" id="procedure" />
<sorting-element type="OBJECT" id="function" />
<sorting-element type="OBJECT" id="package" />
<sorting-element type="OBJECT" id="type" />
<sorting-element type="OBJECT" id="dimension" />
<sorting-element type="OBJECT" id="cluster" />
<sorting-element type="OBJECT" id="dblink" />
<sorting-element type="OBJECT" id="schema" />
<sorting-element type="OBJECT" id="role" />
<sorting-element type="OBJECT" id="user" />
<sorting-element type="RESERVED_WORD" id="function" />
<sorting-element type="RESERVED_WORD" id="parameter" />
</sorting>
<format>
<enforce-code-style-case value="true" />
</format>
</code-completion-settings>
<execution-engine-settings>
<statement-execution>
<fetch-block-size value="100" />
<execution-timeout value="20" />
<debug-execution-timeout value="600" />
<focus-result value="false" />
<prompt-execution value="false" />
</statement-execution>
<script-execution>
<command-line-interfaces />
<execution-timeout value="300" />
</script-execution>
<method-execution>
<execution-timeout value="30" />
<debug-execution-timeout value="600" />
<parameter-history-size value="10" />
</method-execution>
</execution-engine-settings>
<operation-settings>
<transactions>
<uncommitted-changes>
<on-project-close value="ASK" />
<on-disconnect value="ASK" />
<on-autocommit-toggle value="ASK" />
</uncommitted-changes>
<multiple-uncommitted-changes>
<on-commit value="ASK" />
<on-rollback value="ASK" />
</multiple-uncommitted-changes>
</transactions>
<session-browser>
<disconnect-session value="ASK" />
<kill-session value="ASK" />
<reload-on-filter-change value="false" />
</session-browser>
<compiler>
<compile-type value="KEEP" />
<compile-dependencies value="ASK" />
<always-show-controls value="false" />
</compiler>
<debugger>
<debugger-type value="ASK" />
<use-generic-runners value="true" />
</debugger>
</operation-settings>
<ddl-file-settings>
<extensions>
<mapping file-type-id="VIEW" extensions="vw" />
<mapping file-type-id="TRIGGER" extensions="trg" />
<mapping file-type-id="PROCEDURE" extensions="prc" />
<mapping file-type-id="FUNCTION" extensions="fnc" />
<mapping file-type-id="PACKAGE" extensions="pkg" />
<mapping file-type-id="PACKAGE_SPEC" extensions="pks" />
<mapping file-type-id="PACKAGE_BODY" extensions="pkb" />
<mapping file-type-id="TYPE" extensions="tpe" />
<mapping file-type-id="TYPE_SPEC" extensions="tps" />
<mapping file-type-id="TYPE_BODY" extensions="tpb" />
</extensions>
<general>
<lookup-ddl-files value="true" />
<create-ddl-files value="false" />
<synchronize-ddl-files value="true" />
<use-qualified-names value="false" />
<make-scripts-rerunnable value="true" />
</general>
</ddl-file-settings>
<general-settings>
<regional-settings>
<date-format value="MEDIUM" />
<number-format value="UNGROUPED" />
<locale value="SYSTEM_DEFAULT" />
<use-custom-formats value="false" />
</regional-settings>
<environment>
<environment-types>
<environment-type id="development" name="Development" description="Development environment" color="-2430209/-12296320" readonly-code="false" readonly-data="false" />
<environment-type id="integration" name="Integration" description="Integration environment" color="-2621494/-12163514" readonly-code="true" readonly-data="false" />
<environment-type id="production" name="Production" description="Productive environment" color="-11574/-10271420" readonly-code="true" readonly-data="true" />
<environment-type id="other" name="Other" description="" color="-1576/-10724543" readonly-code="false" readonly-data="false" />
</environment-types>
<visibility-settings>
<connection-tabs value="true" />
<dialog-headers value="true" />
<object-editor-tabs value="true" />
<script-editor-tabs value="false" />
<execution-result-tabs value="true" />
</visibility-settings>
</environment>
</general-settings>
</component>
</project>

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="maven" />
<option name="name" value="maven" />
<option name="url" value="http://maven.aliyun.com/nexus/content/groups/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="maven2" />
<option name="name" value="maven2" />
<option name="url" value="http://maven.aliyun.com/nexus/content/repositories/jcenter" />
</remote-repository>
<remote-repository>
<option name="id" value="Google" />
<option name="name" value="Google" />
<option name="url" value="https://dl.google.com/dl/android/maven2/" />
</remote-repository>
</component>
</project>

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="Android Studio default JDK" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

@ -0,0 +1 @@
Subproject commit aec645b6d670e75be67c525ebe11c562f66ff1f7

@ -0,0 +1,29 @@
@startuml
title __NOVELREADER's Component Diagram__\n
component "NovelReader.app.unitTest" {
[NovelReader.app.main]
component "NovelReader.app.main" {
[NovelReader.app.androidTest]
component "NovelReader.app.androidTest" {
[NovelReader.app]
}
}
}
right footer
PlantUML diagram generated by SketchIt! (https://bitbucket.org/pmesmeur/sketch.it)
For more information about this tool, please contact philippe.mesmeur@gmail.com
endfooter
@enduml

@ -0,0 +1,41 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
applicationId "fte.finalproject"
minSdkVersion 22
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.android.support:cardview-v7:28.0.0'
implementation 'com.android.support:recyclerview-v7:28.0.0'
implementation 'de.hdodenhof:circleimageview:2.2.0'
implementation 'com.android.support:cardview-v7:28.0.0'
implementation 'com.squareup.retrofit2:retrofit:2.0.2'
implementation 'com.squareup.retrofit2:converter-scalars:2.0.0'
implementation 'com.squareup.retrofit2:converter-gson:2.1.0'
implementation 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
implementation 'io.reactivex:rxandroid:1.2.1'
implementation 'io.reactivex:rxjava:1.2.1'
implementation 'com.squareup.okhttp3:okhttp:3.2.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
implementation 'io.reactivex.rxjava2:rxjava:2.1.0'
}

@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

@ -0,0 +1 @@
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"1.0","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}]

@ -0,0 +1,26 @@
package com.example;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("fte.finalproject", appContext.getPackageName());
}
}

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/icon"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name="com.example.Activity.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.example.Activity.ReadPageActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:screenOrientation="portrait"/>
<activity android:name="com.example.Activity.BookDetailActivity">
<!--
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
-->
</activity>
<activity
android:name="com.example.Activity.SearchActivity"
android:windowSoftInputMode="adjustPan|stateHidden">
<!--
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
-->
</activity>
<activity android:name="com.example.Activity.CategoryActivity" />
<activity android:name="com.example.Activity.RecomActivity"></activity>
</application>
</manifest>

@ -0,0 +1,409 @@
package com.example.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.example.DataBase.DatabaseControl;
import com.example.Object.BookObj;
import com.example.Object.CategoryObj;
import com.example.Object.ChapterLinkObj;
import com.example.Object.RecomListObj;
import com.example.Object.ShelfBookObj;
import com.example.R;
import com.example.Service.BookService;
public class BookDetailActivity extends AppCompatActivity {
RadioButton addButton;
RadioButton readButton;
// RadioButton downloadButton;
Button moreButton;
Button recom1;
Button recom2;
Button recom3;
ImageView back;
TextView pageTitle;
ImageView bookCover;
TextView bookTitle;
TextView bookInfo;
TextView updateTime;
TextView follower;
TextView retentionRatio;
TextView bookIntro;
RadioGroup recomRG;
// 书籍对象
private BookObj bookObj;
// 同类书籍
private CategoryObj categoryObj;
private List<BookObj> bookObjs = new ArrayList<>();
private Bitmap cover;
private List<ChapterLinkObj> linkList;
private StringBuilder stringBuilder = new StringBuilder();
Handler mHandler = new Handler();
private SimpleDateFormat format = new SimpleDateFormat("yyyy-mm-mm'T'HH:MM:SS");
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_book_detail);
// 获取控件
back = findViewById(R.id.detail_back);
pageTitle = findViewById(R.id.detail_title);
addButton = findViewById(R.id.detail_bottom_add);
readButton = findViewById(R.id.detail_bottom_read);
// downloadButton = findViewById(R.id.detail_bottom_download);
moreButton = findViewById(R.id.detail_more);
bookCover = findViewById(R.id.detail_cover);
bookTitle = findViewById(R.id.detail_bookTitle);
bookInfo = findViewById(R.id.detail_TV);
updateTime = findViewById(R.id.detail_update);
follower = findViewById(R.id.detail_follower2);
retentionRatio = findViewById(R.id.detail_retentionRatio2);
bookIntro = findViewById(R.id.detail_longIntro);
recomRG = findViewById(R.id.detail_recomRG);
recom1 = findViewById(R.id.detail_recom1);
recom2 = findViewById(R.id.detail_recom2);
recom3 = findViewById(R.id.detail_recom3);
Intent intent = getIntent();
final Bundle bundle = intent.getExtras();
bookObj = (BookObj) bundle.getSerializable("bookobj");
// 获取封面图片
final String iconURL = BookService.StaticsUrl + bookObj.getCover();
final Matrix largeMatrix = new Matrix();
final Matrix littleMatrix = new Matrix();
largeMatrix.postScale((float) 2, (float) 2);
littleMatrix.postScale((float) 0.4, (float) 0.4);
if (!isNetWorkConnected(BookDetailActivity.this)) {
Toast.makeText(BookDetailActivity.this, "未连接网络", Toast.LENGTH_SHORT).show();
} else {
new Thread(new Runnable() {
@Override
public void run() {
try {
URL url = new URL(iconURL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(10000);
if (connection.getResponseCode() == 200) {
InputStream inputStream = connection.getInputStream();
cover = BitmapFactory.decodeStream(inputStream);
if (cover != null) {
mHandler.post(new Runnable() {
@Override
public void run() {
Log.d("width", String.valueOf(cover.getWidth()));
Log.d("height", String.valueOf(cover.getHeight()));
littleMatrix.postScale((float) 0.5, (float) 0.5);
}
});
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
try {
URL url = new URL(iconURL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(10000);
if (connection.getResponseCode() == 200) {
InputStream inputStream = connection.getInputStream();
cover = BitmapFactory.decodeStream(inputStream);
mHandler.post(new Runnable() {
@Override
public void run() {
Log.d("width", String.valueOf(cover.getWidth()));
Log.d("height", String.valueOf(cover.getHeight()));
/*if (cover.getWidth() <= 150 && cover.getHeight() <= 200) {
bookCover.setImageBitmap(Bitmap.createBitmap(cover, 0, 0, cover.getWidth(), cover.getHeight(), largeMatrix, true));
} else if (cover.getWidth() > 300 && cover.getHeight() > 400) {
bookCover.setImageBitmap(Bitmap.createBitmap(cover, 0, 0, cover.getWidth(), cover.getHeight(), littleMatrix, true));
} else {
bookCover.setImageBitmap(cover);
}*/
bookCover.setImageBitmap(cover);
}
});
bookCover.setImageBitmap(cover);
}
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
}).start();
if (!isNetWorkConnected(BookDetailActivity.this)) {
Toast.makeText(BookDetailActivity.this, "未连接网络", Toast.LENGTH_SHORT).show();
} else {
// 获取书籍相关信息
new Thread(new Runnable() {
@Override
public void run() {
bookObj = BookService.getBookService().getBookById(bookObj.getId());
mHandler.post(new Runnable() {
@Override
public void run() {
bookTitle.setText(bookObj.getTitle());
pageTitle.setText(bookObj.getTitle());
int wordNum = bookObj.getWordCount() / 10000;
bookInfo.setText(bookObj.getAuthor() + " | " + bookObj.getMinorCate() + " | " + String.valueOf(wordNum) + "万字");
String updateStr = "";
try {
Date date = format.parse(bookObj.getUpdated());
Date now = new Date(System.currentTimeMillis());
long period = now.getTime() - date.getTime();
Log.d("period", String.valueOf(period));
if (period / 86400000 < 1) {
updateStr = "上次更新: 今天";
} else if (period / 86400000 > 1) {
updateStr = "上次更新: " + String.valueOf(period / 86400000) + "天前";
}
} catch (ParseException e) {
e.printStackTrace();
}
updateTime.setText(updateStr);
// int followerNum = bookObj.getLatelyFollower() / 10000;
follower.setText(String.valueOf(bookObj.getLatelyFollower()) + "人");
retentionRatio.setText(bookObj.getRetentionRatio() + "%");
String intro = bookObj.getLongIntro();
if (intro.length() > 80) intro = intro.substring(0, 80);
intro += "...";
bookIntro.setText(intro);
new Thread(new Runnable() {
@Override
public void run() {
categoryObj = BookService.getBookService().getBooksByCategoty("reputation", bookObj.getMajorCate(), 0, 10, bookObj.getGender()[0]);
Log.d("size", String.valueOf(categoryObj.getBooks().size()));
for (int i = 0; i < categoryObj.getBooks().size(); i++) {
final int j = i;
final BookObj temp = BookService.getBookService().getBookById(categoryObj.getBooks().get(j).getId());
mHandler.post(new Runnable() {
@Override
public void run() {
bookObjs.add(temp);
if (j < 3) {
final String iconURL = BookService.StaticsUrl + temp.getCover();
final Button button = (Button) recomRG.getChildAt(j);
button.setText(bookObjs.get(j).getTitle());
new Thread(new Runnable() {
@Override
public void run() {
try {
URL url = new URL(iconURL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(10000);
if (connection.getResponseCode() == 200) {
InputStream inputStream = connection.getInputStream();
final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
mHandler.post(new Runnable() {
@Override
public void run() {
Drawable drawable = null;
drawable = new BitmapDrawable(Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), littleMatrix, true));
drawable.setBounds(0, 0, 270, 360);
button.setCompoundDrawables(null, drawable, null, null);
}
});
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
}
});
}
}
}).start();
}
});
}
}).start();
}
recom1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(BookDetailActivity.this, BookDetailActivity.class);
Bundle bundle = new Bundle();
bundle.putSerializable("bookobj", bookObjs.get(0));
intent.putExtras(bundle);
startActivity(intent);
}
});
recom2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(BookDetailActivity.this, BookDetailActivity.class);
Bundle bundle = new Bundle();
bundle.putSerializable("bookobj", bookObjs.get(1));
intent.putExtras(bundle);
startActivity(intent);
}
});
recom3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(BookDetailActivity.this, BookDetailActivity.class);
Bundle bundle = new Bundle();
bundle.putSerializable("bookobj", bookObjs.get(2));
intent.putExtras(bundle);
startActivity(intent);
}
});
// 返回
back.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
if (DatabaseControl.getInstance(BookDetailActivity.this).judgeBookExist(bookObj.getId())) {
// 已存在
setButtonToDelete();
} else {
// 不存在
setButtonToAdd();
}
// 阅读
readButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(BookDetailActivity.this, ReadPageActivity.class);
Bundle bundle = new Bundle();
bundle.putString("bookid", bookObj.getId());
intent.putExtras(bundle);
startActivity(intent);
}
});
// 下载
/*downloadButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
*//*new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < linkList.size(); i++) {
ChapterObj chapterObj = BookService.getBookService().getChapterByLink(linkList.get(i).getLink());
stringBuilder.append(chapterObj.getIchapter().getTitle());
stringBuilder.append("\n");
stringBuilder.append(chapterObj.getIchapter().getBody());
}
}
}).start();*//*
Toast.makeText(BookDetailActivity.this, "功能开发中,敬请期待", Toast.LENGTH_SHORT).show();
}
});*/
// 查看更多同类书籍
moreButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(BookDetailActivity.this, RecomActivity.class);
Bundle bundle = new Bundle();
RecomListObj recomListObj = new RecomListObj(bookObjs);
bundle.putSerializable("list", recomListObj);
intent.putExtras(bundle);
startActivity(intent);
}
});
}
}
private void setButtonToAdd() {
addButton.setText("加入书架");
addButton.setTextColor(getResources().getColor(R.color.colorRed));
addButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DatabaseControl.getInstance(BookDetailActivity.this).addShelfBook(new ShelfBookObj(bookObj.getId(), bookObj.getTitle(), cover, bookObj.getCover(),0, "online", 0, bookObj.getLongIntro(), bookObj.getAuthor(), bookObj.getMajorCate()));
Toast.makeText(BookDetailActivity.this, "已添加《" + bookObj.getTitle() + "》", Toast.LENGTH_SHORT).show();
setButtonToDelete();
}
});
}
private void setButtonToDelete() {
addButton.setText("移除书架");
addButton.setTextColor(getResources().getColor(R.color.colorGrey));
addButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DatabaseControl.getInstance(BookDetailActivity.this).deleteShelfBook(bookObj.getId());
Toast.makeText(BookDetailActivity.this, "已移除《" + bookObj.getTitle() + "》", Toast.LENGTH_SHORT).show();
setButtonToAdd();
}
});
}
// 辅助函数:判断网络是否连接
private boolean isNetWorkConnected(Context context) {
if (context != null) {
ConnectivityManager mConnectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
if (mNetworkInfo != null) {
return mNetworkInfo.isConnected();
}
}
return false;
}
}

@ -0,0 +1,171 @@
package com.example.Activity;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import com.example.Fragment.DetailCategoryFragment;
import com.example.Fragment.TabFragmentPagerAdapter;
import com.example.R;
//这个Activity可用于榜单和具体分类
public class CategoryActivity extends AppCompatActivity {
private boolean isRanking; //排行榜/分类
private boolean isMale; //男生/女生
private TextView title;
private ImageView backImage;
private RadioGroup RG;
private RadioButton RB1;
private RadioButton RB2;
private RadioButton RB3;
private RadioButton RB4;
private ViewPager viewPager;
private List<Fragment> fragmentList = new ArrayList<>();
private TabFragmentPagerAdapter pagerAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_category);
//获取传递的参数
Bundle bundle = this.getIntent().getExtras();
isRanking = bundle.getBoolean("isRanking");
isMale = bundle.getBoolean("isMale");
//初始化控件
title = findViewById(R.id.category_activity_title);
backImage = findViewById(R.id.category_activity_back);
RG = findViewById(R.id.category_activity_RG);
RB1 = findViewById(R.id.category_activity_RB1);
RB2 = findViewById(R.id.category_activity_RB2);
RB3 = findViewById(R.id.category_activity_RB3);
RB4 = findViewById(R.id.category_activity_RB4);
viewPager = findViewById(R.id.category_activity_viewPager);
//设置显示内容
title.setText(bundle.getString("title"));
if (isRanking) {
RB1.setText("周榜");
RB2.setText("月榜");
RB3.setText("总榜");
RB4.setVisibility(View.GONE);
}
else {
RB1.setText("热门");
RB2.setText("新书");
RB3.setText("好评");
RB4.setVisibility(View.VISIBLE);
}
//设置返回事件
backImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onBackPressed();
}
});
//添加Fragment
if (isRanking) {
//排行榜的Fragment
for (int i = 0; i < 3; ++i) {
DetailCategoryFragment fragment = new DetailCategoryFragment();
Bundle bundle1 = new Bundle();
bundle1.putString("title", bundle.getString("title"));
bundle1.putBoolean("isRanking", isRanking);
bundle1.putBoolean("isMale", isMale);
if (i == 0) bundle1.putString("type", "周榜");
else if (i == 1) bundle1.putString("type", "月榜");
else bundle1.putString("type", "总榜");
fragment.setArguments(bundle1);
fragmentList.add(fragment);
}
}
else {
//具体分类的Fragment
for (int i = 0; i < 4; ++i) {
DetailCategoryFragment fragment = new DetailCategoryFragment();
Bundle bundle1 = new Bundle();
bundle1.putString("title", bundle.getString("title"));
bundle1.putBoolean("isRanking", isRanking);
bundle1.putBoolean("isMale", isMale);
if (i == 0) bundle1.putString("type", "热门");
else if (i == 1) bundle1.putString("type", "新书");
else if (i == 2) bundle1.putString("type", "好评");
else bundle1.putString("type", "完结");
fragment.setArguments(bundle1);
fragmentList.add(fragment);
}
}
viewPager.setOnPageChangeListener(new MyPagerChangeListener());
pagerAdapter = new TabFragmentPagerAdapter(getSupportFragmentManager(), fragmentList);
viewPager.setAdapter(pagerAdapter);
viewPager.setCurrentItem(0);
if (isRanking) viewPager.setOffscreenPageLimit(2);
else viewPager.setOffscreenPageLimit(3);
//设置RadioGroup响应事件
RG.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId){
case R.id.category_activity_RB1:
viewPager.setCurrentItem(0);
break;
case R.id.category_activity_RB2:
viewPager.setCurrentItem(1);
break;
case R.id.category_activity_RB3:
viewPager.setCurrentItem(2);
break;
case R.id.category_activity_RB4:
viewPager.setCurrentItem(3);
break;
}
}
});
}
//设置一个ViewPager的监听事件左右滑动ViewPager时进行处理
public class MyPagerChangeListener implements ViewPager.OnPageChangeListener {
@Override
public void onPageScrollStateChanged(int arg0) {
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageSelected(int arg0) {
switch (arg0) {
case 0:
RB1.setChecked(true);
break;
case 1:
RB2.setChecked(true);
break;
case 2:
RB3.setChecked(true);
break;
case 3:
RB4.setChecked(true);
break;
}
}
}
}

@ -0,0 +1,228 @@
package com.example.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import com.example.Fragment.BookShelfFragment;
import com.example.Fragment.CategoryFragment;
import com.example.Fragment.RankingFragment;
import com.example.Fragment.TabFragmentStatePagerAdapter;
import com.example.R;
//总体界面,包含书架、排行榜、分类
public class MainActivity extends AppCompatActivity {
private RadioGroup radioGroup;
private TextView title;
private ImageView search;
private RadioGroup bottomRG;
private RadioButton bookshelfRB;
private RadioButton rankingRB;
private RadioButton categoryRB;
private RadioGroup topRG;
private RadioButton maleRB;
private RadioButton femaleRB;
private static Context context = null;
private ViewPager viewPager;
private List<Fragment> fragmentList = new ArrayList<>();
private TabFragmentStatePagerAdapter fragmentPagerAdapter;
public static Context getContext() {
return context;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this.getBaseContext();
//初始化控件
radioGroup = findViewById(R.id.main_top_RG);
title = findViewById(R.id.main_title);
search = findViewById(R.id.main_search);
bottomRG = findViewById(R.id.main_bottomRG);
bookshelfRB = findViewById(R.id.main_bottom_bookshelf);
rankingRB = findViewById(R.id.main_bottom_ranking);
categoryRB = findViewById(R.id.main_bottom_category);
topRG = findViewById(R.id.main_top_RG);
maleRB = findViewById(R.id.main_top_male);
femaleRB = findViewById(R.id.main_top_female);
viewPager = findViewById(R.id.main_viewPager);
//初始化Fragment
BookShelfFragment bookShelfFragment = new BookShelfFragment();
RankingFragment rankingFragment = new RankingFragment();
Bundle bundle = new Bundle();
bundle.putBoolean("isMale", true);
rankingFragment.setArguments(bundle);
CategoryFragment categoryFragment = new CategoryFragment();
fragmentList.add(bookShelfFragment);
fragmentList.add(rankingFragment);
fragmentList.add(categoryFragment);
viewPager.setOnPageChangeListener(new MyPagerChangeListener());
fragmentPagerAdapter = new TabFragmentStatePagerAdapter(getSupportFragmentManager(), fragmentList);
viewPager.setAdapter(fragmentPagerAdapter);
viewPager.setCurrentItem(0);
viewPager.setOffscreenPageLimit(2);
//设置底部按钮图标大小
Drawable drawable = getResources().getDrawable(R.mipmap.bookshelf_red);
drawable.setBounds(0, 0, 70, 70);
bookshelfRB.setCompoundDrawables(null, drawable , null,null);
drawable = getResources().getDrawable(R.mipmap.ranking);
drawable.setBounds(0, 0, 70, 70);
rankingRB.setCompoundDrawables(null, drawable, null,null);
drawable = getResources().getDrawable(R.mipmap.category);
drawable.setBounds(0, 0, 70, 70);
categoryRB.setCompoundDrawables(null, drawable,null, null);
//设置顶部按钮图标大小
drawable = getResources().getDrawable(R.mipmap.male_blue);
drawable.setBounds(0, 0, 70, 70);
maleRB.setCompoundDrawables(null, drawable, null, null);
drawable = getResources().getDrawable(R.mipmap.female_black);
drawable.setBounds(0, 0, 70, 70);
femaleRB.setCompoundDrawables(null, drawable, null, null);
//处理顶部RG事件
topRG.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId) {
case R.id.main_top_male:
Drawable drawable = getResources().getDrawable(R.mipmap.male_blue);
drawable.setBounds(0, 0, 70, 70);
maleRB.setCompoundDrawables(null, drawable, null, null);
drawable = getResources().getDrawable(R.mipmap.female_black);
drawable.setBounds(0, 0, 70, 70);
femaleRB.setCompoundDrawables(null, drawable, null, null);
RankingFragment rankingFragment1 = new RankingFragment();
Bundle bundle = new Bundle();
bundle.putBoolean("isMale", true);
rankingFragment1.setArguments(bundle);
fragmentList.set(1, rankingFragment1);
fragmentPagerAdapter.notifyDataSetChanged();
viewPager.setCurrentItem(1);
break;
case R.id.main_top_female:
drawable = getResources().getDrawable(R.mipmap.male_black);
drawable.setBounds(0, 0, 70, 70);
maleRB.setCompoundDrawables(null, drawable, null, null);
drawable = getResources().getDrawable(R.mipmap.female_red);
drawable.setBounds(0, 0, 70, 70);
femaleRB.setCompoundDrawables(null, drawable, null, null);
RankingFragment rankingFragment2 = new RankingFragment();
bundle = new Bundle();
bundle.putBoolean("isMale", false);
rankingFragment2.setArguments(bundle);
fragmentList.set(1, rankingFragment2);
fragmentPagerAdapter.notifyDataSetChanged();
viewPager.setCurrentItem(1);
break;
}
}
});
//处理底部RG事件
bottomRG.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
int index = 0;
switch (checkedId) {
case R.id.main_bottom_bookshelf:
index = 0;
Drawable drawable = getResources().getDrawable(R.mipmap.bookshelf_red);
drawable.setBounds(0, 0, 70, 70);
bookshelfRB.setCompoundDrawables(null, drawable , null,null);
drawable = getResources().getDrawable(R.mipmap.ranking);
drawable.setBounds(0, 0, 70, 70);
rankingRB.setCompoundDrawables(null, drawable, null,null);
drawable = getResources().getDrawable(R.mipmap.category);
drawable.setBounds(0, 0, 70, 70);
categoryRB.setCompoundDrawables(null, drawable,null, null);
break;
case R.id.main_bottom_ranking:
index = 1;
drawable = getResources().getDrawable(R.mipmap.bookshelf);
drawable.setBounds(0, 0, 70, 70);
bookshelfRB.setCompoundDrawables(null, drawable , null,null);
drawable = getResources().getDrawable(R.mipmap.ranking_red);
drawable.setBounds(0, 0, 70, 70);
rankingRB.setCompoundDrawables(null, drawable, null,null);
drawable = getResources().getDrawable(R.mipmap.category);
drawable.setBounds(0, 0, 70, 70);
categoryRB.setCompoundDrawables(null, drawable,null, null);
break;
case R.id.main_bottom_category:
index = 2;
drawable = getResources().getDrawable(R.mipmap.bookshelf);
drawable.setBounds(0, 0, 70, 70);
bookshelfRB.setCompoundDrawables(null, drawable , null,null);
drawable = getResources().getDrawable(R.mipmap.ranking);
drawable.setBounds(0, 0, 70, 70);
rankingRB.setCompoundDrawables(null, drawable, null,null);
drawable = getResources().getDrawable(R.mipmap.category_red);
drawable.setBounds(0, 0, 70, 70);
categoryRB.setCompoundDrawables(null, drawable,null, null);
break;
}
viewPager.setCurrentItem(index);
}
});
//搜索按钮点击事件
search.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(MainActivity.this, SearchActivity.class));
}
});
}
//设置一个ViewPager的监听事件左右滑动ViewPager时进行处理
public class MyPagerChangeListener implements ViewPager.OnPageChangeListener {
@Override
public void onPageScrollStateChanged(int arg0) {
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageSelected(int arg0) {
switch (arg0) {
case 0:
title.setText("书架");
radioGroup.setVisibility(View.GONE);
bookshelfRB.setChecked(true);
break;
case 1:
title.setText("排行榜");
radioGroup.setVisibility(View.VISIBLE);
rankingRB.setChecked(true);
break;
case 2:
title.setText("分类");
radioGroup.setVisibility(View.GONE);
categoryRB.setChecked(true);
break;
}
}
}
}

@ -0,0 +1,120 @@
package com.example.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import com.example.R;
import com.example.RecyclerView.MyRecyclerViewAdapter;
import com.example.RecyclerView.MyViewHolder;
import com.example.Object.BookObj;
import com.example.Object.RecomListObj;
import com.example.Service.BookService;
public class RecomActivity extends AppCompatActivity {
private List<BookObj> bookObjs;
private RecyclerView recyclerView;
private ImageView back;
private Handler mHandler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recom);
// 获取同类书籍
Bundle bundle = getIntent().getExtras();
bookObjs = ((RecomListObj)bundle.getSerializable("list")).getBookObjs();
// 获取相关控件
back = findViewById(R.id.recom_back);
recyclerView = findViewById(R.id.recom_recyclerview);
// 内容填充
MyRecyclerViewAdapter<BookObj> adapter = new MyRecyclerViewAdapter<BookObj>(RecomActivity.this, R.layout.item_book, bookObjs) {
@Override
public void convert(MyViewHolder holder, BookObj bookObj) {
final ImageView imageView = holder.getView(R.id.item_book_cover);
TextView bookName = holder.getView(R.id.item_book_name);
TextView bookAuthor = holder.getView(R.id.item_book_author);
TextView bookType = holder.getView(R.id.item_book_type);
TextView bookIntro = holder.getView(R.id.item_book_intro);
bookName.setText(bookObj.getTitle());
bookType.setText(bookObj.getMajorCate());
bookAuthor.setText(bookObj.getAuthor());
String intro = bookObj.getLongIntro();
if (intro.length() > 50) intro = intro.substring(0, 50);
intro += "...";
bookIntro.setText(intro);
//通过网络获取书籍图标
final String iconURL = BookService.StaticsUrl + bookObj.getCover();
new Thread(new Runnable() {
@Override
public void run() {
try {
URL url = new URL(iconURL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(10000);
if (connection.getResponseCode() == 200) {
InputStream inputStream = connection.getInputStream();
final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
mHandler.post(new Runnable() {
@Override
public void run() {
imageView.setImageBitmap(bitmap);
}
});
}
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
}).start();
}
};
adapter.setOnItemClickListener(new MyRecyclerViewAdapter.OnItemClickListener() {
@Override
public void onClick(int position) {
//跳转到书籍详情界面
Intent intent = new Intent(RecomActivity.this, BookDetailActivity.class);
Bundle bundle = new Bundle();
bundle.putSerializable("bookobj", bookObjs.get(position));
intent.putExtras(bundle);
startActivity(intent);
}
@Override
public void onLongClick(int position) {
}
});
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(RecomActivity.this));
back.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
}

@ -0,0 +1,507 @@
package com.example.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Handler;
import android.os.Looper;
import android.support.constraint.ConstraintLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.SearchView;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import com.example.R;
import com.example.RecyclerView.MyRecyclerViewAdapter;
import com.example.RecyclerView.MyViewHolder;
import com.example.Object.BookObj;
import com.example.Object.SearchResultObj;
import com.example.Service.BookService;
import static com.example.DataBase.DatabaseControl.getInstance;
import static com.example.Service.BookService.getBookService;
public class SearchActivity extends AppCompatActivity {
private SearchView searchView;
private TextView cancelView;
private TextView text1;
private TextView text2;
private TextView text3;
private TextView text4;
private TextView text5;
private TextView text6;
private ImageView deleteView;
private ImageView freshView;
private ListView historyList;
private ListView fuzzyList;
private ConstraintLayout initialLayout;
private LinearLayout searchLayout;
private RecyclerView resultList;
private List<String> histories;
private List<String> tempFuzzy;
private List<SearchResultObj.book> results;
private MyRecyclerViewAdapter recyclerViewAdapter;
private boolean isSubmit;
private boolean flag;
public Handler handler = new Handler();
private String[] hotBooks = {"一品娇宠","剑来","逆天邪神","神医嫡女","官梯",
"最强狂兵","无敌剑域","一世倾城","天骄战纪","元尊",
"天行","修罗武神","永夜君王","家有王妃初长成","神级奶爸",
"神医毒妃","战神狂飙","逆天邪神","神医嫡女","江山美色",
"圣墟","极品透视学生","正道潜龙","斗罗大陆","雪中悍刀行",
"枭臣","将夜","校花的贴身高手","大刁民","偷香高手",};
// 辅助函数:判断网络是否连接
public boolean isNetWorkConnected(Context context) {
if (context != null) {
ConnectivityManager mConnectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
if (mNetworkInfo != null) {
return mNetworkInfo.isConnected();
}
}
return false;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
isSubmit = false;
flag = true; //用于同步问题的布尔变量
//初始化列表
histories = getInstance(getBaseContext()).getAllHistory();
tempFuzzy = new ArrayList<>();
results = new ArrayList<>();
//获取控件
freshView = findViewById(R.id.search_fresh_image);
cancelView = findViewById(R.id.search_cancel_text);
searchView = findViewById(R.id.search_search_searchView);
deleteView = findViewById(R.id.search_delete_image);
historyList = findViewById(R.id.search_history_list);
fuzzyList = findViewById(R.id.search_fuzzy_list);
resultList = findViewById(R.id.search_result_list);
initialLayout = findViewById(R.id.search_initial_layout);
searchLayout = findViewById(R.id.search_afters_layout);
text1 = findViewById(R.id.search_pop_text1);
text2 = findViewById(R.id.search_pop_text2);
text3 = findViewById(R.id.search_pop_text3);
text4 = findViewById(R.id.search_pop_text4);
text5 = findViewById(R.id.search_pop_text5);
text6 = findViewById(R.id.search_pop_text6);
//设置历史列表adapter
final ArrayAdapter<String> historyAdapter = new ArrayAdapter<>(this,R.layout.item_listview,histories);
historyList.setAdapter(historyAdapter);
//设置结果列表adapter
recyclerViewAdapter = new MyRecyclerViewAdapter<SearchResultObj.book>(SearchActivity.this,R.layout.item_book,results) {
@Override
public void convert(MyViewHolder holder, final SearchResultObj.book book) {
TextView name = holder.getView(R.id.item_book_name);
name.setText(book.getTitle());
TextView author = holder.getView(R.id.item_book_author);
author.setText(book.getAuthor());
TextView major = holder.getView(R.id.item_book_type);
major.setText(book.getCat());
TextView intro = holder.getView(R.id.item_book_intro);
String introString = book.getShortIntro();
if (introString.length() > 50){
introString = introString.substring(0,49)+"……";
}
intro.setText(introString);
final ImageView cover = holder.getView(R.id.item_book_cover);
new Thread(new Runnable() {
@Override
public void run() {
try {
if (isNetWorkConnected(MainActivity.getContext())) {
URL url = new URL(BookService.StaticsUrl + book.getCover());
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(10000);
if (connection.getResponseCode() == 200) {
InputStream inputStream = connection.getInputStream();
final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
handler.post(new Runnable() {
@Override
public void run() {
cover.setImageBitmap(bitmap);
}
});
}
}
else{
Looper.prepare();
Toast.makeText(SearchActivity.this,"网络似乎出现了点问题",Toast.LENGTH_SHORT).show();
Looper.loop();
}
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
}).start();
}
};
recyclerViewAdapter.setOnItemClickListener(new MyRecyclerViewAdapter.OnItemClickListener() {
@Override
public void onClick(final int position) {
final Intent intent = new Intent(SearchActivity.this, BookDetailActivity.class);
final Bundle bundle = new Bundle();
new Thread(new Runnable() {
@Override
public void run() {
if (isNetWorkConnected(MainActivity.getContext())) {
final BookObj t = getBookService().getBookById(results.get(position).get_id());
if (t != null)
handler.post(new Runnable() {
@Override
public void run() {
bundle.putSerializable("bookobj", t);
intent.putExtras(bundle);
startActivity(intent);
}
});
}
else {
Looper.prepare();
Toast.makeText(SearchActivity.this,"网络似乎出现了点问题",Toast.LENGTH_SHORT).show();
Looper.loop();
}
}
}).start();
}
@Override
public void onLongClick(int position) {
}
});
resultList.setAdapter(recyclerViewAdapter);
resultList.setLayoutManager(new LinearLayoutManager(this));
//设置模糊关联列表adapter
final ArrayAdapter<String> fuzzyAdapter = new ArrayAdapter<>(this,R.layout.item_listview2,tempFuzzy);
fuzzyList.setAdapter(fuzzyAdapter);
//设置热门搜索函数
text1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String s = text1.getText().toString();
recordClick(s);
}
});
text2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String s = text2.getText().toString();
recordClick(s);
}
});
text3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String s = text3.getText().toString();
recordClick(s);
}
});
text4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String s = text4.getText().toString();
recordClick(s);
}
});
text5.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String s = text5.getText().toString();
recordClick(s);
}
});
text6.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String s = text6.getText().toString();
recordClick(s);
}
});
//设置搜索函数
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(final String s) {
isSubmit = true;
//添加历史
if (!histories.contains(s)){
histories.add(s);
getInstance(getBaseContext()).addSearchHistory(s);
}
//设置可见
searchLayout.setVisibility(View.VISIBLE);
fuzzyList.setVisibility(View.GONE);
resultList.setVisibility(View.VISIBLE);
//填充数据
new Thread(new Runnable() {
@Override
public void run() {
if (isNetWorkConnected(MainActivity.getContext())) {
SearchResultObj tt = getBookService().getSearchResultObj(s, 0, 8);
results.clear();
if (tt != null) {
List<SearchResultObj.book> t = tt.getBookList();
results.addAll(t);
handler.post(new Runnable() {
@Override
public void run() {
recyclerViewAdapter.notifyDataSetChanged();
}
});
}
else {
Looper.prepare();
Toast.makeText(SearchActivity.this,"搜索不到相关内容",Toast.LENGTH_SHORT).show();
Looper.loop();
}
}
else {
Looper.prepare();
Toast.makeText(SearchActivity.this,"网络似乎出现了点问题",Toast.LENGTH_SHORT).show();
Looper.loop();
}
}
}).start();
recyclerViewAdapter.notifyDataSetChanged();
return false;
}
@Override
public boolean onQueryTextChange(final String s) {
//设置可见
if (!isSubmit) {
if (s.equals("")) {
initialLayout.setVisibility(View.VISIBLE);
searchLayout.setVisibility(View.GONE);
}
else {
initialLayout.setVisibility(View.GONE);
searchLayout.setVisibility(View.VISIBLE);
fuzzyList.setVisibility(View.VISIBLE);
resultList.setVisibility(View.GONE);
}
}
else {
if (s.equals("")) {
fuzzyList.setVisibility(View.GONE);
resultList.setVisibility(View.VISIBLE);
}
else {
fuzzyList.setVisibility(View.VISIBLE);
resultList.setVisibility(View.GONE);
}
}
//填充数据
if (!s.equals("")&&flag) {
new Thread(new Runnable() {
@Override
public void run() {
flag = false;
if (isNetWorkConnected(MainActivity.getContext())) {
SearchResultObj tt = getBookService().getSearchResultObj(s, 0, 8);
List<String> t = new ArrayList<>();
if (tt != null) {
List<SearchResultObj.book> tss = tt.getBookList();
int size = tss.size();
for (int i = 0; i < size; i++)
t.add(tss.get(i).getTitle());
}
tempFuzzy.clear();
if (t.size() > 0)
tempFuzzy.addAll(t);
handler.post(new Runnable() {
@Override
public void run() {
fuzzyAdapter.notifyDataSetChanged();
}
});
}
else {
Looper.prepare();
Toast.makeText(SearchActivity.this,"网络似乎出现了点问题",Toast.LENGTH_SHORT).show();
Looper.loop();
}
flag = true;
}
}).start();
fuzzyAdapter.notifyDataSetChanged();
}
return false;
}
});
//设置历史删除函数
deleteView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getInstance(getBaseContext()).deleteHistory();
histories.clear();
historyAdapter.notifyDataSetChanged();
}
});
//设置历史点击函数
historyList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final String s = histories.get(position);
recordClick(s);
}
});
//模糊搜索点击函数
fuzzyList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final String s = tempFuzzy.get(position);
isSubmit = true;
//添加历史
if (!histories.contains(s)){
histories.add(s);
getInstance(getBaseContext()).addSearchHistory(s);
}
//设置可见
initialLayout.setVisibility(View.GONE);
searchLayout.setVisibility(View.VISIBLE);
fuzzyList.setVisibility(View.GONE);
resultList.setVisibility(View.VISIBLE);
//填充数据
new Thread(new Runnable() {
@Override
public void run() {
if (isNetWorkConnected(MainActivity.getContext())) {
SearchResultObj tt = getBookService().getSearchResultObj(s, 0, 8);
List<SearchResultObj.book> t = tt.getBookList();
results.clear();
if (t != null)
results.addAll(t);
handler.post(new Runnable() {
@Override
public void run() {
recyclerViewAdapter.notifyDataSetChanged();
}
});
}
else {
Looper.prepare();
Toast.makeText(SearchActivity.this,"网络似乎出现了点问题",Toast.LENGTH_SHORT).show();
Looper.loop();
}
}
}).start();
recyclerViewAdapter.notifyDataSetChanged();
searchView.setQuery(s,true);
}
});
//取消按钮点击事件
cancelView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
//更换热门图书函数
freshView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
freshPopBook();
}
});
}
public void recordClick(final String s) {
isSubmit = true;
//设置可见
initialLayout.setVisibility(View.GONE);
searchLayout.setVisibility(View.VISIBLE);
fuzzyList.setVisibility(View.GONE);
resultList.setVisibility(View.VISIBLE);
//添加历史
if (!histories.contains(s)){
histories.add(s);
getInstance(getBaseContext()).addSearchHistory(s);
}
//填充数据
new Thread(new Runnable() {
@Override
public void run() {
if (isNetWorkConnected(MainActivity.getContext())) {
SearchResultObj tt = getBookService().getSearchResultObj(s, 0, 8);
results.clear();
if (tt != null) {
List<SearchResultObj.book> t = tt.getBookList();
results.addAll(t);
handler.post(new Runnable() {
@Override
public void run() {
recyclerViewAdapter.notifyDataSetChanged();
}
});
}
else {
Looper.prepare();
Toast.makeText(SearchActivity.this,"搜索不到相关内容",Toast.LENGTH_SHORT).show();
Looper.loop();
}
}
else {
Looper.prepare();
Toast.makeText(SearchActivity.this,"网络似乎出现了点问题",Toast.LENGTH_SHORT).show();
Looper.loop();
}
}
}).start();
recyclerViewAdapter.notifyDataSetChanged();
searchView.setQuery(s,true);
}
public void freshPopBook() {
Random ra =new Random();
int t = ra.nextInt(29);
text1.setText(hotBooks[t]);
t = (t+1)%30;
text2.setText(hotBooks[t]);
t = (t+1)%30;
text3.setText(hotBooks[t]);
t = (t+1)%30;
text4.setText(hotBooks[t]);
t = (t+1)%30;
text5.setText(hotBooks[t]);
t = (t+1)%30;
text6.setText(hotBooks[t]);
}
}

@ -0,0 +1,11 @@
@startuml
'https://plantuml.com/sequence-diagram
autonumber
Alice -> Bob: Authentication Request
Bob --> Alice: Authentication Response
Alice -> Bob: Another authentication Request
Alice <-- Bob: another authentication Response
@enduml

@ -0,0 +1,279 @@
package com.example.DataBase;
import android.content.ContentValues;
import android.content.Context;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.List;
import com.example.Activity.MainActivity;
import com.example.R;
import com.example.Object.ShelfBookObj;
import com.example.Object.UserStatusObj;
public class DatabaseControl extends SQLiteOpenHelper {
private static final String DB_NAME= "readerBase.db";
private static final String TABLE_NAME1 = "shelfbook_table";
private static final String TABLE_NAME2 = "categorybook_table";
private static final String TABLE_NAME3 = "status_table";
private static final int DB_VERSION = 1;
private static DatabaseControl instance = null;
public static DatabaseControl getInstance(Context context) {
if (instance == null) {
instance = new DatabaseControl(context);
}
return instance;
}
//byte[] 转 Bitmap
public Bitmap bytesToBitmap(byte[] b) {
if (b.length != 0) {
return BitmapFactory.decodeByteArray(b, 0, b.length);
} else {
return null;
}
}
//Bitmap → byte[]
public byte[] bitmapToBytes(Bitmap bm) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
return baos.toByteArray();
}
//这个list用于保存所有书架书籍信息
private List<ShelfBookObj> allShelfBook = null;
public List<ShelfBookObj> getAllShelfBook() {
return getAllShelfBookFromDB();
}
//从数据库中查询所有书架书目
private List<ShelfBookObj> getAllShelfBookFromDB() {
SQLiteDatabase db = getWritableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_NAME1, null);
List<ShelfBookObj> list = new ArrayList<>();
while (cursor.moveToNext()) {
String id = cursor.getString(cursor.getColumnIndex("_id"));
String major = cursor.getString(cursor.getColumnIndex("major"));
String author = cursor.getString(cursor.getColumnIndex("author"));
int readChapter = cursor.getInt(cursor.getColumnIndex("progress"));
int type = cursor.getInt(cursor.getColumnIndex("type"));
String name = cursor.getString(cursor.getColumnIndex("name"));
String address = cursor.getString(cursor.getColumnIndex("address"));
String description = cursor.getString(cursor.getColumnIndex("description"));
byte[] imageByte = cursor.getBlob(cursor.getColumnIndex("image"));
list.add(new ShelfBookObj(id,name, bytesToBitmap(imageByte),"",readChapter,address,type,description,author,major));
}
cursor.close();
db.close();
return list;
}
//根据book id删除数据
public void deleteShelfBook(String id) {
SQLiteDatabase db = getWritableDatabase();
db.delete(TABLE_NAME1, "_id = ?", new String[] { id });
}
public void addShelfBook(ShelfBookObj book) {
SQLiteDatabase db = getWritableDatabase();
ContentValues values = new ContentValues();
//开始添加第一条数据_id TEXT PRIMARY KEY, name TEXT, type INTEGER ,progress INTEGER, address TEXT,image BLOB, description TEXT
values.put("name",book.getName());
values.put("description",book.getDescription());
values.put("type",book.getType());
values.put("_id",book.getBookId());
values.put("author",book.getAuthor());
values.put("major",book.getMajor());
values.put("address",book.getAddress());
values.put("progress",book.getReadChapter());
values.put("image",bitmapToBytes(book.getIcon()));
db.insert(TABLE_NAME1,null,values);
db.close();
}
//获取多少条搜索历史
public int getHistoryCount() {
SQLiteDatabase db = getWritableDatabase();
Cursor cursor = db.query(TABLE_NAME2, null, null, null, null, null, null);
return cursor.getCount();
}
//更新阅读进度
public void updateProgress(int progress, String id) {
SQLiteDatabase db = getWritableDatabase();
ContentValues value = new ContentValues();
value.put("progress", progress);
db.update(TABLE_NAME1, value, "_id=?", new String[] { id });
db.close();
}
public List<String> getAllHistory() {
SQLiteDatabase db = getWritableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_NAME2, null);
List<String> list = new ArrayList<>();
while (cursor.moveToNext()) {
String content = cursor.getString(cursor.getColumnIndex("content"));
list.add(content);
}
cursor.close();
db.close();
return list;
}
//搜索历史添加不超过10个
public void addSearchHistory(String s) {
SQLiteDatabase db = getWritableDatabase();
if (getHistoryCount() > 9){
Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_NAME2, null);
cursor.moveToFirst();
String name = cursor.getString(cursor.getColumnIndex("content"));
db.delete(TABLE_NAME2, "content=?", new String[] {name});
}
ContentValues cv = new ContentValues();
cv.put("content", s);
db.insert(TABLE_NAME2, null, cv);
db.close();
}
public boolean judgeBookExist(String id) {
SQLiteDatabase db = getWritableDatabase();
Cursor cursor = db.query(TABLE_NAME1, null, "_id=?", new String[] { id }, null, null, null);
return cursor.moveToFirst();
}
//删除搜索历史
public void deleteHistory() {
SQLiteDatabase db = getWritableDatabase();
db.execSQL("DELETE FROM " + TABLE_NAME2);
}
// 更新用户阅读器习惯的状态
public void updateStatus(int user_id, int hor_or_ver_screen) {
SQLiteDatabase db = getWritableDatabase();
ContentValues value = new ContentValues();
value.put("hor_or_ver_screen", hor_or_ver_screen);
db.update(TABLE_NAME3, value, "user_id=?", new String[] { Integer.toString(user_id)});
db.close();
}
// 获取用户阅读器习惯的横竖屏
public int get_Hor_Or_Ver_Screen_Status(int user_id) {
SQLiteDatabase db = getWritableDatabase();
String id = Integer.toString(user_id);
String sql = String.format("SELECT * FROM " + TABLE_NAME3 + " where user_id='%s'" , id);
Cursor cursor = db.rawQuery(sql, null);
int res = 1;
while (cursor.moveToNext()) {
res = cursor.getInt(cursor.getColumnIndex("hor_or_ver_screen"));
return res;
}
cursor.close();
db.close();
return res;
}
// 更新用户阅读器习惯的状态
public void updateStatus(int user_id, UserStatusObj u) {
SQLiteDatabase db = getWritableDatabase();
ContentValues value = new ContentValues();
value.put("hor_or_ver_screen", u.getHor_or_ver_screen()); // 1表示竖屏0表示横屏
value.put("day_or_night_status", u.getDay_or_night_status()); // 0表示日间1表示夜间
value.put("textSize", u.getTextSize()); // 字体大小
db.update(TABLE_NAME3, value, "user_id=?", new String[] { Integer.toString(user_id)});
db.close();
}
public UserStatusObj get_User_Status_Obj(int user_id) {
SQLiteDatabase db = getWritableDatabase();
String id = Integer.toString(user_id);
String sql = String.format("SELECT * FROM " + TABLE_NAME3 + " where user_id='%s'" , id);
Cursor cursor = db.rawQuery(sql, null);
UserStatusObj res = null;
while (cursor.moveToNext()) {
int hor_or_ver_screen = cursor.getInt(cursor.getColumnIndex("hor_or_ver_screen"));
int day_or_night_status = cursor.getInt(cursor.getColumnIndex("day_or_night_status"));
int textSize = cursor.getInt(cursor.getColumnIndex("textSize"));
res = new UserStatusObj(user_id, hor_or_ver_screen, day_or_night_status, textSize);
return res;
}
cursor.close();
db.close();
return res;
}
public DatabaseControl(Context context) {
super(context, DB_NAME, null, DB_VERSION );
}
@Override//创建数据库
public void onCreate(SQLiteDatabase sqLiteDatabase) {
//书架上的书,含书名、类型(本地还是网络)、阅读进度、资源地址、书的封面
String CREATE_TABLE1 = "CREATE TABLE if not exists "
+ TABLE_NAME1
+ " (_id TEXT PRIMARY KEY, name TEXT, type INTEGER ,progress INTEGER, address TEXT,image BLOB, description TEXT, author TEXT, major TEXT)";
//搜索历史
String CREATE_TABLE2 = "CREATE TABLE if not exists "
+ TABLE_NAME2
+ " (_id INTEGER PRIMARY KEY, content TEXT)";
// 阅读器状态保存
String CREATE_TABLE3 = "CREATE TABLE if not exists "
+ TABLE_NAME3
+ " (user_id INTEGER PRIMARY KEY, hor_or_ver_screen INTEGER, day_or_night_status INTEGER, textSize INTEGER)";
sqLiteDatabase.execSQL(CREATE_TABLE1);
sqLiteDatabase.execSQL(CREATE_TABLE2);
sqLiteDatabase.execSQL(CREATE_TABLE3);
Resources res = MainActivity.getContext().getResources();
Bitmap bitmap = BitmapFactory.decodeResource(res, R.mipmap.bookcover);
ContentValues values = new ContentValues();
ShelfBookObj book = new ShelfBookObj("5816b415b06d1d32157790b1","圣墟",bitmap,"",0,"default",0,"在破败中崛起,在寂灭中复苏。沧海成尘,雷电枯竭,那一缕幽雾又一次临近大地,世间的枷锁被打开了,一个全新的世界就此揭开神秘的一角……","辰东","玄幻");
//开始添加第一条数据_id TEXT PRIMARY KEY, name TEXT, type INTEGER ,progress INTEGER, address TEXT,image BLOB, description TEXT
values.put("name",book.getName());
values.put("description",book.getDescription());
values.put("type",book.getType());
values.put("_id",book.getBookId());
values.put("author",book.getAuthor());
values.put("major",book.getMajor());
values.put("address",book.getAddress());
values.put("progress",book.getReadChapter());
values.put("image",bitmapToBytes(book.getIcon()));
sqLiteDatabase.insert(TABLE_NAME1,null,values);
values.clear();
bitmap = BitmapFactory.decodeResource(res, R.mipmap.bookcover2);
book = new ShelfBookObj("59ba0dbb017336e411085a4e","元尊",bitmap,"",0,"default",0,"《斗破苍穹》《武动乾坤》之后全新力作,朝堂太子踏上了荆棘重生之路…","天蚕土豆","玄幻");
values.put("name",book.getName());
values.put("description",book.getDescription());
values.put("type",book.getType());
values.put("_id",book.getBookId());
values.put("author",book.getAuthor());
values.put("major",book.getMajor());
values.put("address",book.getAddress());
values.put("progress",book.getReadChapter());
values.put("image",bitmapToBytes(book.getIcon()));
sqLiteDatabase.insert(TABLE_NAME1,null,values);
// 往阅读器状态表格中保存一条初始阅读器状态
UserStatusObj u = new UserStatusObj(0,1,0,18);
values.clear();
values.put("user_id", 0); // 用户id为0表示默认状态
values.put("hor_or_ver_screen", u.getHor_or_ver_screen()); // 1表示竖屏0表示横屏
values.put("day_or_night_status", u.getDay_or_night_status()); // 0表示日间1表示夜间
values.put("textSize", u.getTextSize()); // 字体大小
sqLiteDatabase.insert(TABLE_NAME3,null,values);
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int ii) {
}
}

@ -0,0 +1,148 @@
package com.example.Fragment;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
import com.example.R;
import com.example.Activity.ReadPageActivity;
import com.example.DataBase.DatabaseControl;
import com.example.RecyclerView.MyRecyclerViewAdapter;
import com.example.RecyclerView.MyViewHolder;
import com.example.Object.ShelfBookObj;
// 书架界面
public class BookShelfFragment extends Fragment {
// Fragment的视图
View view;
// Fragment内的RecyclerView
RecyclerView recyclerView; // recyclerview
List<ShelfBookObj> myBooks; // recyclerview中的书籍数据
MyRecyclerViewAdapter<ShelfBookObj> adapter; // recyclerview 的 adapter
// book-item 项的各个控件
private ImageView book_cover_imageview_control;
private TextView book_name_textview_control;
private TextView book_author_textview_control;
private TextView book_type_textview_control;
private TextView book_intro_textview_control;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// 获取 Fragment 的视图
view = inflater.inflate(R.layout.fragment_book_shelf, null);
// 获取书籍数据
getMyBooks();
// 设置页面的 RecyclerView
setRecyclerView();
// 返回视图
return view;
}
@Override
public void onResume() {
getMyBooks();
setRecyclerView();
//Toast.makeText(getActivity(), "进入Fragment" + " | " + myBooks.size(), Toast.LENGTH_SHORT).show();
// System.out.println("onResume: " + myBooks.get(0).getReadChapter());
//System.out.println("横竖屏状态MainActivity-BookShelfFragment: " + DatabaseControl.getInstance(getActivity()).get_Hor_Or_Ver_Screen_Status(0));
super.onResume();
}
// 获取书籍数据
private void getMyBooks() {
//Bitmap bitmap = ((BitmapDrawable)getResources().getDrawable(R.mipmap.bookcover)).getBitmap();
/*ShelfBookObj test = new ShelfBookObj("5816b415b06d1d32157790b1", "圣墟", bitmap, 0, "testAddress", 0, "testDescription");
DatabaseControl.getInstance(getActivity()).addShelfBook(test);*/
myBooks = DatabaseControl.getInstance(getActivity()).getAllShelfBook();
//System.out.println("getBookSize: " + myBooks.size());
}
// 设置页面的 RecyclerView
private void setRecyclerView() {
// 获取页面的 RecyclerView 控件
recyclerView = view.findViewById(R.id.fragment_book_shelf_recyclerview);
// 设置 RecyclerView 的布局方式
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
// 设置 RecyclerAdapter
adapter = new MyRecyclerViewAdapter<ShelfBookObj>(getActivity(), R.layout.item_book, myBooks) {
@Override
public void convert(MyViewHolder holder, ShelfBookObj shelfBookObj) {
// 书名
TextView bookName = holder.getView(R.id.item_book_name);
bookName.setText(shelfBookObj.getName());
// 封面
ImageView imageView = holder.getView(R.id.item_book_cover);
imageView.setImageBitmap(shelfBookObj.getIcon());
// 作者
TextView author = holder.getView(R.id.item_book_author);
author.setText(shelfBookObj.getAuthor());
// 类型
TextView major = holder.getView(R.id.item_book_type);
major.setText(shelfBookObj.getMajor());
// 简介
TextView intro = holder.getView(R.id.item_book_intro);
String str = shelfBookObj.getDescription();
if (str.length() > 50) str = str.substring(0, 50);
str += "...";
intro.setText(str);
}
};
adapter.refresh(myBooks);
adapter.setOnItemClickListener(new MyRecyclerViewAdapter.OnItemClickListener() {
@Override
public void onClick(int position) {
Intent intent = new Intent(getActivity(), ReadPageActivity.class);
Bundle bundle = new Bundle();
bundle.putString("bookid", myBooks.get(position).getBookId());
bundle.putInt("currentChapter", myBooks.get(position).getReadChapter());
bundle.putString("bookname", myBooks.get(position).getName());
System.out.println("传进去当前阅读章节数为:" + myBooks.get(position).getReadChapter());
intent.putExtras(bundle);
startActivity(intent);
}
@Override
public void onLongClick(final int position) {
// 长按弹出对话框
AlertDialog.Builder dialog = new AlertDialog.Builder(getActivity());
dialog.setMessage("确定要从书架移除" + myBooks.get(position).getName() + "吗?");
dialog.setNegativeButton("NO", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
dialog.setPositiveButton("YES", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
DatabaseControl.getInstance(getActivity()).deleteShelfBook(myBooks.get(position).getBookId());
getMyBooks();
setRecyclerView();
}
});
dialog.show();
}
});
recyclerView.setAdapter(adapter);
}
}

@ -0,0 +1,96 @@
package com.example.Fragment;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import java.util.ArrayList;
import java.util.List;
import com.example.R;
// 分类的界面
public class CategoryFragment extends Fragment {
private RadioGroup RG;
private RadioButton maleRB;
private RadioButton femaleRB;
private ViewPager viewPager;
private List<Fragment> fragmentList = new ArrayList<>();
private TabFragmentPagerAdapter fragmentPagerAdapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_category, null);
//初始化控件
RG = view.findViewById(R.id.category_RG);
viewPager = view.findViewById(R.id.category_viewPager);
maleRB = view.findViewById(R.id.category_RB_male);
femaleRB = view.findViewById(R.id.category_RB_female);
//初始化Fragment
fragmentList.clear();
MaleInCategoryFragment maleFragment = new MaleInCategoryFragment();
MaleInCategoryFragment femaleFragment = new MaleInCategoryFragment();
Bundle bundle1 = new Bundle();
bundle1.putBoolean("isMale", true);
maleFragment.setArguments(bundle1);
fragmentList.add(maleFragment);
Bundle bundle2 = new Bundle();
bundle2.putBoolean("isMale", false);
femaleFragment.setArguments(bundle2);
fragmentList.add(femaleFragment);
viewPager.setOnPageChangeListener(new MyPagerChangeListener());
fragmentPagerAdapter = new TabFragmentPagerAdapter(getChildFragmentManager(), fragmentList);
viewPager.setAdapter(fragmentPagerAdapter);
viewPager.setCurrentItem(0);
viewPager.setOffscreenPageLimit(1);
RG.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId) {
case R.id.category_RB_male:
viewPager.setCurrentItem(0);
break;
case R.id.category_RB_female:
viewPager.setCurrentItem(1);
break;
}
}
});
return view;
}
//设置一个ViewPager的监听事件左右滑动ViewPager时进行处理
public class MyPagerChangeListener implements ViewPager.OnPageChangeListener {
@Override
public void onPageScrollStateChanged(int arg0) {
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageSelected(int arg0) {
switch (arg0) {
case 0:
maleRB.setChecked(true);
break;
case 1:
femaleRB.setChecked(true);
break;
}
}
}
}

@ -0,0 +1,320 @@
package com.example.Fragment;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
import com.example.Activity.BookDetailActivity;
import com.example.R;
import com.example.RecyclerView.CateRecyclerViewAdapter;
import com.example.Object.AllRankingObj;
import com.example.Object.BookObj;
import com.example.Object.CategoryObj;
import com.example.Object.SingleRankingObj;
import com.example.Service.BookService;
// 具体分类和榜单的Fragment
public class DetailCategoryFragment extends Fragment {
private boolean isRanking; //排行榜/具体分类
private boolean isMale; //男生/女生
private String title; //榜单名/类型名
private String type; //具体榜单/具体类型
private RecyclerView recyclerView;
private ProgressBar progressBar;
private SwipeRefreshLayout swipeRefreshLayout;
private List<BookObj> bookObjList = new ArrayList<>();
private CateRecyclerViewAdapter recyclerViewAdapter;
//具体榜单的id
private String rankingid = "";
private int total; //书籍总数
private int lastVisibleItem = 0;
private final int PAGE_COUNT = 10;
Handler handler = new Handler();
BookService bookService = BookService.getBookService();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.isRanking = getArguments().getBoolean("isRanking");
this.isMale = getArguments().getBoolean("isMale");
if (isRanking == false) {
Log.d("type in args:", getArguments().getString("type"));
switch (getArguments().getString("type")) {
case "热门":
this.type = "hot";
break;
case "新书":
this.type = "new";
break;
case "好评":
this.type = "reputation";
break;
case "完结":
this.type = "over";
break;
}
}
else this.type = getArguments().getString("type");
this.title = getArguments().getString("title");
initBookList();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_detail_category, null);
progressBar = view.findViewById(R.id.detail_category_progressBar);
swipeRefreshLayout = view.findViewById(R.id.detail_category_swipeRefresh);
//设置RecyclerView
recyclerView = view.findViewById(R.id.detail_category_recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerViewAdapter = new CateRecyclerViewAdapter(getBookList(0, PAGE_COUNT), getActivity(), getBookList(0, PAGE_COUNT).size() > 0 ? true : false, isRanking);
recyclerViewAdapter.setOnItemClickListener(new CateRecyclerViewAdapter.OnItemClickListener() {
@Override
public void onClick(int position) {
//跳转到书籍详情界面
Intent intent = new Intent(getActivity(), BookDetailActivity.class);
Bundle bundle = new Bundle();
bundle.putSerializable("bookobj", bookObjList.get(position));
intent.putExtras(bundle);
startActivity(intent);
}
});
recyclerView.setAdapter(recyclerViewAdapter);
//设置下拉显示的动画颜色
swipeRefreshLayout.setColorSchemeColors(Color.RED, Color.BLUE);
//下拉刷新的回调事件
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
//数据刷新
initBookList();
}
});
//设置滑动监听器
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
// 在newState为滑到底部时
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
// 如果没有隐藏footView那么最后一个条目的位置就比我们的getItemCount少1
if (recyclerViewAdapter.isFadeTips() == false && lastVisibleItem + 1 == recyclerViewAdapter.getItemCount()) {
handler.postDelayed(new Runnable() {
@Override
public void run() {
// 然后调用updateRecyclerview方法更新RecyclerView
updateRecyclerView(recyclerViewAdapter.getLastPosition(), recyclerViewAdapter.getLastPosition() + PAGE_COUNT);
}
}, 500);
}
// 如果隐藏了提示条我们又上拉加载时那么最后一个条目就要比getItemCount要少2
if (recyclerViewAdapter.isFadeTips() == true && lastVisibleItem + 2 == recyclerViewAdapter.getItemCount()) {
handler.postDelayed(new Runnable() {
@Override
public void run() {
// 然后调用updateRecyclerview方法更新RecyclerView
updateRecyclerView(recyclerViewAdapter.getLastPosition(), recyclerViewAdapter.getLastPosition() + PAGE_COUNT);
}
}, 500);
}
}
}
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
// 在滑动完成后拿到最后一个可见的item的位置
LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
lastVisibleItem = layoutManager.findLastVisibleItemPosition();
}
});
return view;
}
void initBookList() {
bookObjList.clear();
//检查网络连接
ConnectivityManager connect = (ConnectivityManager)getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = connect.getActiveNetworkInfo();
if (info == null || !info.isAvailable()) {
Toast.makeText(getActivity(), "网络连接状况:未连接", Toast.LENGTH_LONG).show();
return;
}
if (isRanking) getRankingBookList();
else getCateBookList();
}
//获取排行榜书单
void getRankingBookList() {
new Thread(new Runnable() {
@Override
public void run() {
AllRankingObj allRankingObj = bookService.getAllRankingObj();
if (allRankingObj == null || allRankingObj.isOk() == false) {
Looper.prepare();
Toast.makeText(getContext(), "获取数据失败", Toast.LENGTH_LONG).show();
Looper.loop();
Log.d("error", "获取全部排行榜失败");
return;
}
//获取具体榜单的id
if (isMale) { //男生
for (AllRankingObj.subClass subClass : allRankingObj.getMaleList()) {
if (subClass.getShortTitle().equals(title)) {
if (title.equals("热搜榜")) rankingid = subClass.getId();
else {
if (type.equals("周榜")) rankingid = subClass.getId();
else if (type.equals("月榜")) rankingid = subClass.getMonthRank();
else if (type.equals("总榜")) rankingid = subClass.getTotalRank();
else {
System.exit(1);
Log.d("error", "榜单名错误!");
}
}
break;
}
}
}
else { //女生
for (AllRankingObj.subClass subClass : allRankingObj.getFemaleList()) {
if (subClass.getShortTitle().equals(title)) {
if (title.equals("热搜榜")) rankingid = subClass.getId();
else {
if (type.equals("周榜")) rankingid = subClass.getId();
else if (type.equals("月榜")) rankingid = subClass.getMonthRank();
else if (type.equals("总榜")) rankingid = subClass.getTotalRank();
else {
System.exit(1);
Log.d("error", "榜单名不符!");
}
}
break;
}
}
}
//得到id后再获取具体榜单的书籍信息
new Thread(new Runnable() {
@Override
public void run() {
SingleRankingObj singleRankingObj = bookService.getSingleRankingObj(rankingid);
if (singleRankingObj == null || singleRankingObj.isOk() == false) {
Looper.prepare();
Toast.makeText(getContext(), "获取失败", Toast.LENGTH_LONG).show();
Looper.loop();
Log.d("error", "获取单一排行榜失败");
return;
}
List<BookObj> objList = singleRankingObj.getRanking().getBookList();
total = singleRankingObj.getRanking().getTotal();
for (int i = 0; i < objList.size(); ++i) {
BookObj bookObj = objList.get(i);
String intro = bookObj.getShortIntro();
if (intro.length() > 50) intro = intro.substring(0, 50);
intro += "...";
bookObj.setShortIntro(intro);
bookObjList.add(bookObj);
}
handler.post(new Runnable() {
@Override
public void run() {
updateRecyclerView(0, PAGE_COUNT);
progressBar.setVisibility(View.GONE);
//数据加载完毕时取消动画
swipeRefreshLayout.setRefreshing(false);
Toast.makeText(getActivity(), "数据刷新完成", Toast.LENGTH_SHORT).show();
}
});
}
}).start();
}
}).start();
}
//获取具体分类书单
void getCateBookList() {
new Thread(new Runnable() {
@Override
public void run() {
String gender = (isMale == true) ? "male" : "female";
Log.d("type:", "" + type);
final CategoryObj categoryObj = bookService.getBooksByCategoty(type, title, 0, 30000, gender);
if (categoryObj == null || categoryObj.isOk() == false) {
Looper.prepare();
Toast.makeText(getContext(), "获取数据失败", Toast.LENGTH_LONG).show();
Looper.loop();
Log.d("error", "获取主题书单列表失败");
return;
}
total = categoryObj.getTotal();
for (BookObj bookObj : categoryObj.getBooks()) {
if (bookObj.getShortIntro().length() > 50){
String intro = bookObj.getShortIntro();
intro = intro.substring(0, 50);
intro += "...";
bookObj.setShortIntro(intro);
}
bookObjList.add(bookObj);
}
handler.post(new Runnable() {
@Override
public void run() {
//Toast.makeText(getActivity(), "" + bookObjList.size() + " | " + total + " | " + categoryObj.getBooks().size(), Toast.LENGTH_SHORT).show();
updateRecyclerView(0, PAGE_COUNT);
progressBar.setVisibility(View.GONE);
//数据加载完毕时取消动画
swipeRefreshLayout.setRefreshing(false);
Toast.makeText(getActivity(), "数据刷新完成", Toast.LENGTH_SHORT).show();
}
});
}
}).start();
}
private void updateRecyclerView(int fromIndex, int toIndex) {
List<BookObj> newDatas = getBookList(fromIndex, toIndex);
if (newDatas.size() > 0) {
recyclerViewAdapter.updateList(newDatas, true);
} else {
recyclerViewAdapter.updateList(null, false);
}
}
List<BookObj> getBookList(int from, int to) {
List<BookObj> newList = new ArrayList<>();
for (int i = from; i < to && i < bookObjList.size(); ++i) {
newList.add(bookObjList.get(i));
}
return newList;
}
}

@ -0,0 +1,272 @@
package com.example.Fragment;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.Looper;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
import com.example.Activity.CategoryActivity;
import com.example.R;
import com.example.RecyclerView.CategoryRecyObj;
import com.example.RecyclerView.MyRecyclerViewAdapter;
import com.example.RecyclerView.MyViewHolder;
import com.example.Object.ClassificationObj1;
import com.example.Object.ClassificationObj2;
import com.example.Service.BookService;
import static android.app.ProgressDialog.show;
// 分类(男生/女生)界面
public class MaleInCategoryFragment extends Fragment {
// Fragment 的 视图
View view;
// Fragment内的RecyclerView
RecyclerView recyclerView; // recyclerview
List<CategoryRecyObj> myCategories; // recyclerview中的书籍数据
MyRecyclerViewAdapter<CategoryRecyObj> adapter; // recyclerview 的 adapter
// 判断是女性分类还是男性分类
boolean isMale = true;
// 分类数据OBJ
private ClassificationObj1 classificationObj1;
private ClassificationObj2 classificationObj2;
// bookservice 类 (用单例模式获取)
private BookService bookService;
// 一级分类(写死)
public static String[] maleCategoriesName = {"玄幻", "奇幻", "武侠", "仙侠", "都市", "职场", "历史", "军事", "游戏", "竞技", "科幻", "灵异", "同人", "轻小说"};
public static String[] femaleCategoriesName = {"古代言情", "现代言情", "青春校园", "纯爱", "玄幻奇幻", "武侠仙侠", "科幻", "游戏竞技", "悬疑灵异", "同人", "女尊", "莉莉"};
String[] maleCategoriesBookCount = {"(56万本)", "(6.3万本)", "(4.8万本)", "(15万本)", "(38万本)", "(1.8万本)", "(7.9万本)", "(1.6万本)", "(8.9万本)", "(6648本)", "(13万本)", "(5.3万本)", "(4.6万本)", "(9761本)"};
String[] femaleCategoriesBookCount = {"(57万本)", "(71万本)", "(15万本)", "(13万本)", "(15万本)", "(7.8万本)", "(1.8万本)", "(6553本)", "(2.0万本)", "(12万本)", "(2.2万本)", "(2.6万本)"};
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 获取传给Fragment的参数
Bundle bundle = getArguments();
this.isMale = bundle.getBoolean("isMale");
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// 获取 Fragment 视图
view = inflater.inflate(R.layout.fragment_male_in_category, null);
// 获取分类数据
getMyCategories();
// 设置 RecyclerView
setRecyclerView();
// Inflate the layout for this fragment
return view;
}
// 设置 RecyclerView
private void setRecyclerView() {
// 获取页面的 RecyclerView 控件
recyclerView = view.findViewById(R.id.fragment_male_in_category_recyclerview);
// 设置 RecyclerView 的布局方式
recyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 2));
// 设置 Adapter 配置
adapter = new MyRecyclerViewAdapter<CategoryRecyObj>(getActivity(), R.layout.item_category, myCategories) {
@Override
public void convert(MyViewHolder holder, CategoryRecyObj categoryRecyObj) {
TextView categoryName = holder.getView(R.id.item_category_name);
categoryName.setText(categoryRecyObj.getCategoryName());
TextView categoryBookCount = holder.getView(R.id.item_category_count);
categoryBookCount.setText(categoryRecyObj.getBookCount());
}
};
// 每个主类按钮的点击响应处理
adapter.setOnItemClickListener(new MyRecyclerViewAdapter.OnItemClickListener() {
@Override
public void onClick(int position) {
//跳转具体分类界面
Intent intent = new Intent(getActivity(), CategoryActivity.class);
Bundle bundle = new Bundle();
bundle.putBoolean("isRanking", false);
bundle.putBoolean("isMale", isMale);
if (isMale) bundle.putString("title", maleCategoriesName[position]);
else bundle.putString("title", femaleCategoriesName[position]);
intent.putExtras(bundle);
startActivity(intent);
/*System.out.println("onClick");
// 分类信息尚未获取调用BookService去获取
if(classificationObj2 == null) {
boolean isNetWorkConnected = isNetWorkConnected(getActivity());
// 有网络
if(isNetWorkConnected) {
System.out.println("网络连接状况:已连接");
// 调用子线程进行访问,获取一级、二级分类信息
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
classificationObj2 = bookService.getClassification2();
Looper.prepare();
if(classificationObj2 == null) {
Toast.makeText(getActivity(), "还是获取失败啊啊啊啊", Toast.LENGTH_SHORT).show();
}
Looper.loop();
}
});
thread.start();
}
// 无网络
else {
System.out.println("网络连接状况:未连接");
Toast.makeText(getActivity(), "网络连接状况:未连接", Toast.LENGTH_SHORT).show();
}
}
// 已经获取过分类信息
else {
// 获取点击到的一级分类以及对应的二级分类数据
String major;
String[] mins;
if(isMale) {
major = maleCategoriesName[position];
mins = classificationObj2.getMaleList().get(position).getMins();
}
else {
major = femaleCategoriesName[position];
mins = classificationObj2.getFemaleList().get(position).getMins();
}
// 获取失败
if(major == null || mins == null) {
Toast.makeText(getActivity(), "获取失败", Toast.LENGTH_SHORT).show();
}
// 获取数据成功
else {
//Toast.makeText(getActivity(), major + "二级分类框弹出", Toast.LENGTH_SHORT).show();
// 弹出一个二级分类框
Dialog dialog = new Dialog(getActivity());
dialog.setContentView(R.layout.dialog_category);
// 二级分类RecyclerView
RecyclerView dialog_recyclerview = dialog.findViewById(R.id.dialog_category_recyclerview);
// 二级分类数据初始化
List<CategoryRecyObj> dialog_categories = new ArrayList<>();
for(int i = 0; i < mins.length; i++)
dialog_categories.add(new CategoryRecyObj(mins[i], ""));
// 设置 Adapter
MyRecyclerViewAdapter<CategoryRecyObj> dialog_adapter = new MyRecyclerViewAdapter<CategoryRecyObj>(getActivity(), R.layout.item_category, dialog_categories) {
@Override
public void convert(MyViewHolder holder, CategoryRecyObj categoryRecyObj) {
TextView categoryName = holder.getView(R.id.item_category_name);
categoryName.setText(categoryRecyObj.getCategoryName());
TextView categoryBookCount = holder.getView(R.id.item_category_count);
categoryBookCount.setVisibility(View.GONE);
}
};
// 适配 Adapter
dialog_recyclerview.setAdapter(dialog_adapter);
// 设置 RecyclerView 布局
dialog_recyclerview.setLayoutManager(new LinearLayoutManager(getActivity()));
// 设置 dialog 属性并显示
dialog.setCancelable(true);
dialog.show();
}
}*/
}
@Override
public void onLongClick(int position) {
}
});
// 给 RecyclerView 适配 Adapter
recyclerView.setAdapter(adapter);
}
// 获取分类数据
private void getMyCategories() {
boolean isNetWorkConnected = isNetWorkConnected(getActivity());
bookService = BookService.getBookService();
if(isNetWorkConnected) {
System.out.println("网络连接状况:已连接");
// 调用子线程进行访问,获取一级、二级分类信息
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
classificationObj2 = bookService.getClassification2();
Looper.prepare();
if(classificationObj2 == null) {
Toast.makeText(getActivity(), "获取失败", Toast.LENGTH_SHORT).show();
}
Looper.loop();
}
});
thread.start();
}
else {
System.out.println("网络连接状况:未连接");
Toast.makeText(getActivity(), "网络连接状况:未连接", Toast.LENGTH_SHORT).show();
}
myCategories = new ArrayList<>();
// 男生向小说分类
if(isMale) {
for(int i = 0; i < maleCategoriesName.length; i++) {
CategoryRecyObj c = new CategoryRecyObj(maleCategoriesName[i], maleCategoriesBookCount[i]);
myCategories.add(c);
}
}
// 女生向小说分类
else {
for(int i = 0; i < femaleCategoriesName.length; i++) {
CategoryRecyObj c = new CategoryRecyObj(femaleCategoriesName[i], femaleCategoriesBookCount[i]);
myCategories.add(c);
}
}
}
// 辅助函数:判断网络是否连接
public boolean isNetWorkConnected(Context context) {
if (context != null) {
ConnectivityManager mConnectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
if (mNetworkInfo != null) {
return mNetworkInfo.isConnected();
}
}
return false;
}
}

@ -0,0 +1,131 @@
package com.example.Fragment;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import com.example.Activity.CategoryActivity;
import com.example.R;
import com.example.RecyclerView.MyRecyclerViewAdapter;
import com.example.RecyclerView.MyViewHolder;
// 排行榜界面
public class RankingFragment extends Fragment {
private boolean isMale; //男生/女生
private int color1 = Color.parseColor("#F5D6D6");//最热榜
private int color2 = Color.parseColor("#D8F8C2");//热搜榜
private int color3 = Color.parseColor("#F9EBB0");//潜力榜
private int color4 = Color.parseColor("#DBB5F4");//留存榜
private int color5 = Color.parseColor("#CEFDFD");//完结榜
private RecyclerView recyclerView;
private List<String> list = new ArrayList<>();
private MyRecyclerViewAdapter adapter;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle bundle = getArguments();
this.isMale = bundle.getBoolean("isMale");
if (isMale) {
list.add("最热榜");
list.add("热搜榜");
list.add("潜力榜");
list.add("留存榜");
list.add("完结榜");
}
else {
list.add("热搜榜");
list.add("留存榜");
list.add("最热榜");
list.add("潜力榜");
list.add("完结榜");
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_ranking, null);
recyclerView = view.findViewById(R.id.ranking_recycler);
//设置recyclerView的显示
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
adapter = new MyRecyclerViewAdapter<String>(getActivity(), R.layout.item_ranking, list) {
@Override
public void convert(MyViewHolder holder, String type) {
Bitmap bitmap = null;
int color = color1;
switch (type) {
case "最热榜":
if (isMale) bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.male_icon1, null);
else bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.female_icon1, null);
color = color1;
break;
case "热搜榜":
if (isMale) bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.male_icon2, null);
else bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.female_icon2, null);
color = color2;
break;
case "潜力榜":
if (isMale) bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.male_icon3, null);
else bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.female_icon3, null);
color = color3;
break;
case "留存榜":
if (isMale) bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.male_icon4, null);
else bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.female_icon4, null);
color = color4;
break;
case "完结榜":
if (isMale) bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.male_icon5, null);
else bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.female_icon5, null);
color = color5;
break;
}
ImageView imageView = holder.getView(R.id.ranking_item_image);
imageView.setImageBitmap(bitmap);
TextView textView = holder.getView(R.id.ranking_item_text);
textView.setText(type);
RelativeLayout layout = holder.getView(R.id.ranking_item_right);
layout.setBackgroundColor(color);
}
};
//设置RecyclerView的点击响应事件
adapter.setOnItemClickListener(new MyRecyclerViewAdapter.OnItemClickListener() {
@Override
public void onClick(int position) {
//跳转到对应榜单界面
Intent intent = new Intent(getActivity(), CategoryActivity.class);
Bundle bundle = new Bundle();
bundle.putBoolean("isRanking", true);
bundle.putBoolean("isMale", isMale);
bundle.putString("title", list.get(position));
intent.putExtras(bundle);
startActivity(intent);
}
@Override
public void onLongClick(int position) {
}
});
recyclerView.setAdapter(adapter);
return view;
}
}

@ -0,0 +1,73 @@
package com.example.Fragment;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;
import com.example.R;
// 阅读界面的Fragment
public class ReadPageFragment extends Fragment {
// 页面数据
private String title; //章节名
private String content; //本章内容
int day_or_night_status; //日间或夜间模式
int textSize; //字体大小
// 帧页面View
View view;
// 帧页面控件
private TextView titile_control; // 标题
private TextView content_control; // 阅读页内容
private FrameLayout whole_layout_control; // 整个框页面
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.content = getArguments().getString("content");
this.title = getArguments().getString("title");
this.day_or_night_status = getArguments().getInt("day_or_night_status");
this.textSize = getArguments().getInt("textSize");
//System.out.println("日间夜间:" + day_or_night_status);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// 获取帧页面View
view = inflater.inflate(R.layout.fragment_read_page, null);
// 获取页面控件
init_page_control();
// 设置页面内容
init_page_info();
//todo
return view;
}
private void init_page_info() {
titile_control.setText(title); // 设置标题
content_control.setText(content); // 设置阅读页内容
content_control.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize);
if(day_or_night_status == 0) {
whole_layout_control.setBackgroundColor(getResources().getColor(R.color.PapayaWhip));
}
else whole_layout_control.setBackgroundColor(getResources().getColor(R.color.nightBackGround));
//progress_control.setText(Integer.toString(currentChapter+1) + "/" + Integer.toString(totalChapter+1));
}
private void init_page_control() {
titile_control = view.findViewById(R.id.fragment_read_page_title);
content_control = view.findViewById(R.id.fragment_read_page_content);
whole_layout_control = view.findViewById(R.id.fragment_read_page_whole_layout);
//progress_control = view.findViewById(R.id.fragment_read_page_process);
}
}

@ -0,0 +1,28 @@
package com.example.Fragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import java.util.List;
// 碎片适配器
public class TabFragmentPagerAdapter extends FragmentPagerAdapter {
private FragmentManager fm;
private List<Fragment> list;
public TabFragmentPagerAdapter(FragmentManager fm, List<Fragment> list) {
super(fm);
this.fm = fm;
this.list = list;
}
@Override
public Fragment getItem(int i) {
return list.get(i);
}
@Override
public int getCount() {
return list.size();
}
}

@ -0,0 +1,33 @@
package com.example.Fragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.view.PagerAdapter;
import java.util.List;
// 碎片状态适配器
public class TabFragmentStatePagerAdapter extends android.support.v4.app.FragmentStatePagerAdapter {
private FragmentManager fm;
private List<Fragment> list;
public TabFragmentStatePagerAdapter(FragmentManager fm, List<Fragment> list) {
super(fm);
this.fm = fm;
this.list = list;
}
@Override
public int getItemPosition(Object object) {
return PagerAdapter.POSITION_NONE;
}
@Override
public Fragment getItem(int i) {
return list.get(i);
}
@Override
public int getCount() {
return list.size();
}
}

@ -0,0 +1,89 @@
package com.example.Object;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class AllRankingObj {
// 男生
@SerializedName("male")
private List<subClass> maleList;
// 女生
@SerializedName("female")
private List<subClass> femaleList;
@SerializedName("ok")
private boolean ok;
public List<subClass> getMaleList() {
return maleList;
}
public List<subClass> getFemaleList() {
return femaleList;
}
public boolean isOk() {
return ok;
}
public class subClass {
// 周榜id
@SerializedName("_id")
private String id;
// 排行榜全名
@SerializedName("title")
private String title;
// 排行榜大图标
@SerializedName("cover")
private String cover;
@SerializedName("collapse")
private boolean collapse;
// 月榜id
@SerializedName("monthRank")
private String monthRank;
// 总榜id
@SerializedName("totalRank")
private String totalRank;
// 排行榜简称
@SerializedName("shortTitle")
private String shortTitle;
public String getId() {
return id;
}
public String getTitle() {
return title;
}
public String getCover() {
return cover;
}
public boolean isCollapse() {
return collapse;
}
public String getMonthRank() {
return monthRank;
}
public String getTotalRank() {
return totalRank;
}
public String getShortTitle() {
return shortTitle;
}
}
}

@ -0,0 +1,166 @@
package com.example.Object;
import com.google.gson.annotations.SerializedName;
import java.io.Serializable;
// 书籍的对象
public class BookObj implements Serializable {
// 书籍id
@SerializedName("_id")
private String id;
// 书籍标题
@SerializedName("title")
private String title;
// 书籍作者
@SerializedName("author")
private String author;
// 书籍介绍
@SerializedName("longIntro")
private String longIntro;
// 书籍简介
@SerializedName("shortIntro")
private String shortIntro;
// 书籍封面图
@SerializedName("cover")
private String cover;
@SerializedName("site")
private String site;
// 书籍一级分类
@SerializedName("majorCate")
private String majorCate;
// 书籍二级分类
@SerializedName("minorCate")
private String minorCate;
@SerializedName("sizetype")
private int sizetype;
@SerializedName("contentType")
private String contentType;
@SerializedName("allowMonthly")
private boolean allowMonthly;
@SerializedName("banned")
private int banned;
// 最近关注人数
@SerializedName("latelyFollower")
private int latelyFollower;
// 字数
@SerializedName("wordCount")
private int wordCount;
// 留存率
@SerializedName("retentionRatio")
private float retentionRatio;
// 最新章节
@SerializedName("lastChapter")
private String lastChapter;
@SerializedName("updated")
private String updated;
// 性别
@SerializedName("gender")
private String[] gender;
// 标签
@SerializedName("tags")
private String[] tags;
public String getId() {
return id;
}
public String getTitle() {
return title;
}
public String getAuthor() {
return author;
}
public String getShortIntro() {
return shortIntro;
}
public void setShortIntro(String shortIntro) {
this.shortIntro = shortIntro;
}
public String getCover() {
return cover;
}
public String getSite() {
return site;
}
public String getMajorCate() {
return majorCate;
}
public String getMinorCate() {
return minorCate;
}
public int getSizetype() {
return sizetype;
}
public String getContentType() {
return contentType;
}
public boolean isAllowMonthly() {
return allowMonthly;
}
public String getLongIntro() {
return longIntro;
}
public String[] getGender() {
return gender;
}
public int getBanned() {
return banned;
}
public int getLatelyFollower() {
return latelyFollower;
}
public float getRetentionRatio() {
return retentionRatio;
}
public String getLastChapter() {
return lastChapter;
}
public String[] getTags() {
return tags;
}
public int getWordCount() {
return wordCount;
}
public String getUpdated() {
return updated;
}
}

@ -0,0 +1,31 @@
package com.example.Object;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class CategoryObj {
// 书籍总数
@SerializedName("total")
private int total;
// 书籍列表
@SerializedName("books")
private List<BookObj> books;
// 获取结果
@SerializedName("ok")
private boolean ok;
public int getTotal() {
return total;
}
public List<BookObj> getBooks() {
return books;
}
public boolean isOk() {
return ok;
}
}

@ -0,0 +1,42 @@
package com.example.Object;
import com.google.gson.annotations.SerializedName;
import java.io.Serializable;
public class ChapterLinkObj implements Serializable {
// 章节链接
@SerializedName("link")
private String link;
// 章节标题
@SerializedName("title")
private String title;
// 是否不可读
@SerializedName("unreadable")
private boolean unreadable;
public ChapterLinkObj() {
super();
}
public ChapterLinkObj(String _link, String _title, boolean _unreadable) {
link = _link;
title = _title;
unreadable = _unreadable;
}
public String getLink() {
return link;
}
public String getTitle() {
return title;
}
public boolean isUnreadable() {
return unreadable;
}
}

@ -0,0 +1,12 @@
package com.example.Object;
import java.io.Serializable;
import java.util.List;
public class ChapterLinks implements Serializable {
public List<ChapterLinkObj> chapterLinkList;
public List<ChapterLinkObj> getChapterLinkList() {
return chapterLinkList;
}
}

@ -0,0 +1,43 @@
package com.example.Object;
import com.google.gson.annotations.SerializedName;
// 获取章节内容返回结果
public class ChapterObj {
// 请求结果
@SerializedName("ok")
private boolean ok;
@SerializedName("chapter")
private Chapter ichapter;
public boolean isOk() {
return ok;
}
public Chapter getIchapter() {
return ichapter;
}
/*
*
*/
public class Chapter {
// 章节标题
@SerializedName("title")
private String title;
// 章节内容
@SerializedName("body")
private String body;
public String getTitle() {
return title;
}
public String getBody() {
return body;
}
}
}

@ -0,0 +1,90 @@
package com.example.Object;
import com.google.gson.annotations.SerializedName;
import java.util.List;
// 获取一级分类返回结果
public class ClassificationObj1 {
// male分类
@SerializedName("male")
private List<SubClass1> maleList;
// female分类
@SerializedName("female")
private List<SubClass1> femaleList;
// picture分类
@SerializedName("picture")
private List<SubClass1> picList;
@SerializedName("press")
private List<SubClass1> pressList;
@SerializedName("ok")
private boolean ok;
public List<SubClass1> getMaleList() {
return maleList;
}
public List<SubClass1> getFemaleList() {
return femaleList;
}
public List<SubClass1> getPicList() {
return picList;
}
public List<SubClass1> getPressList() {
return pressList;
}
public boolean isOk() {
return ok;
}
// 一级分类
public class SubClass1 {
// 名称
@SerializedName("name")
private String name;
// 书籍数量
@SerializedName("bookCount")
private int bookCount;
// monthlyCount?
@SerializedName("monthlyCount")
private int monthlyCount;
// 分类图标
@SerializedName("icon")
private String icon;
// 封面图链接
@SerializedName("bookCover")
private String[] bookCover;
public String getName() {
return name;
}
public int getBookCount() {
return bookCount;
}
public int getMonthlyCount() {
return monthlyCount;
}
public String getIcon() {
return icon;
}
public String[] getBookCover() {
return bookCover;
}
}
}

@ -0,0 +1,58 @@
package com.example.Object;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class ClassificationObj2 {
@SerializedName("male")
private List<SubClass2> maleList;
@SerializedName("female")
private List<SubClass2> femaleList;
@SerializedName("picture")
private List<SubClass2> picList;
@SerializedName("press")
private List<SubClass2> pressList;
@SerializedName("ok")
private boolean ok;
public List<SubClass2> getMaleList() {
return maleList;
}
public List<SubClass2> getFemaleList() {
return femaleList;
}
public List<SubClass2> getPicList() {
return picList;
}
public List<SubClass2> getPressList() {
return pressList;
}
public boolean isOk() {
return ok;
}
public class SubClass2 {
@SerializedName("major")
private String major;
@SerializedName("mins")
private String[] mins;
public String getMajor() {
return major;
}
public String[] getMins() {
return mins;
}
}
}

@ -0,0 +1,64 @@
package com.example.Object;
import com.google.gson.annotations.SerializedName;
import java.util.List;
// 获取章节列表返回结果
public class CptListObj {
// 请求结果
@SerializedName("ok")
private boolean ok;
@SerializedName("mixToc")
private mixToc imixToc;
public boolean isOk() {
return ok;
}
public mixToc getImixToc() {
return imixToc;
}
/*
*
*/
public class mixToc {
@SerializedName("_id")
private String _id;
// 书籍id
@SerializedName("book")
private String book;
// 章节数
@SerializedName("chaptersCount1")
private int chaptersCount;
// 章节列表
@SerializedName("chapters")
public List<ChapterLinkObj> chapterLinks;
// 更新时间
@SerializedName("updated")
private String updated;
public String get_id() {
return _id;
}
public String getBook() {
return book;
}
public int getChaptersCount() {
return chaptersCount;
}
public List<ChapterLinkObj> getChapterLinks() {
return chapterLinks;
}
public String getUpdated() {
return updated;
}
}
}

@ -0,0 +1,26 @@
package com.example.Object;
import com.google.gson.annotations.SerializedName;
public class FuzzySearchResultObj {
@SerializedName("code")
private int code;
@SerializedName("msg")
private String msg;
@SerializedName("data")
private String[] data;
public int getCode() {
return code;
}
public String getMsg() {
return msg;
}
public String[] getData() {
return data;
}
}

@ -0,0 +1,16 @@
package com.example.Object;
import java.io.Serializable;
import java.util.List;
//
public class RecomListObj implements Serializable {
private List<BookObj> bookObjs;
public RecomListObj(List<BookObj> bookObjs) {
this.bookObjs = bookObjs;
}
public List<BookObj> getBookObjs() {
return bookObjs;
}
}

@ -0,0 +1,185 @@
package com.example.Object;
import com.google.gson.annotations.SerializedName;
import java.util.List;
// 搜索结果对象
public class SearchResultObj {
// 书籍列表
@SerializedName("books")
private List<book> bookList;
// 总数
@SerializedName("total")
private int total;
@SerializedName("ok")
private boolean ok;
public List<book> getBookList() {
return bookList;
}
public int getTotal() {
return total;
}
public boolean isOk() {
return ok;
}
public class book {
// 书籍id
@SerializedName("_id")
private String _id;
@SerializedName("hasCp")
private boolean hasCp;
// 书名
@SerializedName("title")
private String title;
@SerializedName("aliases")
private String aliases;
// 一级分类
@SerializedName("cat")
private String cat;
// 作者
@SerializedName("author")
private String author;
@SerializedName("site")
private String site;
// 封面
@SerializedName("cover")
private String cover;
// 简介
@SerializedName("shortIntro")
private String shortIntro;
// 最新章节
@SerializedName("lastChapter")
private String lastChapter;
// 留存率
@SerializedName("retentionRatio")
private float retentionRatio;
@SerializedName("banned")
private int banned;
@SerializedName("allowMonthly")
private boolean allowMonthly;
// 关注人数
@SerializedName("latelyFollower")
private int latelyFollower;
// 字数
@SerializedName("wordCount")
private int wordCount;
// 类型
@SerializedName("contentType")
private String contentType;
@SerializedName("superscript")
private String superscript;
@SerializedName("sizetype")
private int sizetype;
@SerializedName("highlight")
private highlight mhighlight;
public String get_id() {
return _id;
}
public boolean isHasCp() {
return hasCp;
}
public String getTitle() {
return title;
}
public String getAliases() {
return aliases;
}
public String getCat() {
return cat;
}
public String getAuthor() {
return author;
}
public String getSite() {
return site;
}
public String getCover() {
return cover;
}
public String getShortIntro() {
return shortIntro;
}
public String getLastChapter() {
return lastChapter;
}
public float getRetentionRatio() {
return retentionRatio;
}
public int getBanned() {
return banned;
}
public boolean isAllowMonthly() {
return allowMonthly;
}
public int getLatelyFollower() {
return latelyFollower;
}
public int getWordCount() {
return wordCount;
}
public String getContentType() {
return contentType;
}
public String getSuperscript() {
return superscript;
}
public int getSizetype() {
return sizetype;
}
public highlight getMhighlight() {
return mhighlight;
}
public class highlight {
@SerializedName("title")
private String[] title;
public String[] getTitle() {
return title;
}
}
}
}

@ -0,0 +1,109 @@
package com.example.Object;
import android.graphics.Bitmap;
// 书架书籍对象
public class ShelfBookObj {
String bookId; //id
private Bitmap icon; //图标
private String iconURL; //图标网络url
private String name; //书名
private String description; //描述
private String author; //作者
private String major; //一级分类
int type; //0代表网络图片1代表本地图片
private String address; //本地书籍url
private int readChapter; //阅读到的章节
public ShelfBookObj(String bookId, String name, Bitmap icon, String iconURL, int readChapter, String address,int type,String description,String author, String major) {
this.bookId = bookId;
this.name = name;
this.icon = icon;
this.iconURL = iconURL;
this.readChapter = readChapter;
this.address = address;
this.type = type;
this.description = description;
this.author = author;
this.major = major;
}
public String getIconURL() {
return iconURL;
}
public void setIconURL(String iconURL) {
this.iconURL = iconURL;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getName() {
return name;
}
public Bitmap getIcon() {
return icon;
}
public String getAddress() {
return address;
}
public void setIcon(Bitmap icon) {
this.icon = icon;
}
public int getReadChapter() {
return readChapter;
}
public void setName(String name) {
this.name = name;
}
public void setAddress(String address) {
this.address = address;
}
public void setReadChapter(int readChapter) {
this.readChapter = readChapter;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getBookId() {
return bookId;
}
public void setBookId(String bookId) {
this.bookId = bookId;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getMajor() {
return major;
}
public void setMajor(String major) {
this.major = major;
}
}

@ -0,0 +1,175 @@
package com.example.Object;
import com.google.gson.annotations.SerializedName;
import java.util.List;
// 单独排行对象
public class SingleRankingObj {
@SerializedName("ranking")
private Ranking ranking;
@SerializedName("ok")
private boolean ok;
public Ranking getRanking() {
return ranking;
}
public boolean isOk() {
return ok;
}
public class Ranking {
// 周榜id
@SerializedName("_id")
private String _id;
// 更新时间
@SerializedName("updated")
private String updated;
// 排行榜全名
@SerializedName("title")
private String title;
@SerializedName("tag")
private String tag;
// 排行榜大图标
@SerializedName("cover")
private String cover;
// 排行榜小图标
@SerializedName("icon")
private String icon;
@SerializedName("__v")
private String __v;
// 月榜id
@SerializedName("monthRank")
private String monthRank;
// 总榜id
@SerializedName("totalRank")
private String totalRank;
// 排行榜简称
@SerializedName("shortTitle")
private String shortTitle;
@SerializedName("created")
private String created;
@SerializedName("biTag")
private String biTag;
@SerializedName("isSub")
private boolean isSub;
@SerializedName("collapse")
private boolean collapse;
@SerializedName("new")
private boolean _new;
// 性别
@SerializedName("gender")
private String gender;
@SerializedName("priority")
private int priority;
// 书籍列表
@SerializedName("books")
private List<BookObj> bookList;
// 周榜id
@SerializedName("id")
private String id;
// 总数
@SerializedName("total")
private int total;
public String get_id() {
return _id;
}
public String getUpdated() {
return updated;
}
public String getTitle() {
return title;
}
public String getTag() {
return tag;
}
public String getCover() {
return cover;
}
public String getIcon() {
return icon;
}
public String get__v() {
return __v;
}
public String getMonthRank() {
return monthRank;
}
public String getTotalRank() {
return totalRank;
}
public String getShortTitle() {
return shortTitle;
}
public String getCreated() {
return created;
}
public String getBiTag() {
return biTag;
}
public boolean isSub() {
return isSub;
}
public boolean isCollapse() {
return collapse;
}
public boolean is_new() {
return _new;
}
public String getGender() {
return gender;
}
public int getPriority() {
return priority;
}
public List<BookObj> getBookList() {
return bookList;
}
public String getId() {
return id;
}
public int getTotal() {
return total;
}
}
}

@ -0,0 +1,48 @@
package com.example.Object;
// 用户状态对象
public class UserStatusObj {
int user_id;
int hor_or_ver_screen;
int day_or_night_status;
int textSize;
public UserStatusObj(int user_id, int hor_or_ver_screen, int day_or_night_status, int textSize) {
this.user_id = user_id;
this.hor_or_ver_screen = hor_or_ver_screen;
this.day_or_night_status = day_or_night_status;
this.textSize = textSize;
}
public int getDay_or_night_status() {
return day_or_night_status;
}
public int getHor_or_ver_screen() {
return hor_or_ver_screen;
}
public int getTextSize() {
return textSize;
}
public int getUser_id() {
return user_id;
}
public void setDay_or_night_status(int dat_or_night_status) {
this.day_or_night_status = dat_or_night_status;
}
public void setHor_or_ver_screen(int hor_or_ver_screen) {
this.hor_or_ver_screen = hor_or_ver_screen;
}
public void setTextSize(int textSize) {
this.textSize = textSize;
}
public void setUser_id(int user_id) {
this.user_id = user_id;
}
}

@ -0,0 +1,222 @@
package com.example.RecyclerView;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import com.example.R;
import com.example.Object.BookObj;
import com.example.Service.BookService;
// 用于排行榜、分类界面的RecyclerView的Adapter
public class CateRecyclerViewAdapter extends RecyclerView.Adapter<MyViewHolder> {
private Context context;
private List<BookObj> data;
private boolean isRanking;
private OnItemClickListener onItemClickListener;
private int normalType = 0; // 第一种ViewType正常的item
private int footType = 1; // 第二种ViewType底部的提示View
private boolean hasMore = true; // 变量,是否有更多数据
private boolean fadeTips = false; // 变量,是否隐藏了底部的提示
private Handler mHandler = new Handler(Looper.getMainLooper()); //获取主线程的Handler
public CateRecyclerViewAdapter(List<BookObj> data, Context context, boolean hasMore, boolean isRanking) {
this.data = data;
this.context = context;
this.hasMore = hasMore;
this.isRanking = isRanking;
}
public boolean isFadeTips() {
return fadeTips;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
//根据不同的ViewType绑定不同的布局文件
if (viewType == normalType) {
MyViewHolder holder = MyViewHolder.get(context, viewGroup, R.layout.item_book);
holder.setNormalTypeType(true);
return holder;
}
else {
MyViewHolder holder = MyViewHolder.get(context, viewGroup, R.layout.recycler_footer_view);
holder.setNormalTypeType(false);
return holder;
}
}
@Override
public void onBindViewHolder(@NonNull final MyViewHolder holder, int position) {
if (data.isEmpty()) return;
if (holder.isNormalType() == true) {//是正常的布局
BookObj bookObj = data.get(position);
if (isRanking && !data.isEmpty()) {
ImageView rankingImg = holder.getView(R.id.item_book_rankingImg);
if (position == 0) {//排行榜第一名
rankingImg.setImageBitmap(BitmapFactory.decodeResource(context.getResources(), R.mipmap.first, null));
rankingImg.setVisibility(View.VISIBLE);
} else if (position == 1) {//排行榜第二名
rankingImg.setImageBitmap(BitmapFactory.decodeResource(context.getResources(), R.mipmap.second, null));
rankingImg.setVisibility(View.VISIBLE);
} else if (position == 2) {//排行榜第三名
rankingImg.setImageBitmap(BitmapFactory.decodeResource(context.getResources(), R.mipmap.third, null));
rankingImg.setVisibility(View.VISIBLE);
}
else rankingImg.setVisibility(View.GONE);
}
final ImageView imageView = holder.getView(R.id.item_book_cover);
TextView bookName = holder.getView(R.id.item_book_name);
TextView bookAuthor = holder.getView(R.id.item_book_author);
TextView bookType = holder.getView(R.id.item_book_type);
TextView bookIntro = holder.getView(R.id.item_book_intro);
TextView followers = holder.getView(R.id.item_book_followers);
TextView retention = holder.getView(R.id.item_book_retention);
int num = bookObj.getLatelyFollower();
if (num < 10000) {
followers.setText(bookObj.getLatelyFollower() + "人追");
}
else {
num /= 10000;
followers.setText(num + "万人追");
}
followers.setVisibility(View.VISIBLE);
retention.setText(bookObj.getRetentionRatio() + "%留存率");
retention.setVisibility(View.VISIBLE);
bookName.setText(bookObj.getTitle());
bookType.setText(bookObj.getMajorCate());
bookAuthor.setText(bookObj.getAuthor());
bookIntro.setText(bookObj.getShortIntro());
//通过网络获取书籍图标
final String iconURL = BookService.StaticsUrl + bookObj.getCover();
new Thread(new Runnable() {
@Override
public void run() {
try {
URL url = new URL(iconURL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(10000);
if (connection.getResponseCode() == 200) {
InputStream inputStream = connection.getInputStream();
final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
mHandler.post(new Runnable() {
@Override
public void run() {
imageView.setImageBitmap(bitmap);
}
});
}
} catch (Exception e) {
System.err.println(e.getMessage());
}
}}).start();
}
else {//是提示加载信息的布局
final ProgressBar progressBar = holder.getView(R.id.footer_view_progessBar);
final TextView tips = holder.getView(R.id.footer_view_text);
tips.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.VISIBLE);
// 只有获取数据为空时hasMore为false所以当我们拉到底部时基本都会首先显示“正在加载更多...”
if (hasMore == true) {
// 不隐藏footView提示
fadeTips = false;
if (data.size() > 0) {
// 如果查询数据发现增加之后,就显示正在加载更多数据
tips.setText("正在加载更多数据...");
progressBar.setVisibility(View.VISIBLE);
}
} else {
if (data.size() > 0) {
// 如果查询数据发现并没有增加时,就显示没有更多数据了
tips.setText("没有更多数据了");
// 隐藏提示条
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
// 隐藏提示条
tips.setVisibility(View.GONE);
progressBar.setVisibility(View.GONE);
// 将fadeTips设置true
fadeTips = true;
// hasMore设为true是为了让再次拉到底时会先显示正在加载更多
hasMore = true;
}
}, 500);
}
}
}
//设置监听器
if (onItemClickListener != null) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
onItemClickListener.onClick(holder.getAdapterPosition());
}
});
}
}
@Override
public int getItemCount() {
return data.size() + 1;
}
//获取列表中数据源的最后一个位置
public int getLastPosition() {
return data.size();
}
// 根据条目位置返回ViewType以供onCreateViewHolder方法内获取不同的Holder
@Override
public int getItemViewType(int position) {
if (position == getItemCount() - 1) {
return footType;
} else {
return normalType;
}
}
//下拉刷新时,通过暴露方法将数据源置为空
public void resetDatas() {
data = new ArrayList<>();
}
//更新数据源并修改hasMore的值如果有增加数据hasMore为true否则为false
public void updateList(List<BookObj> newDatas, boolean hasMore) {
// 在原有的数据之上增加新数据
if (newDatas != null) {
data.addAll(newDatas);
}
this.hasMore = hasMore;
notifyDataSetChanged();
}
public interface OnItemClickListener{
void onClick(int position);
}
public void setOnItemClickListener(OnItemClickListener _onItemClickListener) {
this.onItemClickListener = _onItemClickListener;
}
}

@ -0,0 +1,27 @@
package com.example.RecyclerView;
// 分类的实体
public class CategoryRecyObj {
private String categoryName;
private String bookCount;
public CategoryRecyObj(String categoryName, String bookCount) {
this.categoryName = categoryName;
this.bookCount = bookCount;
}
public String getBookCount() {
return bookCount;
}
public String getCategoryName() {
return categoryName;
}
public void setBookCount(String bookCount) {
this.bookCount = bookCount;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
}

@ -0,0 +1,72 @@
package com.example.RecyclerView;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import java.util.List;
public abstract class MyRecyclerViewAdapter<T> extends RecyclerView.Adapter<MyViewHolder> {
private Context context;
private int layoutId;
private List<T> data;
private OnItemClickListener onItemClickListener;
//构造函数
public MyRecyclerViewAdapter(Context _context, int _layoutId, List _data){
context = _context;
layoutId = _layoutId;
data = _data;
}
//创建自定的ViewHolder和绑定ViewHolder
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
MyViewHolder holder = MyViewHolder.get(context, parent, layoutId);
return holder;
}
@Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
convert(holder, data.get(position)); // convert函数需要重写下面会讲
if (onItemClickListener != null) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
onItemClickListener.onClick(holder.getAdapterPosition());
}
});
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
onItemClickListener.onLongClick(holder.getAdapterPosition());
return false;
}
});
}
}
@Override
public int getItemCount() {
if (data == null)
return 0;
return data.size();
}
public abstract void convert(final MyViewHolder holder, final T t);
public interface OnItemClickListener{
void onClick(int position);
void onLongClick(int position);
}
public void setOnItemClickListener(OnItemClickListener _onItemClickListener) {
this.onItemClickListener = _onItemClickListener;
}
public void refresh(List list) {
this.data = list;
notifyDataSetChanged();
}
}

@ -0,0 +1,47 @@
package com.example.RecyclerView;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
// ViewHolder用来复用列表中的控件
public class MyViewHolder extends RecyclerView.ViewHolder {
private SparseArray<View> views;
private View view;
private boolean isNormalType;
public void setNormalTypeType(boolean type) {
this.isNormalType = type;
}
public boolean isNormalType() {
return isNormalType;
}
public MyViewHolder(Context _context, View _view, ViewGroup _viewGroup){
super(_view);
view = _view;
views = new SparseArray<View>();
}
public static MyViewHolder get(Context _context, ViewGroup _viewGroup, int _layoutId) {
View _view = LayoutInflater.from(_context).inflate(_layoutId, _viewGroup, false);
MyViewHolder holder = new MyViewHolder(_context, _view, _viewGroup);
return holder;
}
public <T extends View> T getView(int _viewId) {
View _view = views.get(_viewId);
if (_view == null) {
// 创建view
_view = view.findViewById(_viewId);
// 将view存入views
views.put(_viewId, _view);
}
return (T)_view;
}
}

@ -0,0 +1,27 @@
package com.example.RecyclerView;
import android.graphics.Bitmap;
// 排行榜实体类
public class RankRecyObj {
private Bitmap image;
private String name;
private int color;
public RankRecyObj(Bitmap image, String name, int color) {
this.image = image;
this.name = name;
this.color = color;
}
public String getName() {
return name;
}
public Bitmap getImage() {
return image;
}
public int getColor() {
return color;
}
}

@ -0,0 +1,311 @@
package com.example.Service;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.TimeUnit;
import com.example.Object.AllRankingObj;
import com.example.Object.BookObj;
import com.example.Object.CategoryObj;
import com.example.Object.ChapterObj;
import com.example.Object.ClassificationObj1;
import com.example.Object.ClassificationObj2;
import com.example.Object.CptListObj;
import com.example.Object.FuzzySearchResultObj;
import com.example.Object.SearchResultObj;
import com.example.Object.SingleRankingObj;
import okhttp3.OkHttpClient;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
public class BookService {
public static String ApiUrl = "http://api.zhuishushenqi.com";
public static String StaticsUrl = "http://statics.zhuishushenqi.com";
public static String ChapterUrl = "http://chapter2.zhuishushenqi.com";
public static String FuzzySearchUrl = "https://www.apiopen.top";
private static BookService bookService = new BookService();
public static synchronized BookService getBookService() {
return bookService;
}
OkHttpClient build = new OkHttpClient.Builder()
.connectTimeout(2, TimeUnit.SECONDS)
.readTimeout(2, TimeUnit.SECONDS)
.writeTimeout(2, TimeUnit.SECONDS)
.build();
// 用于API访问
Retrofit retrofitForApi = new Retrofit.Builder()
.baseUrl(ApiUrl)
// 设置json数据解析器
.addConverterFactory(GsonConverterFactory.create())
// RxJava封装OkHttp的Call函数本质还是利用OkHttp请求数据
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.client(build)
.build();
// 用于图片访问
Retrofit retrofitForStatics = new Retrofit.Builder()
.baseUrl(StaticsUrl)
// 设置json数据解析器
.addConverterFactory(GsonConverterFactory.create())
// RxJava封装OkHttp的Call函数本质还是利用OkHttp请求数据
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.client(build)
.build();
// 用于章节访问
Retrofit retrofitForChapter = new Retrofit.Builder()
.baseUrl(ChapterUrl)
// 设置json数据解析器
.addConverterFactory(GsonConverterFactory.create())
// RxJava封装OkHttp的Call函数本质还是利用OkHttp请求数据
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.client(build)
.build();
Retrofit retrofitForFuzzySearch = new Retrofit.Builder()
.baseUrl(FuzzySearchUrl)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.client(build)
.build();
// 用于访问api
private UrlService ApiService = retrofitForApi.create(UrlService.class);
// 用于访问图片
private UrlService StaticsService = retrofitForStatics.create(UrlService.class);
// 用于访问章节
private UrlService ChapterService = retrofitForChapter.create(UrlService.class);
// 用于模糊搜索
private UrlService FuzzySearchService = retrofitForFuzzySearch.create(UrlService.class);
// 所有排行榜
private AllRankingObj allRankingObj;
// 单一排行榜
private SingleRankingObj singleRankingObj;
// 一级分类
private ClassificationObj1 classificationObj1;
// 二级分类
private ClassificationObj2 classificationObj2;
// 书籍列表
private CategoryObj categoryObj;
// 书籍详情
private BookObj bookObj;
// 章节列表
private CptListObj cptListObj;
// 章节内容
private ChapterObj chapterObj;
// 书籍搜索结果
private SearchResultObj searchResultObj;
// 模糊搜索结果
private FuzzySearchResultObj fuzzySearchResultObj;
/*
*
* @param
* @return AllRankingObj
*/
public AllRankingObj getAllRankingObj() {
Response<AllRankingObj> response = null;
try {
response = ApiService.getAllRanking().execute();
allRankingObj = response.body();
} catch (IOException e) {
e.printStackTrace();
}
return allRankingObj;
}
/*
*
* @param rankingId String _id monthRank totalRank AllRankingObj
* @return SingleRankingObj
*/
public SingleRankingObj getSingleRankingObj(String rankingId) {
Response<SingleRankingObj> response = null;
try {
response = ApiService.getSingleRanking(rankingId).execute();
singleRankingObj = response.body();
} catch (IOException e) {
e.printStackTrace();
}
return singleRankingObj;
}
/*
*
* @param
* @return ClassificationObj1
*/
public ClassificationObj1 getClassification1() {
Response<ClassificationObj1> response = null;
try {
response = ApiService.getClassificationObj1().execute();
classificationObj1 = response.body();
} catch (IOException e) {
e.printStackTrace();
}
return classificationObj1;
}
/*
*
* @param
* @return ClassificationObj2
*/
public ClassificationObj2 getClassification2() {
Response<ClassificationObj2> response = null;
try {
response = ApiService.getClassificationObj2().execute();
classificationObj2 = response.body();
} catch (IOException e) {
e.printStackTrace();
}
return classificationObj2;
}
/*
*
* @param type String hot()new()reputation()over()
* major String
* start String 0
* limit String 20
* gender String malefemale
* @return CategoryObj
* bookService.getBooksByCategoty("hot", "玄幻", "0", "20", "male");
*/
public CategoryObj getBooksByCategoty(String type, String major, int start, int limit, String gender) {
Response<CategoryObj> response = null;
try {
response = ApiService.getBooksByCategory(type, major, start, limit, gender).execute();
categoryObj = response.body();
} catch (IOException e) {
e.printStackTrace();
}
return categoryObj;
}
public BookObj getBookById(String bookid) {
Response<BookObj> response = null;
try {
response = ApiService.getBookById(bookid).execute();
bookObj = response.body();
} catch (IOException e) {
e.printStackTrace();
}
return bookObj;
}
/*
*
* @param String bookid idCategoryObj
* @return CptListObj
*/
public CptListObj getChaptersByBookId(String bookid) {
Response<CptListObj> response = null;
try {
response = ApiService.getChapters(bookid).execute();
cptListObj = response.body();
} catch (IOException e) {
e.printStackTrace();
}
return cptListObj;
}
/*
*
* @param String link CptListObj
* @return ChapterObj
*/
public ChapterObj getChapterByLink(String link) {
Response<ChapterObj> response = null;
try {
response = ChapterService.getChapter(link).execute();
chapterObj = response.body();
} catch (IOException e) {
e.printStackTrace();
}
return chapterObj;
}
/*
*
* @param query String
* start
* limit
* @return SearchResultObj
*/
public SearchResultObj getSearchResultObj(String query, int start, int limit) {
Response<SearchResultObj> response = null;
try {
response = ApiService.getSearchResult(query, start, limit).execute();
searchResultObj = response.body();
} catch (IOException e) {
e.printStackTrace();
}
return searchResultObj;
}
/*
*
* @param name String
* @return FuzzyResultObjs
*/
public FuzzySearchResultObj getFuzzySearchResult(String name) {
Response<FuzzySearchResultObj> response = null;
try {
response = FuzzySearchService.getFuzzySearchResult(name).execute();
fuzzySearchResultObj = response.body();
} catch (IOException e) {
e.printStackTrace();
}
return fuzzySearchResultObj;
}
/*
*
* @param path
* @return Bitmap
*/
public Bitmap getImg(String path) {
Response<InputStream> response = null;
Bitmap bitmap = null;
try {
response = StaticsService.getImg(path).execute();
InputStream is = response.body();
bitmap = BitmapFactory.decodeStream(is);
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
}
}

@ -0,0 +1,116 @@
package com.example.Service;
import java.io.InputStream;
import com.example.Object.AllRankingObj;
import com.example.Object.BookObj;
import com.example.Object.CategoryObj;
import com.example.Object.ChapterObj;
import com.example.Object.ClassificationObj1;
import com.example.Object.ClassificationObj2;
import com.example.Object.CptListObj;
import com.example.Object.FuzzySearchResultObj;
import com.example.Object.SearchResultObj;
import com.example.Object.SingleRankingObj;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Path;
import retrofit2.http.Query;
public interface UrlService {
/*
*
* @param
* @return Call<AllRankingObj>
*/
@GET("/ranking/gender")
Call<AllRankingObj> getAllRanking();
/*
*
* @param rankingId String _id monthRank totalRank
* @return Call<SingleRankingObj>
*/
@GET("/ranking/{rankingId}")
Call<SingleRankingObj> getSingleRanking(@Path("rankingId") String rankingId);
/*
*
* @param
* @return Call<ClassificationObj1>
*/
@GET("/cats/lv2/statistics")
Call<ClassificationObj1> getClassificationObj1();
/*
*
* @param
* @return Call<ClassificationObj2>
*/
@GET("/cats/lv2")
Call<ClassificationObj2> getClassificationObj2();
/*
*
* @param type String hot()new()reputation()over()
* major String
* start String 0
* limit String 20
* gender String malefemale
* @return Call<CategoryObj>
*/
@GET("/book/by-categories")
Call<CategoryObj> getBooksByCategory(@Query("type") String type, @Query("major") String major, @Query("start") int start, @Query("limit") int limit, @Query("gender") String gender);
/*
*
* @param bookid String id
* @return Call<BookObj>
*/
@GET("/book/{bookid}")
Call<BookObj> getBookById(@Path("bookid") String bookid);
/*
*
* @param bookid id
* @return Call<CptListObj>
*/
@GET("/mix-atoc/{bookid}?view=chapters")
Call<CptListObj> getChapters(@Path("bookid") String bookid);
/*
*
* @param link
* @return Call<ChapterObj>
*/
@GET("/chapter/{link}")
Call<ChapterObj> getChapter(@Path("link") String link);
/*
*
* @param name String
* start int
* limit int
* @return Call<SearchResultObj>
*/
@GET("/book/fuzzy-search")
Call<SearchResultObj> getSearchResult(@Query("query") String query, @Query("start") int start, @Query("limit") int limit);
/*
*
* @param name
* @return Call<FuzzySearchResultObj>
*/
@GET("/novelSearchApi")
Call<FuzzySearchResultObj> getFuzzySearchResult(@Query("name") String name);
/*
*
* @param path
* @return Call<Bitmap>
*/
@GET("{path}")
Call<InputStream> getImg(@Path("path") String path);
}

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 边框颜色值 -->
<item>
<shape>
<solid android:color="@color/colorGrey" />
</shape>
</item>
<!-- 主体背景颜色值 -->
<item android:top="1dp" android:right="1dp" android:left="1dp" android:bottom="1dp">
<shape>
<solid android:color="#ffffff" />
<padding android:bottom="10dp"
android:left="10dp"
android:right="10dp"
android:top="10dp" />
</shape>
</item>
</layer-list>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<size android:width="10dp"/>
<stroke android:width="0.5dp" android:color="@color/colorGrey"></stroke>
<padding android:bottom="10dp" android:left="10dp" android:right="10dp" android:top="10dp"/>
<corners android:topLeftRadius="10dp" android:bottomLeftRadius="10dp"
android:topRightRadius="10dp" android:bottomRightRadius="10dp"/>
</shape>

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

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

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#FF0000" android:state_pressed="false" android:state_selected="true" />
<item android:color="#FF0000" android:state_checked="true" android:state_pressed="false" />
<item android:color="#000000" />
</selector>

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<solid android:color="#ffffff" />
<stroke android:width="1dip" android:color="#4fa5d5"/>
<corners android:radius="2dp"/>
<padding
android:bottom="3dp"
android:left="3dp"
android:right="3dp"
android:top="3dp"/>
</shape>

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<solid android:color="#ffffff" />
<stroke android:width="1dip" android:color="#90F790"/>
<corners android:radius="2dp"/>
<padding
android:bottom="3dp"
android:left="3dp"
android:right="3dp"
android:top="3dp"/>
</shape>

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 边框颜色值 -->
<item>
<shape>
<solid android:color="@color/colorGrey" />
</shape>
</item>
<!-- 主体背景颜色值 -->
<item android:top="1dp" android:right="1dp" android:left="1dp" android:bottom="1dp">
<shape>
<solid android:color="#ffffff" />
<padding android:bottom="10dp"
android:left="10dp"
android:right="10dp"
android:top="10dp" />
</shape>
</item>
</layer-list>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<size android:width="10dp"/>
<stroke android:width="0.5dp" android:color="@color/colorGrey"></stroke>
<padding android:bottom="10dp" android:left="10dp" android:right="10dp" android:top="10dp"/>
<corners android:topLeftRadius="10dp" android:bottomLeftRadius="10dp"
android:topRightRadius="10dp" android:bottomRightRadius="10dp"/>
</shape>

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

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

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#FF0000" android:state_pressed="false" android:state_selected="true" />
<item android:color="#FF0000" android:state_checked="true" android:state_pressed="false" />
<item android:color="#000000" />
</selector>

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<solid android:color="#ffffff" />
<stroke android:width="1dip" android:color="#4fa5d5"/>
<corners android:radius="2dp"/>
<padding
android:bottom="3dp"
android:left="3dp"
android:right="3dp"
android:top="3dp"/>
</shape>

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<solid android:color="#ffffff" />
<stroke android:width="1dip" android:color="#90F790"/>
<corners android:radius="2dp"/>
<padding
android:bottom="3dp"
android:left="3dp"
android:right="3dp"
android:top="3dp"/>
</shape>

@ -0,0 +1,280 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp"
tools:context=".Activity.BookDetailActivity">
<RelativeLayout
android:id="@+id/top_RL"
android:layout_width="match_parent"
android:layout_height="40dp"
app:layout_constraintBottom_toTopOf="@+id/detail_scrollview"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/detail_back"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_alignParentLeft="true"
android:layout_centerInParent="true"
android:layout_marginStart="10dp"
android:src="@mipmap/back" />
<TextView
android:id="@+id/detail_title"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_centerInParent="true"
android:gravity="center"
android:text=""
android:textColor="#000000"
android:textSize="20sp" />
</RelativeLayout>
<ScrollView
android:id="@+id/detail_scrollview"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:fillViewport="true"
android:scrollbars="vertical"
app:layout_constraintTop_toBottomOf="@id/top_RL">
<LinearLayout
android:id="@+id/detail_topLL"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:orientation="vertical">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/detail_cover"
android:layout_width="100dp"
android:layout_height="150dp" />
<TextView
android:id="@+id/detail_bookTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:layout_margin="10dp"
android:text=""
android:textSize="22sp"
app:layout_constraintLeft_toRightOf="@id/detail_cover"
app:layout_constraintTop_toTopOf="@id/detail_cover" />
<TextView
android:id="@+id/detail_TV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text=""
android:textColor="@color/colorGrey"
android:textSize="14sp"
app:layout_constraintBottom_toTopOf="@+id/detail_update"
app:layout_constraintLeft_toRightOf="@id/detail_cover"
app:layout_constraintTop_toBottomOf="@id/detail_bookTitle" />
<TextView
android:id="@+id/detail_update"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_weight="1"
android:text=""
android:textColor="@color/colorRed"
android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="@id/detail_cover"
app:layout_constraintLeft_toRightOf="@id/detail_cover" />
</android.support.constraint.ConstraintLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:background="@drawable/card_edge">
<TextView
android:id="@+id/detail_follower1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:text="人数: "
android:textColor="@color/colorGrey"
android:textSize="12sp" />
<TextView
android:id="@+id/detail_follower2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="5dp"
android:layout_toRightOf="@id/detail_follower1"
android:text=""
android:textColor="@color/colorBlack"
android:textSize="16sp" />
<TextView
android:id="@+id/detail_retentionRatio1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginRight="5dp"
android:layout_toLeftOf="@+id/detail_retentionRatio2"
android:text="读者留存率: "
android:textColor="@color/colorGrey"
android:textSize="12sp" />
<TextView
android:id="@+id/detail_retentionRatio2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:text=""
android:textColor="@color/colorBlack"
android:textSize="16sp" />
</RelativeLayout>
<TextView
android:id="@+id/detail_longIntro"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:text=""
android:textSize="12sp"
app:layout_constraintTop_toBottomOf="@+id/detail_CV" />
<View
android:layout_width="match_parent"
android:layout_height="5dp"
android:background="@color/colorGrey"
app:layout_constraintBottom_toTopOf="@+id/detail_midRL"
app:layout_constraintTop_toBottomOf="@id/detail_topLL" />
<RelativeLayout
android:id="@+id/detail_midRL"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
app:layout_constraintTop_toBottomOf="@id/detail_topLL">
<TextView
android:id="@+id/detail_recomTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="同类推荐"
android:textColor="@color/colorBlack"
android:textSize="18sp" />
<Button
android:id="@+id/detail_more"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/detail_recomTitle"
android:layout_alignBottom="@id/detail_recomTitle"
android:layout_alignParentRight="true"
android:background="@null"
android:text="更多"
android:textAlignment="center"
android:textColor="@color/colorGrey"
android:textSize="12sp" />
<RadioGroup
android:id="@+id/detail_recomRG"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/detail_recomTitle"
android:orientation="horizontal"
android:weightSum="3">
<Button
android:id="@+id/detail_recom1"
android:layout_width="100dp"
android:layout_height="180dp"
android:layout_weight="1"
android:background="@null"
android:text=""
android:textSize="10sp" />
<Button
android:id="@+id/detail_recom2"
android:layout_width="100dp"
android:layout_height="180dp"
android:layout_marginRight="5dp"
android:layout_weight="1"
android:background="@null"
android:text=""
android:textSize="10sp" />
<Button
android:id="@+id/detail_recom3"
android:layout_width="100dp"
android:layout_height="180dp"
android:layout_weight="1"
android:background="@null"
android:text=""
android:textSize="10sp" />
</RadioGroup>
</RelativeLayout>
</LinearLayout>
</ScrollView>
<RadioGroup
android:id="@+id/detail_bottomRG"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent">
<RadioButton
android:id="@+id/detail_bottom_add"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/buttonstyle"
android:button="@null"
android:gravity="center"
android:padding="10dp"
android:text="加入书架"
android:textColor="@color/colorRed"
android:textSize="16sp" />
<RadioButton
android:id="@+id/detail_bottom_read"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/buttonstyle"
android:button="@null"
android:gravity="center"
android:padding="10dp"
android:text="免费阅读"
android:textColor="@color/colorRed"
android:textSize="16sp" />
</RadioGroup>
</android.support.constraint.ConstraintLayout>

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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=".Activity.CategoryActivity"
android:orientation="vertical"
android:background="#F7F7F7">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="40dp">
<ImageView
android:id="@+id/category_activity_back"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginStart="10dp"
android:layout_alignParentLeft="true"
android:layout_centerInParent="true"
android:src="@mipmap/back"
/>
<TextView
android:id="@+id/category_activity_title"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:text="热搜榜"
android:textSize="20sp"
android:textColor="#000000"
android:layout_centerInParent="true"
android:gravity="center"/>
</RelativeLayout>
<RadioGroup
android:id="@+id/category_activity_RG"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="10dp">
<RadioButton
android:id="@+id/category_activity_RB1"
style="@style/BottomRB"
android:layout_height="40dp"
android:text="周榜"
android:checked="true"/>
<RadioButton
android:id="@+id/category_activity_RB2"
style="@style/BottomRB"
android:layout_height="40dp"
android:text="月榜"/>
<RadioButton
android:id="@+id/category_activity_RB3"
style="@style/BottomRB"
android:layout_height="40dp"
android:text="总榜"/>
<RadioButton
android:id="@+id/category_activity_RB4"
style="@style/BottomRB"
android:layout_height="40dp"
android:text="完结"
android:visibility="gone"/>
</RadioGroup>
<android.support.v4.view.ViewPager
android:id="@+id/category_activity_viewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
</LinearLayout>

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Activity.MainActivity"
android:orientation="vertical"
android:background="#FFFFFF">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginTop="10dp">
<RadioGroup
android:id="@+id/main_top_RG"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_alignParentLeft="true"
android:layout_marginStart="10dp"
android:visibility="gone"
android:layout_alignParentBottom="true">
<RadioButton
android:id="@+id/main_top_male"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:button="@null"
android:drawableTop="@mipmap/male_blue"
android:checked="true"/>
<RadioButton
android:id="@+id/main_top_female"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:button="@null"
android:drawableTop="@mipmap/female_black" />
</RadioGroup>
<!--标题:书架/排行榜/分类-->
<TextView
android:id="@+id/main_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="书架"
android:textSize="20sp"
android:textColor="#030303"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"/>
<ImageView
android:id="@+id/main_search"
android:layout_width="20dp"
android:layout_height="20dp"
android:src="@mipmap/search"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginEnd="10dp"/>
</RelativeLayout>
<android.support.v4.view.ViewPager
android:id="@+id/main_viewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:overScrollMode="never"
android:scrollbars="none"/>
<RadioGroup
android:id="@+id/main_bottomRG"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RadioButton
android:id="@+id/main_bottom_bookshelf"
style="@style/BottomRB"
android:text="书架"
android:drawableTop="@mipmap/bookshelf"
android:checked="true"
/>
<RadioButton
android:id="@+id/main_bottom_ranking"
style="@style/BottomRB"
android:text="排行榜"
android:drawableTop="@mipmap/ranking"
/>
<RadioButton
android:id="@+id/main_bottom_category"
style="@style/BottomRB"
android:text="分类"
android:drawableTop="@mipmap/category"/>
</RadioGroup>
</LinearLayout>

@ -0,0 +1,98 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/read_page_whole_layout"
android:background="@color/PapayaWhip">
<android.support.v4.view.ViewPager
android:id="@+id/read_page_viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never"
android:layout_marginBottom="40sp" />
<!--底部UI-->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/activity_read_page_bottom_layout"
android:layout_alignParentBottom="true"
android:layout_marginBottom="10sp"
android:layout_marginLeft="20sp"
android:layout_marginRight="10sp">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/activity_read_page_battery_layout"
android:layout_centerVertical="true">
<ImageView
android:layout_width="30sp"
android:layout_height="10sp"
android:src="@mipmap/battery"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:id="@+id/activity_read_page_battery_percent"
android:text="87"
android:textSize="7sp"/>
</RelativeLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/activity_read_page_time"
android:text="11:15"
android:layout_toRightOf="@id/activity_read_page_battery_layout" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/activity_read_page_process"
android:text="1/8"
android:layout_alignParentRight="true" />
</RelativeLayout>
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/read_page_progressbar"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"/>
<RadioGroup
android:id="@+id/read_page_bottom_rg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_alignParentBottom="true"
android:clickable="false"
android:visibility="gone">
<RadioButton
android:id="@+id/read_page_day_and_night_rb"
style="@style/BottomRB"
android:text="夜间"
android:drawableTop="@mipmap/nighttime" />
<RadioButton
android:id="@+id/read_page_horizontal_and_vertical_rb"
style="@style/BottomRB"
android:text="横屏"
android:drawableTop="@mipmap/horizontal_screen" />
<RadioButton
android:id="@+id/read_page_setting_rb"
style="@style/BottomRB"
android:text="设置"
android:drawableTop="@mipmap/textsize" />
<!--<RadioButton
android:id="@+id/read_page_download_rb"
style="@style/BottomRB"
android:text="下载"
android:drawableTop="@mipmap/download"/>-->
<RadioButton
android:id="@+id/read_page_catalog_rb"
style="@style/BottomRB"
android:text="目录"
android:drawableTop="@mipmap/catalog"/>
</RadioGroup>
</RelativeLayout>

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical"
tools:context=".Activity.RecomActivity"
android:background="#FFFFFF">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:id="@+id/recom_RL">
<ImageView
android:id="@+id/recom_back"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginStart="10dp"
android:layout_alignParentLeft="true"
android:layout_centerInParent="true"
android:src="@mipmap/back"
/>
<TextView
android:id="@+id/recom_title"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:text="同类推荐"
android:textSize="20sp"
android:textColor="#000000"
android:layout_centerInParent="true"
android:gravity="center"/>
</RelativeLayout>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:id="@+id/recom_recyclerview"
android:layout_centerHorizontal="true">
</android.support.v7.widget.RecyclerView>
</LinearLayout>

@ -0,0 +1,295 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Activity.SearchActivity"
android:background="#FFFFFF">
<LinearLayout
android:id="@+id/search_afters_layout"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="invisible"
app:layout_constraintTop_toBottomOf="@+id/search_top_layout">
<ListView
android:id="@+id/search_fuzzy_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_marginTop="5dp"
android:divider="@null" />
<android.support.v7.widget.RecyclerView
android:id="@+id/search_result_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="1dp"
android:layout_marginBottom="60dp"
android:visibility="invisible" />
</LinearLayout>
<android.support.constraint.ConstraintLayout
android:id="@+id/search_initial_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@+id/search_top_layout">
<ImageView
android:id="@+id/search_n1_image"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_marginStart="15dp"
app:layout_constraintBottom_toBottomOf="@+id/search_pop_text1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/search_pop_text1"
app:srcCompat="@mipmap/number1" />
<ImageView
android:id="@+id/search_n2_image"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_marginStart="15dp"
app:layout_constraintBottom_toBottomOf="@+id/search_pop_text1"
app:layout_constraintStart_toEndOf="@+id/guideline3"
app:layout_constraintTop_toTopOf="@+id/search_pop_text1"
app:srcCompat="@mipmap/number2" />
<ImageView
android:id="@+id/search_n3_image"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_marginStart="15dp"
app:layout_constraintBottom_toBottomOf="@+id/search_pop_text2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/search_pop_text2"
app:srcCompat="@mipmap/number3" />
<ImageView
android:id="@+id/search_n4_image"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_marginStart="15dp"
app:layout_constraintBottom_toBottomOf="@+id/search_pop_text2"
app:layout_constraintStart_toEndOf="@+id/guideline3"
app:layout_constraintTop_toTopOf="@+id/search_pop_text2"
app:srcCompat="@mipmap/number4" />
<ImageView
android:id="@+id/search_n5_image"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_marginStart="15dp"
app:layout_constraintBottom_toBottomOf="@+id/search_pop_text3"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/search_pop_text3"
app:srcCompat="@mipmap/number5" />
<ImageView
android:id="@+id/search_n6_image"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_marginStart="15dp"
app:layout_constraintBottom_toBottomOf="@+id/search_pop_text3"
app:layout_constraintStart_toEndOf="@+id/guideline3"
app:layout_constraintTop_toTopOf="@+id/search_pop_text3"
app:srcCompat="@mipmap/number6" />
<ImageView
android:id="@+id/search_fresh_image"
android:layout_width="23dp"
android:layout_height="23dp"
android:layout_marginEnd="10dp"
app:layout_constraintBottom_toBottomOf="@+id/textView8"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/textView8"
app:srcCompat="@mipmap/fresh" />
<android.support.constraint.Guideline
android:id="@+id/guideline2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.2" />
<android.support.constraint.Guideline
android:id="@+id/guideline3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />
<ImageView
android:id="@+id/search_popular_image"
android:layout_width="23dp"
android:layout_height="23dp"
android:layout_marginStart="15dp"
android:layout_marginTop="18dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@mipmap/heatfire" />
<TextView
android:id="@+id/search_pop_text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="23dp"
android:text="天骄战纪"
android:textSize="15sp"
app:layout_constraintStart_toEndOf="@+id/search_n1_image"
app:layout_constraintTop_toBottomOf="@+id/textView8" />
<TextView
android:id="@+id/search_pop_text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="18dp"
android:text="最强狂兵"
android:textSize="15sp"
app:layout_constraintStart_toEndOf="@+id/search_n3_image"
app:layout_constraintTop_toBottomOf="@+id/search_pop_text1" />
<TextView
android:id="@+id/search_pop_text3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="18dp"
android:text="九星霸体诀"
android:textSize="15sp"
app:layout_constraintStart_toEndOf="@+id/search_n5_image"
app:layout_constraintTop_toBottomOf="@+id/search_pop_text2" />
<TextView
android:id="@+id/search_pop_text4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="23dp"
android:text="官梯"
android:textSize="15sp"
app:layout_constraintStart_toEndOf="@+id/search_n2_image"
app:layout_constraintTop_toBottomOf="@+id/textView8" />
<TextView
android:id="@+id/search_pop_text5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="18dp"
android:text="剑来"
android:textSize="15sp"
app:layout_constraintStart_toEndOf="@+id/search_n4_image"
app:layout_constraintTop_toBottomOf="@+id/search_pop_text4" />
<TextView
android:id="@+id/search_pop_text6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="18dp"
android:text="一世倾城"
android:textSize="15sp"
app:layout_constraintStart_toEndOf="@+id/search_n6_image"
app:layout_constraintTop_toBottomOf="@+id/search_pop_text5" />
<TextView
android:id="@+id/textView8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:text="大家都在搜"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="@+id/search_popular_image"
app:layout_constraintStart_toEndOf="@+id/search_popular_image"
app:layout_constraintTop_toTopOf="@+id/search_popular_image" />
<ImageView
android:id="@+id/search_history_image"
android:layout_width="23dp"
android:layout_height="23dp"
android:layout_marginStart="15dp"
android:layout_marginTop="32dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/search_pop_text3"
app:srcCompat="@mipmap/history" />
<TextView
android:id="@+id/search_history_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="30dp"
android:text="搜索历史"
android:textSize="18sp"
app:layout_constraintStart_toEndOf="@+id/search_history_image"
app:layout_constraintTop_toBottomOf="@+id/search_pop_text3" />
<ImageView
android:id="@+id/search_delete_image"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginEnd="22dp"
android:layout_marginTop="30dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/search_pop_text6"
app:srcCompat="@mipmap/delete" />
<ListView
android:id="@+id/search_history_list"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_marginTop="8dp"
android:divider="@null"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/search_history_image" />
</android.support.constraint.ConstraintLayout>
<android.support.constraint.ConstraintLayout
android:id="@+id/search_top_layout"
android:layout_width="0dp"
android:layout_height="42dp"
android:background="@android:color/holo_red_light"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<android.support.v7.widget.SearchView
android:id="@+id/search_search_searchView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="5dp"
android:layout_marginEnd="10dp"
android:layout_marginStart="5dp"
android:layout_marginTop="5dp"
android:background="@android:color/background_light"
app:defaultQueryHint="搜索作者或者书名"
app:iconifiedByDefault="false"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/search_cancel_text"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/search_cancel_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:text="取消"
android:textColor="?attr/colorBackgroundFloating"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>

@ -0,0 +1,32 @@
<?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:orientation="vertical">
<TextView
android:id="@+id/catalog_title"
android:layout_width="fill_parent"
android:layout_height="40sp"
android:text="圣墟"
android:textSize="20sp"
android:textColor="#000000"
android:gravity="center|center_horizontal"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/colorGrey"
android:id="@+id/catalog_line"
android:layout_marginBottom="5dp">
</View>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/catalog_recylerView">
</android.support.v7.widget.RecyclerView>
</LinearLayout>

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Fragment.CategoryFragment"
android:background="#F7F7F7">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20sp"
android:layout_marginRight="20sp"
android:layout_marginTop="10sp"
android:layout_marginBottom="10sp"
android:background="#F7F7F7">
<android.support.v7.widget.RecyclerView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/dialog_category_recyclerview"
android:layout_centerHorizontal="true">
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
</RelativeLayout>

@ -0,0 +1,44 @@
<?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="match_parent"
android:orientation="vertical">
<!--字体大小调整-->
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/dialog_text_setting_minus_imageview"
android:background="@drawable/buttonstyle"
android:src="@mipmap/minus"
android:layout_margin="10sp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="18"
android:gravity="center_horizontal"
android:textStyle="bold"
android:textSize="30sp"
android:layout_margin="10sp"
android:id="@+id/dialog_text_setting_textSize"
android:layout_toRightOf="@+id/dialog_text_setting_minus_imageview"
android:layout_toLeftOf="@+id/dialog_text_setting_plus_imageview"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/dialog_text_setting_plus_imageview"
android:background="@drawable/buttonstyle"
android:src="@mipmap/plus"
android:layout_margin="10sp"
android:layout_alignParentRight="true"/>
</RelativeLayout>
<!--字体间距调整-->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
</RelativeLayout>
</LinearLayout>

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Fragment.BookShelfFragment">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/fragment_book_shelf_recyclerview"
android:overScrollMode="never"
android:scrollbars="none">
</android.support.v7.widget.RecyclerView>
</FrameLayout>

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Fragment.CategoryFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RadioGroup
android:id="@+id/category_RG"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<RadioButton
android:id="@+id/category_RB_male"
style="@style/BottomRB"
android:layout_height="40dp"
android:text="男生"
android:checked="true"/>
<RadioButton
android:id="@+id/category_RB_female"
style="@style/BottomRB"
android:layout_height="40dp"
android:text="女生"/>
</RadioGroup>
<android.support.v4.view.ViewPager
android:id="@+id/category_viewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:overScrollMode="never"
android:scrollbars="none">
</android.support.v4.view.ViewPager>
</LinearLayout>
</FrameLayout>

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Fragment.DetailCategoryFragment"
android:background="#FFFFFF">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
android:id="@+id/detail_category_progressBar"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerInParent="true"
android:visibility="visible"
style="?android:attr/progressBarStyleLargeInverse"
/>
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/detail_category_swipeRefresh"
android:layout_height="match_parent"
android:layout_width="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/detail_category_recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:overScrollMode="never"/>
</android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>
</FrameLayout>

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Fragment.MaleInCategoryFragment"
android:background="#F7F7F7">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/fragment_male_in_category_recyclerview"
android:overScrollMode="never">
</android.support.v7.widget.RecyclerView>
</FrameLayout>

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Fragment.RankingFragment">
<android.support.v7.widget.RecyclerView
android:id="@+id/ranking_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:overScrollMode="never"
android:layout_margin="5dp"/>
</FrameLayout>

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Fragment.ReadPageFragment"
android:id="@+id/fragment_read_page_whole_layout"
android:background="@color/nightBackGround">
<!-- TODO: Update blank fragment layout -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10sp"
android:layout_marginBottom="10sp"
android:layout_marginLeft="20sp"
android:layout_marginRight="10sp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/fragment_read_page_title"
android:text="第一章 沙漠中的彼岸花"
android:textSize="12sp"/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/fragment_read_page_title"
android:layout_marginTop="10sp"
android:overScrollMode="never"
android:scrollbars="none">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/fragment_read_page_content"
android:text="大漠孤烟直,长河落日圆。\n一望无垠的大漠空旷而高远壮阔而雄浑当红日西坠地平线尽头一片殷红磅礴中亦有种苍凉感。\n上古的烽烟早已在岁月中逝去黄河古道虽然几经变迁但依旧在。\n楚风一个人在旅行很疲惫他躺在黄沙上看着血色的夕阳不知道还要多久才能离开这片大漠。\n数日前他毕业了同时也跟校园中的女神说再见或许见不到了吧毕竟他曾被委婉的告知从此天各一方该分手了。\n离开学院后他便出来旅行。\n落日很红挂在大漠的尽头在空旷中有一种宁静的美。\n楚风坐起来喝了一些水感觉精力恢复了不少他的身体属于修长强健那一类型体质非常好疲惫渐消退。\n站起来眺望他觉得快要离开大漠了再走一段路程或许就会见到牧民的帐篷他决定继续前行。\n一路西进他在大漠中留下一串很长、很远"
android:textSize="18sp"
android:textColor="@color/bookItemNameColor"
android:lineSpacingExtra="5dp"/>
</ScrollView>
</RelativeLayout>
</FrameLayout>

@ -0,0 +1,103 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="20sp"
android:background="#FFFFFF">
<ImageView
android:layout_width="70sp"
android:layout_height="100sp"
android:scaleType="fitXY"
android:id="@+id/item_book_cover"
android:src="@mipmap/bookcover"
android:layout_centerVertical="true"/>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/item_book_text_info_relativelayout"
android:layout_toRightOf="@+id/item_book_cover"
android:layout_marginLeft="20sp"
android:layout_centerVertical="true">
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:id="@+id/item_book_rankingImg"
android:src="@mipmap/first"
android:layout_marginRight="10dp"
android:visibility="gone"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/item_book_name"
android:text="圣墟"
android:textSize="15sp"
android:textColor="@color/bookItemNameColor"
android:layout_toRightOf="@id/item_book_rankingImg"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/item_book_author_and_type_linearlayout"
android:layout_below="@+id/item_book_name"
android:layout_marginTop="5sp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/item_book_author"
android:text="辰东"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/item_vertical_line"
android:text="|"
android:layout_toEndOf="@id/item_book_author"
android:layout_marginLeft="10sp"
android:layout_marginRight="10sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/item_book_type"
android:text="玄幻"/>
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/item_book_intro"
android:layout_below="@id/item_book_author_and_type_linearlayout"
android:textSize="12sp"
android:layout_marginTop="5sp"
android:text="在破败中崛起,在寂灭中复苏。沧海成尘,雷电枯竭,那一缕幽雾有一次临近大地,..."/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/item_book_followers"
android:text="12万人追"
android:textSize="10sp"
android:layout_marginTop="5dp"
android:layout_below="@id/item_book_intro"
android:textColor="#4fa5d5"
android:background="@drawable/textview_border_blue"
android:visibility="gone"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/item_book_retention"
android:text="48.72%留存率"
android:textSize="10sp"
android:layout_toRightOf="@id/item_book_followers"
android:layout_below="@id/item_book_intro"
android:layout_marginStart="10dp"
android:layout_marginTop="5dp"
android:textColor="#90F790"
android:background="@drawable/textview_border_green"
android:visibility="gone"/>
</RelativeLayout>
</RelativeLayout>

@ -0,0 +1,29 @@
<?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:orientation="horizontal"
android:layout_marginTop="10sp"
android:layout_marginBottom="10sp">
<ImageView
android:layout_width="15sp"
android:layout_height="15sp"
android:id="@+id/catalog_icon"
android:src="@mipmap/catalog_icon"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_gravity="center_vertical"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/catalog_title"
android:text="正问卷 第1305章 一幅斑驳画卷贯穿古今"
android:singleLine="true"
android:maxEms="12"
android:ellipsize="end"
android:textSize="15sp"/>
</LinearLayout>

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50sp"
android:layout_margin="10sp">
<RelativeLayout
android:layout_width="150sp"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:background="#FFFFFF">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/item_category_name"
android:layout_margin="10sp"
android:text="玄幻"
android:textStyle="bold"
android:textSize="15sp"
android:textColor="#2B2B2B" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/item_category_count"
android:layout_toRightOf="@+id/item_category_name"
android:layout_centerVertical="true"
android:layout_margin="5sp"
android:text="(17万本)"
android:textSize="13sp" />
</RelativeLayout>
</RelativeLayout>
</RelativeLayout>

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="30dp"
android:layout_marginBottom="5dp"
android:layout_marginStart="15dp"
android:layout_marginTop="5dp"
android:text="TextView"
android:textAllCaps="false"
android:textColor="#A9A9A9"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="52dp"
android:layout_marginBottom="5dp"
android:layout_marginStart="15dp"
android:layout_marginTop="5dp"
android:text="TextView"
android:textAllCaps="false"
android:textSize="21sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:cardCornerRadius="20dp"
app:cardElevation="10dp"
android:layout_margin="10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<RelativeLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#EEEEEE">
<ImageView
android:id="@+id/ranking_item_image"
android:layout_width="50dp"
android:layout_height="70dp"
android:src="@mipmap/male_icon1"
android:layout_centerInParent="true"/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/ranking_item_right"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:background="#FFAEB9">
<TextView
android:id="@+id/ranking_item_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="最热榜"
android:textSize="18sp"
android:textColor="#000000"
android:layout_centerInParent="true"/>
</RelativeLayout>
</LinearLayout>
</android.support.v7.widget.CardView>

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true">
<ProgressBar
android:id="@+id/footer_view_progessBar"
android:layout_width="30dp"
android:layout_height="30dp"
android:visibility="gone"
style="?android:attr/progressBarStyleLargeInverse"/>
<TextView
android:id="@+id/footer_view_text"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_marginStart="20dp"
android:text="数据加载中"
android:layout_gravity="center"
android:visibility="gone"/>
</LinearLayout>
</RelativeLayout>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

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

Loading…
Cancel
Save