增加离线地图下载流程
This commit is contained in:
@@ -27,6 +27,7 @@
|
||||
<!-- 读取缓存数据 -->
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<application
|
||||
android:name=".OMQSApplication"
|
||||
android:allowBackup="true"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
android:fullBackupContent="@xml/backup_rules"
|
||||
@@ -37,9 +38,11 @@
|
||||
android:theme="@style/Theme.OMQualityInspection"
|
||||
tools:targetApi="31">
|
||||
<activity
|
||||
android:name=".ui.activity.LoginActivity"
|
||||
android:name=".ui.activity.login.LoginActivity"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTask"
|
||||
android:screenOrientation="landscape"
|
||||
android:theme="@style/Theme.OMQualityInspection">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
@@ -48,9 +51,11 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ui.activity.MainActivity"
|
||||
android:exported="true"
|
||||
android:theme="@style/Theme.OMQualityInspection"></activity>
|
||||
android:name=".ui.activity.map.MainActivity"
|
||||
android:launchMode="singleTask"
|
||||
android:screenOrientation="landscape"
|
||||
android:theme="@style/Theme.OMQualityInspection" />
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
19
app/src/main/java/com/navinfo/omqs/Constant.kt
Normal file
19
app/src/main/java/com/navinfo/omqs/Constant.kt
Normal file
@@ -0,0 +1,19 @@
|
||||
package com.navinfo.omqs
|
||||
|
||||
class Constant {
|
||||
companion object {
|
||||
/**
|
||||
* 服务器地址
|
||||
*/
|
||||
const val SERVER_ADDRESS = "http://fastmap.navinfo.com/drdc/"
|
||||
|
||||
const val DEBUG = true
|
||||
|
||||
const val message_status_late = "预约,待发送"
|
||||
const val message_status_send_over = "已发送"
|
||||
const val message_version_right_off = "1" //立即发送
|
||||
|
||||
const val MESSAGE_PAGE_SIZE = 30 //消息列表一页最多数量
|
||||
}
|
||||
|
||||
}
|
||||
8
app/src/main/java/com/navinfo/omqs/OMQSApplication.kt
Normal file
8
app/src/main/java/com/navinfo/omqs/OMQSApplication.kt
Normal file
@@ -0,0 +1,8 @@
|
||||
package com.navinfo.omqs
|
||||
|
||||
import android.app.Application
|
||||
import dagger.hilt.android.HiltAndroidApp
|
||||
|
||||
@HiltAndroidApp
|
||||
class OMQSApplication : Application() {
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.navinfo.omqs.model
|
||||
package com.navinfo.omqs.bean
|
||||
|
||||
data class LoginUser(
|
||||
data class LoginUserBean(
|
||||
var username: String = "",
|
||||
var password: String = ""
|
||||
)
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.navinfo.omqs.bean
|
||||
|
||||
data class OfflineMapCityBean(
|
||||
val id: String,
|
||||
val fileName: String,
|
||||
val name: String,
|
||||
val url: String,
|
||||
val version: Long,
|
||||
val fileSize: Long,
|
||||
var currentSize:Long = 0,
|
||||
var status:Int = NONE
|
||||
) {
|
||||
companion object Status{
|
||||
const val NONE = 0 //无状态
|
||||
const val WAITING = 1 //等待中
|
||||
const val LOADING = 2 //下载中
|
||||
const val PAUSE = 3 //暂停
|
||||
const val ERROR = 4 //错误
|
||||
const val DONE = 5 //完成
|
||||
const val UPDATE = 6 //有新版本要更新
|
||||
}
|
||||
fun getFileSizeText(): String {
|
||||
return if (fileSize < 1024.0)
|
||||
"$fileSize B"
|
||||
else if (fileSize < 1048576.0)
|
||||
"%.2f K".format(fileSize / 1024.0)
|
||||
else if (fileSize < 1073741824.0)
|
||||
"%.2f M".format(fileSize / 1048576.0)
|
||||
else
|
||||
"%.2f M".format(fileSize / 1073741824.0)
|
||||
}
|
||||
}
|
||||
94
app/src/main/java/com/navinfo/omqs/hilt/GlobalModule.kt
Normal file
94
app/src/main/java/com/navinfo/omqs/hilt/GlobalModule.kt
Normal file
@@ -0,0 +1,94 @@
|
||||
package com.navinfo.omqs.hilt
|
||||
|
||||
import android.app.Application
|
||||
import android.util.Log
|
||||
import com.google.gson.Gson
|
||||
import com.navinfo.omqs.Constant
|
||||
import com.navinfo.omqs.OMQSApplication
|
||||
import com.navinfo.omqs.http.RetrofitNetworkServiceAPI
|
||||
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
|
||||
|
||||
/**
|
||||
* 全局单例 注入对象
|
||||
*/
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
class GlobalModule {
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideApplication(application: Application): OMQSApplication {
|
||||
return application as OMQSApplication
|
||||
}
|
||||
|
||||
/**
|
||||
* 注入 网络OKHttp 对象
|
||||
*/
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideOkHttpClient(interceptor: HttpLoggingInterceptor): OkHttpClient {
|
||||
return OkHttpClient.Builder().addInterceptor(interceptor)
|
||||
.connectTimeout(60, TimeUnit.SECONDS).writeTimeout(5, TimeUnit.MINUTES)
|
||||
.readTimeout(5, TimeUnit.MINUTES).build()
|
||||
}
|
||||
|
||||
/**
|
||||
* 注入 OHHttp log
|
||||
*/
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideLoggingInterceptor(): HttpLoggingInterceptor {
|
||||
return HttpLoggingInterceptor {
|
||||
if (Constant.DEBUG) {
|
||||
Log.e("jingo", it)
|
||||
}
|
||||
}.apply {
|
||||
level = if (Constant.DEBUG) {
|
||||
HttpLoggingInterceptor.Level.BODY
|
||||
} else {
|
||||
HttpLoggingInterceptor.Level.NONE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideRetrofit(
|
||||
client: Lazy<OkHttpClient>,
|
||||
converterFactory: GsonConverterFactory,
|
||||
): Retrofit {
|
||||
val retrofitBuilder = Retrofit.Builder()
|
||||
.baseUrl(Constant.SERVER_ADDRESS)
|
||||
.client(client.get())
|
||||
.addConverterFactory(converterFactory)
|
||||
|
||||
return retrofitBuilder.build()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGson(): Gson = Gson()
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGsonConverterFactory(gson: Gson): GsonConverterFactory {
|
||||
return GsonConverterFactory.create(gson)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideNetworkService(retrofit: Retrofit): RetrofitNetworkServiceAPI {
|
||||
return retrofit.create(RetrofitNetworkServiceAPI::class.java)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.navinfo.omqs.hilt
|
||||
|
||||
import android.util.Log
|
||||
import com.navinfo.collect.library.map.NIMapController
|
||||
import com.navinfo.omqs.ui.activity.map.MainViewModel
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.components.ActivityRetainedComponent
|
||||
import dagger.hilt.android.scopes.ActivityRetainedScoped
|
||||
|
||||
@InstallIn(ActivityRetainedComponent::class)
|
||||
@Module
|
||||
class MainActivityModule {
|
||||
|
||||
@ActivityRetainedScoped
|
||||
@Provides
|
||||
fun providesMapController(): NIMapController = NIMapController()
|
||||
|
||||
/**
|
||||
* 实验失败,这样创建,viewmodel不会在activity销毁的时候同时销毁
|
||||
*/
|
||||
// @ActivityRetainedScoped
|
||||
// @Provides
|
||||
// fun providesMainViewModel(mapController: NIMapController): MainViewModel {
|
||||
// Log.e("jingo", "MainViewModel 被创建")
|
||||
// return MainViewModel(mapController)
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.navinfo.omqs.hilt
|
||||
|
||||
import com.navinfo.omqs.http.NetworkService
|
||||
import com.navinfo.omqs.http.NetworkServiceImpl
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
|
||||
@InstallIn(SingletonComponent::class)
|
||||
@Module
|
||||
abstract class NetworkServiceModule {
|
||||
|
||||
@Binds
|
||||
abstract fun bindNetworkService(networkServiceImpl: NetworkServiceImpl): NetworkService
|
||||
}
|
||||
53
app/src/main/java/com/navinfo/omqs/http/NetResult.kt
Normal file
53
app/src/main/java/com/navinfo/omqs/http/NetResult.kt
Normal file
@@ -0,0 +1,53 @@
|
||||
package com.navinfo.omqs.http
|
||||
|
||||
/**
|
||||
* Created by Mayokun Adeniyi on 23/05/2020.
|
||||
*/
|
||||
|
||||
/**
|
||||
* 网络返回封装
|
||||
*/
|
||||
|
||||
/**
|
||||
* 在类名之前使用sealed关键字将类声明为密封类。
|
||||
* 密封类仅在编译时限制类型集来确保类型安全的重要性。
|
||||
* 密封类隐式是一个无法实例化的抽象类。
|
||||
*/
|
||||
/**
|
||||
* 二:密封类所具有的特性和与别的类具有不同之处
|
||||
|
||||
①Sealed class(密封类) 是一个有特定数量子类的类,看上去和枚举有点类似,所不同的是,在枚举中,我们每个类型只有一个对象(实例);而在密封类中,同一个类可以拥有几个对象。
|
||||
|
||||
②Sealed class(密封类)的所有子类都必须与密封类在同一文件中
|
||||
|
||||
③Sealed class(密封类)的子类的子类可以定义在任何地方,并不需要和密封类定义在同一个文件中
|
||||
|
||||
④Sealed class(密封类)没有构造函数,不可以直接实例化,只能实例化内部的子类
|
||||
*/
|
||||
/**
|
||||
* 如何获取密封类里面的函数方法
|
||||
* 只能创建密封类子类对象 通过密封类的子类对象调用密封类里的函数方法
|
||||
*/
|
||||
sealed class NetResult<out R> {
|
||||
|
||||
data class Success<out T>(val data: T?) : NetResult<T>()
|
||||
data class Failure(val code: Int, val msg: String) : NetResult<Nothing>()
|
||||
data class Error(val exception: Exception) : NetResult<Nothing>()
|
||||
object Loading : NetResult<Nothing>()
|
||||
|
||||
/**
|
||||
* 密封类通常与表达when时一起使用。 由于密封类的子类将自身类型作为一种情况。
|
||||
因此,密封类中的when表达式涵盖所有情况,从而避免使用else子句。
|
||||
*/
|
||||
override fun toString(): String {
|
||||
return when (this) {
|
||||
is Success<*> -> "网络访问成功,返回正确结果Success[data=$data]"
|
||||
is Failure -> "网络访问成功,返回错误结果Failure[$msg]"
|
||||
is Error -> "网络访问出错 Error[exception=$exception]"
|
||||
is Loading -> "网络访问中 Loading"
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 密封类里面可以有若干个子类,这些子类如果要继承密封类,则必须和密封类在同一个文件里
|
||||
*/
|
||||
13
app/src/main/java/com/navinfo/omqs/http/NetworkService.kt
Normal file
13
app/src/main/java/com/navinfo/omqs/http/NetworkService.kt
Normal file
@@ -0,0 +1,13 @@
|
||||
package com.navinfo.omqs.http
|
||||
|
||||
import com.navinfo.omqs.bean.OfflineMapCityBean
|
||||
|
||||
/**
|
||||
* 网络访问 业务接口
|
||||
*/
|
||||
interface NetworkService {
|
||||
/**
|
||||
* 获取离线地图城市列表
|
||||
*/
|
||||
suspend fun getOfflineMapCityList():NetResult<List<OfflineMapCityBean>>
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.navinfo.omqs.http
|
||||
|
||||
import com.navinfo.omqs.bean.OfflineMapCityBean
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* 网络访问业务接口的具体实现
|
||||
*/
|
||||
class NetworkServiceImpl @Inject constructor(
|
||||
private val netApi: RetrofitNetworkServiceAPI,
|
||||
) : NetworkService {
|
||||
/**
|
||||
* 获取离线地图城市列表
|
||||
*/
|
||||
override suspend fun getOfflineMapCityList(): NetResult<List<OfflineMapCityBean>> =
|
||||
//在IO线程中运行
|
||||
withContext(Dispatchers.IO) {
|
||||
return@withContext try {
|
||||
val result = netApi.retrofitGetOfflineMapCityList()
|
||||
if (result.isSuccessful) {
|
||||
if (result.code() == 200) {
|
||||
NetResult.Success(result.body())
|
||||
} else {
|
||||
NetResult.Failure(result.code(), result.message())
|
||||
}
|
||||
} else {
|
||||
NetResult.Failure(result.code(), result.message())
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
NetResult.Error(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
package com.navinfo.omqs.http
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import com.navinfo.omqs.bean.OfflineMapCityBean
|
||||
import okhttp3.ResponseBody
|
||||
import retrofit2.Response
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Streaming
|
||||
import retrofit2.http.Url
|
||||
import java.util.concurrent.Flow
|
||||
|
||||
/**
|
||||
* retrofit2 网络请求接口
|
||||
*/
|
||||
interface RetrofitNetworkServiceAPI {
|
||||
|
||||
/**
|
||||
* 在 Retrofit2 中,可以使用不同类型的返回值来获取 API 调用的结果。以下是 Retrofit2 支持的一些常见返回类型:
|
||||
|
||||
1. `Call<T>`:表示一个异步请求,其中 `T` 是 API 响应的类型,通常是一个自定义的数据类。使用 `enqueue` 方法来执行异步请求,并在回调中处理响应。
|
||||
|
||||
2. `Response<T>`:表示一个同步请求的响应,其中 `T` 是 API 响应的类型。使用 `execute` 方法来执行同步请求,并返回一个 `Response` 对象,其中包含了响应的状态码、响应头和响应体等信息。
|
||||
|
||||
3. `Observable<T>`:表示一个 RxJava 的 Observable 对象,其中 `T` 是 API 响应的类型。使用 `subscribe` 方法来执行请求,并在 onNext 回调中处理响应。
|
||||
|
||||
4. `Single<T>`:表示一个 RxJava 的 Single 对象,其中 `T` 是 API 响应的类型。使用 `subscribe` 方法来执行请求,并在 onSuccess 回调中处理响应。
|
||||
|
||||
5. `Completable`:表示一个 RxJava 的 Completable 对象,用于执行没有响应体的 API 调用。使用 `subscribe` 方法来执行请求,并在 onComplete 回调中处理响应。
|
||||
|
||||
6. `Flowable<T>`:表示一个 RxJava 的 Flowable 对象,其中 `T` 是 API 响应的类型。类似于 Observable,但支持背压处理。
|
||||
|
||||
7. `Deferred<T>`:表示一个 Kotlin 的 Deferred 对象,其中 `T` 是 API 响应的类型。使用 `await` 方法来执行请求,并返回响应的结果。
|
||||
|
||||
8. `LiveData<Response<T>>`:表示一个 LiveData 对象,其中 `T` 是 API 响应的类型。使用 `observe` 方法来执行请求,并在回调中处理响应。
|
||||
|
||||
总之,Retrofit2 支持多种返回类型,开发者可以根据项目需求选择合适的方式来处理 API 响应结果。
|
||||
*/
|
||||
|
||||
/**
|
||||
* 获取离线地图城市列表
|
||||
*/
|
||||
@GET("/drdc/MapDownload/maplist")
|
||||
suspend fun retrofitGetOfflineMapCityList(): Response<List<OfflineMapCityBean>>
|
||||
|
||||
/**
|
||||
* 下载文件
|
||||
*/
|
||||
@Streaming
|
||||
@GET
|
||||
suspend fun retrofitDownLoadFile(@Url url: String):Response<ResponseBody>
|
||||
|
||||
|
||||
/**
|
||||
* @FormUrlEncoded 请求格式注解,请求实体是一个From表单,每个键值对需要使用@Field注解
|
||||
@Field 请求参数注解,提交请求的表单字段,必须要添加,而且需要配合@FormUrlEncoded使用
|
||||
“token” 参数字段,与后台给的字段需要一致
|
||||
String 声明的参数类型
|
||||
token 实际参数,表示后面token的取值作为"token"的值
|
||||
Post请求如果有参数需要在头部添加@FormUrlEncoded注解,表示请求实体是一个From表单,每个键值对需要使用@Field注解,使用@Field添加参数,这是发送Post请求时,提交请求的表单字段,必须要添加的,而且需要配合@FormUrlEncoded使用,若为在头部添加@FormUrlEncoded注解,会抛出如下异常:
|
||||
当有多个不确定参数时,我们可以使用@FieldMap注解,@FieldMap与@Field的作用一致,可以用于添加多个不确定的参数,类似@QueryMap,Map的key作为表单的键,Map的value作为表单的值。
|
||||
*/
|
||||
// @FormUrlEncoded
|
||||
// @POST("api/dog")
|
||||
// fun postCall(@Field("token") token: String?): Call<Any?>?
|
||||
|
||||
/**
|
||||
* 当有多个不确定参数时,我们可以使用@FieldMap注解,@FieldMap与@Field的作用一致,可以用于添加多个不确定的参数,类似@QueryMap,Map的key作为表单的键,Map的value作为表单的值。
|
||||
*/
|
||||
// @FormUrlEncoded
|
||||
// @POST("api/dog")
|
||||
// open fun postCall(@FieldMap map: Map<String?, Any?>?): Call<Any?>?
|
||||
/**
|
||||
* @GET("v7/weather/now")
|
||||
Call<Wth_now_out> getCall(@QueryMap Map<String, Object> map);
|
||||
*/
|
||||
// @GET("v7/weather/now")
|
||||
// open fun getCall(@QueryMap map: Map<String?, Any?>?): Call<Wth_now_out?>?
|
||||
/**
|
||||
*@Query 请求参数注解,用于Get请求中的参数
|
||||
“location”/“key” 参数字段,与后台给的字段需要一致
|
||||
*/
|
||||
// @GET("v7/weather/now")
|
||||
// open fun getCall(@QueryMap map: Map<String?, Any?>?): Call<Wth_now_out?>?
|
||||
|
||||
/**
|
||||
* @FieldMap 请求参数注解,与@Field作用一致,用于不确定表单参数
|
||||
Map<String, Object> map 通过Map将不确定的参数传入,相当于多个Field参数
|
||||
适用于Post请求的还有一个注解@Body,@Body可以传递自定义类型数据给服务器,多用于post请求发送非表单数据,比如用传递Json格式数据,它可以注解很多东西,比如HashMap、实体类等,我们来看看它用法:
|
||||
特别注意:@Body注解不能用于表单或者支持文件上传的表单的编码,即不能与@FormUrlEncoded和@Multipart注解同时使用
|
||||
*/
|
||||
// @POST("")
|
||||
// open fun getPsotDataBody(@Body body: RequestBody?): Call<Any?>?
|
||||
|
||||
/**
|
||||
* @Path
|
||||
使用第一个get请求网址
|
||||
*/
|
||||
// @GET("v7/weather/{time}")
|
||||
// open fun getCall(@Path("time") time: String?,@QueryMap map: Map<String?, Any?>?): Call<Wth_now_out?>?
|
||||
|
||||
/**
|
||||
* @QueryMap get请求方法参数的注解,上面已经解释了,这里就不重复讲
|
||||
@Path 请求参数注解,用于Url中的占位符{},在网址中的参数
|
||||
@Path注解用于Url中的占位符{},在网址中的参数,如上面 @GET(“v7/weather/{time}”)的time,通过{}占位符来标记time,使用@Path注解传入time的值,注意有的Url既有占位符又有"?"后面的键值对,其实@Query和@Path两者是可以共用的。在发起请求时,{time}会被替换为方法中第二个参数的值time。
|
||||
*/
|
||||
// Map<String ,Object> map = new HashMap<>()Map<String ,Object> map = new HashMap<>();
|
||||
// map.put("location","101010100");
|
||||
// map.put("key","a5cf6ab782a14013b08fb92a57dd2f72");
|
||||
// Call<Wth_now_out> call = apiService.getCall("now",map);
|
||||
/**
|
||||
* 最终{time}会被替换为now,此时形成的牵绊部分Url为:https://devapi.qweather.com/v7/weather/now,剩余**?号**后面的Url由@Query传入。
|
||||
*/
|
||||
|
||||
/**
|
||||
* @HTTP
|
||||
@HTTP注解的作用是替换@GET、@POST、@PUT、@DELETE、@HEAD以及更多拓展功能
|
||||
如可通过此注解代替@POST注解实现post请求,如下:
|
||||
method 表示请求的方法,区分大小写,这里的值retrofit不会再做任何处理,必须要保证正确
|
||||
path 网络请求地址路径
|
||||
hasBody 是否有请求体,boolean类型
|
||||
除请求接口部分的方法有变,别的部分与正常使用@POST请求一致,另外需要注意在使用@HTTP注解实现post请求时,若含有请求体,那么对应的标识注解@FormUrlEncoded一定要加上,若为别的请求体,那么就添加与之对应的标识注解。
|
||||
@HTTP注解可以通过method字段灵活设置具体请求方法,通过path设置网络请求地址,用的比较少。使用方法与设置的请求方法种类一致。
|
||||
*/
|
||||
|
||||
// @FormUrlEncoded
|
||||
// @POST("api/dog")
|
||||
// Call<Object> postCall(@FieldMap Map<String,Object> map);
|
||||
//
|
||||
// @FormUrlEncoded
|
||||
// @HTTP(method = "POST",path = "api/dog", hasBody = true)
|
||||
// Call<Object> postCall1(@FieldMap Map<String,Object> map);
|
||||
/**
|
||||
* @Url
|
||||
如果需要重新地址接口地址,可以使用@Url,将地址以参数的形式传入即可。如果有@Url注解时,GET传入的Url必须省略。不然会抛出如下异常。
|
||||
*/
|
||||
//错误的
|
||||
// @FormUrlEncoded
|
||||
// @POST("api/dog")
|
||||
// open fun postCall(@Url url: String?, @FieldMap map: Map<String?, Any?>?): Call<Any?>?
|
||||
//正确的
|
||||
// @FormUrlEncoded
|
||||
// @POST
|
||||
// open fun postCall(@Url url: String?, @FieldMap map: Map<String?, Any?>?): Call<Any?>?
|
||||
|
||||
/**
|
||||
* @Streaming
|
||||
* @Streaming 表示响应体的数据用流的方式返回,使用于返回数据比较大,该注解在下载大文件时特别有用
|
||||
*/
|
||||
// @Streaming
|
||||
// @POST("gists/public")
|
||||
// open fun getStreamingBig(): Call<ResponseBody?>?
|
||||
|
||||
/**
|
||||
* @Multipart、@part、@PartMap
|
||||
* @Multipart 表示请求实体是一个支持文件上传的表单,需要配合@Part和@PartMap使用,适用于文件上传
|
||||
@Part 用于表单字段,适用于文件上传的情况,@Part支持三种类型:RequestBody、MultipartBody.Part、 任意类型
|
||||
@PartMap 用于多文件上传, 与@FieldMap和@QueryMap的使用类似
|
||||
*/
|
||||
// @Multipart
|
||||
// @POST("user/followers")
|
||||
// open fun getPartData(@Part("name") name: RequestBody?, @Part file: Part?): Call<ResponseBody?>?
|
||||
|
||||
/**
|
||||
* 代码使用逻辑:
|
||||
* 首先声明类型,通过MediaType实现类型的声明,此处使用的时文本类型,然后会根据该类型转化为RequestBody对象,此处使用的参数委RequestBody对象,相当于讲周润发以文本格式转换委RequestBody对象,最终上传时与name形成键值对。
|
||||
*/
|
||||
// //声明类型,这里是文字类型
|
||||
// MediaType textType = MediaType.parse("text/plain");
|
||||
// //根据声明的类型创建RequestBody,就是转化为RequestBody对象
|
||||
// RequestBody name = RequestBody.create(textType, "周润发");
|
||||
|
||||
////创建文件,这里演示图片上传
|
||||
// File file = new File("文件路径");
|
||||
// if (!file.exists()) {
|
||||
// file.mkdir();
|
||||
// }
|
||||
////将文件转化为RequestBody对象
|
||||
////需要在表单中进行文件上传时,就需要使用该格式:multipart/form-data
|
||||
// RequestBody imgBody = RequestBody.create(MediaType.parse("image/png"), file);
|
||||
////将文件转化为MultipartBody.Part
|
||||
////第一个参数:上传文件的key;第二个参数:文件名;第三个参数:RequestBody对象
|
||||
// MultipartBody.Part filePart = MultipartBody.Part.createFormData("key", file.getName(), imgBody);
|
||||
/**
|
||||
* 对于文件类型的上传,我们一般使用MultipartBody.Part类型上传,在上面讲两个参数设置好后,然后调用接口使用请求方法即可:
|
||||
* 此种格式属于文本与文件混合发送的格式。
|
||||
*/
|
||||
// var partDataCall: Call<ResponseBody?>? = retrofit.create(Api::class.java).getPartData(name, filePart)
|
||||
|
||||
/**
|
||||
* @PartMap的使用与@FieldMap和@QueryMap的使用类似,用于多文件上传,我们直接看代码:
|
||||
*/
|
||||
// @Multipart
|
||||
// @POST("user/followers")
|
||||
// open fun getPartMapData(@PartMap map: Map<String?, Part?>?): Call<ResponseBody?>?
|
||||
|
||||
// File file1 = new File("文件路径");
|
||||
// File file2 = new File("文件路径");
|
||||
// if (!file1.exists()) {
|
||||
// file1.mkdir();
|
||||
// }
|
||||
// if (!file2.exists()) {
|
||||
// file2.mkdir();
|
||||
// }
|
||||
// RequestBody requestBody1 = RequestBody.create(MediaType.parse("image/png"), file1);
|
||||
// RequestBody requestBody2 = RequestBody.create(MediaType.parse("image/png"), file2);
|
||||
// MultipartBody.Part filePart1 = MultipartBody.Part.createFormData("file1", file1.getName(), requestBody1);
|
||||
// MultipartBody.Part filePart2 = MultipartBody.Part.createFormData("file2", file2.getName(), requestBody2);
|
||||
//
|
||||
// Map<String,MultipartBody.Part> mapPart = new HashMap<>();
|
||||
// mapPart.put("file1",filePart1);
|
||||
// mapPart.put("file2",filePart2);
|
||||
|
||||
/**
|
||||
* 有关MediaType方法
|
||||
* 概述:MediaType,即是Internet Media Type,互联网媒体类型,也叫做MIME类型,在Http协议消息头中,使用Content-Type来表示具体请求中的媒体类型信息。(也就是说MediaType在网络协议的消息头里面叫做Content-Type)它使用两部分的标识符来确定一个类型,是为了表明我们传的东西是什么类型。
|
||||
常见的媒体格式类型如下:
|
||||
text/html : HTML格式
|
||||
text/plain :纯文本格式
|
||||
text/xml : XML格式
|
||||
image/gif :gif图片格式
|
||||
image/jpeg :jpg图片格式
|
||||
image/png:png图片格式
|
||||
以application开头的媒体格式类型:
|
||||
application/xhtml+xml :XHTML格式
|
||||
application/xml :XML数据格式
|
||||
application/atom+xml :Atom XML聚合格式
|
||||
application/json :JSON数据格式
|
||||
application/pdf :pdf格式
|
||||
application/msword : Word文档格式
|
||||
application/octet-stream : 二进制流数据(如常见的文件下载、上传)
|
||||
application/x-www-form-urlencoded : 中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式
|
||||
另外一种常见的媒体格式是上传文件之时使用的:
|
||||
multipart/form-data : 需要在表单中进行文件上传时,就需要使用该格式
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package com.navinfo.omqs.ui.activity
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.activity.viewModels
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleEventObserver
|
||||
import androidx.lifecycle.LifecycleObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import com.navinfo.omqs.R
|
||||
import com.navinfo.omqs.databinding.ActivityMainBinding
|
||||
|
||||
/**
|
||||
* 地图主页面
|
||||
*/
|
||||
class MainActivity : BaseActivity() {
|
||||
|
||||
private lateinit var binding: ActivityMainBinding
|
||||
private val viewModel by viewModels<MainViewModel>()
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
|
||||
//关联生命周期
|
||||
binding.lifecycleOwner = this
|
||||
//给xml转递对象
|
||||
binding.mainActivity = this
|
||||
//给xml传递viewModel对象
|
||||
binding.viewModel = viewModel
|
||||
//初始化地图
|
||||
viewModel.initMap(this, binding.mapView.mainActivityMap)
|
||||
//让viewModel监听activity生命周期
|
||||
lifecycle.addObserver(viewModel)
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开个人中菜单
|
||||
*/
|
||||
fun openMenu() {
|
||||
binding.mainActivityDrawer.open()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
package com.navinfo.omqs.ui.activity
|
||||
|
||||
import android.content.Context
|
||||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.navinfo.collect.library.map.NIMapController
|
||||
import com.navinfo.collect.library.map.NIMapView
|
||||
|
||||
class MainViewModel : ViewModel(), DefaultLifecycleObserver {
|
||||
/**
|
||||
* 地图控制器
|
||||
*/
|
||||
private lateinit var mapController: NIMapController
|
||||
|
||||
/**
|
||||
* 初始化地图
|
||||
*/
|
||||
fun initMap(context: Context, mapView: NIMapView) {
|
||||
mapController = NIMapController(context = context, mapView = mapView)
|
||||
|
||||
}
|
||||
|
||||
override fun onStart(owner: LifecycleOwner) {
|
||||
super.onStart(owner)
|
||||
//开启定位
|
||||
mapController.locationLayerHandler.startLocation()
|
||||
}
|
||||
|
||||
override fun onPause(owner: LifecycleOwner) {
|
||||
mapController.mMapView.onPause()
|
||||
}
|
||||
|
||||
override fun onDestroy(owner: LifecycleOwner) {
|
||||
mapController.mMapView.onDestroy()
|
||||
//结束定位
|
||||
mapController.locationLayerHandler.stopLocation()
|
||||
}
|
||||
|
||||
override fun onResume(owner: LifecycleOwner) {
|
||||
mapController.mMapView.onResume()
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击我的位置,回到我的位置
|
||||
*/
|
||||
fun onClickLocationButton() {
|
||||
mapController.locationLayerHandler.animateToCurrentPosition()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.navinfo.omqs.ui.activity
|
||||
package com.navinfo.omqs.ui.activity.login
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
@@ -6,6 +6,8 @@ import androidx.activity.viewModels
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import com.navinfo.omqs.R
|
||||
import com.navinfo.omqs.databinding.ActivityLoginBinding
|
||||
import com.navinfo.omqs.ui.activity.map.MainActivity
|
||||
import com.navinfo.omqs.ui.activity.PermissionsActivity
|
||||
|
||||
/**
|
||||
* 登陆页面
|
||||
@@ -35,6 +37,6 @@ class LoginActivity : PermissionsActivity() {
|
||||
fun onClickLoginButton() {
|
||||
val intent = Intent(this@LoginActivity, MainActivity::class.java)
|
||||
startActivity(intent)
|
||||
finish()
|
||||
// finish()
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,15 @@
|
||||
package com.navinfo.omqs.ui.activity
|
||||
package com.navinfo.omqs.ui.activity.login
|
||||
|
||||
import android.view.View
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.navinfo.omqs.model.LoginUser
|
||||
import com.navinfo.omqs.bean.LoginUserBean
|
||||
|
||||
class LoginViewModel : ViewModel() {
|
||||
val loginUser: MutableLiveData<LoginUser> = MutableLiveData()
|
||||
val loginUser: MutableLiveData<LoginUserBean> = MutableLiveData()
|
||||
|
||||
init {
|
||||
loginUser.value = LoginUser(username = "admin", password = "123456")
|
||||
loginUser.value = LoginUserBean(username = "admin", password = "123456")
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -18,6 +18,5 @@ class LoginViewModel : ViewModel() {
|
||||
fun onClick(view: View) {
|
||||
loginUser.value!!.username = "admin2"
|
||||
loginUser.postValue(loginUser.value)
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package com.navinfo.omqs.ui.activity.map
|
||||
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import androidx.activity.viewModels
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.navinfo.collect.library.map.NIMapController
|
||||
import com.navinfo.omqs.R
|
||||
import com.navinfo.omqs.databinding.ActivityMainBinding
|
||||
import com.navinfo.omqs.ui.activity.BaseActivity
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* 地图主页面
|
||||
*/
|
||||
@AndroidEntryPoint
|
||||
class MainActivity : BaseActivity() {
|
||||
|
||||
private lateinit var binding: ActivityMainBinding
|
||||
private val viewModel by viewModels<MainViewModel>()
|
||||
|
||||
//注入地图控制器
|
||||
@Inject
|
||||
lateinit var mapController: NIMapController
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
|
||||
//初始化地图
|
||||
mapController.init(this, binding.mapView.mainActivityMap)
|
||||
//关联生命周期
|
||||
binding.lifecycleOwner = this
|
||||
//给xml转递对象
|
||||
binding.mainActivity = this
|
||||
//给xml传递viewModel对象
|
||||
binding.viewModel = viewModel
|
||||
// lifecycle.addObserver(viewModel)
|
||||
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
|
||||
//开启定位
|
||||
mapController.locationLayerHandler.startLocation()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapController.mMapView.onPause()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
mapController.mMapView.onDestroy()
|
||||
mapController.locationLayerHandler.stopLocation()
|
||||
Log.e("jingo","MainActivity 销毁")
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapController.mMapView.onResume()
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开个人中菜单
|
||||
*/
|
||||
fun openMenu() {
|
||||
binding.mainActivityDrawer.open()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.navinfo.omqs.ui.activity.map
|
||||
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.navinfo.collect.library.map.NIMapController
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.scopes.ActivityRetainedScoped
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
/**
|
||||
* 创建Activity全局viewmode
|
||||
*/
|
||||
@HiltViewModel
|
||||
class MainViewModel @Inject constructor(
|
||||
private val mapController: NIMapController,
|
||||
) : ViewModel() {
|
||||
|
||||
|
||||
/**
|
||||
* 点击我的位置,回到我的位置
|
||||
*/
|
||||
fun onClickLocationButton() {
|
||||
mapController.locationLayerHandler.animateToCurrentPosition()
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
Log.e("jingo","MainViewModel 被释放了")
|
||||
super.onCleared()
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package com.navinfo.omqs.ui.fragment
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.fragment.app.Fragment
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import com.navinfo.omqs.R
|
||||
import com.navinfo.omqs.databinding.FragmentFirstBinding
|
||||
|
||||
/**
|
||||
* A simple [Fragment] subclass as the default destination in the navigation.
|
||||
*/
|
||||
class FirstFragment : Fragment() {
|
||||
|
||||
private var _binding: FragmentFirstBinding? = null
|
||||
|
||||
// This property is only valid between onCreateView and
|
||||
// onDestroyView.
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
|
||||
_binding = FragmentFirstBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
binding.buttonFirst.setOnClickListener {
|
||||
findNavController().navigate(R.id.action_FirstFragment_to_SecondFragment)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.navinfo.omqs.ui.fragment.offlinemap
|
||||
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
|
||||
/**
|
||||
* 离线地图主页面,viewpage适配器
|
||||
*/
|
||||
class OfflineMapAdapter(activity: FragmentActivity) :
|
||||
FragmentStateAdapter(activity) {
|
||||
private val stateFragment = OfflineMapStateListFragment()
|
||||
private val cityListFragment = OfflineMapCityListFragment()
|
||||
override fun getItemCount(): Int {
|
||||
return 2
|
||||
}
|
||||
|
||||
override fun createFragment(position: Int): Fragment {
|
||||
return when (position) {
|
||||
0 -> stateFragment
|
||||
else ->
|
||||
cityListFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.navinfo.omqs.ui.fragment.offlinemap
|
||||
|
||||
import androidx.databinding.ViewDataBinding
|
||||
import com.navinfo.omqs.R
|
||||
import com.navinfo.omqs.BR
|
||||
import com.navinfo.omqs.bean.OfflineMapCityBean
|
||||
import com.navinfo.omqs.databinding.AdapterOfflineMapCityBinding
|
||||
import com.navinfo.omqs.ui.other.BaseRecyclerViewAdapter
|
||||
import com.navinfo.omqs.ui.other.BaseViewHolder
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* 离线地图城市列表 RecyclerView 适配器
|
||||
*/
|
||||
|
||||
class OfflineMapCityListAdapter @Inject constructor() :
|
||||
BaseRecyclerViewAdapter<OfflineMapCityBean>() {
|
||||
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
|
||||
var binding: ViewDataBinding = holder.dataBinding
|
||||
//立刻刷新UI,解决闪烁
|
||||
// binding.executePendingBindings()
|
||||
binding.setVariable(BR.cityBean, data[position])
|
||||
(binding as AdapterOfflineMapCityBinding).offlineMapDownloadBtn.setOnClickListener {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun getItemViewType(position: Int): Int {
|
||||
return R.layout.adapter_offline_map_city
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.navinfo.omqs.ui.fragment.offlinemap
|
||||
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.navinfo.omqs.databinding.FragmentOfflineMapCityListBinding
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
||||
/**
|
||||
* 离线地图城市列表
|
||||
*/
|
||||
@AndroidEntryPoint
|
||||
class OfflineMapCityListFragment : Fragment() {
|
||||
private var _binding: FragmentOfflineMapCityListBinding? = null
|
||||
private val viewModel by viewModels<OfflineMapCityListViewModel>()
|
||||
private val binding get() = _binding!!
|
||||
private val adapter: OfflineMapCityListAdapter by lazy { OfflineMapCityListAdapter() }
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
_binding = FragmentOfflineMapCityListBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val layoutManager = LinearLayoutManager(context)
|
||||
_binding!!.offlineMapCityListRecyclerview.layoutManager = layoutManager
|
||||
_binding!!.offlineMapCityListRecyclerview.adapter = adapter
|
||||
viewModel.cityListLiveData.observe(viewLifecycleOwner) {
|
||||
adapter.refreshData(it)
|
||||
}
|
||||
viewModel.getCityList()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
Log.e("jingo","OfflineMapCityListFragment onDestroyView")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.navinfo.omqs.ui.fragment.offlinemap
|
||||
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import android.widget.Toast
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.navinfo.omqs.http.NetResult
|
||||
import com.navinfo.omqs.http.NetworkService
|
||||
import com.navinfo.omqs.bean.OfflineMapCityBean
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* 离线地图城市列表viewModel
|
||||
*/
|
||||
@HiltViewModel
|
||||
class OfflineMapCityListViewModel @Inject constructor(
|
||||
private val networkService: NetworkService,
|
||||
@ApplicationContext val context: Context
|
||||
) : ViewModel() {
|
||||
|
||||
val cityListLiveData = MutableLiveData<List<OfflineMapCityBean>>()
|
||||
|
||||
/**
|
||||
* 去获取离线地图列表
|
||||
*/
|
||||
fun getCityList() {
|
||||
viewModelScope.launch {
|
||||
when (val result = networkService.getOfflineMapCityList()) {
|
||||
is NetResult.Success -> {
|
||||
cityListLiveData.postValue(result.data!!)
|
||||
}
|
||||
is NetResult.Error -> {
|
||||
Toast.makeText(context, "${result.exception.message}", Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
}
|
||||
is NetResult.Failure -> {
|
||||
Toast.makeText(context, "${result.code}:${result.msg}", Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
}
|
||||
NetResult.Loading -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.navinfo.omqs.ui.fragment.offlinemap
|
||||
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import com.google.android.material.tabs.TabLayout.OnTabSelectedListener
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
import com.navinfo.omqs.databinding.FragmentOfflineMapBinding
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
/**
|
||||
* 离线地图
|
||||
*/
|
||||
class OfflineMapFragment : Fragment() {
|
||||
|
||||
private var _binding: FragmentOfflineMapBinding? = null
|
||||
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
_binding = FragmentOfflineMapBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
//禁止滑动,因为页面在抽屉里,和抽屉的滑动有冲突
|
||||
binding.offlineMapViewpager.isUserInputEnabled = false
|
||||
//创建viewpager2的适配器
|
||||
binding.offlineMapViewpager.adapter = activity?.let { OfflineMapAdapter(it) }
|
||||
//绑定viewpager2与tabLayout
|
||||
TabLayoutMediator(
|
||||
binding.offlineMapTabLayout,
|
||||
binding.offlineMapViewpager
|
||||
) { tab, position ->
|
||||
when (position) {
|
||||
0 -> tab.text = "下载管理"
|
||||
1 -> tab.text = "城市列表"
|
||||
}
|
||||
}.attach()
|
||||
|
||||
//处理返回按钮
|
||||
binding.offlineMapBack.setOnClickListener {
|
||||
findNavController().popBackStack()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
Log.e("jingo","OfflineMapFragment onDestroyView")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.navinfo.omqs.ui.fragment.offlinemap
|
||||
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
import com.navinfo.omqs.databinding.FragmentOfflineMapBinding
|
||||
import com.navinfo.omqs.databinding.FragmentOfflineMapStateListBinding
|
||||
|
||||
|
||||
class OfflineMapStateListFragment : Fragment() {
|
||||
private var _binding: FragmentOfflineMapStateListBinding? = null
|
||||
|
||||
private val binding get() = _binding!!
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
_binding = FragmentOfflineMapStateListBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
Log.e("jingo","OfflineMapStateListFragment onDestroyView")
|
||||
}
|
||||
}
|
||||
@@ -1,40 +1,42 @@
|
||||
package com.navinfo.omqs.ui.fragment
|
||||
package com.navinfo.omqs.ui.fragment.personalcenter
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.fragment.app.Fragment
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import com.navinfo.omqs.R
|
||||
import com.navinfo.omqs.databinding.FragmentSecondBinding
|
||||
import com.navinfo.omqs.databinding.FragmentPersonalCenterBinding
|
||||
|
||||
/**
|
||||
* A simple [Fragment] subclass as the second destination in the navigation.
|
||||
* 个人中心
|
||||
*/
|
||||
class SecondFragment : Fragment() {
|
||||
class PersonalCenterFragment : Fragment() {
|
||||
|
||||
private var _binding: FragmentSecondBinding? = null
|
||||
|
||||
// This property is only valid between onCreateView and
|
||||
// onDestroyView.
|
||||
private var _binding: FragmentPersonalCenterBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
|
||||
_binding = FragmentSecondBinding.inflate(inflater, container, false)
|
||||
_binding = FragmentPersonalCenterBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
binding.buttonSecond.setOnClickListener {
|
||||
findNavController().navigate(R.id.action_SecondFragment_to_FirstFragment)
|
||||
Log.e("jingo", "NIMapController PersonalCenterFragment onViewCreated")
|
||||
binding.root.setNavigationItemSelectedListener {
|
||||
when (it.itemId) {
|
||||
R.id.personal_center_menu_offline_map ->
|
||||
findNavController().navigate(R.id.action_FirstFragment_to_SecondFragment)
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.navinfo.omqs.ui.other
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
|
||||
/**
|
||||
* RecyclerView 适配器基础类
|
||||
*/
|
||||
abstract class BaseRecyclerViewAdapter<T>(var data: List<T> = listOf()) :
|
||||
RecyclerView.Adapter<BaseViewHolder>() {
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
|
||||
return BaseViewHolder(
|
||||
DataBindingUtil.inflate(
|
||||
LayoutInflater.from(parent.context),
|
||||
viewType,
|
||||
parent,
|
||||
false
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return data.size
|
||||
}
|
||||
|
||||
fun refreshData(newData:List<T>){
|
||||
this.data = newData
|
||||
this.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.navinfo.omqs.ui.other
|
||||
|
||||
import androidx.databinding.ViewDataBinding
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
|
||||
/**
|
||||
* dataBinding viewHolder 基类
|
||||
*/
|
||||
open class BaseViewHolder(var dataBinding: ViewDataBinding) :
|
||||
RecyclerView.ViewHolder(dataBinding.root) {
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.navinfo.omqs.ui.widget
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Color
|
||||
import android.graphics.Paint
|
||||
import android.graphics.Rect
|
||||
import android.opengl.ETC1.getHeight
|
||||
import android.opengl.ETC1.getWidth
|
||||
import android.util.AttributeSet
|
||||
import android.widget.ProgressBar
|
||||
|
||||
|
||||
/**
|
||||
* 带文字提示的进度条
|
||||
*/
|
||||
class MyProgressBar : ProgressBar {
|
||||
private lateinit var mPaint: Paint
|
||||
private var text: String = ""
|
||||
private var rate = 0f
|
||||
|
||||
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
|
||||
initView()
|
||||
}
|
||||
|
||||
constructor(context: Context?) : super(context) {
|
||||
initView()
|
||||
}
|
||||
|
||||
private fun initView() {
|
||||
mPaint = Paint()
|
||||
mPaint.isAntiAlias = true
|
||||
mPaint.color = Color.BLUE
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun setProgress(progress: Int) {
|
||||
setText(progress)
|
||||
super.setProgress(progress)
|
||||
}
|
||||
|
||||
private fun setText(progress: Int) {
|
||||
rate = progress * 1.0f / this.getMax()
|
||||
val i = (rate * 100).toInt()
|
||||
text = "$i%"
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onDraw(canvas: Canvas) {
|
||||
super.onDraw(canvas)
|
||||
val rect = Rect()
|
||||
mPaint.getTextBounds(text, 0, text.length, rect)
|
||||
// int x = (getWidth()/2) - rect.centerX();
|
||||
// int y = (getHeight()/2) - rect.centerY();
|
||||
var x = (width * rate).toInt()
|
||||
if (x == width) {
|
||||
// 如果为百分之百则在左边绘制。
|
||||
x = width - rect.right
|
||||
}
|
||||
val y: Int = 0 - rect.top
|
||||
mPaint.textSize = 22f
|
||||
canvas.drawText(text, x.toFloat(), y.toFloat(), mPaint)
|
||||
}
|
||||
}
|
||||
8
app/src/main/res/color/btn_blue_white.xml
Normal file
8
app/src/main/res/color/btn_blue_white.xml
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_enabled="false" android:color="#8cc1ff"/>
|
||||
<item android:state_checked="true" android:color="@color/white"></item>
|
||||
<item android:state_selected="true" android:color="@color/white"></item>
|
||||
<item android:state_pressed="true" android:color="@color/white"></item>
|
||||
<item android:color="#108ee9"></item>
|
||||
</selector>
|
||||
5
app/src/main/res/drawable/baseline_map_24.xml
Normal file
5
app/src/main/res/drawable/baseline_map_24.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<vector android:height="24dp" android:tint="#100F0F"
|
||||
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="M20.5,3l-0.16,0.03L15,5.1 9,3 3.36,4.9c-0.21,0.07 -0.36,0.25 -0.36,0.48V20.5c0,0.28 0.22,0.5 0.5,0.5l0.16,-0.03L9,18.9l6,2.1 5.64,-1.9c0.21,-0.07 0.36,-0.25 0.36,-0.48V3.5c0,-0.28 -0.22,-0.5 -0.5,-0.5zM15,19l-6,-2.11V5l6,2.11V19z"/>
|
||||
</vector>
|
||||
6
app/src/main/res/drawable/btn_back_xml.xml
Normal file
6
app/src/main/res/drawable/btn_back_xml.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
<item android:state_enabled="true" android:state_pressed="false" android:drawable="@mipmap/icon_back_n"/>
|
||||
<item android:state_pressed="true" android:drawable="@mipmap/icon_back_p"/>
|
||||
<item android:state_enabled="false" android:drawable="@mipmap/icon_back_n"/>
|
||||
</selector>
|
||||
26
app/src/main/res/drawable/fm_card_map_btn_bg_line.xml
Normal file
26
app/src/main/res/drawable/fm_card_map_btn_bg_line.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_pressed="true"><shape android:shape="rectangle">
|
||||
<gradient android:type="linear" android:useLevel="true" android:startColor="#03bef3" android:endColor="#0c5ce8" android:angle="45" />
|
||||
<corners android:topLeftRadius="2dp" android:topRightRadius="0dp" android:bottomLeftRadius="2dp" android:bottomRightRadius="0dp" />
|
||||
</shape></item>
|
||||
<item android:state_focused="true"><shape android:shape="rectangle">
|
||||
<gradient android:type="linear" android:useLevel="true" android:startColor="#03bef3" android:endColor="#0c5ce8" android:angle="45" />
|
||||
<corners android:topLeftRadius="2dp" android:topRightRadius="0dp" android:bottomLeftRadius="2dp" android:bottomRightRadius="0dp" />
|
||||
</shape></item>
|
||||
<item android:state_checked="true"><shape android:shape="rectangle">
|
||||
<gradient android:type="linear" android:useLevel="true" android:startColor="#03bef3" android:endColor="#0c5ce8" android:angle="45" />
|
||||
<corners android:topLeftRadius="2dp" android:topRightRadius="0dp" android:bottomLeftRadius="2dp" android:bottomRightRadius="0dp" />
|
||||
</shape></item>
|
||||
<item android:state_selected="true"><shape android:shape="rectangle">
|
||||
<gradient android:type="linear" android:useLevel="true" android:startColor="#03bef3" android:endColor="#0c5ce8" android:angle="45" />
|
||||
<corners android:topLeftRadius="2dp" android:topRightRadius="0dp" android:bottomLeftRadius="2dp" android:bottomRightRadius="0dp" />
|
||||
</shape></item>
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="#ff043683" />
|
||||
<corners android:topLeftRadius="0dp" android:topRightRadius="2dp" android:bottomLeftRadius="0dp" android:bottomRightRadius="2dp" />
|
||||
</shape></item>
|
||||
|
||||
</selector>
|
||||
32
app/src/main/res/drawable/fm_card_map_down_status_bg.xml
Normal file
32
app/src/main/res/drawable/fm_card_map_down_status_bg.xml
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_enabled="false">
|
||||
<shape>
|
||||
<stroke android:width="1.1dp" android:color="@color/cv_gray_153" />
|
||||
<solid android:color="@color/cv_gray_153" />
|
||||
<padding android:bottom="@dimen/default_widget_padding" android:left="@dimen/default_widget_padding" android:right="@dimen/default_widget_padding" android:top="@dimen/default_widget_padding"></padding>
|
||||
</shape>
|
||||
</item>
|
||||
<item android:state_pressed="true">
|
||||
<shape>
|
||||
<stroke android:width="1.1dp" android:color="@color/white" />
|
||||
<solid android:color="@color/white" />
|
||||
<padding android:bottom="@dimen/default_widget_padding" android:left="@dimen/default_widget_padding" android:right="@dimen/default_widget_padding" android:top="@dimen/default_widget_padding"></padding>
|
||||
</shape>
|
||||
</item>
|
||||
<item android:state_selected="true">
|
||||
<shape>
|
||||
<stroke android:width="1.1dp" android:color="@color/cvm_red" />
|
||||
<solid android:color="@color/cvm_red" />
|
||||
<padding android:bottom="@dimen/default_widget_padding" android:left="@dimen/default_widget_padding" android:right="@dimen/default_widget_padding" android:top="@dimen/default_widget_padding"></padding>
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape>
|
||||
<stroke android:width="1.1dp" android:color="@color/btn_blue_solid" />
|
||||
<solid android:color="@color/transp" />
|
||||
<padding android:bottom="@dimen/default_widget_padding" android:left="@dimen/default_widget_padding" android:right="@dimen/default_widget_padding" android:top="@dimen/default_widget_padding"></padding>
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
</selector>
|
||||
@@ -2,17 +2,17 @@
|
||||
<layout 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"
|
||||
tools:context=".ui.activity.LoginActivity">
|
||||
tools:context=".ui.activity.login.LoginActivity">
|
||||
|
||||
<data>
|
||||
|
||||
<variable
|
||||
name="activity"
|
||||
type="com.navinfo.omqs.ui.activity.LoginActivity" />
|
||||
type="com.navinfo.omqs.ui.activity.login.LoginActivity" />
|
||||
|
||||
<variable
|
||||
name="loginUserModel"
|
||||
type="com.navinfo.omqs.ui.activity.LoginViewModel" />
|
||||
type="com.navinfo.omqs.ui.activity.login.LoginViewModel" />
|
||||
</data>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
|
||||
@@ -2,17 +2,17 @@
|
||||
<layout 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"
|
||||
tools:context=".ui.activity.MainActivity">
|
||||
tools:context=".ui.activity.map.MainActivity">
|
||||
|
||||
<data>
|
||||
|
||||
<variable
|
||||
name="mainActivity"
|
||||
type="com.navinfo.omqs.ui.activity.MainActivity" />
|
||||
type="com.navinfo.omqs.ui.activity.map.MainActivity" />
|
||||
|
||||
<variable
|
||||
name="viewModel"
|
||||
type="com.navinfo.omqs.ui.activity.MainViewModel" />
|
||||
type="com.navinfo.omqs.ui.activity.map.MainViewModel" />
|
||||
</data>
|
||||
|
||||
<androidx.drawerlayout.widget.DrawerLayout
|
||||
@@ -27,15 +27,14 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:mainActivity="@{mainActivity}"
|
||||
app:viewModel="@{viewModel}"/>
|
||||
app:viewModel="@{viewModel}" />
|
||||
|
||||
<com.google.android.material.navigation.NavigationView
|
||||
android:id="@+id/nav_view"
|
||||
android:layout_width="wrap_content"
|
||||
<fragment
|
||||
android:id="@+id/main_activity_fragment"
|
||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||
android:layout_width="300dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="left"
|
||||
android:fitsSystemWindows="true"
|
||||
app:headerLayout="@layout/nav_header_main"
|
||||
app:menu="@menu/activity_main_drawer" />
|
||||
app:navGraph="@navigation/nav_graph" />
|
||||
</androidx.drawerlayout.widget.DrawerLayout>
|
||||
</layout>
|
||||
82
app/src/main/res/layout/adapter_offline_map_city.xml
Normal file
82
app/src/main/res/layout/adapter_offline_map_city.xml
Normal file
@@ -0,0 +1,82 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout 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"
|
||||
tools:context="com.navinfo.omqs.ui.fragment.offlinemap.OfflineMapCityListAdapter">
|
||||
|
||||
<data>
|
||||
|
||||
<import type="com.navinfo.omqs.R" />
|
||||
|
||||
<variable
|
||||
name="cityBean"
|
||||
type="com.navinfo.omqs.bean.OfflineMapCityBean" />
|
||||
</data>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="10dp"
|
||||
android:background="@color/cv_bg_color">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/offline_map_city_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@{cityBean.name}"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/default_font_size"
|
||||
app:layout_constraintLeft_toLeftOf="@id/offline_map_city_size"
|
||||
app:layout_constraintRight_toRightOf="@id/offline_map_city_size"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/offline_map_city_size"
|
||||
style="@style/map_size_font_style"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawableLeft="@mipmap/point_blue"
|
||||
android:textSize="@dimen/card_title_font_3size"
|
||||
android:text="@{cityBean.getFileSizeText()}"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/offline_map_city_name" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_city_list_status"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:clickable="true"
|
||||
android:focusable="false"
|
||||
android:shadowColor="@android:color/transparent"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/card_title_font_2size"
|
||||
app:layout_constraintBottom_toBottomOf="@id/offline_map_download_btn"
|
||||
app:layout_constraintRight_toLeftOf="@id/offline_map_download_btn"
|
||||
app:layout_constraintTop_toTopOf="@id/offline_map_download_btn" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/offline_map_download_btn"
|
||||
style="@style/map_download_style_btn"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:shadowColor="@android:color/transparent"
|
||||
android:text="下载"
|
||||
android:textColor="@color/btn_blue_solid"
|
||||
android:textSize="@dimen/card_title_font_2size"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@id/offline_map_progress"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<com.navinfo.omqs.ui.widget.MyProgressBar
|
||||
android:layout_marginTop="5dp"
|
||||
android:visibility="gone"
|
||||
android:id="@+id/offline_map_progress"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:max="100"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</layout>
|
||||
@@ -1,19 +0,0 @@
|
||||
<?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"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||
|
||||
<fragment
|
||||
android:id="@+id/nav_host_fragment_content_main"
|
||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:defaultNavHost="true"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:navGraph="@navigation/nav_graph" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -1,36 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.core.widget.NestedScrollView 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=".ui.fragment.FirstFragment">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="16dp">
|
||||
|
||||
<Button
|
||||
android:id="@+id/button_first"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/next"
|
||||
app:layout_constraintBottom_toTopOf="@id/textview_first"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textview_first"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@string/lorem_ipsum"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/button_first" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
99
app/src/main/res/layout/fragment_map_download.xml
Normal file
99
app/src/main/res/layout/fragment_map_download.xml
Normal file
@@ -0,0 +1,99 @@
|
||||
<?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:background="#000000"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
style="@style/title_default_style"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="#553C3F41">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/btn_back"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:paddingBottom="@dimen/default_widget_padding"
|
||||
android:paddingLeft="@dimen/default_widget_padding"
|
||||
android:paddingRight="@dimen/default_widget_padding"
|
||||
android:paddingTop="@dimen/default_widget_padding"
|
||||
android:src="@drawable/btn_back_xml" />
|
||||
|
||||
<RadioGroup
|
||||
android:id="@+id/rg_city"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rb_manager"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/fm_card_map_btn_bg_line"
|
||||
android:button="@null"
|
||||
android:drawableLeft="@null"
|
||||
android:gravity="center"
|
||||
android:paddingBottom="@dimen/default_widget_padding"
|
||||
android:paddingLeft="@dimen/default_widget_padding"
|
||||
android:paddingRight="@dimen/default_widget_padding"
|
||||
android:paddingTop="@dimen/default_widget_padding"
|
||||
android:text="下载管理"
|
||||
android:textColor="@color/btn_blue_white"
|
||||
android:textSize="18sp" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rb_city_list"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/fm_card_map_btn_bg_line"
|
||||
android:button="@null"
|
||||
android:checked="true"
|
||||
android:drawableLeft="@null"
|
||||
android:gravity="center"
|
||||
android:paddingBottom="@dimen/default_widget_padding"
|
||||
android:paddingLeft="@dimen/default_widget_padding"
|
||||
android:paddingRight="@dimen/default_widget_padding"
|
||||
android:paddingTop="@dimen/default_widget_padding"
|
||||
android:text="城市列表"
|
||||
android:textColor="@color/btn_blue_white"
|
||||
android:textSize="18sp" />
|
||||
</RadioGroup>
|
||||
</RelativeLayout>
|
||||
<EditText
|
||||
android:id="@+id/edt_search"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/input_blue_type"
|
||||
android:hint="搜索"></EditText>
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<TextView
|
||||
android:id="@+id/tv_map_download_network_hint"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:layout_gravity="center"
|
||||
android:textColor="#FFFFFF"
|
||||
android:visibility="gone"
|
||||
android:text="网络错误,请检查网络后重试"></TextView>
|
||||
<!-- <com.yanzhenjie.recyclerview.SwipeRecyclerView-->
|
||||
<!-- android:id="@+id/lv_map_manager"-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:visibility="invisible"-->
|
||||
<!-- android:layout_height="match_parent">-->
|
||||
<!-- </com.yanzhenjie.recyclerview.SwipeRecyclerView>-->
|
||||
<!-- <com.yanzhenjie.recyclerview.SwipeRecyclerView-->
|
||||
<!-- android:id="@+id/lv_map_city"-->
|
||||
<!-- android:visibility="visible"-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="match_parent">-->
|
||||
<!-- </com.yanzhenjie.recyclerview.SwipeRecyclerView>-->
|
||||
</FrameLayout>
|
||||
</LinearLayout>
|
||||
54
app/src/main/res/layout/fragment_offline_map.xml
Normal file
54
app/src/main/res/layout/fragment_offline_map.xml
Normal file
@@ -0,0 +1,54 @@
|
||||
<?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"
|
||||
android:background="@color/design_default_color_background"
|
||||
tools:context=".ui.fragment.offlinemap.OfflineMapFragment">
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/offline_map_tab_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/default_blue"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<com.google.android.material.tabs.TabItem
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="下载管理" />
|
||||
|
||||
<com.google.android.material.tabs.TabItem
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="城市列表" />
|
||||
</com.google.android.material.tabs.TabLayout>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/offline_map_search"
|
||||
style="@style/input_blue_type"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="搜索"
|
||||
app:layout_constraintTop_toBottomOf="@id/offline_map_tab_layout" />
|
||||
|
||||
<androidx.viewpager2.widget.ViewPager2
|
||||
android:id="@+id/offline_map_viewpager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/offline_map_search" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/offline_map_back"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:padding="10dp"
|
||||
android:src="@mipmap/icon_back_n"
|
||||
app:layout_constraintBottom_toBottomOf="@id/offline_map_tab_layout"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/offline_map_tab_layout" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
13
app/src/main/res/layout/fragment_offline_map_city_list.xml
Normal file
13
app/src/main/res/layout/fragment_offline_map_city_list.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?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=".ui.fragment.offlinemap.OfflineMapCityListFragment">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/offline_map_city_list_recyclerview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
18
app/src/main/res/layout/fragment_offline_map_state_list.xml
Normal file
18
app/src/main/res/layout/fragment_offline_map_state_list.xml
Normal file
@@ -0,0 +1,18 @@
|
||||
<?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"
|
||||
android:background="@color/default_red"
|
||||
tools:context=".ui.fragment.offlinemap.OfflineMapStateListFragment">
|
||||
|
||||
<TextView
|
||||
android:text="第一页"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
11
app/src/main/res/layout/fragment_personal_center.xml
Normal file
11
app/src/main/res/layout/fragment_personal_center.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.google.android.material.navigation.NavigationView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="left"
|
||||
android:fitsSystemWindows="true"
|
||||
app:headerLayout="@layout/personal_center_head"
|
||||
app:menu="@menu/personal_center_menu" />
|
||||
@@ -1,35 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.core.widget.NestedScrollView 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=".ui.fragment.SecondFragment">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="16dp">
|
||||
|
||||
<Button
|
||||
android:id="@+id/button_second"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/previous"
|
||||
app:layout_constraintBottom_toTopOf="@id/textview_second"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textview_second"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@string/lorem_ipsum"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/button_second" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
@@ -6,17 +6,17 @@
|
||||
<data>
|
||||
<variable
|
||||
name="mainActivity"
|
||||
type="com.navinfo.omqs.ui.activity.MainActivity" />
|
||||
type="com.navinfo.omqs.ui.activity.map.MainActivity" />
|
||||
|
||||
<variable
|
||||
name="viewModel"
|
||||
type="com.navinfo.omqs.ui.activity.MainViewModel" />
|
||||
type="com.navinfo.omqs.ui.activity.map.MainViewModel" />
|
||||
</data>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".ui.activity.MainActivity">
|
||||
tools:context=".ui.activity.map.MainActivity">
|
||||
|
||||
<com.navinfo.collect.library.map.NIMapView
|
||||
android:id="@+id/main_activity_map"
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:showIn="navigation_view">
|
||||
|
||||
<group android:checkableBehavior="single">
|
||||
<item
|
||||
android:id="@+id/nav_home"
|
||||
android:icon="@drawable/icon_map_zoom_in"
|
||||
android:title="menu_home" />
|
||||
<item
|
||||
android:id="@+id/nav_gallery"
|
||||
android:icon="@drawable/icon_map_zoom_in"
|
||||
android:title="menu_gallery" />
|
||||
<item
|
||||
android:id="@+id/nav_slideshow"
|
||||
android:icon="@drawable/icon_map_zoom_in"
|
||||
android:title="menu_slideshow" />
|
||||
</group>
|
||||
</menu>
|
||||
@@ -1,10 +0,0 @@
|
||||
<menu 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"
|
||||
tools:context="com.navinfo.omqs.ui.activity.MainActivity">
|
||||
<item
|
||||
android:id="@+id/action_settings"
|
||||
android:orderInCategory="100"
|
||||
android:title="@string/action_settings"
|
||||
app:showAsAction="never" />
|
||||
</menu>
|
||||
42
app/src/main/res/menu/personal_center_menu.xml
Normal file
42
app/src/main/res/menu/personal_center_menu.xml
Normal file
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:showIn="navigation_view">
|
||||
|
||||
<group
|
||||
android:id="@+id/group1"
|
||||
android:checkableBehavior="single">
|
||||
<item
|
||||
android:id="@+id/personal_center_menu_offline_map"
|
||||
android:icon="@drawable/baseline_map_24"
|
||||
android:title="离线地图" />
|
||||
<item
|
||||
android:id="@+id/personal_center_menu_offline_map1"
|
||||
android:icon="@drawable/baseline_person_24"
|
||||
android:title="menu_gallery" />
|
||||
<item
|
||||
android:id="@+id/personal_center_menu_offline_map2"
|
||||
android:icon="@drawable/baseline_person_24"
|
||||
android:title="menu_slideshow" />
|
||||
</group>
|
||||
<group
|
||||
android:id="@+id/group2"
|
||||
android:checkableBehavior="single">
|
||||
<item android:title="小标题">
|
||||
<menu>
|
||||
<item
|
||||
android:id="@+id/personal_center_menu_offline_map3"
|
||||
android:icon="@drawable/baseline_person_24"
|
||||
android:title="menu_home" />
|
||||
<item
|
||||
android:id="@+id/personal_center_menu_offline_map4"
|
||||
android:icon="@drawable/baseline_person_24"
|
||||
android:title="menu_gallery" />
|
||||
<item
|
||||
android:id="@+id/personal_center_menu_offline_map5"
|
||||
android:icon="@drawable/baseline_person_24"
|
||||
android:title="menu_slideshow" />
|
||||
</menu>
|
||||
</item>
|
||||
</group>
|
||||
</menu>
|
||||
BIN
app/src/main/res/mipmap-xhdpi/icon_back_n.png
Normal file
BIN
app/src/main/res/mipmap-xhdpi/icon_back_n.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
BIN
app/src/main/res/mipmap-xhdpi/icon_back_p.png
Normal file
BIN
app/src/main/res/mipmap-xhdpi/icon_back_p.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
BIN
app/src/main/res/mipmap-xhdpi/point_blue.png
Normal file
BIN
app/src/main/res/mipmap-xhdpi/point_blue.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 123 B |
@@ -3,13 +3,13 @@
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/nav_graph"
|
||||
app:startDestination="@id/FirstFragment">
|
||||
app:startDestination="@id/PersonalCenterFragment">
|
||||
|
||||
<fragment
|
||||
android:id="@+id/FirstFragment"
|
||||
android:name="com.navinfo.omqs.ui.fragment.FirstFragment"
|
||||
android:label="@string/first_fragment_label"
|
||||
tools:layout="@layout/fragment_first">
|
||||
android:id="@+id/PersonalCenterFragment"
|
||||
android:name="com.navinfo.omqs.ui.fragment.personalcenter.PersonalCenterFragment"
|
||||
android:label="@string/personal_center"
|
||||
tools:layout="@layout/fragment_personal_center">
|
||||
|
||||
<action
|
||||
android:id="@+id/action_FirstFragment_to_SecondFragment"
|
||||
@@ -17,12 +17,12 @@
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/SecondFragment"
|
||||
android:name="com.navinfo.omqs.ui.fragment.SecondFragment"
|
||||
android:name="com.navinfo.omqs.ui.fragment.offlinemap.OfflineMapFragment"
|
||||
android:label="@string/second_fragment_label"
|
||||
tools:layout="@layout/fragment_second">
|
||||
tools:layout="@layout/fragment_offline_map">
|
||||
|
||||
<action
|
||||
android:id="@+id/action_SecondFragment_to_FirstFragment"
|
||||
app:destination="@id/FirstFragment" />
|
||||
app:destination="@id/PersonalCenterFragment" />
|
||||
</fragment>
|
||||
</navigation>
|
||||
@@ -2,4 +2,8 @@
|
||||
<resources>
|
||||
<color name="black">#FF000000</color>
|
||||
<color name="white">#FFFFFFFF</color>
|
||||
<color name="cv_gray_153">#999999</color>
|
||||
<color name="cvm_red">#FF3B30</color>
|
||||
<color name="cv_bg_color">#553C3F41</color>
|
||||
<color name="btn_blue_solid">#108ee9</color>
|
||||
</resources>
|
||||
@@ -5,4 +5,8 @@
|
||||
<dimen name="activity_vertical_margin">16dp</dimen>
|
||||
<dimen name="nav_header_vertical_spacing">8dp</dimen>
|
||||
<dimen name="nav_header_height">176dp</dimen>
|
||||
<dimen name="default_widget_padding">10dp</dimen>
|
||||
<dimen name="default_font_size" comment="默认字体大小,style中父最顶层">15dp</dimen>
|
||||
<dimen name="card_title_font_2size">13sp</dimen>
|
||||
<dimen name="card_title_font_3size">10sp</dimen>
|
||||
</resources>
|
||||
@@ -2,47 +2,11 @@
|
||||
<string name="app_name">OMQualityInspection</string>
|
||||
<string name="action_settings">Settings</string>
|
||||
<!-- Strings used for fragments for navigation -->
|
||||
<string name="first_fragment_label">First Fragment</string>
|
||||
<string name="personal_center">个人中心</string>
|
||||
<string name="second_fragment_label">Second Fragment</string>
|
||||
<string name="next">Next</string>
|
||||
<string name="previous">Previous</string>
|
||||
|
||||
<string name="lorem_ipsum">
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam in scelerisque sem. Mauris
|
||||
volutpat, dolor id interdum ullamcorper, risus dolor egestas lectus, sit amet mattis purus
|
||||
dui nec risus. Maecenas non sodales nisi, vel dictum dolor. Class aptent taciti sociosqu ad
|
||||
litora torquent per conubia nostra, per inceptos himenaeos. Suspendisse blandit eleifend
|
||||
diam, vel rutrum tellus vulputate quis. Aliquam eget libero aliquet, imperdiet nisl a,
|
||||
ornare ex. Sed rhoncus est ut libero porta lobortis. Fusce in dictum tellus.\n\n
|
||||
Suspendisse interdum ornare ante. Aliquam nec cursus lorem. Morbi id magna felis. Vivamus
|
||||
egestas, est a condimentum egestas, turpis nisl iaculis ipsum, in dictum tellus dolor sed
|
||||
neque. Morbi tellus erat, dapibus ut sem a, iaculis tincidunt dui. Interdum et malesuada
|
||||
fames ac ante ipsum primis in faucibus. Curabitur et eros porttitor, ultricies urna vitae,
|
||||
molestie nibh. Phasellus at commodo eros, non aliquet metus. Sed maximus nisl nec dolor
|
||||
bibendum, vel congue leo egestas.\n\n
|
||||
Sed interdum tortor nibh, in sagittis risus mollis quis. Curabitur mi odio, condimentum sit
|
||||
amet auctor at, mollis non turpis. Nullam pretium libero vestibulum, finibus orci vel,
|
||||
molestie quam. Fusce blandit tincidunt nulla, quis sollicitudin libero facilisis et. Integer
|
||||
interdum nunc ligula, et fermentum metus hendrerit id. Vestibulum lectus felis, dictum at
|
||||
lacinia sit amet, tristique id quam. Cras eu consequat dui. Suspendisse sodales nunc ligula,
|
||||
in lobortis sem porta sed. Integer id ultrices magna, in luctus elit. Sed a pellentesque
|
||||
est.\n\n
|
||||
Aenean nunc velit, lacinia sed dolor sed, ultrices viverra nulla. Etiam a venenatis nibh.
|
||||
Morbi laoreet, tortor sed facilisis varius, nibh orci rhoncus nulla, id elementum leo dui
|
||||
non lorem. Nam mollis ipsum quis auctor varius. Quisque elementum eu libero sed commodo. In
|
||||
eros nisl, imperdiet vel imperdiet et, scelerisque a mauris. Pellentesque varius ex nunc,
|
||||
quis imperdiet eros placerat ac. Duis finibus orci et est auctor tincidunt. Sed non viverra
|
||||
ipsum. Nunc quis augue egestas, cursus lorem at, molestie sem. Morbi a consectetur ipsum, a
|
||||
placerat diam. Etiam vulputate dignissim convallis. Integer faucibus mauris sit amet finibus
|
||||
convallis.\n\n
|
||||
Phasellus in aliquet mi. Pellentesque habitant morbi tristique senectus et netus et
|
||||
malesuada fames ac turpis egestas. In volutpat arcu ut felis sagittis, in finibus massa
|
||||
gravida. Pellentesque id tellus orci. Integer dictum, lorem sed efficitur ullamcorper,
|
||||
libero justo consectetur ipsum, in mollis nisl ex sed nisl. Donec maximus ullamcorper
|
||||
sodales. Praesent bibendum rhoncus tellus nec feugiat. In a ornare nulla. Donec rhoncus
|
||||
libero vel nunc consequat, quis tincidunt nisl eleifend. Cras bibendum enim a justo luctus
|
||||
vestibulum. Fusce dictum libero quis erat maximus, vitae volutpat diam dignissim.
|
||||
</string>
|
||||
<string name="input_user_name">请输入用户名</string>
|
||||
<string name="input_password">请输入密码</string>
|
||||
<string name="login">登录</string>
|
||||
|
||||
57
app/src/main/res/values/styles.xml
Normal file
57
app/src/main/res/values/styles.xml
Normal file
@@ -0,0 +1,57 @@
|
||||
<resources>
|
||||
|
||||
<style name="title_default_style" comment="默认顶标题样式">
|
||||
<item name="android:layout_width">match_parent</item>
|
||||
<item name="android:layout_height">20dp</item>
|
||||
<item name="android:clickable">true</item>
|
||||
<item name="android:focusable">true</item>
|
||||
<item name="android:layout_alignParentTop">true</item>
|
||||
<item name="android:background">@color/default_blue</item>
|
||||
<item name="android:paddingBottom">6dp</item>
|
||||
<item name="android:paddingLeft">14dp</item>
|
||||
<item name="android:paddingRight">14dp</item>
|
||||
<item name="android:paddingTop">6dp</item>
|
||||
<item name="android:gravity">center_vertical</item>
|
||||
</style>
|
||||
|
||||
<!-- 默认字体 -->
|
||||
<style name="content_font_default">
|
||||
<item name="android:gravity">center_vertical</item>
|
||||
<item name="android:textSize">15dp</item>
|
||||
<item name="android:layout_width">wrap_content</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
</style>
|
||||
|
||||
|
||||
<!-- 输入框基本样式 -->
|
||||
<style name="input_blue_type" parent="content_font_default">
|
||||
<item name="android:textSize">16sp</item>
|
||||
<item name="android:background">#FFFFFF</item>
|
||||
<item name="android:textColor">#1890ff</item>
|
||||
<item name="android:padding">10dp</item>
|
||||
<item name="android:imeOptions">actionDone</item>
|
||||
<item name="android:singleLine">true</item>
|
||||
</style>
|
||||
|
||||
|
||||
<style name="map_size_font_style" comment="离线地图gdb/nds大小字体样式">
|
||||
<item name="android:layout_width">wrap_content</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:drawablePadding">4dp</item>
|
||||
<item name="android:textColor">@color/white</item>
|
||||
<item name="android:textSize">9sp</item>
|
||||
<item name="android:focusable">false</item>
|
||||
<item name="android:clickable">false</item>
|
||||
</style>
|
||||
|
||||
<style name="map_download_style_btn" comment="离线地图下载的按钮样式">
|
||||
<item name="android:layout_width">wrap_content</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:layout_gravity">center_vertical</item>
|
||||
<item name="android:padding">@dimen/default_widget_padding</item>
|
||||
<item name="android:background">@drawable/fm_card_map_down_status_bg</item>
|
||||
<item name="android:gravity">center_horizontal</item>
|
||||
<item name="android:textColor">@color/btn_blue_white</item>
|
||||
<item name="android:textSize">15sp</item>
|
||||
</style>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user