main
lihang_ch01 4 months ago
parent 2da7826712
commit e3f10f7ecd

@ -0,0 +1,15 @@
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties

@ -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,407 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DBNavigator.Project.DatabaseFileManager">
<open-files />
</component>
<component name="DBNavigator.Project.ParserDiagnosticsManager">
<diagnostics-history />
</component>
<component name="DBNavigator.Project.Settings">
<connections />
<browser-settings>
<general>
<display-mode value="TABBED" />
<navigation-history-size value="100" />
<show-object-details value="false" />
<enable-sticky-paths value="true" />
</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" />
<exit-on-changes value="ASK" />
</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>
</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,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetDropDown">
<targetSelectedWithDropDown>
<Target>
<type value="QUICK_BOOT_TARGET" />
<deviceKey>
<Key>
<type value="VIRTUAL_DEVICE_PATH" />
<value value="C:\Users\LH\.android\avd\Pixel_3a_API_33_x86_64.avd" />
</Key>
</deviceKey>
</Target>
</targetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2025-04-20T13:01:29.217614900Z" />
</component>
</project>

@ -0,0 +1,21 @@
<?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="gradleJvm" value="17" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DesignSurface">
<option name="filePathToZoomLevelMap">
<map>
<entry key="..\:/Applacation/Android/RommteStory/app/src/main/res/drawable/bg_boarder.xml" value="0.1" />
<entry key="..\:/Applacation/Android/RommteStory/app/src/main/res/layout/activity_main.xml" value="0.1" />
<entry key="..\:/Applacation/Android/RommteStory/app/src/main/res/layout/activity_story.xml" value="0.1" />
<entry key="..\:/Applacation/Android/RommteStory/app/src/main/res/layout/add_memo_activity_layout.xml" value="0.1" />
<entry key="..\:/Applacation/Android/RommteStory/app/src/main/res/layout/fragment_dashboard.xml" value="0.1" />
<entry key="..\:/Applacation/Android/RommteStory/app/src/main/res/layout/fragment_detail.xml" value="0.1" />
<entry key="..\:/Applacation/Android/RommteStory/app/src/main/res/layout/fragment_home.xml" value="0.1" />
<entry key="..\:/Applacation/Android/RommteStory/app/src/main/res/layout/fragment_honor.xml" value="0.15" />
<entry key="..\:/Applacation/Android/RommteStory/app/src/main/res/layout/fragment_memo.xml" value="0.1" />
<entry key="..\:/Applacation/Android/RommteStory/app/src/main/res/layout/fragment_mine.xml" value="0.25" />
<entry key="..\:/Applacation/Android/RommteStory/app/src/main/res/layout/fragment_notifications.xml" value="0.1" />
<entry key="..\:/Applacation/Android/RommteStory/app/src/main/res/layout/honor_img.xml" value="0.1" />
<entry key="..\:/Applacation/Android/RommteStory/app/src/main/res/layout/honor_item.xml" value="0.1" />
<entry key="..\:/Applacation/Android/RommteStory/app/src/main/res/layout/item_listview.xml" value="0.1" />
<entry key="..\:/Applacation/Android/RommteStory/app/src/main/res/layout/top_part_04.xml" value="0.1" />
<entry key="..\:/Applacation/Android/RommteStory/app/src/main/res/layout/top_part_2.xml" value="0.1" />
<entry key="..\:/Applacation/Android/RommteStory/app/src/main/res/menu/bottom_nav_menu.xml" value="0.1" />
<entry key="..\:/Applacation/Android/RommteStory/app/src/main/res/menu/bottom_nav_menu_main.xml" value="0.3109375" />
<entry key="..\:/Applacation/Android/RommteStory/app/src/main/res/menu/menu_sub.xml" value="0.3109375" />
<entry key="..\:/Applacation/Android/RommteStory/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml" value="0.2815" />
<entry key="..\:/Users/LH/Desktop/android/RommteStory/app/src/main/res/layout/add_memo_activity_layout.xml" value="0.16847826086956522" />
<entry key="..\:/Users/LH/Desktop/android/RommteStory/app/src/main/res/layout/fragment_detail.xml" value="0.15443840579710144" />
<entry key="..\:/Users/LH/Desktop/android/RommteStory/app/src/main/res/layout/fragment_honor.xml" value="0.16847826086956522" />
<entry key="..\:/Users/LH/Desktop/android/RommteStory/app/src/main/res/layout/fragment_memo.xml" value="0.16847826086956522" />
<entry key="..\:/Users/LH/Desktop/android/RommteStory/app/src/main/res/layout/honor_img.xml" value="0.16847826086956522" />
<entry key="..\:/Users/LH/Desktop/android/RommteStory/app/src/main/res/layout/honor_item.xml" value="0.16847826086956522" />
<entry key="..\:/Users/LH/Desktop/android/RommteStory/app/src/main/res/layout/memo_item.xml" value="0.16847826086956522" />
<entry key="..\:/Users/LH/Desktop/android/RommteStory/app/src/main/res/layout/top_part_2.xml" value="0.16847826086956522" />
</map>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="11" 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,58 @@
plugins {
id 'com.android.application'
}
android {
compileSdk 32
defaultConfig {
applicationId "com.lh.app"
minSdk 21
targetSdk 32
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildFeatures {
viewBinding true
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
implementation 'androidx.navigation:navigation-fragment:2.3.5'
implementation 'androidx.navigation:navigation-ui:2.3.5'
implementation 'com.google.android.gms:play-services-location:18.0.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
//noinspection GradleCompatible
implementation 'androidx.recyclerview:recyclerview:1.2.1'//RecycleView
//
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
implementation 'com.google.android.gms:play-services-location:21.0.1'
//
implementation 'com.github.bumptech.glide:glide:4.15.1' // 使
annotationProcessor 'com.github.bumptech.glide:compiler:4.15.1'
//
implementation 'com.amap.api:3dmap-location-search:latest.integration'
}

@ -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,26 @@
package com.lh.app;
import android.content.Context;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.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.getInstrumentation().getTargetContext();
assertEquals("com.lh.app", appContext.getPackageName());
}
}

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.lh.app">
<!--允许程序读写手机状态和身份-->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- 获取手机外部存储读写权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!-- 手机照片访问权限 -->
<uses-permission android:name="android.permission.CAMERA"/>
<!-- 地图权限 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<!-- 定位权限 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- 高德地图Key配置 -->
<meta-data
android:name="com.amap.api.v2.apikey"
android:value="93c4ba27c64acc7adc4f22b3576a345f" />
<application
android:name=".MyApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:hardwareAccelerated="true"
android:screenOrientation="portrait"
android:theme="@style/Theme.RommteStory">
<activity
android:name=".ui.memo.Story_activity"
android:windowSoftInputMode="adjustPan"
android:exported="false" />
<activity
android:name=".ui.memo.AddMemo_activity"
android:exported="false" />
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

@ -0,0 +1,182 @@
package com.lh.app;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import com.lh.app.ui.honor.HonorFragment;
import com.lh.app.ui.detail.DetailFragment;
import com.lh.app.ui.memo.MemoFragment;
import com.lh.app.ui.mine.MineFragment;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.viewpager.widget.ViewPager;
import com.lh.app.databinding.ActivityMainBinding;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private ActivityMainBinding binding;
BottomNavigationView navView;
private ViewPager mViewPager;
//设置顶部菜单栏
ActionBar actionBar;
//
public static boolean isShowViewPage_memo = false;
public static boolean isShowViewPage_honor = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("MainActivity","onCreate");
actionBar = getSupportActionBar();
assert actionBar != null;
actionBar.setTitle(R.string.title_detail);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
addUi();
addUiListener();
initPageAdapter();
}
@Override
protected void onStart() {
super.onStart();
if(isShowViewPage_memo){
mViewPager.setCurrentItem(1);
isShowViewPage_memo = false;
}
if(isShowViewPage_honor){
mViewPager.setCurrentItem(2);
isShowViewPage_honor = false;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d("MainActivity","onDestroy");
}
//添加组件及变量声明
private void addUi() {
navView = findViewById(R.id.nav_view);
mViewPager = findViewById(R.id.mViewPager);
}
//初始化页面监听器
private void initPageAdapter() {
//Fragment列表将fragment放入列表中放入mPagerAdapter
final ArrayList<Fragment> fgLists = new ArrayList<>(4);
fgLists.add(new DetailFragment());
fgLists.add(new MemoFragment());
fgLists.add(new HonorFragment());
fgLists.add(new MineFragment());
FragmentPagerAdapter mPagerAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) {
@Override
public Fragment getItem(int position) {
return fgLists.get(position);
}
@Override
public int getCount() {
return fgLists.size();
}
};
mViewPager.setAdapter(mPagerAdapter);
//设置预加载页面数量的方法
mViewPager.setOffscreenPageLimit(1);
}
//添加组件监听器
private void addUiListener() {
navView.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
mViewPager.addOnPageChangeListener(onPageChangeListener);
}
//底部导航栏监听器
@SuppressLint("NonConstantResourceId")
private final BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener = new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
// 清除之前的选中状态
Menu menu = navView.getMenu();
for (int i = 0; i < menu.size(); i++) {
MenuItem menuItem = menu.getItem(i);
menuItem.setChecked(false);
}
switch (item.getItemId()) {
case R.id.navigation_detail:
mViewPager.setCurrentItem(0);
item.setChecked(true);
break;
case R.id.navigation_memo:
mViewPager.setCurrentItem(1);
item.setChecked(true);
break;
case R.id.navigation_communicate:
mViewPager.setCurrentItem(2);
item.setChecked(true);
break;
case R.id.navigation_mine:
mViewPager.setCurrentItem(3);
item.setChecked(true);
break;
}
return false;
}
};
//页面改变监听器
private final ViewPager.OnPageChangeListener onPageChangeListener = new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
//在滑动中
}
@Override
public void onPageSelected(int position) {
actionBar.setDisplayHomeAsUpEnabled(false);
//写滑动页面后做的事使每一个fragment与一个page相对应
switch (position) {
case 0:
navView.setSelectedItemId(R.id.navigation_detail);
actionBar.setTitle(R.string.title_detail);
break;
case 1:
navView.setSelectedItemId(R.id.navigation_memo);
actionBar.setTitle(R.string.title_memo);
break;
case 2:
navView.setSelectedItemId(R.id.navigation_communicate);
actionBar.setTitle(R.string.title_honor);
break;
case 3:
navView.setSelectedItemId(R.id.navigation_mine);
actionBar.setTitle(R.string.title_mine);
break;
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
};
}

@ -0,0 +1,53 @@
package com.lh.app;
import android.app.Application;
import android.content.res.Configuration;
import android.util.Log;
import androidx.annotation.NonNull;
import java.util.HashMap;
/**
* Created by on .
*/
public class MyApplication extends Application {
private static MyApplication mApp;
//声明一个公共的信息映射对象,可当全局变量使用
public HashMap<String, String> infoMap = new HashMap<>();
public static RoommateDBHelper mHelper;
//得到Application唯一实例
public static MyApplication getInstance(){
return mApp;
}
//在App启用时调用
@Override
public void onCreate() {
super.onCreate();
mApp = this;
Log.d("ning","MyApplication onCreate");
mHelper = RoommateDBHelper.getInstance(this);
//打开数据库帮助器读写连接
mHelper.openWriteLink();
mHelper.openReadLink();
}
//在App终止时调用
@Override
public void onTerminate() {
super.onTerminate();
Log.d("ning","MyApplication onTerminate");
//关闭数据库连接
mHelper.closeLink();
}
//配置改变时被调用,如:横屏变竖屏
@Override
public void onConfigurationChanged(@NonNull Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.d("ning","MyApplication onConfigurationChanged");
}
}

@ -0,0 +1,360 @@
package com.lh.app;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import com.lh.app.ui.detail.Roommate;
import com.lh.app.ui.honor.Honor;
import com.lh.app.ui.memo.Memo;
import java.util.ArrayList;
import java.util.List;
public class RoommateDBHelper extends SQLiteOpenHelper {
private static final String DB_NAME = "roommate.db";
private static final int DB_VERSION = 1;
private static final String TABLE_NAME_ROOMMATE_INFO = "roommate_info";//舍友信息表
private static final String TABLE_NAME_ROOMMATE_MEMO = "roommate_memo";//舍友备忘录表
private static final String TABLE_NAME_ROOMMATE_HONOR = "roommate_honor";//舍友大事记表
private static RoommateDBHelper mHelper = null;
private SQLiteDatabase mRDB = null;//钥匙,用来读
private SQLiteDatabase mWDB = null;//钥匙,用来写
private RoommateDBHelper(Context context){
//向父类方法传参,上下文、数据库名、游标、版本号
super(context,DB_NAME,null,DB_VERSION);
}
//利用单例模式去获取数据库帮助库的唯一实例
public static RoommateDBHelper getInstance(Context context){
if (mHelper==null){
mHelper = new RoommateDBHelper(context);
}
return mHelper;
}
public static String getTableNameRoommateInfo() {
return TABLE_NAME_ROOMMATE_INFO;
}
public static String getTableNameRoommateMemo() {
return TABLE_NAME_ROOMMATE_MEMO;
}
//打开数据库的读连接
public SQLiteDatabase openReadLink(){
if (mRDB==null||!mRDB.isOpen()){
mRDB = mHelper.getReadableDatabase();
}
return mRDB;
}
//打开数据库的写连接
public SQLiteDatabase openWriteLink(){
if (mWDB==null||!mWDB.isOpen()){
mWDB = mHelper.getWritableDatabase();
}
return mWDB;
}
//关闭数据库连接
public void closeLink(){
//关闭读链接
if (mRDB!=null&&mRDB.isOpen()){
mRDB.close();
mRDB = null;
}
//关闭写连接
if (mWDB!=null&&mWDB.isOpen()){
mWDB.close();
mWDB = null;
}
}
//创建数据库,执行建表语句
@Override
public void onCreate(SQLiteDatabase db) {
//建表语句
String sql_01 = "create table if not exists "+ TABLE_NAME_ROOMMATE_INFO +" (" +
"_id integer primary key autoincrement not null," +
"name varchar not null," +
"id varchar not null,"+
"height long not null," +
"weight float not null," +
"married integer not null,"+
"birthday varchar not null,"+
"hobby varchar not null,"+
"position integer not null);";//记录在屏幕上位置
String sql_02 = "create table if not exists "+ TABLE_NAME_ROOMMATE_MEMO +" (" +
"_id integer primary key autoincrement not null," +
"name varchar not null," +
"title varchar not null," +
"content varchar not null," +
"date varchar not null,"+
"isDelete int not null,"+//是否是被删除记录(是1否0)
"isRevise int not null);";//是否是被修改记录(是1否0)
String sql_03 = "create table if not exists "+ TABLE_NAME_ROOMMATE_HONOR +" (" +
"_id integer primary key autoincrement not null," +
"imagePath varchar not null," +
"content varchar not null);";//是否是被修改记录(是1否0)
//建表
db.execSQL(sql_01);
db.execSQL(sql_02);
db.execSQL(sql_03);
}
//数据库版本变化时执行
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
/* String sql = "alter table "+ TABLE_NAME_ROOMMATE_INFO +" add column phone varchar;";
db.execSQL(sql);*/
}
/**
*
* */
//向指定表中添加一行数据
public long insert(String table_name,ContentValues values){
if (table_name.equals(TABLE_NAME_ROOMMATE_INFO) || table_name.equals(TABLE_NAME_ROOMMATE_MEMO))
//若第三个参数values不为null,并且元素个数大于0可以吧第二个参数置为null
//返回行号,若为-1,表示添加失败
return mWDB.insert(table_name,null,values);
else return -1;
}
/**
*
* */
//通过名字删除舍友信息表数据
public long deleteByName(String name){
//返回删除的行数
return mWDB.delete(TABLE_NAME_ROOMMATE_INFO,"name=?",new String[]{name});
//mWDB.delete(TABLE_NAME,"name=? and age=?",new String[]{name,age});
}
//清空指定表内容
public long deleteAll(String table_name){
//删除所有,返回删除的行数
return mWDB.delete(table_name,"1=1",null);
}
//删除舍友备忘录表中指定数据
public long deleteMemoByType(Memo memo, boolean isDelete, boolean isRevise){
String name = memo.getName();
String title = memo.getTitle();
String content = memo.getContent();
String date = memo.getDate();
String INT_isDelete = isDelete?"1":"0";
String INT_isRevise = isRevise?"1":"0";
//返回删除的行数
return mWDB.delete(TABLE_NAME_ROOMMATE_MEMO,
"name=? and title=? and content=? and date=? and isDelete=? and isRevise=?",
new String[]{name,title,content,date,INT_isDelete,INT_isRevise});
}
//删除舍友备忘录中指定类型全部数据
public long deleteMemoAllType(boolean isDelete,boolean isRevise){
String INT_isDelete = isDelete?"1":"0";
String INT_isRevise = isRevise?"1":"0";
//返回删除的行数
return mWDB.delete(TABLE_NAME_ROOMMATE_MEMO, "isDelete=? and isRevise=?", new String[]{INT_isDelete,INT_isRevise});
}
/**
*
* */
//更新室友表中数据
public long update_roommateInfo(ContentValues values,String name){
//返回更改的行数
return mWDB.update(TABLE_NAME_ROOMMATE_INFO,values,"name=?",new String[]{name});
}
//更新室友备忘录中显示数据的状态
public long update_roommateMemo(Memo memo,boolean isDelete,boolean isRevise){
ContentValues values = new ContentValues();
values.put("name",memo.getName());
values.put("title",memo.getTitle());
values.put("content",memo.getContent());
values.put("date",memo.getDate());
values.put("isDelete", isDelete);
values.put("isRevise", isRevise);
//返回更改的行数
return mWDB.update(TABLE_NAME_ROOMMATE_MEMO,values,
"name=? and title=? and content=? and date=? and isDelete=? and isRevise=?",
new String[]{memo.getName(),memo.getTitle(),memo.getContent(),memo.getDate(),"0","0"});
}
//更新室友备忘录中显示数据的状态为被删除
public void update_roommateAllMemoToDelete(){
//先查询备忘录中显示的数据
List<Memo> memoList = query_roommateMemoByType(false,false);
//循环遍历列表,将其类型改为删除
for (Memo memo:memoList){
long row = update_roommateMemo(memo,true,false);
Log.d("UpdateMemoTable","删除备忘录"+row+"条");
}
}
/**
*
* */
//查询室友信息全部数据
public List<Roommate> query_roommateInfo_All(){
List<Roommate> list = new ArrayList<>();
//返回结果集的游标
Cursor cursor = mRDB.query(TABLE_NAME_ROOMMATE_INFO,null,null,null,null,null,null);
//循环取出游标指向的每条数据
while (cursor.moveToNext()){
Roommate roommate = new Roommate();
roommate.setName(cursor.getString(1));
roommate.setId(cursor.getString(2));
roommate.setHeight(cursor.getLong(3));
roommate.setWeight(cursor.getFloat(4));
//Sqlite没有布尔类型用0表示false,用1表示true
roommate.setMarried(cursor.getInt(5) != 0);
roommate.setBirthday(cursor.getString(6));
roommate.setHobby(cursor.getString(7));
list.add(roommate);
}
cursor.close();
return list;
}
//返回舍友信息表中所有舍友姓名列表
public List<String> query_roommateName(){
List<String> list = new ArrayList<>();
//返回结果集的游标
Cursor cursor = mRDB.query(TABLE_NAME_ROOMMATE_INFO, new String[]{"name"},null,null,null,null,null);
//循环取出游标指向的每条数据
while (cursor.moveToNext()){
String name;
name = cursor.getString(0);
list.add(name);
}
cursor.close();
return list;
}
//通过名字查询指定室友信息数据
public Roommate query_roommateInfo_ByName(String name){
Roommate roommate = new Roommate();
//返回结果集的游标
Cursor cursor = mRDB.query(TABLE_NAME_ROOMMATE_INFO,null,
"name=?",new String[]{name},
null,null,null);
//循环取出游标指向的每条数据
while (cursor.moveToNext()){
roommate.setName(cursor.getString(1));
roommate.setId(cursor.getString(2));
roommate.setHeight(cursor.getLong(3));
roommate.setWeight(cursor.getFloat(4));
//Sqlite没有布尔类型用0表示false,用1表示true
roommate.setMarried(cursor.getInt(5) != 0);
roommate.setBirthday(cursor.getString(6));
roommate.setHobby(cursor.getString(7));
}
cursor.close();
return roommate;
}
//返回室友信息表是否为空
public Boolean query_roommateInfo_isEmpty(){
List<Roommate> list = new ArrayList<>();
//返回结果集的游标
Cursor cursor = mRDB.query(TABLE_NAME_ROOMMATE_INFO,null,null,null,null,null,null);
if (cursor.getCount()==0) return true;
cursor.close();
return false;
}
//查询室友名在屏幕上位置
public int query_roommate_position(String name){
//返回结果集的游标
Cursor cursor = mRDB.query(TABLE_NAME_ROOMMATE_INFO,new String[]{"position"},
"name=?",new String[]{name}, null,null,null);
//使游标移到第一个位置
cursor.moveToFirst();
return cursor.getInt(0);
}
//查询室友备忘录中指定类型数据
//参数(1,1)表示:查询被修改过的数据;(1,0)表示:查询被删除数据:(0,0)表示:查询要显示的数据;(0,1)表示:查询增加数据
public List<Memo> query_roommateMemoByType(boolean isDelete,boolean isRevise){
List<Memo> list = new ArrayList<>();
String INT_isDelete = isDelete?"1":"0";
String INT_isRevise = isRevise?"1":"0";
//返回结果集的游标
Cursor cursor = mRDB.query(TABLE_NAME_ROOMMATE_MEMO,null,"isDelete=? and isRevise=?",new String[]{INT_isDelete,INT_isRevise},null,null,null);
//循环取出游标指向的每条数据
while (cursor.moveToNext()){
Memo memo = new Memo(cursor.getString(1),cursor.getString(2),
cursor.getString(3),cursor.getString(4));
list.add(memo);
}
cursor.close();
return list;
}
//查询室友备忘录指定数据
public Memo query_roommateMemo_ByDate(String name,String title,String content,String date){
Memo memo = null;
//返回结果集的游标
Cursor cursor = mRDB.query(TABLE_NAME_ROOMMATE_MEMO,null,
"name=? title=? and content=? and date=?",new String[]{name,title,content,date},
null,null,null);
//循环取出游标指向的每条数据
while (cursor.moveToNext()){
memo = new Memo(cursor.getString(1),cursor.getString(2),
cursor.getString(3),cursor.getString(4));
}
cursor.close();
return memo;
}
//查询备忘录指定类型行数
//参数(1,1)表示:查询被修改过的数据;(1,0)表示:查询被删除数据:(0,0)表示:查询要显示的数据;(0,1)表示:查询增加数据
public int query_roommateMemo_rowsNumByType(boolean isDelete, boolean isRevise){
List<Memo> list = new ArrayList<>();
String INT_isDelete = isDelete?"1":"0";
String INT_isRevise = isRevise?"1":"0";
//返回结果集的游标
Cursor cursor = mRDB.query(TABLE_NAME_ROOMMATE_MEMO,null,"isDelete=? and isRevise=?",new String[]{INT_isDelete,INT_isRevise},null,null,null);
//循环取出游标指向的每条数据
while (cursor.moveToNext()){
Memo memo = new Memo(cursor.getString(1),cursor.getString(2),
cursor.getString(3),cursor.getString(4));
list.add(memo);
}
cursor.close();
return list.size();
}
/**
*
* */
//插入大事记表数据
public long insert_honor(Honor honor){
ContentValues values = new ContentValues();
values.put("imagePath",honor.getImageLocation());
values.put("content",honor.getContent());
//若第三个参数values不为null,并且元素个数大于0可以吧第二个参数置为null
//返回行号,若为-1,表示添加失败
return mWDB.insert(TABLE_NAME_ROOMMATE_HONOR,null,values);
}
//查询大事记全部数据
public List<Honor> query_honor_All(){
List<Honor> honorList = new ArrayList<>();
//返回结果集的游标
Cursor cursor = mRDB.query(TABLE_NAME_ROOMMATE_HONOR,null,null,null,null,null,null);
//循环取出游标指向的每条数据
while (cursor.moveToNext()){
Honor honor = new Honor();
honor.setImageLocation(cursor.getString(1));
honor.setContent(cursor.getString(2));
honorList.add(honor);
}
cursor.close();
return honorList;
}
//删除大事记指定数据
public long delete_honorByLocation(String imagePath){
return mWDB.delete(TABLE_NAME_ROOMMATE_HONOR, "imagePath=?", new String[]{imagePath});
}
}

@ -0,0 +1,75 @@
package com.lh.app.tool;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatImageView;
public class CircleImageView extends AppCompatImageView {
//画笔
private Paint mPaint;
//圆形图片的半径
private int mRadius;
//图片的宿放比例
private float mScale;
public CircleImageView(Context context) {
super(context);
}
public CircleImageView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public CircleImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//由于是圆形,宽高应保持一致
int size = Math.min(getMeasuredWidth(), getMeasuredHeight());
mRadius = size / 2;
setMeasuredDimension(size, size);
}
@SuppressLint("DrawAllocation")
@Override
protected void onDraw(Canvas canvas) {
mPaint = new Paint();
Drawable drawable = getDrawable();
if (null != drawable) {
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
//初始化BitmapShader传入bitmap对象
BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
//计算缩放比例
mScale = (mRadius * 2.0f) / Math.min(bitmap.getHeight(), bitmap.getWidth());
Matrix matrix = new Matrix();
matrix.setScale(mScale, mScale);
bitmapShader.setLocalMatrix(matrix);
mPaint.setShader(bitmapShader);
//画圆形,指定好坐标,半径,画笔
canvas.drawCircle(mRadius, mRadius, mRadius, mPaint);
} else {
super.onDraw(canvas);
}
}
}

@ -0,0 +1,112 @@
package com.lh.app.tool;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.provider.MediaStore;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class ImageUtils {
//uri转bitmap
public static Bitmap uriToBitmap(Context context, Uri uri){
if (uri == null) return null;
Bitmap bitmap = null;
try {
// decodeStream()可以将output_image.jpg解析成Bitmap对象。
bitmap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return bitmap;
}
public static String getRealPathFromUri(Context context, Uri uri) {
if (uri == null) {
return null;
}
// 检查Uri是否是文件类型的Uri
if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
// 检查Uri是否是Content类型的Uri
if ("content".equalsIgnoreCase(uri.getScheme())) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(uri, projection, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
return cursor.getString(columnIndex);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null) {
cursor.close();
}
}
}
return null;
}
public static Bitmap stringToBitmap(String filePath) {
if (filePath == null || filePath.isEmpty()) {
return null;
}
File file = new File(filePath);
if (!file.exists()) {
return null;
}
return BitmapFactory.decodeFile(filePath);
}
/***
* Bitmap
* @param filePath
* @return Bitmap
*/
public static Bitmap loadBitmapFromPath(String filePath) {
// 创建一个文件对象
File imageFile = new File(filePath);
// 检查文件是否存在
if (imageFile.exists()) {
// 从文件路径加载 Bitmap
return BitmapFactory.decodeFile(imageFile.getAbsolutePath());
} else {
// 文件不存在,返回 null 或者处理错误
return null;
}
}
// 临时创建图片文件
public static File createImageFile(Context context) {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
String fileName = "JPEG_" + timeStamp + ".jpg";
File storageDir = context.getExternalCacheDir(); // 使用缓存目录,避免申请存储权限
File photoFile = new File(storageDir, fileName);
try {
if (photoFile.createNewFile()) {
return photoFile;
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
//根据路径读取图片
public static Bitmap getBitmapFromPath(String path){
Bitmap bitmap = BitmapFactory.decodeFile(path);
return bitmap;
}
}

@ -0,0 +1,263 @@
package com.lh.app.tool;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Description;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.LimitLine;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
/**
*
*/
public class LineChartManager {
private LineChart lineChart;
private YAxis leftAxis;
private YAxis rightAxis;
private XAxis xAxis;
private LineData lineData;
private LineDataSet lineDataSet;
private List<ILineDataSet> lineDataSets = new ArrayList<>();
private SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");//设置日期格式
private List<String> timeList = new ArrayList<>(); //存储x轴的时间
//一条曲线
public LineChartManager(LineChart mLineChart, String name, int color) {
this.lineChart = mLineChart;
leftAxis = lineChart.getAxisLeft();
rightAxis = lineChart.getAxisRight();
xAxis = lineChart.getXAxis();
initLineChart();
initLineDataSet(name, color);
}
//多条曲线
public LineChartManager(LineChart mLineChart, List<String> names, List<Integer> colors) {
this.lineChart = mLineChart;
leftAxis = lineChart.getAxisLeft();
rightAxis = lineChart.getAxisRight();
xAxis = lineChart.getXAxis();
initLineChart();
initLineDataSet(names, colors);
}
/**
* LineChar
*/
private void initLineChart() {
lineChart.setDrawGridBackground(false);
//显示边界
lineChart.setDrawBorders(true);
//折线图例 标签 设置
Legend legend = lineChart.getLegend();
legend.setForm(Legend.LegendForm.LINE);
legend.setTextSize(11f);
//显示位置
legend.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT);
legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);
legend.setDrawInside(false);
//X轴设置显示位置在底部
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setGranularity(1f);
xAxis.setLabelCount(10);
//保证Y轴从0开始不然会上移一点
leftAxis.setAxisMinimum(0f);
rightAxis.setAxisMinimum(0f);
}
/**
* 线(线)
*
* @param name
* @param color
*/
private void initLineDataSet(String name, int color) {
lineDataSet = new LineDataSet(null, name);
lineDataSet.setLineWidth(1.5f);
lineDataSet.setCircleRadius(1.5f);
lineDataSet.setColor(color);
lineDataSet.setCircleColor(color);
lineDataSet.setHighLightColor(color);
//设置曲线填充
lineDataSet.setDrawFilled(false);
lineDataSet.setDrawValues(false);
lineDataSet.setAxisDependency(YAxis.AxisDependency.LEFT);
lineDataSet.setValueTextSize(10f);
lineDataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
//添加一个空的 LineData
lineData = new LineData();
lineChart.setData(lineData);
lineChart.invalidate();
}
/**
* 线线
*
* @param names
* @param colors
*/
private void initLineDataSet(List<String> names, List<Integer> colors) {
for (int i = 0; i < names.size(); i++) {
lineDataSet = new LineDataSet(null, names.get(i));
lineDataSet.setColor(colors.get(i));
lineDataSet.setLineWidth(1.5f);
lineDataSet.setCircleRadius(1.5f);
lineDataSet.setColor(colors.get(i));
lineDataSet.setDrawFilled(false);
lineDataSet.setDrawValues(false);
lineDataSet.setCircleColor(colors.get(i));
lineDataSet.setHighLightColor(colors.get(i));
lineDataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
lineDataSet.setAxisDependency(YAxis.AxisDependency.LEFT);
lineDataSet.setValueTextSize(10f);
lineDataSets.add(lineDataSet);
}
//添加一个空的 LineData
lineData = new LineData();
lineChart.setData(lineData);
lineChart.invalidate();
}
/**
* 线
*
* @param number
*/
public void addEntry(int number) {
//最开始的时候才添加 lineDataSet一个lineDataSet 代表一条线)
if (lineDataSet.getEntryCount() == 0) {
lineData.addDataSet(lineDataSet);
}
lineChart.setData(lineData);
//避免集合数据过多,及时清空(做这样的处理,并不知道有没有用,但还是这样做了)
if (timeList.size() > 11) {
timeList.clear();
}
timeList.add(df.format(System.currentTimeMillis()));
Entry entry = new Entry(lineDataSet.getEntryCount(), number);
lineData.addEntry(entry, 0);
//通知数据已经改变
lineData.notifyDataChanged();
lineChart.notifyDataSetChanged();
//设置在曲线图中显示的最大数量
lineChart.setVisibleXRangeMaximum(10);
//移到某个位置
lineChart.moveViewToX(lineData.getEntryCount() - 5);
}
/**
* 线
*
* @param numbers
*/
public void addEntry(List<Float> numbers) {
if (lineDataSets.get(0).getEntryCount() == 0) {
lineData = new LineData(lineDataSets);
lineChart.setData(lineData);
}
if (timeList.size() > 100) {
timeList.clear();
}
timeList.add(df.format(System.currentTimeMillis()));
for (int i = 0; i < numbers.size(); i++) {
Entry entry = new Entry(lineDataSet.getEntryCount(), numbers.get(i));
lineData.addEntry(entry, i);
lineData.notifyDataChanged();
lineChart.notifyDataSetChanged();
lineChart.setVisibleXRangeMaximum(6);
lineChart.moveViewToX(lineData.getEntryCount() - 5);
}
}
/**
* Y
*
* @param max
* @param min
* @param labelCount
*/
public void setYAxis(float max, float min, int labelCount) {
if (max < min) {
return;
}
leftAxis.setAxisMaximum(max);
leftAxis.setAxisMinimum(min);
leftAxis.setLabelCount(labelCount, false);
rightAxis.setAxisMaximum(max);
rightAxis.setAxisMinimum(min);
rightAxis.setLabelCount(labelCount, false);
lineChart.invalidate();
}
/**
* 线
*
* @param high
* @param name
*/
public void setHightLimitLine(float high, String name, int color) {
if (name == null) {
name = "高限制线";
}
LimitLine hightLimit = new LimitLine(high, name);
hightLimit.setLineWidth(4f);
hightLimit.setTextSize(10f);
hightLimit.setLineColor(color);
hightLimit.setTextColor(color);
leftAxis.addLimitLine(hightLimit);
lineChart.invalidate();
}
/**
* 线
*
* @param low
* @param name
*/
public void setLowLimitLine(int low, String name) {
if (name == null) {
name = "低限制线";
}
LimitLine hightLimit = new LimitLine(low, name);
hightLimit.setLineWidth(4f);
hightLimit.setTextSize(10f);
leftAxis.addLimitLine(hightLimit);
lineChart.invalidate();
}
/**
*
*
* @param str
*/
public void setDescription(String str) {
Description description = new Description();
description.setText(str);
lineChart.setDescription(description);
lineChart.invalidate();
}
}

@ -0,0 +1,51 @@
package com.lh.app.tool;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Build;
import androidx.core.app.NotificationCompat;
/**
* Created by LiShiyao on 2022.11.12.
*/
public class NotificationUtil {
private Context context;
private String contentTitle;
private String contentText;
private int smallIcon;
private Bitmap largeIcon;
public NotificationUtil(Context context, String contentTitle, String contentText, int smallIcon, Bitmap largeIcon) {
this.context = context;
this.contentTitle = contentTitle;
this.contentText = contentText;
this.smallIcon = smallIcon;
this.largeIcon = largeIcon;
}
//通知提醒
public void notification(){
//
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
String channelId = "whatever";
String channelName = "whatever content";
int important = NotificationManager.IMPORTANCE_HIGH;
manager.createNotificationChannel(new NotificationChannel(channelId,channelName,important));
}
Notification notification;
notification = new NotificationCompat.Builder(context,"whatever")
.setContentTitle(contentTitle)
.setContentText(contentText)
.setWhen(System.currentTimeMillis())
.setSmallIcon(smallIcon)
.setLargeIcon(largeIcon)
.setAutoCancel(false)
.build();
manager.notify(1,notification);
}
}

@ -0,0 +1,10 @@
package com.lh.app.tool;
import android.content.Context;
import android.widget.Toast;
public class ToastUtil {
public static void show(Context context,String desc){
Toast.makeText(context, desc, Toast.LENGTH_SHORT).show();
}
}

@ -0,0 +1,19 @@
package com.lh.app.ui.detail;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
public class DashboardViewModel extends ViewModel {
private final MutableLiveData<String> mText;
public DashboardViewModel() {
mText = new MutableLiveData<>();
mText.setValue("This is dashboard fragment");
}
public LiveData<String> getText() {
return mText;
}
}

@ -0,0 +1,730 @@
package com.lh.app.ui.detail;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Color;
import android.os.Bundle;
import android.os.SystemClock;
import android.text.Html;
import android.text.TextUtils;
import android.util.Log;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.github.mikephil.charting.charts.LineChart;
import com.lh.app.MyApplication;
import com.lh.app.R;
import com.lh.app.RoommateDBHelper;
import com.lh.app.tool.LineChartManager;
import com.lh.app.tool.ToastUtil;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
public class DetailFragment extends Fragment {
//室友名显示控件
private TextView tv_roommate1;
private TextView tv_roommate2;
private TextView tv_roommate3;
//室友名默认值
private final String name1_default="mate1";
private final String name2_default="mate2";
private final String name3_default="mate3";
//室友图片显示控件
private ImageView img_roma1;
private ImageView img_roma2;
private ImageView img_roma3;
//信息输入控件
private ScrollView scr_enterInfo;//输入信息布局
private EditText ed_name;
private EditText ed_sno;
private EditText ed_weight;
private EditText ed_height;
private EditText ed_birthday;
private EditText ed_hobby;
private CheckBox ckb_isMarried;
//其它控件
private TextView tv_showText;
private Button but_toSource;
private Button but_sure;
private Button but_clear;
private int select_mate=0;//选择的室友123
//控件双击控制
private long lastClickTime = 0;
//图像控件
private LineChart mLineChart;
//数据库帮助器对象实例
private final RoommateDBHelper mHelper = MyApplication.mHelper;
//活动视图
private View view;
//上下文
private Context context;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
//Fragment被创建时被调用
super.onCreate(savedInstanceState);
Log.d("fragment_detail"," onCreate");
}
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
Log.d("fragment_detail"," onCreateView");
//创建Fragment视图
view = inflater.inflate(R.layout.fragment_detail,container,false);
//获取上下文
context = getActivity();
//引入组件
inductUI();
//向组件中填充文本
initUI();
//设置组件监听器
addListenerToUI();
return view;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.d("fragment_detail","onActivityCreated");
}
@Override
public void onStart() {
//无焦点但可见时,调用此方法
super.onStart();
Log.d("fragment_detail"," onStart");
}
@Override
public void onPause() {
//Fragment失去焦点但可见时调用此方法.
super.onPause();
Log.d("fragment_detail"," onPause");
}
@Override
public void onStop() {
//Fragment不可见时调用此方法.
super.onStop();
Log.d("fragment_detail"," onStop");
}
@Override
public void onDestroyView() {
//当Fragment被移除时被调用
super.onDestroyView();
Log.d("fragment_detail"," onDestroyView");
}
//引入组件
private void inductUI(){
//引入标签
tv_roommate1 = view.findViewById(R.id.roommate1);
tv_roommate2 = view.findViewById(R.id.roommate2);
tv_roommate3 = view.findViewById(R.id.roommate3);
tv_showText = view.findViewById(R.id.text);
img_roma1 = view.findViewById(R.id.roommate1_img);
img_roma2 = view.findViewById(R.id.roommate2_img);
img_roma3 = view.findViewById(R.id.roommate3_img);
ed_name = view.findViewById(R.id.ed_name) ;
ed_sno = view.findViewById(R.id.ed_sno) ;
ed_weight = view.findViewById(R.id.ed_weight);
ed_height = view.findViewById(R.id.ed_height);
ed_birthday = view.findViewById(R.id.ed_birthday) ;
ed_hobby = view.findViewById(R.id.ed_hobby) ;
ckb_isMarried = view.findViewById(R.id.ckb_isMarried);
scr_enterInfo = view.findViewById(R.id.scr_enterIfo) ;
but_toSource = view.findViewById(R.id.source_button);
but_sure = view.findViewById(R.id.sure_but);
but_clear = view.findViewById(R.id.but_clear);
mLineChart = view.findViewById(R.id.show_img_curve);
}
/*初始化可见组件的样式*/
private void initUI() {
//判断舍友信息是否为空
if (!mHelper.query_roommateInfo_isEmpty()){
int pos1,pos2,pos3;
//查询数据库中舍友信息表中全部名字
List<String> list_roommateName = mHelper.query_roommateName();
//将已录入人数的姓名显示在对应TextView上
switch (list_roommateName.size()){
case 1:
pos1 = mHelper.query_roommate_position(list_roommateName.get(0));
setName(pos1,list_roommateName.get(0));
break;
case 2:
pos1 = mHelper.query_roommate_position(list_roommateName.get(0));
pos2 = mHelper.query_roommate_position(list_roommateName.get(1));
setName(pos1,list_roommateName.get(0));
setName(pos2,list_roommateName.get(1));
break;
case 3:
pos1 = mHelper.query_roommate_position(list_roommateName.get(0));
pos2 = mHelper.query_roommate_position(list_roommateName.get(1));
pos3 = mHelper.query_roommate_position(list_roommateName.get(2));
setName(pos1,list_roommateName.get(0));
setName(pos2,list_roommateName.get(1));
setName(pos3,list_roommateName.get(2));
break;
}
}
}
@SuppressLint("ClickableViewAccessibility")
private void addListenerToUI(){
//舍友姓名单击效果
tv_roommate1.setOnClickListener(this::onClick);
tv_roommate2.setOnClickListener(this::onClick);
tv_roommate3.setOnClickListener(this::onClick);
//舍友图片双击效果
img_roma1.setOnClickListener(this::onClick);
img_roma2.setOnClickListener(this::onClick);
img_roma3.setOnClickListener(this::onClick);
//添加图片长按效果
registerForContextMenu(img_roma1);
registerForContextMenu(img_roma2);
registerForContextMenu(img_roma3);
//"打回原型"按钮长按效果
but_toSource.setOnTouchListener(this::onTouch);
//信息录入“确认”按钮单击效果
but_sure.setOnClickListener(this::onClick);
//“清空数据”按钮单击效果
but_clear.setOnClickListener(this::onClick);
}
//组件点击
@SuppressLint("NonConstantResourceId")
private void onClick(View v){
switch (v.getId()){
case R.id.roommate1:
TextView_show(1, (String) tv_roommate1.getText());
break;
case R.id.roommate2:
TextView_show(2, (String) tv_roommate2.getText());
break;
case R.id.roommate3:
TextView_show(3, (String) tv_roommate3.getText());
break;
case R.id.roommate1_img:
clickImg(1);
break;
case R.id.roommate2_img:
clickImg(2);
break;
case R.id.roommate3_img:
clickImg(3);
break;
case R.id.sure_but:
sure_but_show();
break;
case R.id.but_clear:
//弹出弹框提示
showAlertDialog();
break;
}
}
//显示对话框提示
@SuppressLint("DiscouragedPrivateApi")
private void showAlertDialog(){
AlertDialog dialog = new AlertDialog.Builder(context)
.setIcon(R.drawable.img_delete)
.setTitle(Html.fromHtml("<font color=\"black\">信息提示</font>"))
.setMessage(Html.fromHtml("<font color=\"red\">确认全删除?</font>"))
.setPositiveButton("是", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int i) {//确认按钮监听事件
mHelper.deleteAll(RoommateDBHelper.getTableNameRoommateInfo());
ToastUtil.show(context,"删除完成");
switch (select_mate){
case 1:
tv_roommate1.setText(name1_default);
break;
case 2:
tv_roommate2.setText(name2_default);
break;
case 3:
tv_roommate3.setText(name3_default);
break;
}
dialog.dismiss();
}
})
.setNegativeButton("否", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int i) {//返回按钮监听事件
dialog.dismiss();
}
})
.create();
dialog.show();
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(Color.BLACK);
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextSize(25);
dialog.getButton(DialogInterface.BUTTON_NEGATIVE).setTextColor(Color.BLUE);
dialog.getButton(DialogInterface.BUTTON_NEGATIVE).setTextSize(25);
}
//"打回原型"按钮被按下
@SuppressLint("UseCompatLoadingForDrawables")
private boolean onTouch(View view, MotionEvent event) {
if(view.getId() == R.id.source_button){
if (event.getAction() == MotionEvent.ACTION_DOWN){
if(select_mate==1) img_roma1.setImageDrawable(context.getDrawable(R.drawable.img_dog1));
else if(select_mate==2) img_roma2.setImageDrawable(context.getDrawable(R.drawable.img_dog3));
else if(select_mate==3) img_roma3.setImageDrawable(context.getDrawable(R.drawable.img_dog2));
}
else if(event.getAction() == MotionEvent.ACTION_UP){
if(select_mate==1) img_roma1.setImageDrawable(context.getDrawable(R.drawable.hyt));
else if(select_mate==2) img_roma2.setImageDrawable(context.getDrawable(R.drawable.wyz1));
else if(select_mate==3) img_roma3.setImageDrawable(context.getDrawable(R.drawable.wz));
}
}
return false;
}
//信息录入"确认"按钮点击事件
private void sure_but_show() {
//判断输入是否有空
if(TextUtils.isEmpty(ed_name.getText()) || TextUtils.isEmpty(ed_sno.getText()) ||
TextUtils.isEmpty(ed_height.getText()) || TextUtils.isEmpty(ed_weight.getText())||
TextUtils.isEmpty(ed_birthday.getText()) || TextUtils.isEmpty(ed_hobby.getText()))
{
Toast.makeText(context,"输入不能有空!",Toast.LENGTH_SHORT).show();
}
else{
//设置舍友信息
Roommate roommate = new Roommate();
roommate.setName(String.valueOf(ed_name.getText()));
roommate.setId(String.valueOf(ed_sno.getText()));
roommate.setHeight(Integer.parseInt(String.valueOf(ed_height.getText())));
roommate.setWeight(Float.parseFloat(String.valueOf(ed_weight.getText())));
roommate.setBirthday(String.valueOf(ed_birthday.getText()));
roommate.setMarried(ckb_isMarried.isChecked());
roommate.setHobby(String.valueOf(ed_hobby.getText()));
//保存舍友信息到键值对中
ContentValues values = new ContentValues();
values.put("name",roommate.getName());
values.put("id",roommate.getId());
values.put("height",roommate.getHeight());
values.put("weight",roommate.getWeight());
values.put("married",roommate.isMarried());
values.put("birthday",roommate.getBirthday());
values.put("hobby",roommate.getHobby());
values.put("position",select_mate);
//若是第一次录入内容,添加数据
if(isFirstInput()) {
//保存键值对到数据库中的舍友信息表中
mHelper.insert(RoommateDBHelper.getTableNameRoommateInfo(),values);
}
//若非第一次录入内容,修改数据
else {
String name = getName();
long row = mHelper.update_roommateInfo(values,name);
Log.d("UpdateMemoTable","修改备忘录"+row+"条");
}
//设置指定textview的text
setTextToTV(roommate.getName());
//隐藏输入框
scr_enterInfo.setVisibility(View.GONE);
}
}
//舍友名字点击事件
@SuppressLint("SetTextI18n")
private void TextView_show(int i, String name) {
//选择室友序号
select_mate = i;
//设置字体颜色
changeTextColor();
//隐藏信息录入
scr_enterInfo.setVisibility(View.GONE);
//曲线显示隐藏
mLineChart.setVisibility(View.GONE);
//清空文本域
tv_showText.setText("");
//室友信息弹出动画
startAnim();
//判断舍友姓名是否为空
if (name.equals("mate"+i)) return;
//读取数据库信息
Roommate roommate = mHelper.query_roommateInfo_ByName(name);
//写入具体内容
int[][] bodyRhythm = body_rhythm(roommate.getBirthday());
tv_showText.setText("姓名:"+roommate.getName()+"\n学号:"+roommate.getId()+"身高:"+roommate.getHeight()+
"\n体重:"+roommate.getWeight()+"\n生日:"+ roommate.getBirthday()+"\n爱好:"+roommate.getHobby()+
"\n\n人体生物节律\n 已运行周期数 新周期开始天数"+
"\n智力: "+bodyRhythm[0][0]+" "+bodyRhythm[1][0]+
"\n情绪: "+bodyRhythm[0][1]+" "+bodyRhythm[1][1]+
"\n体力: "+bodyRhythm[0][2]+" "+bodyRhythm[1][2], TextView.BufferType.EDITABLE);
}
//改变文本颜色
public void changeTextColor() {
//设置字体变换颜色
int[] color = new int[2];
color[0] = Color.parseColor("#64E14B");
color[1] = Color.parseColor("#2B2B2B");
//改变字体颜色
if(select_mate == 1){
tv_roommate1.setTextColor(color[0]);
tv_roommate2.setTextColor(color[1]);
tv_roommate3.setTextColor(color[1]);
}else if(select_mate == 2){
tv_roommate1.setTextColor(color[1]);
tv_roommate2.setTextColor(color[0]);
tv_roommate3.setTextColor(color[1]);
}else{
tv_roommate1.setTextColor(color[1]);
tv_roommate2.setTextColor(color[1]);
tv_roommate3.setTextColor(color[0]);
}
}
//文本框弹出效果
private void startAnim() {
//设置动画从自身位置的最下端向上滑动了自身的高度持续时间为500ms
final TranslateAnimation ctrlAnimation = new TranslateAnimation(
TranslateAnimation.RELATIVE_TO_SELF, 0, TranslateAnimation.RELATIVE_TO_SELF, 0,
TranslateAnimation.RELATIVE_TO_SELF, 1, TranslateAnimation.RELATIVE_TO_SELF, 0);
ctrlAnimation.setDuration(500l); //设置动画的过渡时间
tv_showText.postDelayed(new Runnable() {
@Override
public void run() {
tv_showText.setVisibility(View.VISIBLE);
tv_showText.startAnimation(ctrlAnimation);
}
}, 000);
}
//点击图片事件
private void clickImg(int i) {
//获取当前系统当前毫秒数
long currentTimeMills = SystemClock.uptimeMillis();
//两次间隔小于300ms代表双击
if(currentTimeMills-lastClickTime<300){
//改变选择的照片
select_mate = i;
//改变文字颜色
changeTextColor();
//舍友录入信息清空
setInputTextEmpty();
//隐藏曲线显示、文本显示
tv_showText.setVisibility(View.GONE);
mLineChart.setVisibility(View.GONE);
//显示输入框
scr_enterInfo.setVisibility(View.VISIBLE);
textShow();
return;
}
//更新最后一次点击时间
lastClickTime = currentTimeMills;
}
//清空输入文本和显示文本域
private void setInputTextEmpty() {
tv_showText.setText("");
ed_name.setText("");
ed_sno.setText("");
ed_weight.setText("");
ed_height.setText("");
ed_hobby.setText("");
ed_birthday.setText("");
ckb_isMarried.setChecked(false);
}
//设置指定textView的text
private void setTextToTV(String name) {
switch (select_mate){
case 1:
tv_roommate1.setText(name);
break;
case 2:
tv_roommate2.setText(name);
break;
case 3:
tv_roommate3.setText(name);
break;
}
}
//向信息录入中填充文本信息
private void textShow() {
//若未给室友录入信息,弹出清空后的输入界面
if (isFirstInput()) {
setInputTextEmpty();
return;
}
Roommate roommate = new Roommate();
//判断点击室友名,从数据库中取出数据
switch (select_mate){
case 1:
if ((tv_roommate1.getText()).equals(name1_default)) return;
roommate = mHelper.query_roommateInfo_ByName((String) tv_roommate1.getText());
break;
case 2:
if ((tv_roommate2.getText()).equals(name2_default)) return;
roommate = mHelper.query_roommateInfo_ByName((String) tv_roommate2.getText());
break;
case 3:
if ((tv_roommate3.getText()).equals(name3_default)) return;
roommate = mHelper.query_roommateInfo_ByName((String) tv_roommate3.getText());
break;
}
//填充数据
ed_name.setText(roommate.getName());
ed_sno.setText(roommate.getId());
ed_weight.setText(String.valueOf(roommate.getWeight()));
ed_height.setText(String.valueOf(roommate.getHeight()));
ed_birthday.setText(roommate.getBirthday());
ed_hobby.setText(roommate.getHobby());
ckb_isMarried.setChecked(roommate.isMarried());
}
//是否是第一次为室友录入信息或是否为该室友录入信息
public boolean isFirstInput() {
switch (select_mate){
case 1:
if (name1_default.contentEquals(tv_roommate1.getText())) return true;
break;
case 2:
if (name2_default.contentEquals(tv_roommate2.getText())) return true;
break;
case 3:
if (name3_default.contentEquals(tv_roommate3.getText())) return true;
break;
}
return false;
}
//得到指定室友在textView上的名字
public String getName() {
switch (select_mate){
case 1:
return (String) tv_roommate1.getText();
case 2:
return (String) tv_roommate2.getText();
case 3:
return (String) tv_roommate3.getText();
}
return "mate";
}
//填充文本框文本
private void setName(int pos,String name) {
switch (pos){
case 1:
tv_roommate1.setText(name);
break;
case 2:
tv_roommate2.setText(name);
break;
case 3:
tv_roommate3.setText(name);
break;
}
}
//长按显示菜单
@SuppressLint("NonConstantResourceId")
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
//子菜单部分
MenuInflater inflater = new MenuInflater(context);
inflater.inflate(R.menu.menu_sub,menu);
switch (v.getId()){
case R.id.roommate1_img:
select_mate = 1;
changeTextColor();
break;
case R.id.roommate2_img:
select_mate = 2;
changeTextColor();
break;
case R.id.roommate3_img:
select_mate = 3;
changeTextColor();
break;
default:
break;
}
super.onCreateContextMenu(menu, v, menuInfo);
}
//上下文菜单被点击时触发该方法
@SuppressLint("NonConstantResourceId")
@Override
public boolean onContextItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.item_revise_introduce:
//填充内容,显示输入
textShow();
mLineChart.setVisibility(View.GONE);
tv_showText.setVisibility(View.GONE);
scr_enterInfo.setVisibility(View.VISIBLE);
break;
case R.id.item_show_curve:
//判断是否给舍友录入信息
if(isFirstInput()) {
ToastUtil.show(context, "没有信息!");
return true;
}
show_body_rhythm_curve();
mLineChart.setVisibility(View.VISIBLE);
scr_enterInfo.setVisibility(View.GONE);
tv_showText.setVisibility(View.GONE);
break;
default:
break;
}
return true;
}
//显示曲线图
private void show_body_rhythm_curve() {
Roommate roommate = mHelper.query_roommateInfo_ByName(getName());
String birthday = roommate.getBirthday();
int[][] body_rhythm_data = body_rhythm_month(birthday);
List<String> list_name = new ArrayList<>();
List<Integer> list_color = new ArrayList<>();
list_name.add("智力");
list_name.add("情绪");
list_name.add("体力");
list_color.add(Color.BLACK);
list_color.add(Color.GREEN);
list_color.add(Color.BLUE);
LineChartManager manager = new LineChartManager(mLineChart,list_name,list_color);
//设置图像显示内容
manager.setDescription("月份");
manager.setYAxis(60,-60,30);
manager.setHightLimitLine(30,"最高",Color.BLACK);
List<Float> list_numbers = new ArrayList<>();
for(int i=0;i<31;i++){
list_numbers.add((float) body_rhythm_data[1][i]);
list_numbers.add((float) body_rhythm_data[2][i]);
list_numbers.add((float) body_rhythm_data[3][i]);
manager.addEntry(list_numbers);
list_numbers.clear();
}
}
/**
*
* @param birthday : 2000.08.04
* @return body_rhythm
* */
private int[][] body_rhythm(String birthday){
int[][] body_rhythm = new int[2][3];
String bornYear,bornMonth,bornDay;
//计算生日年-月-日 统一格式
String[] bornData = birthday.split("\\.+");
bornYear = bornData[0];
bornMonth = bornData[1];
bornDay = bornData[2];
String endTime = bornYear+"-"+bornMonth+"-"+bornDay;
//计算当前年-月-日 统一格式
Calendar calendar = Calendar.getInstance();
int nowYear = calendar.get(Calendar.YEAR); //年
int nowMonth = calendar.get(Calendar.MONTH)+1; //月
int nowDay = calendar.get(Calendar.DAY_OF_MONTH); //日
String startTime = nowYear+"-"+nowMonth+"-"+nowDay;
//计算当前时间与出生相隔天数
SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd");
long nd = 1000*24*60*60;//一天的毫秒数
long diff = 0;
try {
//getTime()返回毫秒数
diff = sd.parse(startTime).getTime() - sd.parse(endTime).getTime();
} catch (ParseException e) {
e.printStackTrace();
}
long days = diff/nd;//计算相差多少天
//使用公式计算智力(IT)、情绪(mood)、体力(HP)节律周期(cycle)天数
body_rhythm[0][0] = (int) (days/32);
body_rhythm[0][1] = (int) (days/28);
body_rhythm[0][2] = (int) (days/23);
//使用公式计算智力(IT)、情绪(mood)、体力(HP)节律新周期运行天数
body_rhythm[1][0] = (int) (days%32);
body_rhythm[1][1] = (int) (days%28);
body_rhythm[1][2] = (int) (days%23);
return body_rhythm;
}
/**
*
* @param birthday : 2000.08.04
* @return body_rhythm
* */
private int[][] body_rhythm_month(String birthday){
int[][] body_rhythm = new int[4][32];
String bornYear,bornMonth,bornDay;
//计算生日年-月-日 统一格式
String[] bornData = birthday.split("\\.+");
bornYear = bornData[0];
bornMonth = bornData[1];
bornDay = bornData[2];
String endTime = bornYear+"-"+bornMonth+"-"+bornDay;
//计算当前年-月-日 统一格式
Calendar calendar = Calendar.getInstance();
int nowYear = calendar.get(Calendar.YEAR); //年
int nowMonth = calendar.get(Calendar.MONTH)+1; //月
int nowDay = 1;
String startTime;
while (nowDay<30){
startTime = nowYear+"-"+nowMonth+"-"+nowDay;
//计算当前时间与出生相隔天数
SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd");
long nd = 1000*24*60*60;//一天的毫秒数
long diff = 0;
try {
//getTime()返回毫秒数
diff = sd.parse(startTime).getTime() - sd.parse(endTime).getTime();
} catch (ParseException e) {
e.printStackTrace();
}
long days = diff/nd;//计算相差多少天
//使用公式计算智力(IT)、情绪(mood)、体力(HP)节律周期(cycle)天数
body_rhythm[0][0] = (int) (days/32);
body_rhythm[0][1] = (int) (days/28);
body_rhythm[0][2] = (int) (days/23);
//使用公式计算智力(IT)、情绪(mood)、体力(HP)节律新周期运行天数
body_rhythm[1][nowDay-1] = (int) (days%32);
body_rhythm[2][nowDay-1] = (int) (days%28);
body_rhythm[3][nowDay-1] = (int) (days%23);
nowDay++;
}
return body_rhythm;
}
}

@ -0,0 +1,78 @@
package com.lh.app.ui.detail;
public class Roommate {
private String name;
private String id;
private long height;//单位cm
private float weight;//单位kg
private boolean married;
private String birthday;
private String hobby;
public Roommate(){ }
public Roommate(String name, String id, long height, float weight, boolean married, String birthday, String hobby) {
this.name = name;
this.id = id;
this.height = height;
this.weight = weight;
this.married = married;
this.birthday = birthday;
this.hobby = hobby;
}
public String getName() {
return name;
}
public String getId() {
return id;
}
public long getHeight() {
return height;
}
public float getWeight() {
return weight;
}
public boolean isMarried() {
return married;
}
public String getHobby() {
return hobby;
}
public String getBirthday() {
return birthday;
}
public void setName(String name) {
this.name = name;
}
public void setId(String id) {
this.id = id;
}
public void setHeight(long height) {
this.height = height;
}
public void setWeight(float weight) {
this.weight = weight;
}
public void setMarried(boolean married) {
this.married = married;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", height=" + height +
", weight=" + weight +
", married=" + married +
'}';
}
}

@ -0,0 +1,40 @@
package com.lh.app.ui.honor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import androidx.core.content.FileProvider;
import java.io.FileNotFoundException;
/**
* Created by LiShiyao on 2022.11.17
*/
public class Honor {
private String content;
private String imageLocation;
public Honor(){}
public Honor(String content, String imageLocation) {
this.content = content;
this.imageLocation = imageLocation;
}
public String getContent() {
return content;
}
public String getImageLocation() {
return imageLocation;
}
public void setContent(String content) {
this.content = content;
}
public void setImageLocation(String imageLocation) {
this.imageLocation = imageLocation;
}
}

@ -0,0 +1,99 @@
package com.lh.app.ui.honor;
import android.content.ContentResolver;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.core.content.FileProvider;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.lh.app.R;
import com.lh.app.tool.ImageUtils;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
public class HonorAdapter extends RecyclerView.Adapter<HonorAdapter.ViewHolder> {
private List<Honor> mHonorList;
public static List<Honor> selectHonor = new ArrayList<>();
private Context mContext;
static class ViewHolder extends RecyclerView.ViewHolder{
View view;
ImageView imageImage;
TextView tv_describe;
CheckBox ckb_honorItem;
public ViewHolder(View view){
super(view);
this.view = view;
imageImage = (ImageView) view.findViewById(R.id.img_honor);
tv_describe = (TextView) view.findViewById(R.id.tv_describe);
ckb_honorItem = view.findViewById(R.id.ckb_honorItem);
}
}
public HonorAdapter(List<Honor> honorList,Context context){
mHonorList = honorList;
mContext = context;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view;
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.honor_item,parent,false);
final ViewHolder holder = new ViewHolder(view);
//list的点击事件
holder.view.setOnClickListener(view1 -> {
int position = holder.getAdapterPosition();
Honor honor = mHonorList.get(position);
Toast.makeText(view.getContext(),"you clicked view " +position,Toast.LENGTH_SHORT).show();
});
return holder;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Honor honor = mHonorList.get(position);
Uri uri = Uri.parse(honor.getImageLocation());
Glide.with(mContext)
.load(uri)
.error(R.drawable.ic_no_picture)
.into(holder.imageImage);
holder.tv_describe.setText(honor.getContent());
//设置单选框监听器
holder.ckb_honorItem.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked) selectHonor.add(honor);
else selectHonor.remove(honor);
}
});
}
@Override
public int getItemCount() {
return mHonorList.size();
}
}

@ -0,0 +1,266 @@
package com.lh.app.ui.honor;
import static com.lh.app.tool.ImageUtils.uriToBitmap;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.text.InputType;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.lh.app.MyApplication;
import com.lh.app.R;
import com.lh.app.RoommateDBHelper;
import java.util.ArrayList;
import java.util.List;
;
public class HonorFragment extends Fragment {
private static final int REQUEST_CODE_PERMISSION = 100;
private List<Honor> mHonorList = new ArrayList<>();
private RecyclerView recyclerView;
private View view;
private Context context;
private Button but_addHonor;
private ImageView img_imageHonor;
private EditText edt_describe;
private LinearLayout ll_inputHonor;
private Button but_backHonor;
private Button but_sureHonor;
private Button but_deleteHonor;
private TextView tv_emptyHonor;
private ActivityResultLauncher<Intent> mFromAlumn;
private Image checkImage = null;
private HonorAdapter adapter;
//数据库帮助器对象实例
private RoommateDBHelper mHelper = MyApplication.mHelper;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("ning","Communicate Fragment onCreate");
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_honor,container,false);
context = getActivity();
addUI_Listener();
text_Control();
initList();
setRecycleView();
return view;
}
@Override
public void onStart() {
//无焦点但可见时,调用此方法
super.onStart();
Log.d("HonorActivity","onStart");
}
@Override
public void onPause() {
//Fragment失去焦点但可见时调用此方法.
super.onPause();
}
@Override
public void onStop() {
//Fragment不可见时调用此方法.
super.onStop();
}
@Override
public void onDestroyView() {
//当Fragment被移除时被调用
super.onDestroyView();
}
//对文本进行控制
private void text_Control(){
edt_describe.setInputType(InputType.TYPE_TEXT_FLAG_MULTI_LINE);//多行文本输入
edt_describe.setGravity(Gravity.TOP);//文本显示在最上方
edt_describe.setSingleLine(false);//改变默认单行模式
edt_describe.setHorizontallyScrolling(false);//取消水平滚动
}
@SuppressLint("CutPasteId")
private void addUI_Listener() {
but_addHonor = view.findViewById(R.id.but_addHonor);
img_imageHonor = view.findViewById(R.id.img_imgHonor);
edt_describe = view.findViewById(R.id.edt_contentHonor);
ll_inputHonor = view.findViewById(R.id.ll_inputHonor);
but_backHonor = view.findViewById(R.id.but_backHonor);
but_sureHonor = view.findViewById(R.id.but_sureHonor);
but_deleteHonor = view.findViewById(R.id.but_removeHonor);
tv_emptyHonor = view.findViewById(R.id.tv_emptyHonor);
but_addHonor.setOnClickListener(this::onClick);
img_imageHonor.setOnClickListener(this::onClick);
but_backHonor.setOnClickListener(this::onClick);
but_sureHonor.setOnClickListener(this::onClick);
but_deleteHonor.setOnClickListener(this::onClick);
//选择图片
mFromAlumn = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult result) {
//用户取消选择图片
if (result.getResultCode() == Activity.RESULT_OK) {
//用户选择了图片
assert result.getData() != null;
Uri uri = result.getData().getData();
checkImage = new Image(uriToBitmap(context,uri),uri.toString());
img_imageHonor.setImageBitmap(checkImage.getImage());
// 获取持久化权限
context.getContentResolver().takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
}
}
});
}
@SuppressLint("NonConstantResourceId")
private void onClick(View view) {
switch (view.getId()){
case R.id.but_backHonor:
recyclerView.setVisibility(View.VISIBLE);
ll_inputHonor.setVisibility(View.GONE);
break;
case R.id.but_addHonor:
recyclerView.setVisibility(View.GONE);
ll_inputHonor.setVisibility(View.VISIBLE);
img_imageHonor.setImageResource(R.drawable.img_add);
break;
case R.id.but_removeHonor:
remove();
break;
case R.id.img_imgHonor:
//检查权限
if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this.getActivity(),
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
REQUEST_CODE_PERMISSION);
}
else {
//选择图片
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
// 指定显示图片
intent.setType("image/*");
mFromAlumn.launch(intent);
}
break;
case R.id.but_sureHonor:
if (edt_describe.getText().toString().trim().equals("")){
Toast.makeText(context,"描述不能有空!",Toast.LENGTH_SHORT).show();
}
else {
Honor honor = new Honor(String.valueOf(edt_describe.getText()),checkImage.getLocation());
//保存到数据库中
if (mHelper.insert_honor(honor) != -1){
Toast.makeText(context,"添加成功!",Toast.LENGTH_SHORT).show();
}
else Toast.makeText(context,"添加失败!",Toast.LENGTH_SHORT).show();
ll_inputHonor.setVisibility(View.GONE);
recyclerView.setVisibility(View.VISIBLE);
add(0, honor);
}
break;
}
}
/*初始化列表*/
private void initList() {
mHonorList.clear();
List<Honor> honorList = mHelper.query_honor_All();
if (!honorList.isEmpty()){
mHonorList.addAll(honorList);
//隐藏空提示
tv_emptyHonor.setVisibility(View.GONE);
}
}
private void setRecycleView() {
adapter = new HonorAdapter(mHonorList,context);
recyclerView = view.findViewById(R.id.rv_honor);
LinearLayoutManager layoutManager = new LinearLayoutManager(context,LinearLayoutManager.VERTICAL,false);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
}
/*添加子项*/
private void add(int position, Honor honor){
Log.d("Roommate_activity","添加子项!");
//tv_empty.setVisibility(View.GONE);
mHonorList.add(position,honor);
adapter.notifyItemInserted(position);
//隐藏空提示
tv_emptyHonor.setVisibility(View.GONE);
}
/*删除子项*/
@SuppressLint("NotifyDataSetChanged")
private void remove(){
for(Honor honor:HonorAdapter.selectHonor){
mHonorList.remove(honor);
mHelper.delete_honorByLocation(honor.getImageLocation());
}
//更新RecycleView
adapter.notifyDataSetChanged();
//将选中子项列表清空
HonorAdapter.selectHonor.clear();
//若子项全被清空,则出现“没有数据”提示
if(mHonorList.isEmpty()) tv_emptyHonor.setVisibility(View.VISIBLE);
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CODE_PERMISSION) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 权限已授予
onClick(img_imageHonor);
} else {
// 权限被拒绝
}
}
}
}

@ -0,0 +1,31 @@
package com.lh.app.ui.honor;
import android.graphics.Bitmap;
/** 图像信息类 */
public class Image {
private Bitmap image;
private String location;
public Image(Bitmap image, String location) {
this.image = image;
this.location = location;
}
public Bitmap getImage() {
return image;
}
public void setImage(Bitmap image) {
this.image = image;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
}

@ -0,0 +1,82 @@
package com.lh.app.ui.honor;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class ImageTools {
/**
* uri
*
* @param uri
* @param activity
* @return
* @throws IOException
*/
public static Bitmap getBitmapFromUri(Uri uri, Activity activity) throws IOException {
InputStream inputStream = activity.getContentResolver().openInputStream(uri);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
options.inDither = true;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
BitmapFactory.decodeStream(inputStream, null, options);
inputStream.close();
int originalWidth = options.outWidth;
int originalHeight = options.outHeight;
if (originalWidth == -1 || originalHeight == -1) {
return null;
}
float height = 800f;
float width = 480f;
int be = 1; //be=1表示不缩放
if (originalWidth > originalHeight && originalWidth > width) {
be = (int) (originalWidth / width);
} else if (originalWidth < originalHeight && originalHeight > height) {
be = (int) (originalHeight / height);
}
if (be <= 0) {
be = 1;
}
BitmapFactory.Options bitmapOptinos = new BitmapFactory.Options();
bitmapOptinos.inSampleSize = be;
bitmapOptinos.inDither = true;
bitmapOptinos.inPreferredConfig = Bitmap.Config.ARGB_8888;
inputStream = activity.getContentResolver().openInputStream(uri);
Bitmap bitmap = BitmapFactory.decodeStream(inputStream, null, bitmapOptinos);
inputStream.close();
return compressImage(bitmap);
}
/**
*
*
* @param bitmap
* @return
*/
public static Bitmap compressImage(Bitmap bitmap) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
int options = 100;
while (byteArrayOutputStream.toByteArray().length / 1024 > 100) {
byteArrayOutputStream.reset();
//第一个参数 :图片格式 ,第二个参数: 图片质量100为最高0为最差 ,第三个参数:保存压缩后的数据的流
bitmap.compress(Bitmap.CompressFormat.JPEG, options, byteArrayOutputStream);
options -= 10;
}
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
Bitmap bitmapImage = BitmapFactory.decodeStream(byteArrayInputStream, null, null);
return bitmapImage;
}
}

@ -0,0 +1,19 @@
package com.lh.app.ui.honor;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
public class NotificationsViewModel extends ViewModel {
private final MutableLiveData<String> mText;
public NotificationsViewModel() {
mText = new MutableLiveData<>();
mText.setValue("This is notifications fragment");
}
public LiveData<String> getText() {
return mText;
}
}

@ -0,0 +1,228 @@
package com.lh.app.ui.memo;
import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.text.InputType;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextClock;
import android.widget.Toast;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import com.lh.app.MainActivity;
import com.lh.app.MyApplication;
import com.lh.app.R;
import com.lh.app.RoommateDBHelper;
import com.lh.app.tool.NotificationUtil;
public class AddMemo_activity extends AppCompatActivity {
private TextClock clock;
private EditText title_edt;
private EditText content_edt;
private Button back_button;
private Button success_button;
private RadioGroup group;
private String select_roommateName = "全部";//选择室友
public static boolean is_backData = false;//是否带回数据
public static Memo jumpMemo = null; //修改前对应的Memo
public static boolean is_revise = false;//是否修改数据
//数据库帮助器对象实例
private RoommateDBHelper mHelper = MyApplication.mHelper;
@SuppressLint("NonConstantResourceId")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.add_memo_activity_layout);
addUI();
//判断点击打开页面来源,以下来自子项的点击,即修改内容
if(is_revise){
//获取传入数据
jumpMemo = Roommate_memo_adapter.jumpMemo;
//对控件文本及状态进行填充
title_edt.setText(jumpMemo.getTitle());
content_edt.setText(jumpMemo.getContent());
switch (jumpMemo.getName()){
case "全部":
group.check(R.id.btn_all);
break;
case "刘治浩":
group.check(R.id.btn_lzh);
break;
case "谭宗辉":
group.check(R.id.btn_tzh);
break;
case "樊彪":
group.check(R.id.btn_fb);
break;
case "李石尧":
group.check(R.id.btn_lsy);
break;
}
}
else {
title_edt.setText("");
content_edt.setText("");
}
text_Control();
Menu_part();
}
/*添加组件*/
@SuppressLint("NonConstantResourceId")
private void addUI(){
back_button = (Button) findViewById(R.id.back_button);
success_button = (Button)findViewById(R.id.success_button) ;
title_edt = (EditText)findViewById(R.id.title_edt) ;
content_edt = (EditText) findViewById(R.id.content_edt);
clock = (TextClock) findViewById(R.id.clock);
group = (RadioGroup)findViewById(R.id.radioGroup) ;
/*对菜单栏按钮点击事件监听*/
back_button.setOnClickListener(this::onclick);
success_button.setOnClickListener(this::onclick);
group.setOnCheckedChangeListener(radioChangeListener);
}
//RadioGroup监听器
@SuppressLint("NonConstantResourceId")
private final RadioGroup.OnCheckedChangeListener radioChangeListener = new RadioGroup.OnCheckedChangeListener(){
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId) {
case R.id.btn_all:
RadioButton radioButton_01 = AddMemo_activity.this.findViewById(R.id.btn_all);
select_roommateName = radioButton_01.getText().toString();
break;
case R.id.btn_lzh:
RadioButton radioButton_02 = AddMemo_activity.this.findViewById(R.id.btn_lzh);
select_roommateName = radioButton_02.getText().toString();
break;
case R.id.btn_tzh:
RadioButton radioButton_03 = AddMemo_activity.this.findViewById(R.id.btn_tzh);
select_roommateName = radioButton_03.getText().toString();
break;
case R.id.btn_fb:
RadioButton radioButton_04 = AddMemo_activity.this.findViewById(R.id.btn_fb);
select_roommateName = radioButton_04.getText().toString();
break;
case R.id.btn_lsy:
RadioButton radioButton_05 = AddMemo_activity.this.findViewById(R.id.btn_lsy);
select_roommateName = radioButton_05.getText().toString();
break;
}
Toast.makeText(AddMemo_activity.this, "name:" + select_roommateName, Toast.LENGTH_SHORT).show();
}
};
//按钮点击事件
@SuppressLint("NonConstantResourceId")
private void onclick(View view){
switch (view.getId()){
case R.id.back_button:
is_backData = false;
is_revise = false;
MainActivity.isShowViewPage_memo = true;
Intent intent = new Intent(AddMemo_activity.this,MainActivity.class);
startActivity(intent);
finish();//销毁当前活动
break;
case R.id.success_button:
//将数据存入内存
String name = select_roommateName;
String title = String.valueOf(title_edt.getText());
String content = String.valueOf(content_edt.getText());
String now_time = (String)clock.getText();
//对输入进行判断
if (!title.equals("") && !content.equals("")) {
//打印存入数据
String date =String.format(title+" "+content+" "+now_time+" %s", name);
Log.d("Roommate_activity","存入数据:"+date);
Memo memo = new Memo(name,title,content,now_time);
//将增加数据存入数据库
ContentValues values01 = new ContentValues();
values01.put("name", select_roommateName);
values01.put("title",title);
values01.put("content",content);
values01.put("date",now_time);
values01.put("isDelete",false);
values01.put("isRevise",false);
mHelper.insert(RoommateDBHelper.getTableNameRoommateMemo(),values01);
if (is_revise){
mHelper.update_roommateMemo(jumpMemo,true,true);
}
else {
//将增加数据存入数据库
ContentValues values02 = new ContentValues();
values02.put("name", select_roommateName);
values02.put("title",title);
values02.put("content",content);
values02.put("date",now_time);
values02.put("isDelete",false);
values02.put("isRevise",true);
mHelper.insert(RoommateDBHelper.getTableNameRoommateMemo(),values02);
}
//通知显示
notification(memo);
//返回界面
is_backData = true;
jumpMemo = null;
is_revise = false;
Roommate_memo_adapter.jumpMemo = null;
Toast.makeText(this, "完成", Toast.LENGTH_SHORT).show();
Log.d("Roommate_activity","返回!");
//重新转跳到首界面
MainActivity.isShowViewPage_memo = true;
intent = new Intent(AddMemo_activity.this,MainActivity.class);
startActivity(intent);
finish();
}
else Toast.makeText(this, "标题和内容不能为空", Toast.LENGTH_SHORT).show();
break;
}
}
//通知提醒
private void notification(Memo memo){
//
NotificationUtil notificationUtil;
if(is_revise){
notificationUtil = new NotificationUtil(this,"修改通知","您在备忘录中修改了一条通知!!!",
R.drawable.add_small_icon, BitmapFactory.decodeResource(getResources(),memo.getImgID() ));
}
else {
notificationUtil = new NotificationUtil(this,"添加通知","您在备忘录中添加了一条通知!!!",
R.drawable.add_small_icon, BitmapFactory.decodeResource(getResources(), memo.getImgID()));
}
notificationUtil.notification();
}
//对文本进行控制
private void text_Control(){
content_edt.setInputType(InputType.TYPE_TEXT_FLAG_MULTI_LINE);//多行文本输入
content_edt.setGravity(Gravity.TOP);//文本显示在最上方
content_edt.setSingleLine(false);//改变默认单行模式
content_edt.setHorizontallyScrolling(false);//取消水平滚动
}
/*菜单栏编写*/
private void Menu_part(){
/*隐藏菜单栏*/
ActionBar actionBar = getSupportActionBar();
if(actionBar != null){
actionBar.hide();
}
}
}

@ -0,0 +1,19 @@
package com.lh.app.ui.memo;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
public class HomeViewModel extends ViewModel {
private final MutableLiveData<String> mText;
public HomeViewModel() {
mText = new MutableLiveData<>();
mText.setValue("This is home fragment");
}
public LiveData<String> getText() {
return mText;
}
}

@ -0,0 +1,45 @@
package com.lh.app.ui.memo;
import com.lh.app.R;
/**
* Created by LiShiyao on 2022/10/5.
*/
public class Memo {
private String name;
private String title;
private String content;
private String date;
public Memo(){}
public Memo(String name, String title, String content, String time){
this.name = name;
this.title = title;
this.content = content;
this.date = time;
}
public Memo(String title, String content){
this.title = title;
this.content = content;
}
public String getName() {
return name;
}
public String getTitle(){
return title;
}
public String getContent(){
return content;
}
public String getDate(){
return date;
}
public int getImgID(){
if ("全部".equals(name)) return R.drawable.img_dog1;
else if ("刘治浩".equals(name)) return R.drawable.hyt;
else if ("谭宗辉".equals(name)) return R.drawable.pyy;
else if ("樊彪".equals(name)) return R.drawable.yyqx;
else return R.drawable.dc;
}
}

@ -0,0 +1,307 @@
package com.lh.app.ui.memo;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.lh.app.MyApplication;
import com.lh.app.R;
import com.lh.app.RoommateDBHelper;
import com.lh.app.tool.NotificationUtil;
import java.util.ArrayList;
import java.util.List;
public class MemoFragment extends Fragment {
//数据库帮助器对象实例
private RoommateDBHelper mHelper = MyApplication.mHelper;
//recycleView中子项列表
private List<Memo> memoList = new ArrayList<>();
private Roommate_memo_adapter adapter;
//空数据文本
private TextView tv_empty;
//备忘录子项数量
private int memoNum = 0;
//定义菜单项标识
private final int REMOVE = 110;
private final int ADD = 111;
private final int REVISE = 112;
//活动视图
private View view;
//上下文
private Context context;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
Log.d("fragment_memo","onCreate");
//Fragment被创建时被调用
super.onCreate(savedInstanceState);
//指出fragment愿意添加item到选项菜单
setHasOptionsMenu(true);
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
Log.d("fragment_memo","onCreateView");
//获取活动视图和活动上下文
view = inflater.inflate(R.layout.fragment_memo,container,false);
context = getActivity();
//将选中子项列表清空
Roommate_memo_adapter.checkList.clear();
//设置recycleView配置
setRecycleView();
addUI_and_Listener();
//初始化备忘录列表和备忘录行数
initList();
return view;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.d("fragment_memo","onActivityCreated");
}
@Override
public void onStart() {
//无焦点但可见时,调用此方法
super.onStart();
Log.d("fragment_memo","onStart");
}
@Override
public void onPause() {
//Fragment失去焦点但可见时调用此方法.
super.onPause();
Log.d("fragment_memo","onPause");
}
@Override
public void onStop() {
//Fragment不可见时调用此方法.
super.onStop();
Log.d("fragment_memo","onStop");
}
@Override
public void onDestroyView() {
//当Fragment被移除时被调用
super.onDestroyView();
Log.d("fragment_memo","onDestroyView");
}
/*添加组件及其监听器*/
private void addUI_and_Listener(){
Button but_add = view.findViewById(R.id.add_but);
Button remove_btn = view.findViewById(R.id.remove_btn);
Button clear_btn = view.findViewById(R.id.clear_btn);
tv_empty = view.findViewById(R.id.empty_tv);
but_add.setOnClickListener(this::onClick);
remove_btn.setOnClickListener(this::onClick);
clear_btn.setOnClickListener(this::onClick);
}
/*设置RecycleView样式*/
private void setRecycleView() {
//竖直流布局
RecyclerView recyclerView = view.findViewById(R.id.recycleView_horizontal);
LinearLayoutManager LayoutManager2 = new LinearLayoutManager(context);
//LayoutManager2.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(LayoutManager2);
adapter = new Roommate_memo_adapter(memoList);
recyclerView.setAdapter(adapter);
}
/*初始化recycleView列表*/
private void initList() {
//更新文件行数
memoNum = mHelper.query_roommateMemo_rowsNumByType(false,false);
Log.d("Roommate_activity","文件行数:"+ memoNum);
//若备忘录子项不为0则添加到recycleView中
if (memoNum !=0){
//先清空序列
memoList.clear();
//取备忘录中被显示数据
List<Memo> memoList = mHelper.query_roommateMemoByType(false,false);
for (Memo memo:memoList){
add(0,memo);
}
}
}
//点击事件
@SuppressLint("NonConstantResourceId")
private void onClick(View view) {
switch (view.getId()){
case R.id.add_but:
Intent intent = new Intent(context, AddMemo_activity.class);
startActivity(intent);
getActivity().finish();
break;
case R.id.remove_btn:
remove();
break;
case R.id.clear_btn:
//弹出弹框提示
new AlertDialog.Builder(context)
.setTitle("信息提示")
.setMessage("确认全删除?")
.setPositiveButton("是", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int i) {//确认按钮监听事件
//请空子项、清空备忘录表中数据、弹出通知、更新备忘录子项数
clear();
//弹框消失
dialog.dismiss();
}
})
.setNegativeButton("否", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int i) {//返回按钮监听事件
dialog.dismiss();
}
}).show();//显示弹框
break;
default:
throw new IllegalStateException("Unexpected value: " + view);
}
}
/*添加子项*/
private void add(int position,Memo memo){
Log.d("Roommate_activity","添加子项!");
tv_empty.setVisibility(View.GONE);
memoList.add(position,memo);
adapter.notifyItemInserted(position);
}
/*删除子项*/
@SuppressLint("NotifyDataSetChanged")
private void remove(){
//获取要被删除子项列表
List<Memo> checklist = Roommate_memo_adapter.checkList;
int remove_num = checklist.size();
//判断是否有要被删除的子项
if (remove_num == 0) {
Toast.makeText(context, "请选择数据!!!", Toast.LENGTH_SHORT).show();
}
else {
//循环删除被选中子项
while(checklist.size()!=0){
Memo memo = checklist.get(0);
//删除在子项列表中位置
memoList.remove(memo);
//修改备忘录表中被删除子项type为删除状态10
mHelper.update_roommateMemo(memo,true,false);
//删除被选中子项列表位置
Roommate_memo_adapter.checkList.remove(0);
}
//更新文件行数
memoNum = mHelper.query_roommateMemo_rowsNumByType(false,false);
//更新RecycleView
adapter.notifyDataSetChanged();
//将选中子项列表清空
Roommate_memo_adapter.checkList.clear();
//若子项全被清空,则出现“没有数据”提示
if(memoList.size()==0) tv_empty.setVisibility(View.VISIBLE);
//显示删除通知
show_TypeOfDeleteNotification(remove_num);
}
}
/*清空子项*/
@SuppressLint("NotifyDataSetChanged")
private void clear(){
if (memoList.size()!=0){
//清空recycleView中子项
memoList.clear();
adapter.notifyDataSetChanged();
//出现空数据提示
tv_empty.setVisibility(View.VISIBLE);
//修改备忘录表中被删除子项type
mHelper.update_roommateAllMemoToDelete();
//显示删除通知
show_TypeOfDeleteNotification(memoNum);
//更新备忘录子项数为0
memoNum = 0;
}
else Toast.makeText(context, "子项已被清空", Toast.LENGTH_SHORT).show();
}
//显示删除通知
private void show_TypeOfDeleteNotification(int remove_num){
NotificationUtil notificationUtil = new NotificationUtil(context,"删除通知",
"您在备忘录中删除了"+remove_num+"条通知!!!",R.drawable.add_small_icon,
BitmapFactory.decodeResource(getResources(),R.drawable.remove_large_icon));
notificationUtil.notification();
}
/*重写顶部菜单栏菜单键*/
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
int id = item.getItemId();
Intent intent = new Intent(context,Story_activity.class);
switch (id){
case REMOVE:
Toast.makeText(context, "删除记录", Toast.LENGTH_SHORT).show();
Story_activity.open_type = 1;
startActivity(intent);
break;
case ADD:
Toast.makeText(context, "添加记录", Toast.LENGTH_SHORT).show();
Story_activity.open_type = 2;
startActivity(intent);
break;
case REVISE:
Toast.makeText(context, "修改记录", Toast.LENGTH_SHORT).show();
Story_activity.open_type = 3;
startActivity(intent);
break;
case android.R.id.home:
//no
return true;
default:
break;
}
return super.onOptionsItemSelected(item);
}
/**
*
* activity
* */
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.add(0,REMOVE,1,"删除记录");
menu.add(0,ADD,2,"增加记录");
menu.add(0,REVISE,3,"修改记录");
}
}

@ -0,0 +1,166 @@
package com.lh.app.ui.memo;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.lh.app.R;
import java.util.ArrayList;
import java.util.List;
/**
* Created by LiShiyao on 2022.10.5
*/
public class Roommate_memo_adapter extends RecyclerView.Adapter<Roommate_memo_adapter.ViewHolder> {
private List<Memo> mMemoList;
//选中的数据
public static List<Memo> checkList = new ArrayList<>();
//跳转至AddMemo界面携带的Memo
public static Memo jumpMemo = null;
public static int click_type = 1;//默认打开编辑界面
/**
* RecyclerView.ViewHolder
* */
static class ViewHolder extends RecyclerView.ViewHolder{
View memoView;
ImageView memoImage;
CheckBox isSelect;
RelativeLayout body_rel;
TextView memoTitle;
TextView memoContent;
TextView memoDate;
//修改
LinearLayout lil_showInfo;
ImageView img_back_showInfo;
TextView tv_title_showInfo;
TextView tv_date_showInfo;
TextView tv_content_showInfo;
TextView tv_roommate_showInfo;
// 作用:获取布局中的组件实例
// view参数 最外层布局(小方块)
public ViewHolder(View view){
super(view);
memoView = view;
memoImage = view.findViewById(R.id.memo_image);
isSelect = view.findViewById(R.id.ck_select);
body_rel = view.findViewById(R.id.body_rel);
memoTitle = view.findViewById(R.id.title_tev);
memoContent = view.findViewById(R.id.content_tev);
memoDate = view.findViewById(R.id.date_tv);
lil_showInfo = view.findViewById(R.id.lil_showInfo);
img_back_showInfo = view.findViewById(R.id.img_back_showInfo);
tv_title_showInfo = view.findViewById(R.id.tv_title_showInfo);
tv_date_showInfo = view.findViewById(R.id.tv_date_showInfo);
tv_content_showInfo = view.findViewById(R.id.tv_content_showInfo);
tv_roommate_showInfo = view.findViewById(R.id.tv_roommate_showInfo);
}
}
/**
*
*
* */
public Roommate_memo_adapter(List<Memo> memoList){
mMemoList = memoList;
}
//因为继承自RecyclerView.Adapter必须重写onCreateViewHolder、onBindViewHolder、getItemCount
/**
* onCreateViewHolder()ViewHolder
* onBindViewHolder() recycleView
* getItemCount() recycleView
* */
@SuppressLint("NonConstantResourceId")
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view;
//1.加载布局
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.memo_item,parent,false);
//2.创建ViewHolder实例
final ViewHolder holder = new ViewHolder(view);
//3.创建点击事件
//为view (小方块)创建监听事件
holder.body_rel.setOnClickListener(view1 -> {
if (click_type==1){//在备忘录界面点击子项
int position = holder.getAdapterPosition();
Memo memo = mMemoList.get(position);
jumpMemo = memo;//携带的Memo跳转
AddMemo_activity.is_revise = true;
//跳转界面
Intent intent = new Intent(view.getContext(), AddMemo_activity.class);
view.getContext().startActivity(intent);
}
if (click_type==2){//在增、删、改界面上点击
holder.lil_showInfo.setVisibility(View.VISIBLE);
int position = holder.getAdapterPosition();
Memo memo = mMemoList.get(position);
holder.tv_title_showInfo.setText(memo.getTitle());
holder.tv_date_showInfo.setText(memo.getDate());
holder.tv_content_showInfo.setText(memo.getContent());
holder.tv_roommate_showInfo.setText(memo.getName());
//禁用单选按钮,若被选中,取消选中
if (holder.isSelect.isChecked()) holder.isSelect.setChecked(false);
holder.isSelect.setEnabled(false);
}
//Toast.makeText(view.getContext(),"you clicked view " +memo.getImageId(),Toast.LENGTH_SHORT).show();
});
holder.img_back_showInfo.setOnClickListener(view1 -> {
holder.lil_showInfo.setVisibility(View.GONE);
//启用单选按钮
holder.isSelect.setEnabled(true);
});
//4.返回ViewHolder实例
return holder;
}
@SuppressLint("SetTextI18n")
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
//通过position参数 获得当前 Memo 实例
Memo memo = mMemoList.get(position);
//获得子项数据
holder.memoImage.setImageResource(memo.getImgID());
holder.memoTitle.setText(memo.getTitle());
//防止文本过长
String content = memo.getContent();
if (content.length()>14){
holder.memoContent.setText(content.substring(0,14)+"...");
}
else holder.memoContent.setText(content);
holder.memoDate.setText(memo.getDate());
//为checkBox创建监听事件
holder.isSelect.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
//单选按钮被选中将memo加入队列否则退出队列
if(isChecked) checkList.add(memo);
if (!isChecked) checkList.remove(memo);
}
});
}
@Override
public int getItemCount() {
return mMemoList.size();
}
}

@ -0,0 +1,290 @@
package com.lh.app.ui.memo;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.lh.app.MyApplication;
import com.lh.app.R;
import com.lh.app.RoommateDBHelper;
import com.lh.app.tool.NotificationUtil;
import java.util.ArrayList;
import java.util.List;
public class Story_activity extends AppCompatActivity {
private RecyclerView recyclerView_story;
private Roommate_memo_adapter adapter;
private List<Memo> memoList = new ArrayList<>();
private int memoNum = 0;
private Button btn_clear_story;
private TextView tv_empty;
private TextView tv_story_type;
private Button btn_back;
private Button but_remove_story;
private LinearLayout lil_showInfo;
public static int open_type = 0;//1:删除记录、2:增加记录、3:修改记录
//数据库帮助器对象实例
private RoommateDBHelper mHelper = MyApplication.mHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_story);
//将选中子项列表清空
Roommate_memo_adapter.checkList.clear();
Roommate_memo_adapter.click_type = 2;//点击子项出现详情1->2
addUI_and_listener();//添加UI和监听器
setTopPart();//顶部菜单隐藏
setRecycleView();
initList();
}
//添加UI和监听器
private void addUI_and_listener() {
btn_clear_story = (Button) findViewById(R.id.btn_clear_story);
tv_empty = (TextView) findViewById(R.id.empty_tv_story);
btn_back = (Button) findViewById(R.id.but_back_04) ;
tv_story_type = (TextView) findViewById(R.id.tv_title_04);
but_remove_story = (Button)findViewById(R.id.but_remove_story) ;
btn_clear_story.setOnClickListener(this::onclick);
btn_back.setOnClickListener(this::onclick);
but_remove_story.setOnClickListener(this::onclick);
}
@SuppressLint("NonConstantResourceId")
private void onclick(View view){
switch (view.getId()){
case R.id.but_back_04:
//将选中子项列表清空
Roommate_memo_adapter.checkList.clear();
//恢复点击子项显示编辑界面2->1
Roommate_memo_adapter.click_type = 1;
finish();
break;
case R.id.but_remove_story:
remove();
break;
case R.id.btn_clear_story:
//弹出弹框提示
new AlertDialog.Builder(Story_activity.this)
.setTitle("信息提示")
.setMessage("确认全删除?")
.setPositiveButton("是", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int i) {//确认按钮监听事件
//请空子项
clear();
//弹框消失
dialog.dismiss();
}
})
.setNegativeButton("否", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int i) {//返回按钮监听事件
dialog.dismiss();
}
}).show();//显示弹框
break;
}
}
/*初始化recycleView列表*/
private void initList() {
//更新文件行数
updateMemoNum();
Log.d("Roommate_activity","文件行数:"+ memoNum);
//若备忘录子项不为0则添加到recycleView中
if (memoNum !=0){
//先清空序列
memoList.clear();
//取备忘录中被显示数据
List<Memo> memoList = getMemoList();
for (Memo memo:memoList){
add(0,memo);//向recycleView开头插入子项
}
}
}
/*添加子项*/
private void add(int position,Memo memo){
Log.d("Roommate_activity","添加子项!");
tv_empty.setVisibility(View.GONE);
memoList.add(position,memo);
adapter.notifyItemInserted(position);
}
/*删除子项*/
@SuppressLint("NotifyDataSetChanged")
private void remove(){
//获取要被删除子项列表
List<Memo> checklist = Roommate_memo_adapter.checkList;
int remove_num = checklist.size();
//判断是否有要被删除的子项
if (remove_num == 0) {
Toast.makeText(this, "请选择数据!!!", Toast.LENGTH_SHORT).show();
}
else {
//循环删除被选中子项
while(checklist.size()!=0){
Memo memo = checklist.get(0);
//删除在子项列表中位置
memoList.remove(memo);
//删除在数据库中位置
deleteMemo(memo);
//删除被选中子项列表位置
Roommate_memo_adapter.checkList.remove(0);
}
//更新文件行数
memoNum = mHelper.query_roommateMemo_rowsNumByType(false,false);
//更新RecycleView
adapter.notifyDataSetChanged();
//将选中子项列表清空
Roommate_memo_adapter.checkList.clear();
//若子项全被清空,则出现“没有数据”提示
if(memoList.size()==0) tv_empty.setVisibility(View.VISIBLE);
//显示删除通知
show_TypeOfDeleteNotification(remove_num);
}
}
/*清空子项*/
@SuppressLint("NotifyDataSetChanged")
private void clear(){
if (memoList.size()!=0){
//清空recycleView中子项
memoList.clear();
adapter.notifyDataSetChanged();
//出现空数据提示
tv_empty.setVisibility(View.VISIBLE);
//清空文件数据
deleteAllTypeMemo();
//显示删除通知
show_TypeOfDeleteNotification(memoNum);
//更新备忘录子项数为0
memoNum = 0;
}
else Toast.makeText(this, "子项已被清空", Toast.LENGTH_SHORT).show();
}
//显示删除通知
private void show_TypeOfDeleteNotification(int remove_num){
NotificationUtil notificationUtil = new NotificationUtil(this,"删除通知",
"您在备忘录中删除了"+remove_num+"条通知!!!",R.drawable.add_small_icon,
BitmapFactory.decodeResource(getResources(),R.drawable.remove_large_icon));
notificationUtil.notification();
}
/*设置RecycleView样式*/
private void setRecycleView() {
//竖直流布局
recyclerView_story = (RecyclerView) findViewById(R.id.recycleView_story);
LinearLayoutManager LayoutManager2 = new LinearLayoutManager(this);
//LayoutManager2.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView_story.setLayoutManager(LayoutManager2);
adapter = new Roommate_memo_adapter(memoList);
recyclerView_story.setAdapter(adapter);
}
/**
*
* */
private void setTopPart(){
//隐藏菜单栏
ActionBar actionBar = getSupportActionBar();
if(actionBar != null){
actionBar.hide();
}
//设置菜单标题
switch (open_type) {
case 1:
tv_story_type.setText("删除记录");
break;
case 2:
tv_story_type.setText("增加记录");
break;
case 3:
tv_story_type.setText("修改记录");
break;
}
}
/*更新文件行数*/
private void updateMemoNum(){
switch (open_type) {
case 1:
memoNum = mHelper.query_roommateMemo_rowsNumByType(true,false);
break;
case 2:
memoNum = mHelper.query_roommateMemo_rowsNumByType(false,true);
break;
case 3:
memoNum = mHelper.query_roommateMemo_rowsNumByType(true,true);
break;
}
}
//取备忘录中指定数据
private List<Memo> getMemoList(){
switch (open_type) {
case 1:
return mHelper.query_roommateMemoByType(true,false);
case 2:
return mHelper.query_roommateMemoByType(false,true);
case 3:
return mHelper.query_roommateMemoByType(true,true);
}
return null;
}
//删除数据库备忘录表中指定类型数据
private void deleteMemo(Memo memo) {
long row = 0;
switch (open_type) {
case 1:
//删除删除子项1,0
row = mHelper.deleteMemoByType(memo,true,false);
break;
case 2:
//删除增加子项1,0
row = mHelper.deleteMemoByType(memo,false,true);
break;
case 3:
//删除修改子项1,0
row = mHelper.deleteMemoByType(memo,true,true);
break;
}
Log.d("delete"+open_type+"型","删除第"+row+"行");
}
//删除数据库备忘录表中指定类型全部数据
private void deleteAllTypeMemo() {
switch (open_type) {
case 1:
mHelper.deleteMemoAllType(true,false);
case 2:
mHelper.deleteMemoAllType(false,true);
case 3:
mHelper.deleteMemoAllType(true,true);
}
}
}

@ -0,0 +1,459 @@
package com.lh.app.ui.mine;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.Looper;
import android.provider.Settings;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.core.app.ActivityCompat;
import androidx.fragment.app.Fragment;
import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.LocationSource;
import com.amap.api.maps.MapView;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.MyLocationStyle;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.tasks.OnSuccessListener;
import com.lh.app.R;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
/**
* Fragment
*
* - android.permission.ACCESS_FINE_LOCATION
* - android.permission.ACCESS_COARSE_LOCATION
* - android.permission.INTERNET
* - android.permission.ACCESS_NETWORK_STATE
*/
public class MineFragment extends Fragment implements AMapLocationListener, LocationSource {
private static final int LOCATION_PERMISSION_REQUEST_CODE = 1;
private static final int REQUEST_ENABLE_GPS = 2;
private FusedLocationProviderClient fusedLocationClient;
private MapView mapView;
private AMap aMap;
private TextView tvLocation;
private Button btnLocation;
// 高德定位相关
private AMapLocationClient locationClient;
private AMapLocationClientOption locationOption;
private OnLocationChangedListener mapLocationListener;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 设置隐私合规接口
AMapLocationClient.updatePrivacyShow(getContext(), true, true);
AMapLocationClient.updatePrivacyAgree(getContext(), true);
fusedLocationClient = LocationServices.getFusedLocationProviderClient(getContext());
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_mine, container, false);
initViews(view);
initMap(savedInstanceState, view);
return view;
}
private void initViews(View view) {
tvLocation = view.findViewById(R.id.text_location);
btnLocation = view.findViewById(R.id.btn_getLocation);
btnLocation.setOnClickListener(v -> checkLocationAndPermission());
}
private void initMap(Bundle savedInstanceState, View view) {
mapView = view.findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
if (aMap == null) {
aMap = mapView.getMap();
setupMap();
}
}
private void setupMap() {
// 设置地图参数
aMap.getUiSettings().setZoomControlsEnabled(true);
aMap.getUiSettings().setMyLocationButtonEnabled(false); // 使用自定义按钮
// 设置定位蓝点样式
MyLocationStyle myLocationStyle = new MyLocationStyle();
myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);
myLocationStyle.interval(5000); // 定位间隔
myLocationStyle.strokeColor(android.R.color.transparent);
myLocationStyle.radiusFillColor(0x500000FF);
aMap.setMyLocationStyle(myLocationStyle);
// 设置定位源
aMap.setLocationSource(this);
aMap.setMyLocationEnabled(true);
}
private void checkLocationAndPermission() {
if (!isNetworkConnected()) {
showNetworkDisconnectedAlert();
return;
}
if (!isGpsEnabled()) {
showGpsDisabledAlert();
return;
}
if (hasLocationPermission()) {
startLocation();
} else {
requestLocationPermission();
}
}
private boolean isGpsEnabled() {
LocationManager manager = (LocationManager) requireContext()
.getSystemService(Context.LOCATION_SERVICE);
return manager.isProviderEnabled(LocationManager.GPS_PROVIDER);
}
private void showGpsDisabledAlert() {
new AlertDialog.Builder(requireContext())
.setTitle("GPS未开启")
.setMessage("需要开启GPS才能获取精确位置")
.setPositiveButton("去设置", (dialog, which) -> {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivityForResult(intent, REQUEST_ENABLE_GPS);
})
.setNegativeButton("取消", null)
.show();
}
private boolean hasLocationPermission() {
return ActivityCompat.checkSelfPermission(requireContext(),
Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(requireContext(),
Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED;
}
private void requestLocationPermission() {
if (shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION) ||
shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_COARSE_LOCATION)) {
new AlertDialog.Builder(requireContext())
.setTitle("需要位置权限")
.setMessage("应用需要位置权限来提供定位服务")
.setPositiveButton("确定", (dialog, which) -> {
requestPermissions(
new String[]{
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
},
LOCATION_PERMISSION_REQUEST_CODE);
})
.setNegativeButton("取消", null)
.show();
} else {
requestPermissions(
new String[]{
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
},
LOCATION_PERMISSION_REQUEST_CODE);
}
}
private void startLocation() {
requestLocationUpdates();
if (locationClient == null) {
initLocationClient();
}
if (!locationClient.isStarted()) {
locationClient.startLocation();
btnLocation.setText("定位中...");
}
}
@SuppressLint("MissingPermission")
private void getLastLocation() {
fusedLocationClient.getLastLocation()
.addOnSuccessListener(requireActivity(), new OnSuccessListener<Location>() {
@Override
public void onSuccess(Location location) {
if (location != null) {
// 获取到位置信息
double latitude = location.getLatitude();
double longitude = location.getLongitude();
Log.d("Location", "Latitude: " + latitude + ", Longitude: " + longitude);
} else {
// 位置信息为空
Log.d("Location", "No location found");
}
}
});
}
private void requestLocationUpdates() {
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setInterval(10000); // 更新间隔
locationRequest.setFastestInterval(5000); // 最快更新间隔
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); // 高精度模式
LocationCallback locationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
if (locationResult == null) {
return;
}
for (Location location : locationResult.getLocations()) {
Log.d("Location", "Latitude: " + location.getLatitude() + ", Longitude: " + location.getLongitude());
getAddressFromLocation(location.getLatitude(),location.getLongitude());
}
}
};
if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper());
}
private void getAddressFromLocation(double latitude, double longitude) {
Geocoder geocoder = new Geocoder(getContext(), Locale.getDefault());
try {
List<Address> addresses = geocoder.getFromLocation(latitude, longitude, 1);
if (addresses != null && addresses.size() > 0) {
Address address = addresses.get(0);
String province = address.getAdminArea(); // 省
String city = address.getLocality(); // 市
String district = address.getSubLocality(); // 区
String fullAddress = String.format("%s,%s,%s", province, city, district);
Log.d("Location", "Full Address: " + fullAddress);
// 更新 UI 或其他逻辑
getActivity().runOnUiThread(() -> tvLocation.setText(fullAddress));
}
} catch (IOException e) {
Log.e("Location", "Error getting address", e);
}
}
private void initLocationClient() {
try {
locationClient = new AMapLocationClient(requireContext());
locationOption = new AMapLocationClientOption();
// 修改定位参数
locationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
locationOption.setNeedAddress(true); // 确保这个设置为true
locationOption.setOnceLocation(false);//false表示连续定位
locationOption.setWifiActiveScan(true);
locationOption.setHttpTimeOut(20000); // 设置超时时间
locationOption.setLocationCacheEnable(false); // 关闭缓存
locationOption.setInterval(10000);
locationClient.setLocationOption(locationOption);
locationClient.setLocationListener(this);
} catch (Exception e) {
Log.e("Location", "初始化定位失败", e);
Toast.makeText(requireContext(), "定位初始化失败", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onLocationChanged(AMapLocation location) {
if (location == null) {
Log.e("Location", "定位结果为空");
return;
}
// 打印完整的定位信息用于调试
Log.d("Location", "完整定位信息: " + location.toString());
if (location.getErrorCode() == 0) {
updateLocationUI(location);
} else {
showLocationError(location);
// 尝试重新启动定位
if (locationClient != null) {
locationClient.stopLocation();
locationClient.startLocation();
}
}
}
private void updateLocationUI(AMapLocation location) {
// 移动地图到当前位置
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 16));
/* // 获取省、市、区信息
String province = location.getProvince();
String city = location.getCity();
String district = location.getDistrict();
// 检查是否为空
Log.d("Location", "Province: " + province + ", City: " + city + ", District: " + district);
// 构建显示信息
StringBuilder locationInfoBuilder = new StringBuilder();
if (province != null && !province.isEmpty()) {
locationInfoBuilder.append(province).append("省");
}
if (city != null && !city.isEmpty()) {
locationInfoBuilder.append(city).append("市");
}
if (district != null && !district.isEmpty()) {
locationInfoBuilder.append(district).append("区");
}
String locationInfo = locationInfoBuilder.toString();
if (locationInfo.isEmpty()) {
locationInfo = "未获取到详细地址信息";
}
// 更新 UI
if (tvLocation != null) {
String finalLocationInfo = locationInfo;
getActivity().runOnUiThread(() -> tvLocation.setText(finalLocationInfo));
} else {
Log.e("Location", "tvLocation is null");
}*/
// 通知地图更新蓝点位置
if (mapLocationListener != null) {
mapLocationListener.onLocationChanged(location);
}
}
private void showLocationError(AMapLocation location) {
String errorInfo = String.format("定位失败\n错误码: %d\n错误信息: %s",
location.getErrorCode(),
location.getErrorInfo());
tvLocation.setText(errorInfo);
Toast.makeText(requireContext(), errorInfo, Toast.LENGTH_SHORT).show();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
if (requestCode == LOCATION_PERMISSION_REQUEST_CODE) {
if (grantResults.length >= 2 &&
grantResults[0] == PackageManager.PERMISSION_GRANTED &&
grantResults[1] == PackageManager.PERMISSION_GRANTED) {
startLocation();
} else {
Toast.makeText(requireContext(), "定位权限被拒绝", Toast.LENGTH_SHORT).show();
}
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
if (requestCode == REQUEST_ENABLE_GPS && isGpsEnabled()) {
startLocation();
}
}
// ========== LocationSource 接口实现 ==========
@Override
public void activate(OnLocationChangedListener listener) {
mapLocationListener = listener;
}
@Override
public void deactivate() {
mapLocationListener = null;
}
// ========== 生命周期管理 ==========
@Override
public void onResume() {
super.onResume();
mapView.onResume();
}
@Override
public void onPause() {
super.onPause();
mapView.onPause();
stopLocation();
}
@Override
public void onDestroy() {
super.onDestroy();
mapView.onDestroy();
releaseLocation();
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
}
private void stopLocation() {
if (locationClient != null && locationClient.isStarted()) {
locationClient.stopLocation();
btnLocation.setText("开始定位");
}
}
private void releaseLocation() {
if (locationClient != null) {
locationClient.stopLocation();
locationClient.onDestroy();
locationClient = null;
}
}
private boolean isNetworkConnected() {
Context context = requireContext();
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = null;
if (connectivityManager != null) {
networkInfo = connectivityManager.getActiveNetworkInfo();
}
return networkInfo != null && networkInfo.isConnected();
}
private void showNetworkDisconnectedAlert() {
new AlertDialog.Builder(requireContext())
.setTitle("网络连接断开")
.setMessage("请检查网络连接后重试")
.setPositiveButton("确定", null)
.show();
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
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="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 460 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 圆角 -->
<corners
android:radius="10dp"
android:topLeftRadius="10dp"
android:topRightRadius="10dp"
android:bottomLeftRadius="10dp"
android:bottomRightRadius="10dp"/><!-- 设置圆角半径 -->
<!-- 填充 -->
<solid android:color="#FDFDC0"/>
<!-- 描边 -->
<stroke
android:width="2dp"
android:color="#7A7A7A"
android:dashWidth="20dp"
android:dashGap="0dp"/><!--设置虚线的间隔宽度-->
<!-- 大小 -->
<size
android:width="50dp"
android:height="50dp"/><!-- 宽度和高度 -->
</shape>

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 圆角 -->
<corners
android:radius="10dp"
android:topLeftRadius="10dp"
android:topRightRadius="10dp"
android:bottomLeftRadius="10dp"
android:bottomRightRadius="10dp"/><!-- 设置圆角半径 -->
<!-- 渐变 -->
<gradient
android:startColor="#88D3FA"
android:centerColor="#C0E6FB"
android:endColor="@android:color/black"
android:useLevel="true"
android:angle="135"
android:type="linear"
android:centerX="10"
android:centerY="10"
android:gradientRadius="90"/>
<!-- 文本与边间隔 -->
<padding
android:left="10dp"
android:top="2dp"
android:right="10dp"
android:bottom="2dp"/><!-- 各方向的间隔 -->
<!-- 描边 -->
<stroke
android:width="1dp"
android:color="#88D3FA"
android:dashWidth="2dp"
android:dashGap="0dp"/>
</shape>
<!--
填充:设置填充的颜色
间隔:设置四个方向上的间隔
大小:设置大小
圆角同时设置五个属性则Radius属性无效
android:Radius="20dp" 设置四个角的半径
android:topLeftRadius="20dp" 设置左上角的半径
android:topRightRadius="20dp" 设置右上角的半径
android:bottomLeftRadius="20dp" 设置右下角的半径
android:bottomRightRadius="20dp" 设置左下角的半径
描边dashWidth和dashGap属性只要其中一个设置为0dp则边框为实现边框
android:width="20dp" 设置边边的宽度
android:color="@android:color/black" 设置边边的颜色
android:dashWidth="2dp" 设置虚线的宽度
android:dashGap="20dp" 设置虚线的间隔宽度
渐变:当设置填充颜色后,无渐变效果。
angle的值必须是45的倍数包括0仅在type="linear"有效,不然会报错。
android:useLevel 这个属性不知道有什么用。
-->

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 圆角 -->
<corners
android:radius="10dp"
android:topLeftRadius="10dp"
android:topRightRadius="10dp"
android:bottomLeftRadius="10dp"
android:bottomRightRadius="8dp"/><!-- 设置圆角半径 -->
<!-- 填充 -->
<solid android:color="#333232"/>
<!-- 大小 -->
<size
android:width="2dp"
android:height="5dp"/><!-- 宽度和高度 -->
</shape>

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M3,13h8L11,3L3,3v10zM3,21h8v-6L3,15v6zM13,21h8L21,11h-8v10zM13,3v6h8L21,3h-8z" />
</vector>

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z" />
</vector>

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<vector
android:height="108dp"
android:width="108dp"
android:viewportHeight="108"
android:viewportWidth="108"
xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#3DDC84"
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,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.89,2 2,2zM18,16v-5c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2z" />
</vector>

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 圆角 -->
<corners
android:radius="10dp"
android:topLeftRadius="10dp"
android:topRightRadius="10dp"
android:bottomLeftRadius="10dp"
android:bottomRightRadius="10dp"/><!-- 设置圆角半径 -->
<!-- 渐变 -->
<gradient
android:startColor="#88D3FA"
android:centerColor="#C0E6FB"
android:endColor="@android:color/black"
android:useLevel="true"
android:angle="135"
android:type="linear"
android:centerX="10"
android:centerY="10"
android:gradientRadius="90"/>
<!-- 文本与边间隔 -->
<padding
android:left="10dp"
android:top="2dp"
android:right="10dp"
android:bottom="2dp"/><!-- 各方向的间隔 -->
<!-- 描边 -->
<stroke
android:width="5dp"
android:color="#2F69DD"
android:dashWidth="2dp"
android:dashGap="0dp"/>
</shape>
<!--
填充:设置填充的颜色
间隔:设置四个方向上的间隔
大小:设置大小
圆角同时设置五个属性则Radius属性无效
android:Radius="20dp" 设置四个角的半径
android:topLeftRadius="20dp" 设置左上角的半径
android:topRightRadius="20dp" 设置右上角的半径
android:bottomLeftRadius="20dp" 设置右下角的半径
android:bottomRightRadius="20dp" 设置左下角的半径
描边dashWidth和dashGap属性只要其中一个设置为0dp则边框为实现边框
android:width="20dp" 设置边边的宽度
android:color="@android:color/black" 设置边边的颜色
android:dashWidth="2dp" 设置虚线的宽度
android:dashGap="20dp" 设置虚线的间隔宽度
渐变:当设置填充颜色后,无渐变效果。
angle的值必须是45的倍数包括0仅在type="linear"有效,不然会报错。
android:useLevel 这个属性不知道有什么用。
-->

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#40AE45" android:state_checked="true"/>
<item android:color="#45AEBC" android:state_checked="false"/>
</selector>

@ -0,0 +1,29 @@
<androidx.constraintlayout.widget.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">
<androidx.viewpager.widget.ViewPager
android:id="@+id/mViewPager"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@+id/nav_view"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/nav_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:background="?android:attr/windowBackground"
app:itemIconTint="@drawable/sl_tab_color"
app:itemTextColor="@drawable/sl_tab_color"
app:menu="@menu/bottom_nav_menu_main" />
</androidx.constraintlayout.widget.ConstraintLayout>

@ -0,0 +1,65 @@
<?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">
<include
android:id="@+id/menu"
layout="@layout/top_part_04"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/menu"
android:padding="10dp">
<TextView
android:id="@+id/empty_tv_story"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:textSize="24dp"
android:text="没有数据~~~"
android:layout_centerHorizontal="true"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycleView_story"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/line"
android:layout_below="@+id/empty_tv_story"
android:layout_marginBottom="5dp" />
<TextView
android:id="@+id/line"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#9E9999"
android:layout_above="@+id/lil_btn"/>
<LinearLayout
android:id="@+id/lil_btn"
android:layout_width="match_parent"
android:layout_height="70dp"
android:orientation="horizontal"
android:layout_alignParentBottom="true"
android:padding="10dp">
<Button
android:id="@+id/but_remove_story"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="移除" />
<Button
android:id="@+id/btn_clear_story"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="清空记录"
/>
</LinearLayout>
</RelativeLayout>
</RelativeLayout>

@ -0,0 +1,100 @@
<?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">
<include
android:id="@+id/Top"
android:layout_width="match_parent"
android:layout_height="wrap_content"
layout="@layout/top_part_2" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp">
<EditText
android:id="@+id/title_edt"
android:layout_width="match_parent"
android:layout_height="50dp"
android:textSize="20sp"
android:hint="标题"/>
<TextClock
android:id="@+id/clock"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/title_edt"
android:gravity="left"
android:format24Hour="MMM dd日 H:mm"
android:textColor="#999999"
android:textSize="15sp" />
<EditText
android:id="@+id/content_edt"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/radioGroup"
android:layout_below="@+id/clock"
android:layout_marginTop="20dp"
android:layout_marginBottom="10dp"
android:background="@drawable/bg_boarder"
android:imeOptions="actionDone"
android:inputType="text"
android:maxLines="100"
android:padding="10dp"
android:singleLine="false"
android:textColor="#3C3F41"
android:textColorLink="#F7413A"
android:textCursorDrawable="@drawable/cursor_style"
android:textSize="15sp"
android:textStyle="normal" />
<RadioGroup
android:id="@+id/radioGroup"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_alignParentBottom="true"
android:orientation="horizontal">
<RadioButton
android:id="@+id/btn_all"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:checked="true"
android:text="全部" />
<RadioButton
android:id="@+id/btn_lzh"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="-60dp"
android:text="李航" />
<RadioButton
android:id="@+id/btn_tzh"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:text="张三龙" />
<RadioButton
android:id="@+id/btn_fb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:text="李航" />
<RadioButton
android:id="@+id/btn_lsy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:text="陈瑞育" />
</RadioGroup>
</RelativeLayout>
</LinearLayout>

@ -0,0 +1,267 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp">
<LinearLayout
android:id="@+id/L"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_centerHorizontal="true">
<TextClock
android:id="@+id/timeText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:format24Hour="HH:mm"
android:format12Hour="hh:mm"
android:gravity="center"
android:textColor="@color/black"
android:textStyle="bold"
android:textSize="24sp"/>
<TextClock
android:id="@+id/dataTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:format12Hour="yyyy/MM/dd E"
android:format24Hour="yyyy/MM/dd E"
android:gravity="center"
android:textColor="@color/black"
android:textSize="14sp"
android:layout_marginLeft="10dp"/>
</LinearLayout>
<ImageView
android:id="@+id/roommate1_img"
android:layout_width="80dp"
android:layout_height="100dp"
android:layout_below="@+id/roommate1"
android:layout_marginTop="10dp"
android:src="@drawable/hyt" />
<TextView
android:id="@+id/roommate1"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_below="@+id/L"
android:layout_marginTop="10dp"
android:fontFamily="@font/you_light"
android:text="mate1"
android:textSize="24dp" />
<ImageView
android:id="@+id/roommate2_img"
android:layout_width="80dp"
android:layout_height="100dp"
android:layout_below="@+id/roommate2"
android:layout_marginLeft="20dp"
android:layout_marginTop="10dp"
android:layout_toRightOf="@+id/roommate1_img"
android:src="@drawable/wyz1" />
<TextView
android:id="@+id/roommate2"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_below="@+id/L"
android:layout_marginLeft="20dp"
android:layout_marginTop="10dp"
android:layout_toRightOf="@+id/roommate1"
android:fontFamily="@font/you_light"
android:text="mate2"
android:textSize="24dp" />
<ImageView
android:id="@+id/roommate3_img"
android:layout_width="80dp"
android:layout_height="100dp"
android:layout_below="@+id/roommate3"
android:layout_marginLeft="20dp"
android:layout_marginTop="10dp"
android:layout_toRightOf="@+id/roommate2"
android:src="@drawable/wz" />
<TextView
android:id="@+id/roommate3"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_below="@id/L"
android:layout_marginLeft="20dp"
android:layout_marginTop="10dp"
android:layout_toRightOf="@id/roommate2"
android:fontFamily="@font/you_light"
android:text="mate3"
android:textSize="24dp" />
<RatingBar
android:id="@+id/roommate1_star"
style="?android:attr/ratingBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/roommate1_img"
android:isIndicator="false"
android:numStars="5"
android:rating="5"
android:stepSize="0.5"
tools:ignore="SpeakableTextPresentCheck,SpeakableTextPresentCheck" />
<RatingBar
android:id="@+id/roommate2_star"
style="?android:attr/ratingBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/roommate2_img"
android:layout_marginLeft="20dp"
android:layout_toRightOf="@+id/roommate1_star"
android:isIndicator="false"
android:numStars="5"
android:rating="5"
android:stepSize="0.5"
tools:ignore="SpeakableTextPresentCheck" />
<RatingBar
android:id="@+id/roommate3_star"
style="?android:attr/ratingBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/roommate3_img"
android:layout_marginLeft="20dp"
android:layout_toRightOf="@+id/roommate2_star"
android:isIndicator="false"
android:numStars="5"
android:rating="5"
android:stepSize="0.5"
tools:ignore="SpeakableTextPresentCheck" />
<Button
android:id="@+id/source_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/roommate1_star"
android:layout_marginTop="10dp"
android:text="打回原形" />
<Button
android:id="@+id/but_clear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/roommate2_star"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_toRightOf="@+id/source_button"
android:text="清空数据库" />
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/source_button"
android:layout_marginTop="10dp"
android:fontFamily="@font/you_light"
android:hint="无内容"
android:lineSpacingExtra="10dp"
android:padding="10dp"
android:textSize="18dp"
android:visibility="visible"
android:background="#5174C3E3"/>
<ScrollView
android:id="@+id/scr_enterIfo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:background="#50232323"
android:layout_below="@+id/source_button"
android:padding="20dp"
android:visibility="gone">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="80dp"
android:text="录入舍友介绍"
android:textSize="25dp" />
<EditText
android:id="@+id/ed_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:inputType="textPersonName"
android:hint="姓名"/>
<EditText
android:id="@+id/ed_sno"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:inputType="number"
android:hint="学号"/>
<EditText
android:id="@+id/ed_weight"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:inputType="number"
android:numeric="decimal"
android:hint="体重(kg)"/>
<EditText
android:id="@+id/ed_height"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:inputType="number"
android:numeric="integer"
android:hint="身高(cm)"/>
<EditText
android:id="@+id/ed_birthday"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:inputType="date"
android:hint="出生日期(2000.10.10)"/>
<!--textMultiLine 多行输入-->
<EditText
android:id="@+id/ed_hobby"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:inputType="textMultiLine"
android:maxLength="100"
android:hint="爱好(小于100字)"/>
<CheckBox
android:id="@+id/ckb_isMarried"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="是否结婚"
android:textSize="20dp"
android:layout_marginTop="5dp"/>
<Button
android:id="@+id/sure_but"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginLeft="200dp"
android:text="完成"/>
</LinearLayout>
</ScrollView>
<com.github.mikephil.charting.charts.LineChart
android:id="@+id/show_img_curve"
android:layout_marginTop="20dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/source_button"
android:background="#50232323"
android:padding="20dp"
android:visibility="gone"
android:orientation="vertical"/>
</RelativeLayout>

@ -0,0 +1,97 @@
<?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">
<TextView
android:id="@+id/tv_emptyHonor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="没有数据~~~"
android:textSize="24dp" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_honor"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/L"
android:padding="10dp" />
<LinearLayout
android:id="@+id/ll_inputHonor"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/L"
android:orientation="vertical"
android:padding="10dp"
android:visibility="gone">
<Button
android:id="@+id/but_backHonor"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="@drawable/back"/>
<ImageView
android:id="@+id/img_imgHonor"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_marginTop="10dp"
android:src="@drawable/img_add"
android:background="@drawable/img_honor_style"
android:scaleType="centerInside"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="描述:"
android:textSize="28dp"/>
<EditText
android:id="@+id/edt_contentHonor"
android:layout_width="match_parent"
android:layout_height="150dp"
android:background="@drawable/bg_boarder"
android:imeOptions="actionDone"
android:inputType="text"
android:maxLines="100"
android:padding="10dp"
android:singleLine="false"
android:textColor="#3C3F41"
android:textColorLink="#F7413A"
android:textCursorDrawable="@drawable/cursor_style"
android:textSize="15sp"
android:textStyle="normal"/>
<Button
android:id="@+id/but_sureHonor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="确定"/>
</LinearLayout>
<LinearLayout
android:id="@+id/L"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_alignParentBottom="true"
android:orientation="horizontal"
android:padding="10dp">
<Button
android:id="@+id/but_addHonor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="添加"/>
<Button
android:id="@+id/but_removeHonor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="移除"
android:layout_marginLeft="10dp"/>
<Button
android:id="@+id/btn_clearHonor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="清空"
android:layout_marginLeft="10dp"/>
</LinearLayout>
</RelativeLayout>

@ -0,0 +1,65 @@
<?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:id="@+id/allMemo_Rel"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycleView_horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/line" />
<TextView
android:id="@+id/empty_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="没有数据~~~"
android:textSize="24dp" />
<TextView
android:id="@+id/line"
android:layout_width="match_parent"
android:layout_height="2px"
android:background="#AFB1B3"
android:layout_above="@+id/L"/>
<LinearLayout
android:id="@+id/L"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_alignParentBottom="true"
android:orientation="horizontal"
android:padding="10dp">
<Button
android:id="@+id/add_but"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="添加"/>
<Button
android:id="@+id/remove_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="移除"
android:layout_marginLeft="10dp"/>
<Button
android:id="@+id/clear_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="清空"
android:layout_marginLeft="10dp"/>
</LinearLayout>
</RelativeLayout>
</LinearLayout>

@ -0,0 +1,268 @@
<?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:padding="10dp">
<com.lh.app.tool.CircleImageView
android:id="@+id/img_headPicture"
android:layout_width="80dp"
android:layout_height="80dp"
android:scaleType="centerCrop"
android:src="@drawable/img_cat" />
<TextView
android:id="@+id/text_Account"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/img_headPicture"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:text="航航子最帅"
android:textSize="24dp"/>
<TextView
android:id="@+id/text_describe"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2025 你在,我在,便是温暖时光"
android:layout_toRightOf="@+id/img_headPicture"
android:layout_below="@id/text_Account"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:textSize="18dp"/>
<TextView
android:id="@+id/line_1"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_below="@+id/img_headPicture"
android:layout_marginTop="10dp"
android:background="#AEABAB" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_below="@+id/line_1">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@id/text_name1"
android:layout_width="90dp"
android:layout_height="wrap_content"
android:text="姓名:"
android:textSize="20dp"
android:layout_marginTop="20dp"
android:gravity="center_horizontal"
/>
<TextView
android:id="@+id/text_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/text_name1"
android:layout_marginLeft="10dp"
android:layout_marginTop="20dp"
android:text="李航"
android:textSize="20dp"
android:gravity="center_horizontal"/>
<TextView
android:id="@+id/line_2"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_below="@+id/text_name"
android:layout_toRightOf="@+id/text_name1"
android:layout_marginLeft="10dp"
android:background="#AEABAB"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp">
<TextView
android:id="@id/text_weight2"
android:layout_width="90dp"
android:layout_height="wrap_content"
android:text="体重(kg):"
android:textSize="20dp"
android:layout_marginTop="20dp"
android:gravity="center_horizontal"
/>
<TextView
android:id="@+id/text_weight"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="20dp"
android:layout_toRightOf="@+id/text_weight2"
android:gravity="center_horizontal"
android:text="60"
android:textSize="20dp" />
<TextView
android:id="@+id/line_3"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_below="@+id/text_weight"
android:layout_toRightOf="@+id/text_weight2"
android:layout_marginLeft="10dp"
android:background="#AEABAB"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp">
<TextView
android:id="@id/text_height2"
android:layout_width="90dp"
android:layout_height="wrap_content"
android:text="身高(cm):"
android:textSize="20dp"
android:layout_marginTop="20dp"
android:gravity="center_horizontal"
/>
<TextView
android:id="@+id/text_height"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/text_height2"
android:layout_marginLeft="10dp"
android:layout_marginTop="20dp"
android:text="175"
android:textSize="20dp"
android:gravity="center_horizontal"/>
<TextView
android:id="@+id/line_4"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_below="@+id/text_height"
android:layout_toRightOf="@+id/text_height2"
android:layout_marginLeft="10dp"
android:background="#AEABAB"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp">
<TextView
android:id="@id/text_birthday2"
android:layout_width="90dp"
android:layout_height="wrap_content"
android:text="生日:"
android:textSize="20dp"
android:layout_marginTop="20dp"
android:gravity="center_horizontal"
/>
<TextView
android:id="@+id/text_birthday"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/text_birthday2"
android:layout_marginLeft="10dp"
android:layout_marginTop="20dp"
android:text="2000.8.4"
android:textSize="20dp"
android:gravity="center_horizontal"/>
<TextView
android:id="@+id/line_5"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_below="@+id/text_birthday"
android:layout_toRightOf="@+id/text_birthday2"
android:layout_marginLeft="10dp"
android:background="#AEABAB"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp">
<TextView
android:id="@id/text_hobby2"
android:layout_width="90dp"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:gravity="center_horizontal"
android:text="爱好:"
android:textSize="20dp" />
<TextView
android:id="@+id/text_hobby"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/text_hobby2"
android:layout_marginLeft="10dp"
android:layout_marginTop="20dp"
android:text="游泳+篮球+游戏+音乐"
android:textSize="20dp"
android:gravity="center_horizontal"/>
<TextView
android:id="@+id/line_6"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_below="@+id/text_hobby"
android:layout_toRightOf="@+id/text_hobby2"
android:layout_marginLeft="10dp"
android:background="#AEABAB"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp">
<TextView
android:id="@+id/text_hobby3"
android:layout_width="90dp"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:gravity="center_horizontal"
android:text="当前位置:"
android:textSize="20sp" />
<TextView
android:id="@+id/text_location"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="20dp"
android:layout_toStartOf="@+id/btn_getLocation"
android:layout_toEndOf="@+id/text_hobby3"
android:gravity="center_horizontal"
android:text="---"
android:textSize="20sp" />
<Button
android:id="@+id/btn_getLocation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="更新位置"
android:layout_alignParentEnd="true"
android:layout_marginEnd="10dp" />
<TextView
android:id="@+id/line_7"
android:layout_width="wrap_content"
android:layout_height="1dp"
android:layout_below="@+id/text_location"
android:layout_marginTop="10dp"
android:layout_marginStart="10dp"
android:layout_toEndOf="@+id/text_hobby3"
android:layout_toStartOf="@id/btn_getLocation"
android:background="#AEABAB" />
</RelativeLayout>
<!-- 高德地图容器 -->
<com.amap.api.maps.MapView
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- 定位按钮 -->
<ImageButton
android:id="@+id/btn_location"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:layout_margin="16dp"
android:background="@drawable/ic_my_location"
android:contentDescription="定位到当前位置" />
</LinearLayout>
</RelativeLayout>

@ -0,0 +1,20 @@
<?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:orientation="vertical"
android:padding="10dp">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="请选择一项照片"
android:layout_centerHorizontal="true"
android:textSize="24dp"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/img_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_title"
android:nestedScrollingEnabled="false"/>
</RelativeLayout>

@ -0,0 +1,22 @@
<?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:orientation="vertical">
<CheckBox
android:id="@+id/ckb_honorItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ImageView
android:id="@+id/img_honor"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_toRightOf="@+id/ckb_honorItem"
android:scaleType="centerInside"/>
<TextView
android:id="@+id/tv_describe"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/img_honor"
/>
</RelativeLayout>

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 显示查询到的手机本地图片 -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!-- 图片显示 -->
<ImageView
android:id="@+id/image_img"
android:layout_width="100dp"
android:layout_height="100dp">
</ImageView>
<CheckBox
android:id="@+id/is_select"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>

@ -0,0 +1,163 @@
<?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:orientation="horizontal">
<CheckBox
android:id="@+id/ck_select"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginTop="30dp"
android:layout_gravity="center"
android:padding="5dp" />
<RelativeLayout
android:id="@+id/body_rel"
android:layout_width="wrap_content"
android:layout_height="90dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:layout_toRightOf="@+id/ck_select"
android:background="@drawable/button_style"
android:padding="10dp">
<ImageView
android:id="@+id/memo_image"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_gravity="center_horizontal" />
<TextView
android:id="@+id/title_tev"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginStart="20dp"
android:layout_toRightOf="@+id/memo_image"
android:hint="title"
android:textSize="16dp" />
<TextView
android:id="@+id/content_tev"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/title_tev"
android:layout_gravity="center_horizontal"
android:layout_marginStart="20dp"
android:layout_toEndOf="@+id/memo_image"
android:hint="content"
android:textSize="12sp" />
<TextView
android:id="@+id/date_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:text="date"
android:textSize="12sp" />
</RelativeLayout>
<LinearLayout
android:id="@+id/lil_showInfo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#8A515050"
android:orientation="vertical"
android:visibility="gone">
<ImageView
android:id="@+id/img_back_showInfo"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginTop="80dp"
android:src="@drawable/back" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="-45dp"
android:text="详情"
android:textSize="30dp"
android:textColor="#F1E9E9"/>
<RelativeLayout
android:layout_width="300dp"
android:layout_height="350dp"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:layout_marginBottom="20dp"
android:background="@drawable/button_style"
android:padding="10dp">
<TextView
android:id="@+id/tv_title_default"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="标题:"
android:textSize="15dp" />
<TextView
android:id="@+id/tv_title_showInfo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/tv_title_default" />
<TextView
android:id="@+id/tv_date_default"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_title_showInfo"
android:layout_marginTop="5dp"
android:text="时间:"
android:textSize="15dp" />
<TextView
android:id="@+id/tv_date_showInfo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_title_showInfo"
android:layout_marginTop="5dp"
android:layout_toRightOf="@+id/tv_date_default" />
<TextView
android:id="@+id/tv_content_default"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_date_showInfo"
android:layout_marginTop="5dp"
android:text="内容:"
android:textSize="15dp" />
<TextView
android:id="@+id/tv_content_showInfo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_date_showInfo"
android:layout_marginTop="5dp"
android:layout_toRightOf="@+id/tv_content_default" />
<TextView
android:id="@+id/tv_roommate_default"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_content_showInfo"
android:layout_marginTop="5dp"
android:text="选择室友:"
android:textSize="15dp" />
<TextView
android:id="@+id/tv_roommate_showInfo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_content_showInfo"
android:layout_marginTop="5dp"
android:layout_toRightOf="@+id/tv_roommate_default" />
</RelativeLayout>
</LinearLayout>
</RelativeLayout>

@ -0,0 +1,32 @@
<?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="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:paddingLeft="20dp"
android:paddingTop="10dp"
android:paddingRight="20dp"
android:paddingBottom="10dp"
android:background="@color/color_TopPart">
<Button
android:id="@+id/but_back_04"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:background="@drawable/back"
tools:ignore="TouchTargetSizeCheck,TouchTargetSizeCheck,SpeakableTextPresentCheck,SpeakableTextPresentCheck" />
<TextView
android:id="@+id/tv_title_04"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="@string/menuTitle"
android:textSize="24dp" />
</RelativeLayout>
</LinearLayout>

@ -0,0 +1,43 @@
<?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="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:paddingLeft="20dp"
android:paddingTop="10dp"
android:paddingRight="20dp"
android:paddingBottom="10dp"
android:background="@color/color_TopPart">
<Button
android:id="@+id/back_button"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:background="@drawable/back" />
<TextView
android:id="@+id/title_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="@string/menuTitle"
android:textSize="24dp" />
<Button
android:id="@+id/success_button"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:background="@drawable/success" />
</RelativeLayout>
</LinearLayout>

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/navigation_detail"
android:icon="@drawable/img_detail"
android:title="@string/title_detail"
android:checked="true" />
<item
android:id="@+id/navigation_memo"
android:icon="@drawable/img_memo"
android:title="@string/title_memo"
android:checked="false"/>
<item
android:id="@+id/navigation_communicate"
android:icon="@drawable/img_honor"
android:title="@string/title_honor"
android:checked="false"/>
<item
android:id="@+id/navigation_mine"
android:icon="@drawable/img_mine"
android:title="@string/title_mine"
android:checked="false"/>
</menu>

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
tools:ignore="MissingDefaultResource">
<item android:id="@+id/submenu" android:title="选择菜单">
<menu>
<group android:checkableBehavior="none">
<item android:id="@+id/item_revise_introduce" android:title="修改介绍"/>
<item android:id="@+id/item_show_curve" android:title="显示节律曲线"/>
</group>
</menu>
</item>
</menu>

@ -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="@mipmap/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="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

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

Loading…
Cancel
Save