使用Hilt框架
This commit is contained in:
parent
dc6d5424dc
commit
6852953866
2
.idea/gradle.xml
generated
2
.idea/gradle.xml
generated
@ -8,7 +8,7 @@
|
|||||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
<option name="gradleHome" value="$USER_HOME$/.gradle/wrapper/dists/gradle-7.2-all/260hg96vuh6ex27h9vo47iv4d/gradle-7.2" />
|
<option name="gradleHome" value="$USER_HOME$/.gradle/wrapper/dists/gradle-7.2-all/260hg96vuh6ex27h9vo47iv4d/gradle-7.2" />
|
||||||
<option name="gradleJvm" value="corretto-11" />
|
<option name="gradleJvm" value="JDK" />
|
||||||
<option name="modules">
|
<option name="modules">
|
||||||
<set>
|
<set>
|
||||||
<option value="$PROJECT_DIR$" />
|
<option value="$PROJECT_DIR$" />
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id 'com.android.application'
|
id 'com.android.application'
|
||||||
id 'org.jetbrains.kotlin.android'
|
id 'org.jetbrains.kotlin.android'
|
||||||
|
id 'kotlin-android'
|
||||||
|
id 'kotlin-kapt'
|
||||||
|
id 'dagger.hilt.android.plugin'
|
||||||
|
// id 'com.google.dagger.hilt.android'
|
||||||
}
|
}
|
||||||
apply plugin: 'kotlin-android'
|
|
||||||
apply plugin: 'kotlin-kapt'
|
|
||||||
//apply plugin: 'realm-android'
|
//apply plugin: 'realm-android'
|
||||||
android {
|
android {
|
||||||
namespace 'com.navinfo.volvo'
|
namespace 'com.navinfo.volvo'
|
||||||
@ -21,7 +25,7 @@ android {
|
|||||||
// 指定room.schemaLocation生成的文件路径
|
// 指定room.schemaLocation生成的文件路径
|
||||||
javaCompileOptions {
|
javaCompileOptions {
|
||||||
annotationProcessorOptions {
|
annotationProcessorOptions {
|
||||||
arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
|
arguments += ["room.schemaLocation": "$projectDir/schemas".toString()]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ndk {
|
ndk {
|
||||||
@ -41,45 +45,84 @@ android {
|
|||||||
}
|
}
|
||||||
kotlinOptions {
|
kotlinOptions {
|
||||||
jvmTarget = '1.8'
|
jvmTarget = '1.8'
|
||||||
|
freeCompilerArgs += [
|
||||||
|
"-Xjvm-default=all",
|
||||||
|
]
|
||||||
}
|
}
|
||||||
buildFeatures {
|
buildFeatures {
|
||||||
viewBinding true
|
viewBinding true
|
||||||
dataBinding true
|
dataBinding true
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
||||||
implementation 'androidx.core:core-ktx:1.8.0'
|
implementation 'androidx.core:core-ktx:1.8.0'
|
||||||
implementation 'androidx.appcompat:appcompat:1.5.1'
|
implementation 'androidx.appcompat:appcompat:1.5.1'
|
||||||
implementation 'com.google.android.material:material:1.7.0'
|
implementation 'com.google.android.material:material:1.7.0'
|
||||||
implementation "androidx.compose.material3:material3:1.0.0-alpha04"
|
implementation "androidx.compose.material3:material3:1.0.0-alpha04"
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||||
|
|
||||||
|
|
||||||
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.4.1'
|
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.4.1'
|
||||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.1'
|
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.1'
|
||||||
|
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.1"
|
||||||
|
implementation "androidx.lifecycle:lifecycle-common-java8:2.4.1"
|
||||||
|
|
||||||
implementation 'androidx.navigation:navigation-fragment-ktx:2.4.1'
|
implementation 'androidx.navigation:navigation-fragment-ktx:2.4.1'
|
||||||
implementation 'androidx.navigation:navigation-ui-ktx:2.4.1'
|
implementation 'androidx.navigation:navigation-ui-ktx:2.4.1'
|
||||||
|
|
||||||
testImplementation 'junit:junit:4.13.2'
|
testImplementation 'junit:junit:4.13.2'
|
||||||
androidTestImplementation 'androidx.test.ext:junit:1.1.4'
|
androidTestImplementation 'androidx.test.ext:junit:1.1.4'
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0'
|
||||||
|
|
||||||
|
//room
|
||||||
implementation 'com.tencent.wcdb:room:1.1-19' // 代替 room-runtime,同时也不需要再引用 wcdb-android
|
implementation 'com.tencent.wcdb:room:1.1-19' // 代替 room-runtime,同时也不需要再引用 wcdb-android
|
||||||
|
|
||||||
api 'androidx.sqlite:sqlite:2.2.0'
|
api 'androidx.sqlite:sqlite:2.2.0'
|
||||||
implementation 'androidx.room:room-runtime:2.4.3'
|
implementation 'androidx.room:room-runtime:2.4.3'
|
||||||
|
implementation 'androidx.room:room-ktx:2.4.3'
|
||||||
annotationProcessor 'androidx.room:room-compiler:2.4.3'
|
annotationProcessor 'androidx.room:room-compiler:2.4.3'
|
||||||
annotationProcessor 'android.arch.persistence.room:compiler:1.1.1'
|
annotationProcessor 'android.arch.persistence.room:compiler:1.1.1'
|
||||||
kapt 'android.arch.persistence.room:compiler:1.1.1'// compiler 需要用 room 的
|
kapt 'android.arch.persistence.room:compiler:1.1.1'// compiler 需要用 room 的
|
||||||
kapt 'androidx.room:room-compiler:2.4.3'
|
kapt 'androidx.room:room-compiler:2.4.3'
|
||||||
|
kapt 'androidx.room:room-ktx:2.4.3'
|
||||||
androidTestImplementation "android.arch.persistence.room:testing:1.1.1"
|
androidTestImplementation "android.arch.persistence.room:testing:1.1.1"
|
||||||
// implementation "android.arch.lifecycle:extensions:1.1.1"
|
// implementation "android.arch.lifecycle:extensions:1.1.1"
|
||||||
// annotationProcessor "android.arch.lifecycle:compiler:1.1.1"
|
// annotationProcessor "android.arch.lifecycle:compiler:1.1.1"
|
||||||
implementation 'com.tencent.wcdb:wcdb-android:1.1-19'
|
implementation 'com.tencent.wcdb:wcdb-android:1.1-19'
|
||||||
|
|
||||||
|
|
||||||
// 文件选择器 https://github.com/rosuH/AndroidFilePicker/blob/master/README_CN.md
|
// 文件选择器 https://github.com/rosuH/AndroidFilePicker/blob/master/README_CN.md
|
||||||
implementation 'me.rosuh:AndroidFilePicker:0.8.2'
|
implementation 'me.rosuh:AndroidFilePicker:0.8.2'
|
||||||
// 时间选择器 https://github.com/Gredicer/datetimepicker
|
// 时间选择器 https://github.com/Gredicer/datetimepicker
|
||||||
implementation 'com.github.Gredicer:datetimepicker:V1.0.0'
|
implementation 'com.github.Gredicer:datetimepicker:V1.0.0'
|
||||||
implementation 'com.google.code.gson:gson:2.10'
|
|
||||||
implementation 'com.yanzhenjie.recyclerview:x:1.3.2'
|
implementation 'com.yanzhenjie.recyclerview:x:1.3.2'
|
||||||
|
// implementation 'androidx.appcompat:appcompat:1.5.1'
|
||||||
|
|
||||||
|
// // Koin
|
||||||
|
// implementation("io.insert-koin:koin-android:3.3.2")
|
||||||
|
// implementation("io.insert-koin:koin-core:3.3.2")
|
||||||
|
|
||||||
|
// Retrofit 网络请求相关
|
||||||
|
implementation("com.squareup.retrofit2:retrofit:2.9.0")
|
||||||
|
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
|
||||||
|
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
|
||||||
|
// const val chuck = "com.readystatesoftware.chuck:library:${Versions.chuck}"
|
||||||
|
// const val chuckNoOp = "com.readystatesoftware.chuck:library-no-op:${Versions.chuck}"
|
||||||
|
implementation("com.squareup.okhttp3:okhttp:4.9.0")
|
||||||
|
implementation("com.squareup.okhttp3:logging-interceptor:4.9.0")
|
||||||
|
implementation("com.google.code.gson:gson:2.8.6")
|
||||||
|
|
||||||
|
|
||||||
|
//hilt
|
||||||
|
implementation "com.google.dagger:hilt-android:2.41"
|
||||||
|
kapt "com.google.dagger:hilt-compiler:2.41"
|
||||||
|
// implementation "androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03"
|
||||||
|
// androidTestImplementation "com.google.dagger:hilt-android-testing:2.41"
|
||||||
|
// kaptAndroidTest "com.google.dagger:hilt-android-compiler:2.41"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
kapt {
|
||||||
|
correctErrorTypes true
|
||||||
}
|
}
|
@ -3,6 +3,7 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools">
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
<application
|
<application
|
||||||
|
android:name=".MyApplication"
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:configChanges="locale"
|
android:configChanges="locale"
|
||||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||||
@ -14,7 +15,7 @@
|
|||||||
android:theme="@style/Theme.NavinfoVolvo"
|
android:theme="@style/Theme.NavinfoVolvo"
|
||||||
tools:targetApi="31">
|
tools:targetApi="31">
|
||||||
<activity
|
<activity
|
||||||
android:name="com.navinfo.volvo.MainActivity"
|
android:name="com.navinfo.volvo.ui.MainActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:label="@string/app_name">
|
android:label="@string/app_name">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
@ -28,5 +29,5 @@
|
|||||||
android:value="" />
|
android:value="" />
|
||||||
</activity>
|
</activity>
|
||||||
</application>
|
</application>
|
||||||
|
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
|
||||||
</manifest>
|
</manifest>
|
14
app/src/main/java/com/navinfo/volvo/Constant.kt
Normal file
14
app/src/main/java/com/navinfo/volvo/Constant.kt
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package com.navinfo.volvo
|
||||||
|
|
||||||
|
import java.lang.Boolean
|
||||||
|
|
||||||
|
class Constant {
|
||||||
|
companion object{
|
||||||
|
/**
|
||||||
|
* 服务器地址
|
||||||
|
*/
|
||||||
|
const val SERVER_ADDRESS = "http://ec2-52-81-73-5.cn-north-1.compute.amazonaws.com.cn:8088/"
|
||||||
|
val DEBUG = Boolean.parseBoolean("true")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
11
app/src/main/java/com/navinfo/volvo/MyApplication.kt
Normal file
11
app/src/main/java/com/navinfo/volvo/MyApplication.kt
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package com.navinfo.volvo
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import dagger.hilt.android.HiltAndroidApp
|
||||||
|
|
||||||
|
@HiltAndroidApp
|
||||||
|
open class MyApplication : Application() {
|
||||||
|
override fun onCreate() {
|
||||||
|
super.onCreate()
|
||||||
|
}
|
||||||
|
}
|
20
app/src/main/java/com/navinfo/volvo/database/AppDatabase.kt
Normal file
20
app/src/main/java/com/navinfo/volvo/database/AppDatabase.kt
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package com.navinfo.volvo.database
|
||||||
|
|
||||||
|
import androidx.room.Database
|
||||||
|
import androidx.room.RoomDatabase
|
||||||
|
import com.navinfo.volvo.database.dao.MessageDao
|
||||||
|
import com.navinfo.volvo.database.dao.UserDao
|
||||||
|
import com.navinfo.volvo.model.Attachment
|
||||||
|
import com.navinfo.volvo.model.Message
|
||||||
|
import com.navinfo.volvo.model.User
|
||||||
|
|
||||||
|
@Database(
|
||||||
|
entities = [Message::class, Attachment::class, User::class],
|
||||||
|
version = 1,
|
||||||
|
exportSchema = false
|
||||||
|
)
|
||||||
|
abstract class AppDatabase : RoomDatabase() {
|
||||||
|
abstract fun getMessageDao(): MessageDao
|
||||||
|
|
||||||
|
abstract fun getUserDao(): UserDao
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.navinfo.volvo.db.dao;
|
package com.navinfo.volvo.database;
|
||||||
|
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@ -10,10 +10,11 @@ import androidx.room.RoomDatabase;
|
|||||||
import androidx.sqlite.db.SupportSQLiteDatabase;
|
import androidx.sqlite.db.SupportSQLiteDatabase;
|
||||||
import androidx.sqlite.db.SupportSQLiteOpenHelper;
|
import androidx.sqlite.db.SupportSQLiteOpenHelper;
|
||||||
|
|
||||||
import com.navinfo.volvo.db.dao.entity.Message;
|
import com.navinfo.volvo.database.dao.MessageDao;
|
||||||
import com.navinfo.volvo.db.dao.entity.Attachment;
|
import com.navinfo.volvo.database.dao.UserDao;
|
||||||
import com.navinfo.volvo.db.dao.entity.Message;
|
import com.navinfo.volvo.model.Message;
|
||||||
import com.navinfo.volvo.db.dao.entity.User;
|
import com.navinfo.volvo.model.Attachment;
|
||||||
|
import com.navinfo.volvo.model.User;
|
||||||
import com.tencent.wcdb.database.SQLiteCipherSpec;
|
import com.tencent.wcdb.database.SQLiteCipherSpec;
|
||||||
import com.tencent.wcdb.database.SQLiteDatabase;
|
import com.tencent.wcdb.database.SQLiteDatabase;
|
||||||
|
|
||||||
@ -39,6 +40,8 @@ public abstract class MapLifeDataBase extends RoomDatabase {
|
|||||||
*/
|
*/
|
||||||
public abstract MessageDao getMessageDao();
|
public abstract MessageDao getMessageDao();
|
||||||
|
|
||||||
|
public abstract UserDao getUserDao();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据库秘钥
|
* 数据库秘钥
|
||||||
*/
|
*/
|
@ -1,10 +1,10 @@
|
|||||||
package com.navinfo.volvo.db.dao
|
package com.navinfo.volvo.database.dao
|
||||||
|
|
||||||
import androidx.room.Dao
|
import androidx.room.Dao
|
||||||
import androidx.room.Insert
|
import androidx.room.Insert
|
||||||
import androidx.room.OnConflictStrategy
|
import androidx.room.OnConflictStrategy
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import com.navinfo.volvo.db.dao.entity.Message
|
import com.navinfo.volvo.model.Message
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
interface MessageDao {
|
interface MessageDao {
|
12
app/src/main/java/com/navinfo/volvo/database/dao/UserDao.kt
Normal file
12
app/src/main/java/com/navinfo/volvo/database/dao/UserDao.kt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package com.navinfo.volvo.database.dao
|
||||||
|
|
||||||
|
import androidx.room.Dao
|
||||||
|
import androidx.room.Insert
|
||||||
|
import androidx.room.OnConflictStrategy
|
||||||
|
import com.navinfo.volvo.model.User
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
interface UserDao {
|
||||||
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
|
suspend fun insertUser(vararg user: User)
|
||||||
|
}
|
@ -1,13 +0,0 @@
|
|||||||
package com.navinfo.volvo.db.dao.entity
|
|
||||||
|
|
||||||
import androidx.room.Entity
|
|
||||||
import androidx.room.PrimaryKey
|
|
||||||
|
|
||||||
@Entity(tableName = "User")
|
|
||||||
data class User(
|
|
||||||
@PrimaryKey()
|
|
||||||
val id:String,
|
|
||||||
var name:String,
|
|
||||||
var nickname:String,
|
|
||||||
|
|
||||||
)
|
|
16
app/src/main/java/com/navinfo/volvo/di/key/ViewModelKey.kt
Normal file
16
app/src/main/java/com/navinfo/volvo/di/key/ViewModelKey.kt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package com.navinfo.volvo.di.key
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import dagger.MapKey
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
|
||||||
|
@MustBeDocumented
|
||||||
|
@MapKey
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
@Target(
|
||||||
|
AnnotationTarget.FUNCTION,
|
||||||
|
AnnotationTarget.PROPERTY_GETTER,
|
||||||
|
AnnotationTarget.PROPERTY_SETTER
|
||||||
|
)
|
||||||
|
internal annotation class ViewModelKey(val value: KClass<out ViewModel>)
|
@ -0,0 +1,57 @@
|
|||||||
|
package com.navinfo.volvo.di.module
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.room.Room
|
||||||
|
import com.navinfo.volvo.database.AppDatabase
|
||||||
|
import com.navinfo.volvo.database.dao.MessageDao
|
||||||
|
import com.navinfo.volvo.database.dao.UserDao
|
||||||
|
import com.tencent.wcdb.database.SQLiteCipherSpec
|
||||||
|
import com.tencent.wcdb.room.db.WCDBOpenHelperFactory
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.components.SingletonComponent
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
|
||||||
|
@InstallIn(SingletonComponent::class)
|
||||||
|
@Module
|
||||||
|
class DatabaseModule {
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
@Provides
|
||||||
|
fun provideDatabase(context: Context): AppDatabase {
|
||||||
|
val DB_PASSWORD = "123456";
|
||||||
|
val cipherSpec = SQLiteCipherSpec()
|
||||||
|
.setPageSize(1024)
|
||||||
|
.setSQLCipherVersion(3)
|
||||||
|
val factory = WCDBOpenHelperFactory()
|
||||||
|
.passphrase(DB_PASSWORD.toByteArray()) // passphrase to the database, remove this line for plain-text
|
||||||
|
.cipherSpec(cipherSpec) // cipher to use, remove for default settings
|
||||||
|
.writeAheadLoggingEnabled(true) // enable WAL mode, remove if not needed
|
||||||
|
.asyncCheckpointEnabled(true); // enable asynchronous checkpoint, remove if not needed
|
||||||
|
|
||||||
|
return Room.databaseBuilder(context, AppDatabase::class.java, "NavinfoVolvoDb")
|
||||||
|
|
||||||
|
// [WCDB] Specify open helper to use WCDB database implementation instead
|
||||||
|
// of the Android framework.
|
||||||
|
.openHelperFactory(factory)
|
||||||
|
|
||||||
|
// Wipes and rebuilds instead of migrating if no Migration object.
|
||||||
|
// Migration is not part of this codelab.
|
||||||
|
// .fallbackToDestructiveMigration().addCallback(sRoomDatabaseCallback)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
@Provides
|
||||||
|
fun provideMessageDao(database: AppDatabase): MessageDao {
|
||||||
|
return database.getMessageDao()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
@Provides
|
||||||
|
fun provideUserDao(database: AppDatabase): UserDao {
|
||||||
|
return database.getUserDao()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package com.navinfo.volvo.di.module
|
||||||
|
|
||||||
|
import com.navinfo.volvo.di.scope.DefaultDispatcher
|
||||||
|
import com.navinfo.volvo.di.scope.IoDispatcher
|
||||||
|
import com.navinfo.volvo.di.scope.MainDispatcher
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.components.SingletonComponent
|
||||||
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
|
||||||
|
|
||||||
|
@InstallIn(SingletonComponent::class)
|
||||||
|
@Module
|
||||||
|
object DispatcherModule {
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@DefaultDispatcher
|
||||||
|
fun provideDefaultDispatcher(): CoroutineDispatcher = Dispatchers.Default
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@IoDispatcher
|
||||||
|
fun providesIODispatcher(): CoroutineDispatcher = Dispatchers.IO
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@MainDispatcher
|
||||||
|
fun providesMainDispatcher(): CoroutineDispatcher = Dispatchers.Main
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package com.navinfo.volvo.di.module
|
||||||
|
|
||||||
|
import com.navinfo.volvo.repository.NetworkDataSource
|
||||||
|
import com.navinfo.volvo.repository.NetworkDataSourceImp
|
||||||
|
import dagger.Binds
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.components.SingletonComponent
|
||||||
|
|
||||||
|
@InstallIn(SingletonComponent::class)
|
||||||
|
@Module
|
||||||
|
abstract class NetworkDataModule {
|
||||||
|
@Binds
|
||||||
|
abstract fun bindNetworkData(networkDataSourceImp: NetworkDataSourceImp): NetworkDataSource
|
||||||
|
}
|
@ -0,0 +1,104 @@
|
|||||||
|
package com.navinfo.volvo.di.module
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import android.content.Context
|
||||||
|
import com.google.gson.Gson
|
||||||
|
import com.navinfo.volvo.Constant
|
||||||
|
import com.navinfo.volvo.repository.service.NetworkService
|
||||||
|
import com.navinfo.volvo.tools.GsonUtil
|
||||||
|
import dagger.Lazy
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.components.SingletonComponent
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import okhttp3.logging.HttpLoggingInterceptor
|
||||||
|
import retrofit2.Retrofit
|
||||||
|
import retrofit2.converter.gson.GsonConverterFactory
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
|
||||||
|
@InstallIn(SingletonComponent::class)
|
||||||
|
@Module
|
||||||
|
class NetworkUtilModule {
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
fun provideContext(application: Application): Context {
|
||||||
|
return application.applicationContext
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
fun provideOkHttpClient(interceptor: HttpLoggingInterceptor): OkHttpClient {
|
||||||
|
return OkHttpClient.Builder().addInterceptor(interceptor).build()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
fun provideLoggingInterceptor(): HttpLoggingInterceptor {
|
||||||
|
return HttpLoggingInterceptor().apply {
|
||||||
|
level = if (Constant.DEBUG) {
|
||||||
|
HttpLoggingInterceptor.Level.BODY
|
||||||
|
} else {
|
||||||
|
HttpLoggingInterceptor.Level.NONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
fun provideRetrofit(
|
||||||
|
client: Lazy<OkHttpClient>,
|
||||||
|
converterFactory: GsonConverterFactory,
|
||||||
|
context: Context
|
||||||
|
): Retrofit {
|
||||||
|
val retrofitBuilder = Retrofit.Builder()
|
||||||
|
.baseUrl(Constant.SERVER_ADDRESS)
|
||||||
|
.client(client.get())
|
||||||
|
.addConverterFactory(converterFactory)
|
||||||
|
|
||||||
|
// val okHttpClientBuilder = OkHttpClient.Builder()
|
||||||
|
// .addInterceptor { chain ->
|
||||||
|
//
|
||||||
|
// val original = chain.request()
|
||||||
|
// val originalHttpUrl = original.url
|
||||||
|
//
|
||||||
|
// val url = originalHttpUrl.newBuilder()
|
||||||
|
// .addQueryParameter("appid", BuildConfig.API_KEY)
|
||||||
|
// .build()
|
||||||
|
//
|
||||||
|
// Timber.d("Started making network call")
|
||||||
|
//
|
||||||
|
// val requestBuilder = original.newBuilder()
|
||||||
|
// .url(url)
|
||||||
|
//
|
||||||
|
// val request = requestBuilder.build()
|
||||||
|
// return@addInterceptor chain.proceed(request)
|
||||||
|
// }
|
||||||
|
// .readTimeout(60, TimeUnit.SECONDS)
|
||||||
|
// if (Constant.DEBUG) {
|
||||||
|
// okHttpClientBuilder.addInterceptor(ChuckInterceptor(context))
|
||||||
|
// }
|
||||||
|
// return retrofitBuilder.client(okHttpClientBuilder.build()).build()
|
||||||
|
return retrofitBuilder.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
fun provideGson(): Gson = GsonUtil.getInstance()
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
fun provideGsonConverterFactory(gson: Gson): GsonConverterFactory {
|
||||||
|
return GsonConverterFactory.create(gson)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
fun provideNetworkService(retrofit: Retrofit): NetworkService {
|
||||||
|
return retrofit.create(NetworkService::class.java)
|
||||||
|
}
|
||||||
|
}
|
20
app/src/main/java/com/navinfo/volvo/di/module/UtilModule.kt
Normal file
20
app/src/main/java/com/navinfo/volvo/di/module/UtilModule.kt
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package com.navinfo.volvo.di.module
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import com.navinfo.volvo.util.SharedPreferenceHelper
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.components.SingletonComponent
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@InstallIn(SingletonComponent::class)
|
||||||
|
@Module
|
||||||
|
class UtilModule {
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
fun provideSharedPreferencesHelper(context: Context): SharedPreferenceHelper {
|
||||||
|
return SharedPreferenceHelper.getInstance(context)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package com.navinfo.volvo.di.module
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Provider
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory for all ViewModels.
|
||||||
|
* reference : https://github.com/googlesamples/android-architecture-components
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
class ViewModelFactory @Inject constructor(
|
||||||
|
private val viewModelMap: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>
|
||||||
|
) : ViewModelProvider.Factory {
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||||
|
var viewModel = viewModelMap[modelClass]
|
||||||
|
|
||||||
|
if (viewModel == null) {
|
||||||
|
for (entry in viewModelMap) {
|
||||||
|
if (modelClass.isAssignableFrom(entry.key)) {
|
||||||
|
viewModel = entry.value
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (viewModel == null) throw IllegalArgumentException("Unknown model class $modelClass")
|
||||||
|
return viewModel.get() as T
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package com.navinfo.volvo.di.module
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import com.navinfo.volvo.di.key.ViewModelKey
|
||||||
|
import com.navinfo.volvo.ui.fragments.home.MessageViewModel
|
||||||
|
import com.navinfo.volvo.ui.fragments.login.LoginViewModel
|
||||||
|
import dagger.Binds
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.components.SingletonComponent
|
||||||
|
import dagger.multibindings.IntoMap
|
||||||
|
|
||||||
|
@InstallIn(SingletonComponent::class)
|
||||||
|
@Module
|
||||||
|
abstract class ViewModelModule {
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
abstract fun bindViewModelFactory(viewModelFactory: ViewModelFactory): ViewModelProvider.Factory
|
||||||
|
|
||||||
|
@IntoMap
|
||||||
|
@Binds
|
||||||
|
@ViewModelKey(LoginViewModel::class)
|
||||||
|
abstract fun bindLoginFragmentViewModel(viewModel: LoginViewModel): ViewModel
|
||||||
|
|
||||||
|
@IntoMap
|
||||||
|
@Binds
|
||||||
|
@ViewModelKey(MessageViewModel::class)
|
||||||
|
abstract fun bindMessageFragmentViewModel(viewModel: MessageViewModel): ViewModel
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package com.navinfo.volvo.di.scope
|
||||||
|
|
||||||
|
import javax.inject.Qualifier
|
||||||
|
|
||||||
|
@Retention(AnnotationRetention.BINARY)
|
||||||
|
@Qualifier
|
||||||
|
annotation class DefaultDispatcher
|
||||||
|
|
||||||
|
@Retention(AnnotationRetention.BINARY)
|
||||||
|
@Qualifier
|
||||||
|
annotation class IoDispatcher
|
||||||
|
|
||||||
|
@Retention(AnnotationRetention.BINARY)
|
||||||
|
@Qualifier
|
||||||
|
annotation class MainDispatcher
|
@ -1,4 +1,4 @@
|
|||||||
package com.navinfo.volvo.db.dao.entity
|
package com.navinfo.volvo.model
|
||||||
|
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
@ -1,4 +1,4 @@
|
|||||||
package com.navinfo.volvo.db.dao.entity
|
package com.navinfo.volvo.model
|
||||||
|
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
52
app/src/main/java/com/navinfo/volvo/model/User.kt
Normal file
52
app/src/main/java/com/navinfo/volvo/model/User.kt
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package com.navinfo.volvo.model
|
||||||
|
|
||||||
|
import androidx.room.Entity
|
||||||
|
import androidx.room.PrimaryKey
|
||||||
|
import androidx.room.TypeConverter
|
||||||
|
import androidx.room.TypeConverters
|
||||||
|
import com.google.gson.reflect.TypeToken
|
||||||
|
import com.navinfo.volvo.tools.GsonUtil
|
||||||
|
import org.jetbrains.annotations.NotNull
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
import java.time.LocalTime
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@Entity(tableName = "User")
|
||||||
|
@TypeConverters()
|
||||||
|
data class User(
|
||||||
|
@PrimaryKey()
|
||||||
|
@NotNull
|
||||||
|
val id: String,
|
||||||
|
var name: String,
|
||||||
|
var nickname: String,
|
||||||
|
){
|
||||||
|
@Inject constructor():this("${System.currentTimeMillis()}","df","sdfds")
|
||||||
|
}
|
||||||
|
|
||||||
|
class UserConverters() {
|
||||||
|
@TypeConverter
|
||||||
|
fun stringToUser(value: String): User {
|
||||||
|
val type = object : TypeToken<User>() {
|
||||||
|
|
||||||
|
}.type
|
||||||
|
return GsonUtil.getInstance().fromJson(value, type)
|
||||||
|
}
|
||||||
|
|
||||||
|
@TypeConverter
|
||||||
|
fun userToString(user: User): String {
|
||||||
|
return GsonUtil.getInstance().toJson(user)
|
||||||
|
}
|
||||||
|
|
||||||
|
@TypeConverter
|
||||||
|
fun userListToString(list: List<User>): String {
|
||||||
|
return GsonUtil.getInstance().toJson(list)
|
||||||
|
}
|
||||||
|
|
||||||
|
@TypeConverter
|
||||||
|
fun stringToUserList(value: String): List<User> {
|
||||||
|
val type = object : TypeToken<List<User>>() {
|
||||||
|
|
||||||
|
}.type
|
||||||
|
return GsonUtil.getInstance().fromJson(value, type)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package com.navinfo.volvo.model.network
|
||||||
|
|
||||||
|
data class NetworkPostMessage(
|
||||||
|
val name: String,//问候名称,非必填项
|
||||||
|
val who: String, //我是谁
|
||||||
|
val toWho: String, //发送给谁
|
||||||
|
val startTime: String, //2023-01-02 15:49:50", //创建开始时间 非必填项 暂不支持按时间查询
|
||||||
|
val endTime: String,//" 2023-01-03 15:52:50", //创建结束时间 非必填项 暂不支持按时间查询
|
||||||
|
val pageSize: String, //查询数量
|
||||||
|
val pageNum: String, //分页查询
|
||||||
|
) {
|
||||||
|
constructor(who: String, toWho: String) : this("", who, toWho, "", "", "10", "1") {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.navinfo.volvo.repository
|
||||||
|
|
||||||
|
import com.navinfo.volvo.model.Message
|
||||||
|
import com.navinfo.volvo.model.network.NetworkPostMessage
|
||||||
|
import com.navinfo.volvo.util.NetResult
|
||||||
|
|
||||||
|
interface NetworkDataSource {
|
||||||
|
suspend fun getCardList(message: NetworkPostMessage): NetResult<List<Message>>
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package com.navinfo.volvo.repository
|
||||||
|
|
||||||
|
import com.navinfo.volvo.di.scope.IoDispatcher
|
||||||
|
import com.navinfo.volvo.model.Message
|
||||||
|
import com.navinfo.volvo.model.network.NetworkPostMessage
|
||||||
|
import com.navinfo.volvo.repository.service.NetworkService
|
||||||
|
import com.navinfo.volvo.tools.GsonUtil
|
||||||
|
import com.navinfo.volvo.util.NetResult
|
||||||
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import okhttp3.FormBody
|
||||||
|
import okhttp3.MediaType
|
||||||
|
import okhttp3.MediaType.Companion.toMediaType
|
||||||
|
import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
||||||
|
class NetworkDataSourceImp @Inject constructor(
|
||||||
|
private val netWorkService: NetworkService,
|
||||||
|
@IoDispatcher private val ioDispatcher: CoroutineDispatcher
|
||||||
|
) : NetworkDataSource {
|
||||||
|
|
||||||
|
override suspend fun getCardList(message: NetworkPostMessage): NetResult<List<Message>> =
|
||||||
|
withContext(ioDispatcher) {
|
||||||
|
return@withContext try {
|
||||||
|
val stringBody = GsonUtil.getInstance().toJson(message).toRequestBody("application/json;charset=utf-8".toMediaType())
|
||||||
|
val result = netWorkService.queryCardListByApp(stringBody)
|
||||||
|
if (result.isSuccessful) {
|
||||||
|
val list = result.body()
|
||||||
|
NetResult.Success(list)
|
||||||
|
} else {
|
||||||
|
NetResult.Success(null)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
NetResult.Error(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package com.navinfo.volvo.repository.service
|
||||||
|
|
||||||
|
import com.navinfo.volvo.model.Message
|
||||||
|
import okhttp3.RequestBody
|
||||||
|
import retrofit2.Response
|
||||||
|
import retrofit2.http.Body
|
||||||
|
import retrofit2.http.POST
|
||||||
|
|
||||||
|
interface NetworkService {
|
||||||
|
@POST("/navi/cardDelivery/queryCardListByApp")
|
||||||
|
suspend fun queryCardListByApp(@Body body: RequestBody): Response<List<Message>>
|
||||||
|
}
|
10
app/src/main/java/com/navinfo/volvo/ui/BaseFragment.kt
Normal file
10
app/src/main/java/com/navinfo/volvo/ui/BaseFragment.kt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package com.navinfo.volvo.ui
|
||||||
|
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
abstract class BaseFragment : Fragment() {
|
||||||
|
@Inject
|
||||||
|
lateinit var viewModelFactoryProvider: ViewModelProvider.Factory
|
||||||
|
}
|
@ -1,17 +1,18 @@
|
|||||||
package com.navinfo.volvo
|
package com.navinfo.volvo.ui
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import com.google.android.material.bottomnavigation.BottomNavigationView
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.navigation.Navigation
|
|
||||||
import androidx.navigation.findNavController
|
import androidx.navigation.findNavController
|
||||||
import androidx.navigation.ui.AppBarConfiguration
|
import androidx.navigation.ui.AppBarConfiguration
|
||||||
import androidx.navigation.ui.setupActionBarWithNavController
|
import androidx.navigation.ui.setupActionBarWithNavController
|
||||||
import androidx.navigation.ui.setupWithNavController
|
import androidx.navigation.ui.setupWithNavController
|
||||||
|
import com.google.android.material.bottomnavigation.BottomNavigationView
|
||||||
import com.navinfo.volvo.R
|
import com.navinfo.volvo.R
|
||||||
import com.navinfo.volvo.databinding.ActivityMainBinding
|
import com.navinfo.volvo.databinding.ActivityMainBinding
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
|
||||||
|
@AndroidEntryPoint
|
||||||
class MainActivity : AppCompatActivity() {
|
class MainActivity : AppCompatActivity() {
|
||||||
|
|
||||||
private lateinit var binding: ActivityMainBinding
|
private lateinit var binding: ActivityMainBinding
|
||||||
@ -21,23 +22,39 @@ class MainActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
binding = ActivityMainBinding.inflate(layoutInflater)
|
binding = ActivityMainBinding.inflate(layoutInflater)
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
|
setupNavigation()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupNavigation() {
|
||||||
val navView: BottomNavigationView = binding.navView
|
val navView: BottomNavigationView = binding.navView
|
||||||
|
val newMessageView = binding.newMessageFab
|
||||||
val navController = findNavController(R.id.nav_host_fragment_activity_main)
|
val navController = findNavController(R.id.nav_host_fragment_activity_main)
|
||||||
// Passing each menu ID as a set of Ids because each
|
|
||||||
// menu should be considered as top level destinations.
|
|
||||||
val appBarConfiguration = AppBarConfiguration(
|
val appBarConfiguration = AppBarConfiguration(
|
||||||
setOf(
|
setOf(
|
||||||
R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications, R.id.navigation_obtain_message
|
R.id.navigation_message, R.id.navigation_dashboard, R.id.navigation_notifications,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
setupActionBarWithNavController(navController, appBarConfiguration)
|
setupActionBarWithNavController(navController, appBarConfiguration)
|
||||||
navView.setupWithNavController(navController)
|
navView.setupWithNavController(navController)
|
||||||
findViewById<View>(R.id.fab_new_message).apply {
|
navController.addOnDestinationChangedListener { controller, destination, arguments ->
|
||||||
this.setOnClickListener {
|
if (destination.id == R.id.navigation_message
|
||||||
navController.navigate(R.id.fab_new_message)
|
|| destination.id == R.id.navigation_dashboard
|
||||||
|
|| destination.id == R.id.navigation_notifications
|
||||||
|
|| destination.id == R.id.navigation_obtain_message
|
||||||
|
) {
|
||||||
|
runOnUiThread {
|
||||||
|
navView.visibility = View.VISIBLE
|
||||||
|
newMessageView.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
runOnUiThread {
|
||||||
|
navView.visibility = View.GONE
|
||||||
|
newMessageView.visibility = View.GONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSupportNavigateUp() =
|
||||||
|
findNavController(R.id.nav_host_fragment_activity_main).navigateUp()
|
||||||
}
|
}
|
@ -7,7 +7,7 @@ import android.widget.ImageView
|
|||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.navinfo.volvo.R
|
import com.navinfo.volvo.R
|
||||||
import com.navinfo.volvo.db.dao.entity.Message
|
import com.navinfo.volvo.model.Message
|
||||||
|
|
||||||
class MessageAdapter : RecyclerView.Adapter<MessageAdapter.MyViewHolder>() {
|
class MessageAdapter : RecyclerView.Adapter<MessageAdapter.MyViewHolder>() {
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package com.navinfo.volvo.ui.dashboard
|
package com.navinfo.volvo.ui.fragments.dashboard
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
@ -23,7 +23,7 @@ class DashboardFragment : Fragment() {
|
|||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View {
|
): View {
|
||||||
val dashboardViewModel =
|
val dashboardViewModel =
|
||||||
ViewModelProvider(this).get(DashboardViewModel::class.java)
|
ViewModelProvider(this)[DashboardViewModel::class.java]
|
||||||
|
|
||||||
_binding = FragmentDashboardBinding.inflate(inflater, container, false)
|
_binding = FragmentDashboardBinding.inflate(inflater, container, false)
|
||||||
val root: View = binding.root
|
val root: View = binding.root
|
@ -1,4 +1,4 @@
|
|||||||
package com.navinfo.volvo.ui.dashboard
|
package com.navinfo.volvo.ui.fragments.dashboard
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
@ -1,11 +1,10 @@
|
|||||||
package com.navinfo.volvo.ui.home
|
package com.navinfo.volvo.ui.fragments.home
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.Display
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.viewModels
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.recyclerview.widget.DividerItemDecoration
|
import androidx.recyclerview.widget.DividerItemDecoration
|
||||||
@ -13,12 +12,14 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
|||||||
import com.navinfo.volvo.R
|
import com.navinfo.volvo.R
|
||||||
import com.navinfo.volvo.databinding.FragmentHomeBinding
|
import com.navinfo.volvo.databinding.FragmentHomeBinding
|
||||||
import com.navinfo.volvo.tools.DisplayUtil
|
import com.navinfo.volvo.tools.DisplayUtil
|
||||||
|
import com.navinfo.volvo.ui.BaseFragment
|
||||||
import com.navinfo.volvo.ui.adapter.MessageAdapter
|
import com.navinfo.volvo.ui.adapter.MessageAdapter
|
||||||
import com.navinfo.volvo.ui.message.ObtainMessageViewModel
|
import com.navinfo.volvo.ui.fragments.message.ObtainMessageViewModel
|
||||||
import com.yanzhenjie.recyclerview.*
|
import com.yanzhenjie.recyclerview.*
|
||||||
import com.yanzhenjie.recyclerview.SwipeRecyclerView.LoadMoreListener
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
|
||||||
class HomeFragment : Fragment(), OnItemClickListener, OnItemMenuClickListener {
|
@AndroidEntryPoint
|
||||||
|
class MessageFragment : BaseFragment(), OnItemClickListener, OnItemMenuClickListener {
|
||||||
|
|
||||||
private var _binding: FragmentHomeBinding? = null
|
private var _binding: FragmentHomeBinding? = null
|
||||||
|
|
||||||
@ -26,28 +27,26 @@ class HomeFragment : Fragment(), OnItemClickListener, OnItemMenuClickListener {
|
|||||||
// onDestroyView.
|
// onDestroyView.
|
||||||
private val binding get() = _binding!!
|
private val binding get() = _binding!!
|
||||||
|
|
||||||
|
private val viewModel by viewModels<MessageViewModel> { viewModelFactoryProvider }
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View {
|
): View {
|
||||||
val homeViewModel =
|
// val homeViewModel =
|
||||||
ViewModelProvider(this).get(HomeViewModel::class.java)
|
// ViewModelProvider(this)[MessageViewModel::class.java]
|
||||||
val obtainMessageViewModel = ViewModelProvider(requireActivity()).get(ObtainMessageViewModel::class.java)
|
// val obtainMessageViewModel =
|
||||||
|
// ViewModelProvider(requireActivity()).get(ObtainMessageViewModel::class.java)
|
||||||
|
|
||||||
_binding = FragmentHomeBinding.inflate(inflater, container, false)
|
_binding = FragmentHomeBinding.inflate(inflater, container, false)
|
||||||
val root: View = binding.root
|
val root: View = binding.root
|
||||||
|
initView()
|
||||||
|
return root
|
||||||
|
}
|
||||||
|
|
||||||
// val textView: TextView = binding.tvNewMessage
|
|
||||||
// textView.setOnClickListener {
|
private fun initView() {
|
||||||
// val message = Message(1, "新建标题", "", "", "", 0, "1", "2", mutableListOf())
|
|
||||||
// obtainMessageViewModel.setCurrentMessage(message)
|
|
||||||
// // 跳转到新建Message的Fragment
|
|
||||||
// Navigation.findNavController(it).navigate(R.id.home_2_obtain_message)
|
|
||||||
// }
|
|
||||||
// homeViewModel.text.observe(viewLifecycleOwner) {
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
val recyclerview: SwipeRecyclerView = binding.homeMessageRecyclerview
|
val recyclerview: SwipeRecyclerView = binding.homeMessageRecyclerview
|
||||||
recyclerview.adapter = null //先设置null,否则会报错
|
recyclerview.adapter = null //先设置null,否则会报错
|
||||||
//创建菜单选项
|
//创建菜单选项
|
||||||
@ -70,8 +69,6 @@ class HomeFragment : Fragment(), OnItemClickListener, OnItemMenuClickListener {
|
|||||||
shareItem.text = context!!.getString(R.string.share)
|
shareItem.text = context!!.getString(R.string.share)
|
||||||
shareItem.setTextColor(R.color.white)
|
shareItem.setTextColor(R.color.white)
|
||||||
rightMenu.addMenuItem(shareItem)
|
rightMenu.addMenuItem(shareItem)
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
val layoutManager = LinearLayoutManager(context)
|
val layoutManager = LinearLayoutManager(context)
|
||||||
val adapter = MessageAdapter()
|
val adapter = MessageAdapter()
|
||||||
@ -84,12 +81,21 @@ class HomeFragment : Fragment(), OnItemClickListener, OnItemMenuClickListener {
|
|||||||
|
|
||||||
}
|
}
|
||||||
recyclerview.adapter = adapter
|
recyclerview.adapter = adapter
|
||||||
homeViewModel.getMessageList().observe(viewLifecycleOwner, Observer { contacts ->
|
// homeViewModel.getMessageList().observe(viewLifecycleOwner, Observer { contacts ->
|
||||||
adapter.setItem(contacts)
|
// adapter.setItem(contacts)
|
||||||
})
|
// })
|
||||||
return root
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onStart() {
|
||||||
|
super.onStart()
|
||||||
|
getMessageList()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getMessageList() {
|
||||||
|
viewModel.getMessageList()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
_binding = null
|
_binding = null
|
@ -0,0 +1,47 @@
|
|||||||
|
package com.navinfo.volvo.ui.fragments.home
|
||||||
|
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.navinfo.volvo.model.Message
|
||||||
|
import com.navinfo.volvo.model.network.NetworkPostMessage
|
||||||
|
import com.navinfo.volvo.repository.NetworkDataSource
|
||||||
|
import com.navinfo.volvo.util.NetResult
|
||||||
|
import com.navinfo.volvo.util.asLiveData
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class MessageViewModel @Inject constructor(
|
||||||
|
private val repository: NetworkDataSource
|
||||||
|
) : ViewModel() {
|
||||||
|
|
||||||
|
private val _isLoading = MutableLiveData<Boolean>()
|
||||||
|
val isLoading = _isLoading.asLiveData()
|
||||||
|
|
||||||
|
private val _messageList = MutableLiveData<List<Message>>()
|
||||||
|
val messageList = _messageList.asLiveData()
|
||||||
|
|
||||||
|
fun getMessageList() {
|
||||||
|
_isLoading.postValue(true)
|
||||||
|
viewModelScope.launch {
|
||||||
|
val messagePost = NetworkPostMessage(who = "北京测试", toWho = "volvo测试")
|
||||||
|
when (val result = repository.getCardList(messagePost)) {
|
||||||
|
is NetResult.Success -> {
|
||||||
|
_isLoading.value = false
|
||||||
|
if (result.data != null) {
|
||||||
|
val list = result.data
|
||||||
|
_messageList.value = list
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is NetResult.Error -> {
|
||||||
|
_isLoading.value = false
|
||||||
|
}
|
||||||
|
is NetResult.Loading -> {
|
||||||
|
_isLoading.postValue(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
package com.navinfo.volvo.ui.fragments.login
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.fragment.app.viewModels
|
||||||
|
import androidx.navigation.Navigation
|
||||||
|
import androidx.navigation.findNavController
|
||||||
|
import androidx.navigation.fragment.findNavController
|
||||||
|
import com.navinfo.volvo.R
|
||||||
|
import com.navinfo.volvo.databinding.FragmentLoginBinding
|
||||||
|
import com.navinfo.volvo.ui.BaseFragment
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
|
||||||
|
|
||||||
|
@AndroidEntryPoint
|
||||||
|
class LoginFragment : BaseFragment() {
|
||||||
|
|
||||||
|
// private var loginViewModel:LoginViewModel by viewModel(get())
|
||||||
|
private var viewBinding: FragmentLoginBinding? = null
|
||||||
|
|
||||||
|
// This property is only valid between onCreateView and
|
||||||
|
// onDestroyView.
|
||||||
|
private val binding get() = viewBinding!!
|
||||||
|
|
||||||
|
private val viewModel by viewModels<LoginViewModel> { viewModelFactoryProvider }
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
|
||||||
|
viewBinding = FragmentLoginBinding.inflate(inflater, container, false)
|
||||||
|
val root: View = binding.root
|
||||||
|
binding.loginFragmentRegisterButton.setOnClickListener {
|
||||||
|
}
|
||||||
|
binding.loginFragmentLoginButton.setOnClickListener {
|
||||||
|
findNavController().navigate(R.id.action_login_to_home)
|
||||||
|
}
|
||||||
|
return root
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun onDestroyView() {
|
||||||
|
viewBinding = null
|
||||||
|
super.onDestroyView()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package com.navinfo.volvo.ui.fragments.login
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import com.navinfo.volvo.database.AppDatabase
|
||||||
|
import com.navinfo.volvo.model.User
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class LoginViewModel @Inject constructor(private val dataBase: AppDatabase) : ViewModel() {
|
||||||
|
|
||||||
|
private val _user = MutableLiveData<User>().apply {
|
||||||
|
|
||||||
|
}
|
||||||
|
val user: LiveData<User> = _user
|
||||||
|
|
||||||
|
fun liveDataOnclick(view: View) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun userRegister(username: String, password: String) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.navinfo.volvo.ui.message
|
package com.navinfo.volvo.ui.fragments.message
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
@ -29,13 +29,13 @@ class ObtainMessageFragment: Fragment() {
|
|||||||
_binding = FragmentObtainMessageBinding.inflate(inflater, container, false)
|
_binding = FragmentObtainMessageBinding.inflate(inflater, container, false)
|
||||||
val root: View = binding.root
|
val root: View = binding.root
|
||||||
|
|
||||||
obtainMessageViewModel?.getMessageLiveData()?.observe(
|
obtainMessageViewModel.getMessageLiveData()?.observe(
|
||||||
viewLifecycleOwner, Observer {
|
viewLifecycleOwner, Observer {
|
||||||
// 初始化界面显示内容
|
// 初始化界面显示内容
|
||||||
if(it.title!=null)
|
if(it.title!=null)
|
||||||
binding.tvMessageTitle?.setText(it.title)
|
binding.tvMessageTitle.setText(it.title)
|
||||||
if (it.sendDate!=null) {
|
if (it.sendDate!=null) {
|
||||||
binding.btnSendTime.setText(it.sendDate)
|
binding.btnSendTime.text = it.sendDate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -43,7 +43,7 @@ class ObtainMessageFragment: Fragment() {
|
|||||||
return root
|
return root
|
||||||
}
|
}
|
||||||
|
|
||||||
fun initView() {
|
private fun initView() {
|
||||||
// 设置问候信息提示的红色星号
|
// 设置问候信息提示的红色星号
|
||||||
binding.tiLayoutTitle.markRequiredInRed()
|
binding.tiLayoutTitle.markRequiredInRed()
|
||||||
// 设置点击按钮选择发送时间
|
// 设置点击按钮选择发送时间
|
||||||
@ -59,6 +59,9 @@ class ObtainMessageFragment: Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 点击按钮选择拍照
|
// 点击按钮选择拍照
|
||||||
|
binding.edtSendTo.setOnClickListener {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
@ -1,11 +1,9 @@
|
|||||||
package com.navinfo.volvo.ui.message
|
package com.navinfo.volvo.ui.fragments.message
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.liveData
|
import com.navinfo.volvo.model.Message
|
||||||
import com.navinfo.volvo.db.dao.entity.Message
|
import com.navinfo.volvo.model.AttachmentType
|
||||||
import com.navinfo.volvo.db.dao.entity.AttachmentType
|
|
||||||
|
|
||||||
class ObtainMessageViewModel: ViewModel() {
|
class ObtainMessageViewModel: ViewModel() {
|
||||||
private val msgLiveData: MutableLiveData<Message> by lazy {
|
private val msgLiveData: MutableLiveData<Message> by lazy {
|
@ -1,4 +1,4 @@
|
|||||||
package com.navinfo.volvo.ui.notifications
|
package com.navinfo.volvo.ui.fragments.notifications
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
@ -1,4 +1,4 @@
|
|||||||
package com.navinfo.volvo.ui.notifications
|
package com.navinfo.volvo.ui.fragments.notifications
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
@ -1,34 +0,0 @@
|
|||||||
package com.navinfo.volvo.ui.home
|
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
|
||||||
import androidx.lifecycle.MutableLiveData
|
|
||||||
import androidx.lifecycle.ViewModel
|
|
||||||
import com.navinfo.volvo.db.dao.entity.Message
|
|
||||||
|
|
||||||
class HomeViewModel : ViewModel() {
|
|
||||||
|
|
||||||
private val messageList: LiveData<MutableList<Message>> =
|
|
||||||
MutableLiveData<MutableList<Message>>().apply {
|
|
||||||
value = mutableListOf<Message>()
|
|
||||||
value!!.add(Message())
|
|
||||||
value!!.add(Message())
|
|
||||||
value!!.add(Message())
|
|
||||||
value!!.add(Message())
|
|
||||||
value!!.add(Message())
|
|
||||||
value!!.add(Message())
|
|
||||||
value!!.add(Message())
|
|
||||||
value!!.add(Message())
|
|
||||||
value!!.add(Message())
|
|
||||||
value!!.add(Message())
|
|
||||||
value!!.add(Message())
|
|
||||||
value!!.add(Message())
|
|
||||||
value!!.add(Message())
|
|
||||||
value!!.add(Message())
|
|
||||||
value!!.add(Message())
|
|
||||||
value!!.add(Message())
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getMessageList(): LiveData<MutableList<Message>> {
|
|
||||||
return messageList
|
|
||||||
}
|
|
||||||
}
|
|
28
app/src/main/java/com/navinfo/volvo/util/LiveDataUtils.kt
Normal file
28
app/src/main/java/com/navinfo/volvo/util/LiveDataUtils.kt
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package com.navinfo.volvo.util
|
||||||
|
|
||||||
|
import androidx.lifecycle.LifecycleOwner
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import androidx.lifecycle.Observer
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This functions helps in transforming a [MutableLiveData] of type [T]
|
||||||
|
* to a [LiveData] of type [T]
|
||||||
|
*/
|
||||||
|
fun <T> MutableLiveData<T>.asLiveData() = this as LiveData<T>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function helps to observe a [LiveData] once
|
||||||
|
*/
|
||||||
|
fun <T> LiveData<T>.observeOnce(lifecycleOwner: LifecycleOwner, observer: Observer<T>) {
|
||||||
|
observe(
|
||||||
|
lifecycleOwner,
|
||||||
|
object : Observer<T> {
|
||||||
|
override fun onChanged(t: T?) {
|
||||||
|
observer.onChanged(t)
|
||||||
|
removeObserver(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
24
app/src/main/java/com/navinfo/volvo/util/NetResult.kt
Normal file
24
app/src/main/java/com/navinfo/volvo/util/NetResult.kt
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package com.navinfo.volvo.util
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Mayokun Adeniyi on 23/05/2020.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A generic class that holds a value with its loading status.
|
||||||
|
* @param <T>
|
||||||
|
*/
|
||||||
|
sealed class NetResult<out R> {
|
||||||
|
|
||||||
|
data class Success<out T>(val data: T?) : NetResult<T>()
|
||||||
|
data class Error(val exception: Exception) : NetResult<Nothing>()
|
||||||
|
object Loading : NetResult<Nothing>()
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return when (this) {
|
||||||
|
is Success<*> -> "Success[data=$data]"
|
||||||
|
is Error -> "Error[exception=$exception]"
|
||||||
|
is Loading -> "Loading"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,131 @@
|
|||||||
|
package com.navinfo.volvo.util
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
import android.preference.PreferenceManager
|
||||||
|
import androidx.core.content.edit
|
||||||
|
import com.google.gson.Gson
|
||||||
|
|
||||||
|
|
||||||
|
class SharedPreferenceHelper {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
private const val WEATHER_PREF_TIME = "Weather pref time"
|
||||||
|
private const val WEATHER_FORECAST_PREF_TIME = "Forecast pref time"
|
||||||
|
private const val CITY_ID = "City ID"
|
||||||
|
private var prefs: SharedPreferences? = null
|
||||||
|
private const val LOCATION = "LOCATION"
|
||||||
|
|
||||||
|
@Volatile
|
||||||
|
private var instance: SharedPreferenceHelper? = null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This checks if there is an existing instance of the [SharedPreferences] in the
|
||||||
|
* specified [context] and creates one if there isn't or else, it returns the
|
||||||
|
* already existing instance. This function ensures that the [SharedPreferences] is
|
||||||
|
* accessed at any instance by a single thread.
|
||||||
|
*/
|
||||||
|
fun getInstance(context: Context): SharedPreferenceHelper {
|
||||||
|
synchronized(this) {
|
||||||
|
val _instance = instance
|
||||||
|
if (_instance == null) {
|
||||||
|
prefs = PreferenceManager.getDefaultSharedPreferences(context)
|
||||||
|
instance = _instance
|
||||||
|
}
|
||||||
|
return SharedPreferenceHelper()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function saves the initial time [System.nanoTime] at which the weather information
|
||||||
|
* at the user's location is accessed.
|
||||||
|
* @param time the value of [System.nanoTime] when the weather information is received.
|
||||||
|
*/
|
||||||
|
fun saveTimeOfInitialWeatherFetch(time: Long) {
|
||||||
|
prefs?.edit(commit = true) {
|
||||||
|
putLong(WEATHER_PREF_TIME, time)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function returns the saved value of [System.nanoTime] when the weather information
|
||||||
|
* at the user's location was accessed.
|
||||||
|
* @see saveTimeOfInitialWeatherFetch
|
||||||
|
*/
|
||||||
|
fun getTimeOfInitialWeatherFetch() = prefs?.getLong(WEATHER_PREF_TIME, 0L)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function saves the initial time [System.nanoTime] at which the weather forecast
|
||||||
|
* at the user's location is accessed.
|
||||||
|
* @param time the value of [System.nanoTime] when the weather forecast is received.
|
||||||
|
*/
|
||||||
|
fun saveTimeOfInitialWeatherForecastFetch(time: Long) {
|
||||||
|
prefs?.edit(commit = true) {
|
||||||
|
putLong(WEATHER_FORECAST_PREF_TIME, time)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function returns the saved value of [System.nanoTime] when the weather forecast
|
||||||
|
* at the user's location was accessed.
|
||||||
|
* @see saveTimeOfInitialWeatherForecastFetch
|
||||||
|
*/
|
||||||
|
fun getTimeOfInitialWeatherForecastFetch() = prefs?.getLong(WEATHER_FORECAST_PREF_TIME, 0L)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function saves the [cityId] of the location whose weather information has been
|
||||||
|
* received.
|
||||||
|
* @param cityId the id of the location whose weather has been received
|
||||||
|
*/
|
||||||
|
fun saveCityId(cityId: Int) {
|
||||||
|
prefs?.edit(commit = true) {
|
||||||
|
putInt(CITY_ID, cityId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function returns the id of the location whose weather information has been received.
|
||||||
|
* @see saveCityId
|
||||||
|
*/
|
||||||
|
fun getCityId() = prefs?.getInt(CITY_ID, 0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function gets the value of the cache duration the user set in the
|
||||||
|
* Settings Fragment.
|
||||||
|
*/
|
||||||
|
fun getUserSetCacheDuration() = prefs?.getString("cache_key", "0")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function gets the value of the app theme the user set in the
|
||||||
|
* Settings Fragment.
|
||||||
|
*/
|
||||||
|
fun getSelectedThemePref() = prefs?.getString("theme_key", "")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function gets the value of the temperature unit the user set in the
|
||||||
|
* Settings Fragment.
|
||||||
|
*/
|
||||||
|
fun getSelectedTemperatureUnit() = prefs?.getString("unit_key", "")
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * This function saves a [LocationModel]
|
||||||
|
// */
|
||||||
|
// fun saveLocation(location: LocationModel) {
|
||||||
|
// prefs?.edit(commit = true) {
|
||||||
|
// val gson = Gson()
|
||||||
|
// val json = gson.toJson(location)
|
||||||
|
// putString(LOCATION, json)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * This function gets the value of the saved [LocationModel]
|
||||||
|
// */
|
||||||
|
// fun getLocation(): LocationModel {
|
||||||
|
// val gson = Gson()
|
||||||
|
// val json = prefs?.getString(LOCATION, null)
|
||||||
|
// return gson.fromJson(json, LocationModel::class.java)
|
||||||
|
// }
|
||||||
|
}
|
7
app/src/main/res/anim/from_left.xml
Normal file
7
app/src/main/res/anim/from_left.xml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:duration="800">
|
||||||
|
<translate
|
||||||
|
android:fromXDelta="-100%"
|
||||||
|
android:toXDelta="0%" />
|
||||||
|
</set>
|
9
app/src/main/res/anim/from_right.xml
Normal file
9
app/src/main/res/anim/from_right.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<set
|
||||||
|
android:duration="800"
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<translate
|
||||||
|
android:fromXDelta="100%"
|
||||||
|
android:toXDelta="0%"
|
||||||
|
/>
|
||||||
|
</set>
|
9
app/src/main/res/anim/to_left.xml
Normal file
9
app/src/main/res/anim/to_left.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<set
|
||||||
|
android:duration="800"
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<translate
|
||||||
|
android:fromXDelta="0%"
|
||||||
|
android:toXDelta="-100%"
|
||||||
|
/>
|
||||||
|
</set>
|
9
app/src/main/res/anim/to_right.xml
Normal file
9
app/src/main/res/anim/to_right.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<set
|
||||||
|
android:duration="800"
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<translate
|
||||||
|
android:fromXDelta="0%"
|
||||||
|
android:toXDelta="100%"
|
||||||
|
/>
|
||||||
|
</set>
|
10
app/src/main/res/drawable-v24/shape_divider_linear.xml
Normal file
10
app/src/main/res/drawable-v24/shape_divider_linear.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item
|
||||||
|
android:left="10dp" >
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<solid android:color="#F6F6F6" />
|
||||||
|
<size android:height="1dp" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</layer-list>
|
1
app/src/main/res/drawable-v24/shape_radius5_white.xml
Normal file
1
app/src/main/res/drawable-v24/shape_radius5_white.xml
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/white" />
<!-- <stroke-->
<!-- android:width="1dp"-->
<!-- android:color="@color/color_dcdcdc" />-->
<corners android:radius="5dp" />
</shape>
|
@ -0,0 +1,5 @@
|
|||||||
|
<vector android:autoMirrored="true" android:height="24dp"
|
||||||
|
android:tint="#000000" android:viewportHeight="24"
|
||||||
|
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M10,6L8.59,7.41 13.17,12l-4.58,4.59L10,18l6,-6z"/>
|
||||||
|
</vector>
|
5
app/src/main/res/drawable/ic_baseline_star_8.xml
Normal file
5
app/src/main/res/drawable/ic_baseline_star_8.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<vector android:height="8dp" android:tint="#FF0202"
|
||||||
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
|
android:width="8dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M12,17.27L18.18,21l-1.64,-7.03L22,9.24l-7.19,-0.61L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21z"/>
|
||||||
|
</vector>
|
@ -6,6 +6,7 @@
|
|||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<com.google.android.material.bottomnavigation.BottomNavigationView
|
<com.google.android.material.bottomnavigation.BottomNavigationView
|
||||||
|
android:visibility="gone"
|
||||||
android:id="@+id/nav_view"
|
android:id="@+id/nav_view"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@ -31,14 +32,14 @@
|
|||||||
app:navGraph="@navigation/mobile_navigation" />
|
app:navGraph="@navigation/mobile_navigation" />
|
||||||
|
|
||||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
android:id="@+id/fab_new_message"
|
android:visibility="gone"
|
||||||
|
android:id="@+id/new_message_fab"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="10dp"
|
android:layout_marginBottom="10dp"
|
||||||
android:src="@drawable/ic_add_24dp"
|
android:src="@drawable/ic_add_24dp"
|
||||||
|
app:elevation="8dp"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
app:layout_constraintRight_toRightOf="parent" />
|
||||||
app:elevation="8dp"
|
|
||||||
/>
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -1,10 +1,11 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context="com.navinfo.volvo.ui.dashboard.DashboardFragment">
|
tools:context="com.navinfo.volvo.ui.fragments.dashboard.DashboardFragment">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/text_dashboard"
|
android:id="@+id/text_dashboard"
|
||||||
|
@ -6,5 +6,5 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context=".ui.home.HomeFragment">
|
tools:context=".ui.fragments.home.MessageFragment">
|
||||||
</com.yanzhenjie.recyclerview.SwipeRecyclerView>
|
</com.yanzhenjie.recyclerview.SwipeRecyclerView>
|
||||||
|
78
app/src/main/res/layout/fragment_login.xml
Normal file
78
app/src/main/res/layout/fragment_login.xml
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<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"
|
||||||
|
tools:context="com.navinfo.volvo.ui.fragments.login.LoginFragment">
|
||||||
|
|
||||||
|
|
||||||
|
<androidx.constraintlayout.utils.widget.ImageFilterView
|
||||||
|
android:id="@+id/login_fragment_logo"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:src="@mipmap/ic_launcher"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintVertical_bias="0.2"
|
||||||
|
app:roundPercent="0.2" />
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:id="@+id/login_fragment_user_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="20dp"
|
||||||
|
android:layout_marginRight="20dp"
|
||||||
|
android:scrollbarAlwaysDrawHorizontalTrack="true"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintVertical_bias="0.4">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="用户名" />
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="20dp"
|
||||||
|
android:layout_marginRight="20dp"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/login_fragment_user_layout">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="密码" />
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||||
|
android:id="@+id/login_fragment_register_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingLeft="10dp"
|
||||||
|
android:paddingRight="10dp"
|
||||||
|
android:text="注册"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintHorizontal_chainStyle="spread"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toLeftOf="@id/login_fragment_login_button"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintVertical_bias="0.7" />
|
||||||
|
|
||||||
|
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||||
|
android:id="@+id/login_fragment_login_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingLeft="10dp"
|
||||||
|
android:paddingRight="10dp"
|
||||||
|
android:text="登录"
|
||||||
|
app:layout_constraintBaseline_toBaselineOf="@id/login_fragment_register_button"
|
||||||
|
app:layout_constraintLeft_toRightOf="@id/login_fragment_register_button"
|
||||||
|
app:layout_constraintRight_toRightOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -4,7 +4,7 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context=".ui.notifications.NotificationsFragment">
|
tools:context=".ui.fragments.notifications.NotificationsFragment">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/text_notifications"
|
android:id="@+id/text_notifications"
|
||||||
|
@ -1,19 +1,20 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:padding="@dimen/activity_default_padding"
|
android:padding="@dimen/activity_default_padding"
|
||||||
tools:context=".ui.message.ObtainMessageFragment">
|
tools:context=".ui.fragments.message.ObtainMessageFragment">
|
||||||
|
|
||||||
<ScrollView
|
<ScrollView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
android:overScrollMode="never"
|
android:overScrollMode="never"
|
||||||
android:scrollbars="none">
|
android:scrollbars="none"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
@ -24,10 +25,10 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="@dimen/default_widget_padding"
|
android:layout_margin="@dimen/default_widget_padding"
|
||||||
|
android:hint="问候信息"
|
||||||
app:counterEnabled="true"
|
app:counterEnabled="true"
|
||||||
app:counterMaxLength="10"
|
app:counterMaxLength="10"
|
||||||
app:errorEnabled="true"
|
app:errorEnabled="true"
|
||||||
android:hint="问候信息"
|
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
@ -82,22 +83,24 @@
|
|||||||
android:text="上传图片:"></TextView>
|
android:text="上传图片:"></TextView>
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
|
style="@style/Widget.Material3.Button.ElevatedButton"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
style="@style/Widget.Material3.Button.ElevatedButton"
|
android:padding="@dimen/default_widget_padding"
|
||||||
app:icon="@drawable/ic_baseline_camera_24"
|
|
||||||
android:text="点击拍照"
|
android:text="点击拍照"
|
||||||
android:padding="@dimen/default_widget_padding"></com.google.android.material.button.MaterialButton>
|
app:icon="@drawable/ic_baseline_camera_24"></com.google.android.material.button.MaterialButton>
|
||||||
|
|
||||||
<Space
|
<Space
|
||||||
android:layout_width="@dimen/default_widget_padding"
|
android:layout_width="@dimen/default_widget_padding"
|
||||||
android:layout_height="wrap_content"></Space>
|
android:layout_height="wrap_content"></Space>
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
|
style="@style/Widget.Material3.Button.ElevatedButton"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
style="@style/Widget.Material3.Button.ElevatedButton"
|
android:padding="@dimen/default_widget_padding"
|
||||||
app:icon="@drawable/ic_baseline_image_search_24"
|
|
||||||
android:text="相册选择"
|
android:text="相册选择"
|
||||||
android:padding="@dimen/default_widget_padding"></com.google.android.material.button.MaterialButton>
|
app:icon="@drawable/ic_baseline_image_search_24"></com.google.android.material.button.MaterialButton>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
@ -119,22 +122,24 @@
|
|||||||
android:text="上传音频:"></TextView>
|
android:text="上传音频:"></TextView>
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
|
style="@style/Widget.Material3.Button.ElevatedButton"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
style="@style/Widget.Material3.Button.ElevatedButton"
|
android:padding="@dimen/default_widget_padding"
|
||||||
app:icon="@drawable/ic_baseline_fiber_manual_record_24"
|
|
||||||
android:text="长按录音"
|
android:text="长按录音"
|
||||||
android:padding="@dimen/default_widget_padding"></com.google.android.material.button.MaterialButton>
|
app:icon="@drawable/ic_baseline_fiber_manual_record_24"></com.google.android.material.button.MaterialButton>
|
||||||
|
|
||||||
<Space
|
<Space
|
||||||
android:layout_width="@dimen/default_widget_padding"
|
android:layout_width="@dimen/default_widget_padding"
|
||||||
android:layout_height="wrap_content"></Space>
|
android:layout_height="wrap_content"></Space>
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
|
style="@style/Widget.Material3.Button.ElevatedButton"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
style="@style/Widget.Material3.Button.ElevatedButton"
|
android:padding="@dimen/default_widget_padding"
|
||||||
app:icon="@drawable/ic_baseline_audio_file_24"
|
|
||||||
android:text="音频选择"
|
android:text="音频选择"
|
||||||
android:padding="@dimen/default_widget_padding"></com.google.android.material.button.MaterialButton>
|
app:icon="@drawable/ic_baseline_audio_file_24"></com.google.android.material.button.MaterialButton>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
@ -157,8 +162,12 @@
|
|||||||
android:id="@+id/layer_send_info"
|
android:id="@+id/layer_send_info"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:animateLayoutChanges="true"
|
||||||
|
android:background="@drawable/shape_radius5_white"
|
||||||
|
android:divider="@drawable/shape_divider_linear"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:padding="@dimen/default_widget_padding"
|
android:padding="@dimen/default_widget_padding"
|
||||||
|
android:showDividers="middle"
|
||||||
app:layout_constraintTop_toBottomOf="@id/div_send_info">
|
app:layout_constraintTop_toBottomOf="@id/div_send_info">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
@ -187,31 +196,17 @@
|
|||||||
tools:ignore="TouchTargetSizeCheck,SpeakableTextPresentCheck"></androidx.appcompat.widget.AppCompatEditText>
|
tools:ignore="TouchTargetSizeCheck,SpeakableTextPresentCheck"></androidx.appcompat.widget.AppCompatEditText>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
style="@style/default_line"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="*"
|
|
||||||
android:textColor="@color/red"></TextView>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="发给谁:"></TextView>
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatEditText
|
|
||||||
android:id="@+id/edt_send_to"
|
android:id="@+id/edt_send_to"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@drawable/selector_bg_4_round_corner"
|
android:drawableStart="@drawable/ic_baseline_star_8"
|
||||||
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck"></androidx.appcompat.widget.AppCompatEditText>
|
android:drawableEnd="@drawable/ic_baseline_navigate_next_24"
|
||||||
</LinearLayout>
|
android:paddingTop="8dp"
|
||||||
|
android:paddingBottom="8dp"
|
||||||
|
android:text="发给谁:" />
|
||||||
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
style="@style/default_line"
|
style="@style/default_line"
|
||||||
@ -233,18 +228,19 @@
|
|||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/btn_send_time"
|
android:id="@+id/btn_send_time"
|
||||||
|
style="@style/Widget.Material3.Button.ElevatedButton"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
style="@style/Widget.Material3.Button.ElevatedButton"
|
android:padding="@dimen/default_widget_padding"
|
||||||
app:icon="@drawable/ic_baseline_access_time_24"
|
|
||||||
android:text="现在"
|
android:text="现在"
|
||||||
android:padding="@dimen/default_widget_padding"></com.google.android.material.button.MaterialButton>
|
app:icon="@drawable/ic_baseline_access_time_24"></com.google.android.material.button.MaterialButton>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/navigation_home"
|
android:id="@+id/navigation_message"
|
||||||
android:icon="@drawable/ic_home_black_24dp"
|
android:icon="@drawable/ic_home_black_24dp"
|
||||||
android:title="@string/title_home" />
|
android:title="@string/title_home" />
|
||||||
<item
|
<item
|
||||||
|
@ -3,40 +3,50 @@
|
|||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/mobile_navigation"
|
android:id="@+id/mobile_navigation"
|
||||||
app:startDestination="@+id/navigation_home">
|
app:startDestination="@+id/navigation_login">
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/navigation_home"
|
android:id="@+id/navigation_login"
|
||||||
android:name="com.navinfo.volvo.ui.home.HomeFragment"
|
android:name="com.navinfo.volvo.ui.fragments.login.LoginFragment"
|
||||||
android:label="@string/title_home"
|
android:label="login"
|
||||||
tools:layout="@layout/fragment_home" >
|
tools:layout="@layout/fragment_login">
|
||||||
<action android:id="@+id/home_2_obtain_message"
|
<action
|
||||||
app:destination="@id/navigation_obtain_message">
|
android:id="@+id/action_login_to_home"
|
||||||
|
app:destination="@id/navigation_message"
|
||||||
</action>
|
app:enterAnim="@anim/from_left"
|
||||||
|
app:exitAnim="@anim/to_right"
|
||||||
|
app:popEnterAnim="@anim/from_right"
|
||||||
|
app:popExitAnim="@anim/to_left"
|
||||||
|
app:popUpTo="@id/navigation_login"
|
||||||
|
app:popUpToInclusive="true" />
|
||||||
</fragment>
|
</fragment>
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/navigation_message"
|
||||||
|
android:name="com.navinfo.volvo.ui.fragments.home.MessageFragment"
|
||||||
|
android:label="@string/title_home"
|
||||||
|
tools:layout="@layout/fragment_home"></fragment>
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/navigation_dashboard"
|
android:id="@+id/navigation_dashboard"
|
||||||
android:name="com.navinfo.volvo.ui.dashboard.DashboardFragment"
|
android:name="com.navinfo.volvo.ui.fragments.dashboard.DashboardFragment"
|
||||||
android:label="@string/title_dashboard"
|
android:label="@string/title_dashboard"
|
||||||
tools:layout="@layout/fragment_dashboard" />
|
tools:layout="@layout/fragment_dashboard" />
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/fab_new_message"
|
android:id="@+id/fab_new_message"
|
||||||
android:name="com.navinfo.volvo.ui.dashboard.DashboardFragment"
|
android:name="com.navinfo.volvo.ui.fragments.dashboard.DashboardFragment"
|
||||||
android:label="@string/title_dashboard"
|
android:label="@string/title_dashboard"
|
||||||
tools:layout="@layout/fragment_dashboard" />
|
tools:layout="@layout/fragment_dashboard" />
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/navigation_notifications"
|
android:id="@+id/navigation_notifications"
|
||||||
android:name="com.navinfo.volvo.ui.notifications.NotificationsFragment"
|
android:name="com.navinfo.volvo.ui.fragments.notifications.NotificationsFragment"
|
||||||
android:label="@string/title_notifications"
|
android:label="@string/title_notifications"
|
||||||
tools:layout="@layout/fragment_notifications" />
|
tools:layout="@layout/fragment_notifications" />
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/navigation_obtain_message"
|
android:id="@+id/navigation_obtain_message"
|
||||||
android:name="com.navinfo.volvo.ui.message.ObtainMessageFragment"
|
android:name="com.navinfo.volvo.ui.fragments.message.ObtainMessageFragment"
|
||||||
android:label="问候编辑"
|
android:label="问候编辑"
|
||||||
tools:layout="@layout/fragment_obtain_message" />
|
tools:layout="@layout/fragment_obtain_message" />
|
||||||
</navigation>
|
</navigation>
|
@ -1,6 +1,6 @@
|
|||||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||||
<!-- Base application theme. -->
|
<!-- Base application theme. -->
|
||||||
<style name="Theme.NavinfoVolvo" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
<style name="Theme.NavinfoVolvo" parent="Theme.Material3.DynamicColors.DayNight">
|
||||||
<!-- Primary brand color. -->
|
<!-- Primary brand color. -->
|
||||||
<item name="colorPrimary">@color/purple_200</item>
|
<item name="colorPrimary">@color/purple_200</item>
|
||||||
<item name="colorPrimaryVariant">@color/purple_700</item>
|
<item name="colorPrimaryVariant">@color/purple_700</item>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||||
<!-- Base application theme. -->
|
<!-- Base application theme. -->
|
||||||
<style name="Theme.NavinfoVolvo" parent="Theme.Material3.DayNight.NoActionBar">
|
<style name="Theme.NavinfoVolvo" parent="Theme.Material3.DynamicColors.Light">
|
||||||
<!-- Primary brand color. -->
|
<!-- Primary brand color. -->
|
||||||
<item name="colorPrimary">@color/purple_500</item>
|
<item name="colorPrimary">@color/purple_500</item>
|
||||||
<item name="colorPrimaryVariant">@color/purple_700</item>
|
<item name="colorPrimaryVariant">@color/purple_700</item>
|
||||||
|
17
build.gradle
17
build.gradle
@ -1,19 +1,22 @@
|
|||||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
buildscript {
|
buildscript {
|
||||||
// ext.kotlin_version = '1.7.0'
|
// ext.kotlin_version = '1.7.20'
|
||||||
ext.kotlin_version = '1.6.20'
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// classpath "com.android.tools.build:gradle:4.1.1"
|
// classpath 'com.android.tools.build:gradle:7.3.1'
|
||||||
// classpath('androidx.multidex:multidex:2.0.1')
|
classpath('androidx.multidex:multidex:2.0.1')
|
||||||
// classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
|
// classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
|
||||||
// classpath "io.realm:realm-gradle-plugin:10.10.1"
|
// classpath "io.realm:realm-gradle-plugin:10.10.1"
|
||||||
// classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
// classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
|
classpath "com.google.dagger:hilt-android-gradle-plugin:2.41"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id 'com.android.application' version '7.3.1' apply false
|
id 'com.android.application' version '7.1.2' apply false
|
||||||
id 'com.android.library' version '7.3.1' apply false
|
id 'com.android.library' version '7.1.2' apply false
|
||||||
id 'org.jetbrains.kotlin.android' version '1.7.20' apply false
|
id 'org.jetbrains.kotlin.android' version '1.6.10' apply false
|
||||||
|
// id 'com.google.dagger.hilt.android' version "2.44.2" apply false
|
||||||
// id 'io.realm.kotlin' version '0.10.0' apply false
|
// id 'io.realm.kotlin' version '0.10.0' apply false
|
||||||
}
|
}
|
||||||
|
allprojects {
|
||||||
|
}
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,4 +1,4 @@
|
|||||||
#Fri Dec 23 11:23:50 CST 2022
|
#Wed Jan 04 11:16:08 CST 2023
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
|
Loading…
x
Reference in New Issue
Block a user