commit 92216611488c2fb13a5100f770274468245e8aa7 Author: tabidachinokaze Date: Thu Feb 13 18:28:29 2025 +0800 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fe3b002 --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +*.iml +.gradle +/local.properties +/.idea +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties +/.kotlin \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts new file mode 100644 index 0000000..3531ccd --- /dev/null +++ b/app/build.gradle.kts @@ -0,0 +1,86 @@ +plugins { + alias(libs.plugins.android.application) + alias(libs.plugins.kotlin.android) + alias(libs.plugins.kotlin.compose) + id("kotlin-parcelize") +} + +android { + namespace = "com.zywl.test1229" + compileSdk = 34 + + defaultConfig { + applicationId = "com.zywl.test1229" + minSdk = 29 + targetSdk = 34 + versionCode = 1 + versionName = "1.0" + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + kotlinOptions { + jvmTarget = "11" + } + buildFeatures { + compose = true + } + packagingOptions { + exclude("META-INF/DEPENDENCIES") + exclude("META-INF/LICENSE") + exclude("META-INF/LICENSE.txt") + exclude("META-INF/NOTICE") + } +} + +dependencies { + + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.lifecycle.runtime.ktx) + implementation(libs.androidx.activity.compose) + implementation(platform(libs.androidx.compose.bom)) + implementation(libs.androidx.ui) + implementation(libs.androidx.ui.graphics) + implementation(libs.androidx.ui.tooling.preview) + implementation(libs.androidx.material3) + implementation(libs.androidx.navigation.runtime.ktx) + implementation(libs.androidx.navigation.compose) + testImplementation(libs.junit) + androidTestImplementation(libs.androidx.junit) + androidTestImplementation(libs.androidx.espresso.core) + androidTestImplementation(platform(libs.androidx.compose.bom)) + androidTestImplementation(libs.androidx.ui.test.junit4) + debugImplementation(libs.androidx.ui.tooling) + debugImplementation(libs.androidx.ui.test.manifest) + // https://mvnrepository.com/artifact/com.google.code.gson/gson + implementation("com.google.code.gson:gson:2.10.1") + implementation("org.jetbrains.kotlin:kotlin-reflect:1.5.21") + +// implementation(files("libs/poi-5.3.0.jar")) + implementation("org.apache.poi:poi-ooxml:5.2.3"){ + exclude(group = "org.apache.logging.log4j", module = "log4j-api") + } // 主要的poi库 + implementation("org.apache.poi:poi:5.2.3") { + exclude(group = "org.apache.logging.log4j", module = "log4j-api") + } // 用于处理Excel文件(.xlsx) + implementation("org.apache.xmlbeans:xmlbeans:5.0.2") // Apache Commons IO +// implementation ("org.apache.logging.log4j:log4j-api:2.14.1") // Log4j API +// implementation ("org.apache.logging.log4j:log4j-core:2.14.1") // Log4j Core + +// implementation("org.apache.logging.log4j:log4j-core:2.17.1") // 或其他最新版本 + implementation("org.apache.logging.log4j:log4j-api:2.17.1") // 或其他最新版本 + +} \ No newline at end of file diff --git a/app/libs/poi-5.3.0.jar b/app/libs/poi-5.3.0.jar new file mode 100644 index 0000000..8c5d318 Binary files /dev/null and b/app/libs/poi-5.3.0.jar differ diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/app/src/androidTest/java/com/zywl/test1229/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/zywl/test1229/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..9e5eb39 --- /dev/null +++ b/app/src/androidTest/java/com/zywl/test1229/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package com.zywl.test1229 + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("com.zywl.test1229", appContext.packageName) + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..07ea30b --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/pile_data.json b/app/src/main/assets/pile_data.json new file mode 100644 index 0000000..e57082e --- /dev/null +++ b/app/src/main/assets/pile_data.json @@ -0,0 +1,42 @@ +{ + "primeExlP": { + "pipeLine":"管线", + "tempNo":"测绘临时编号", + "stakeType": "桩类型", + "latitude": "X", + "longitude": "Y", + "depth": "Z(85高程,桩根部)", + "pipeDepth": "管中埋深(米)", + "mileage": "里程", + "buryTech": "埋设工艺", + "isInPoint": "是否出入土点", + "terrain": "地形", + "picture": "照片名", + "collectDate": "采集日期" + }, + "primeExlL": { + + }, + "primeExlPFixedSizeWidth": { + "pipeLine":8.38, + "tempNo":10.75, + "stakeType": 8.38, + "latitude":9.38, + "longitude": 9.38, + "depth": 14.5, + "pipeDepth": 13, + "mileage": 8.38, + "buryTech": 13.75, + "isInPoint": 10, + "terrain": 14, + "picture": 10, + "collectDate": 9 + }, + "primeExlLFixedSizeWidth": { + + }, + "primeExlFixedHeight": { + "title": 25, + "context": 15 + } +} \ No newline at end of file diff --git a/app/src/main/assets/poishadow-all.jar b/app/src/main/assets/poishadow-all.jar new file mode 100644 index 0000000..d29c713 Binary files /dev/null and b/app/src/main/assets/poishadow-all.jar differ diff --git a/app/src/main/assets/test.xls b/app/src/main/assets/test.xls new file mode 100644 index 0000000..0ba27a9 Binary files /dev/null and b/app/src/main/assets/test.xls differ diff --git a/app/src/main/java/com/zywl/test1229/MainActivity.kt b/app/src/main/java/com/zywl/test1229/MainActivity.kt new file mode 100644 index 0000000..b4b4ca8 --- /dev/null +++ b/app/src/main/java/com/zywl/test1229/MainActivity.kt @@ -0,0 +1,211 @@ +package com.zywl.test1229 + +import android.annotation.SuppressLint +import android.content.Intent +import android.content.pm.ActivityInfo +import android.os.Build +import android.os.Bundle +import android.os.Environment +import android.provider.Settings +import android.util.Log +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.activity.enableEdgeToEdge +import androidx.annotation.RequiresApi +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.unit.dp +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleEventObserver +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.compose.LocalLifecycleOwner +import androidx.lifecycle.viewmodel.compose.viewModel +import androidx.navigation.NavController +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.composable +import androidx.navigation.compose.rememberNavController +import com.google.gson.Gson +import com.zywl.test1229.bean.Constant +import com.zywl.test1229.bean.PointInfo +import com.zywl.test1229.bean.StakeInfo +import com.zywl.test1229.data.SimpleViewModel +import com.zywl.test1229.ktx.toast +import com.zywl.test1229.ui.theme.Test1229Theme +import com.zywl.test1229.utils.ExcelUtils +import com.zywl.test1229.utils.Tools +import com.zywl.test1229.view.FilesScreen +import com.zywl.test1229.view.FloatingButtonS + +import com.zywl.test1229.view.PermissionDialog +import com.zywl.test1229.view.StakeInfoViewPager +import com.zywl.test1229.view.TopBar +import com.zywl.test1229.view.mainPager + +class MainActivity : ComponentActivity() { + var lastBackPressedTime: Long = 0 + val backPressInterval: Long = 2000 + @RequiresApi(Build.VERSION_CODES.R) + @SuppressLint("SourceLockedOrientationActivity") + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + enableEdgeToEdge() + requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT + setContent { + MyApp() + } + } + val outerItems:MutableList = mutableListOf( + StakeInfo("awdawd","awdawd","awdawda",1231.0,1231.0,0.0,"awdawd","awdawd","awdawd","否","awdawd","awdawda","awda"), + StakeInfo("awdawd","awdawd","awdawda",1231.0,1231.0,0.0,"awdawd","awdawd","awdawd","否","awdawd","awdawda","awda"), + StakeInfo("awdawd","awdawd","awdawda",1231.0,1231.0,0.0,"awdawd","awdawd","awdawd","否","awdawd","awdawda","awda"), + StakeInfo("awdawd","awdawd","awdawda",1231.0,1231.0,0.0,"awdawd","awdawd","awdawd","否","awdawd","awdawda","awda"), + StakeInfo("awdawd","awdawd","awdawda",1231.0,1231.0,0.0,"awdawd","awdawd","awdawd","否","awdawd","awdawda","awda"),) + var isFirst=true + @RequiresApi(Build.VERSION_CODES.R) + @Composable + fun MyApp(){ + val navController = rememberNavController() +// val viewModel:SimpleViewModel> by lazy { SimpleViewModel() } + val viewModel:SimpleViewModel> = viewModel() +// viewModel.setData(outerItems) +// viewModel.setData(mutableListOf()) + NavHost(navController = navController, startDestination = "home") { + composable("home") { + HomePager(navController,viewModel) + } + composable("info") { + StakeInfoViewPager().MainView(navController,viewModel) + } + composable("info/{data}") { backStackEntry -> + val json = backStackEntry.arguments?.getString("data") + val stakeInfo=Gson().fromJson(json,StakeInfo::class.java) + StakeInfoViewPager().MainView(navController,viewModel=viewModel,stakeInfo) + } + composable("files") { + FilesScreen(navController,viewModel) + } + } + } + @RequiresApi(Build.VERSION_CODES.R) + @Composable + fun HomePager(navController: NavController,viewModel: SimpleViewModel>){ + Test1229Theme() { + var isLoading by remember { mutableStateOf(true) } + val context = LocalContext.current + val lifecycleOwner = LocalLifecycleOwner.current + val (isPermissionGranted, onPermissionChange) = remember { mutableStateOf(Environment.isExternalStorageManager()) } + val permissionDialog = remember { mutableStateOf(false) } + DisposableEffect(Unit) { + val observer = object : LifecycleEventObserver { + @RequiresApi(Build.VERSION_CODES.R) + override fun onStateChanged( + source: LifecycleOwner, + event: Lifecycle.Event + ) { + Log.d("MainActivity", "onStateChanged: $event") + when (event) { + Lifecycle.Event.ON_RESUME -> { + onPermissionChange(Environment.isExternalStorageManager()) + } + + else -> Unit + } + } + } + lifecycleOwner.lifecycle.addObserver(observer) + onDispose { + lifecycleOwner.lifecycle.removeObserver(observer) + } + } + LaunchedEffect(isPermissionGranted) { + if (isPermissionGranted&&!isFirst) { + context.toast("权限已授权") + } + } + if(isPermissionGranted){ + permissionDialog.value=false + LaunchedEffect(Unit) { + val dataTmp=viewModel.stateFlow.value.data + if (dataTmp==null){ + Log.d("MainActivity","LaunchedEffect $isLoading $dataTmp") + val directory=Constant.SDCARD+"/"+Constant.projectName+"/backup" + val data = ExcelUtils().parseExcel("$directory/main.xls") + viewModel.setData(data) + } + isLoading = false + } + if (isLoading){ + Column( + modifier = Modifier.fillMaxSize(), + horizontalAlignment = Alignment.CenterHorizontally, // 水平居中 + verticalArrangement = Arrangement.Center // 垂直居中 + ){ + CircularProgressIndicator( + modifier = Modifier.width(64.dp), + color = MaterialTheme.colorScheme.secondary, + trackColor = MaterialTheme.colorScheme.surfaceVariant, + ) + Spacer(Modifier.fillMaxWidth().height(26.dp)) + Text( + text = "数据加载中....", + ) + } + }else{ + Scaffold( + modifier = Modifier.fillMaxSize(), + topBar = { + if (context is MainActivity) { + // 当前是 MainActivity,可以访问 MainActivity 的成员 + val activity: MainActivity = context + // 做你需要的操作 + TopBar(activity) + } + + }, + floatingActionButton = { + FloatingButtonS(navController,viewModel) + } + ) { innerPadding -> + mainPager(navController,viewModel,Modifier.padding(innerPadding)) + } + } + + + }else{ + permissionDialog.value=true + } + PermissionDialog( + visible = permissionDialog.value, + onConfirm = { + val intent = Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION) + isFirst=false + context.startActivity(intent) + }, + onDismissRequest = { + context.toast("权限取消授权") + finish() + } + ) + } + } +} diff --git a/app/src/main/java/com/zywl/test1229/bean/Constant.kt b/app/src/main/java/com/zywl/test1229/bean/Constant.kt new file mode 100644 index 0000000..ca01892 --- /dev/null +++ b/app/src/main/java/com/zywl/test1229/bean/Constant.kt @@ -0,0 +1,14 @@ +package com.zywl.test1229.bean + +import android.os.Environment + +class Constant { + companion object{ + val stakeTypeArray = listOf("里程桩","测试桩","转角桩","警示桩") + val depthArray = listOf("超长无法探测") + val BuriedTechnologyArray = listOf("定向钻穿河","定向钻穿河路","直管平铺","平铺弯头") + val terrainArray = listOf("铺装路面","绿化带","山坡","荒地") + var SDCARD: String = Environment.getExternalStorageDirectory().absolutePath + var projectName="Test1229" + } +} \ No newline at end of file diff --git a/app/src/main/java/com/zywl/test1229/bean/LineInfo.kt b/app/src/main/java/com/zywl/test1229/bean/LineInfo.kt new file mode 100644 index 0000000..73f63bb --- /dev/null +++ b/app/src/main/java/com/zywl/test1229/bean/LineInfo.kt @@ -0,0 +1,54 @@ +package com.zywl.test1229.bean + +data class LineInfo( + var IsDrawNoteText:String="", + var NoteX:String="", + var NoteY:String="", + var PsCheQiBenLe:String="", + var PsCheQiBenX:String="0.0", + var PsCheQiBenY:String="0.0", + var PsCheQiEndLe:String="", + var PsCheQiEndX:String="0.0", + var PsCheQiEndY:String="0.0", + var belong:String="", + var benDeep:String="0.00", + var benExpNum:String="", + var burialDifference:String="", + var buried:String="", + var cabNum:String="", + var d_S:String="", + var endDeep:String="", + var endExpNum:String="", + var endLatitude:String="", + var endLongitude:String="", + var exp_Date:String="", + var flowDirection:String="", + var holeDiameter:String="", + var id:String="", + var labelTag:String="", + var material:String="", + var measureDate:String="", + var measureEnd:String="", + var measureStart:String="", + var pipeLength:String="", + var pipeSize:String="", + var pressure:String="", + var puzzle:String="", + var remark:String="", + var rowXCol:String="", + var startLatitude:String="", + var startLongitude:String="", + var state:String="", + var totalHole:String="", + var usedHole:String="", + var voltage:String="", + var Edit:String="", + var code:String="", + var datasetName:String="", + var pipeType:String="", + var rangeExpression:String="", + var shortCode:String="", + var submitName:String="", + var sysId:String="", + var type:String="", +) diff --git a/app/src/main/java/com/zywl/test1229/bean/PointInfo.kt b/app/src/main/java/com/zywl/test1229/bean/PointInfo.kt new file mode 100644 index 0000000..3afe71b --- /dev/null +++ b/app/src/main/java/com/zywl/test1229/bean/PointInfo.kt @@ -0,0 +1,83 @@ +package com.zywl.test1229.bean + +data class PointInfo( + var DotleadAng:String="0.0", + var ExpCheQiX:String="0.0", + var ExpCheQiY:String="0.0", + var ExpX:String="0.0", + var ExpY:String="0.0", + var Explain1:String="", + var ExplainX:String="0.0", + var ExplainY:String="0.0", + var ExplaninAng:String="0.0", + var MapX:String="0.0", + var MeasuerPoint:String="0", + var PpdAng:String="0.0", + var PpdX:String="0.0", + var PpdY:String="0.0", + var PsCheQiLeftR:String="", + var PsCheQiX:String="0.0", + var PsCheQiY:String="0.0", + var buildingStructures:String="", + var buryTech:String="", + var collectDate:String="", + var depth:String="0.0", + var endDirDepth:String="", + var expGroup:String="", + var exp_Date:String="", + var exp_Num:String="", + var feature:String="", + var fireHydrantDs:String="", + var id:String="", + var isInPoint:String="", + var isWithLadder:String="", + var latitude:String="0.0", + var locationType:String="", + var longitude:String="0.0", + var mileage:String="", + var picture:String="", + var pipeDepth:String="", + var pipeLine:String="", + var pipeOffset:String="", + var puzzle:String="", + var remark:String="", + var road:String="", + var serialNum:String="0", + var situation:String="", + var stakeType:String="", + var startDirDepth:String="", + var state:String="", + var subsid:String="", + var surf_H:String="0.000", + var symbol:String="", + var symbolExpression:String="", + var symbolID:String="", + var symbolSizeX:String="", + var symbolSizeY:String="", + var tempNo:String="", + var terrain:String="", + var valveWellDs:String="", + var valveWellEmbedding:String="", + var valveWellInstallType:String="", + var valveWellOpenState:String="", + var valveWellTexture:String="", + var valveWellType:String="", + var wellCoverMaterial:String="", + var wellCoverSize:String="", + var wellDeep:String="", + var wellMud:String="", + var wellShape:String="", + var wellSize:String="", + var wellStatus:String="", + var wellType:String="", + var wellWater:String="", + var Edit:String="", + var code:String="", + var datasetName:String="", + var pipeType:String="", + var rangeExpression:String="", + var shortCode:String="", + var submitName:String="", + var sysId:String="", + var type:String="", + ) diff --git a/app/src/main/java/com/zywl/test1229/bean/StakeInfo.kt b/app/src/main/java/com/zywl/test1229/bean/StakeInfo.kt new file mode 100644 index 0000000..4cd9c43 --- /dev/null +++ b/app/src/main/java/com/zywl/test1229/bean/StakeInfo.kt @@ -0,0 +1,21 @@ +package com.zywl.test1229.bean + +import android.os.Parcelable +import kotlinx.android.parcel.Parcelize + +@Parcelize +data class StakeInfo( + var tempNo:String, + var pipeLine:String, + var stakeType:String, + var latitude:Double, + var longitude:Double, + var z:Double, + var pipeDepth:String, + var mileage:String, + var buryTech:String, + var isInPoint:String, + var terrain:String, + var imageName:String, + var collectDate:String, +):Parcelable diff --git a/app/src/main/java/com/zywl/test1229/bean/User.kt b/app/src/main/java/com/zywl/test1229/bean/User.kt new file mode 100644 index 0000000..ab4d613 --- /dev/null +++ b/app/src/main/java/com/zywl/test1229/bean/User.kt @@ -0,0 +1,10 @@ +package com.zywl.test1229.bean + +import android.os.Parcelable +import kotlinx.android.parcel.Parcelize + +@Parcelize +data class User( + val name:String, + val age:Int +):Parcelable diff --git a/app/src/main/java/com/zywl/test1229/data/SimpleViewModel.kt b/app/src/main/java/com/zywl/test1229/data/SimpleViewModel.kt new file mode 100644 index 0000000..327492c --- /dev/null +++ b/app/src/main/java/com/zywl/test1229/data/SimpleViewModel.kt @@ -0,0 +1,18 @@ +package com.zywl.test1229.data + +import androidx.lifecycle.ViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow + +class SimpleViewModel :ViewModel() { + private val _stateFlow = MutableStateFlow(Result()) + val stateFlow = _stateFlow.asStateFlow() + + fun setData(data:T){ + _stateFlow.value=Result(data = data) + } + + data class Result( + val data:T?=null + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/zywl/test1229/ktx/Context.kt b/app/src/main/java/com/zywl/test1229/ktx/Context.kt new file mode 100644 index 0000000..5c44547 --- /dev/null +++ b/app/src/main/java/com/zywl/test1229/ktx/Context.kt @@ -0,0 +1,8 @@ +package com.zywl.test1229.ktx + +import android.content.Context +import android.widget.Toast + +fun Context.toast(text: String, duration: Int = Toast.LENGTH_SHORT) { + Toast.makeText(this, text, duration).show() +} \ No newline at end of file diff --git a/app/src/main/java/com/zywl/test1229/ui/theme/Color.kt b/app/src/main/java/com/zywl/test1229/ui/theme/Color.kt new file mode 100644 index 0000000..d631c3e --- /dev/null +++ b/app/src/main/java/com/zywl/test1229/ui/theme/Color.kt @@ -0,0 +1,11 @@ +package com.zywl.test1229.ui.theme + +import androidx.compose.ui.graphics.Color + +val Purple80 = Color(0xFFD0BCFF) +val PurpleGrey80 = Color(0xFFCCC2DC) +val Pink80 = Color(0xFFEFB8C8) + +val Purple40 = Color(0xFF6650a4) +val PurpleGrey40 = Color(0xFF625b71) +val Pink40 = Color(0xFF7D5260) \ No newline at end of file diff --git a/app/src/main/java/com/zywl/test1229/ui/theme/Theme.kt b/app/src/main/java/com/zywl/test1229/ui/theme/Theme.kt new file mode 100644 index 0000000..01fc5fc --- /dev/null +++ b/app/src/main/java/com/zywl/test1229/ui/theme/Theme.kt @@ -0,0 +1,58 @@ +package com.zywl.test1229.ui.theme + +import android.app.Activity +import android.os.Build +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.dynamicDarkColorScheme +import androidx.compose.material3.dynamicLightColorScheme +import androidx.compose.material3.lightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.platform.LocalContext + +private val DarkColorScheme = darkColorScheme( + primary = Purple80, + secondary = PurpleGrey80, + tertiary = Pink80 +) + +private val LightColorScheme = lightColorScheme( + primary = Purple40, + secondary = PurpleGrey40, + tertiary = Pink40 + + /* Other default colors to override + background = Color(0xFFFFFBFE), + surface = Color(0xFFFFFBFE), + onPrimary = Color.White, + onSecondary = Color.White, + onTertiary = Color.White, + onBackground = Color(0xFF1C1B1F), + onSurface = Color(0xFF1C1B1F), + */ +) + +@Composable +fun Test1229Theme( + darkTheme: Boolean = isSystemInDarkTheme(), + // Dynamic color is available on Android 12+ + dynamicColor: Boolean = true, + content: @Composable () -> Unit +) { + val colorScheme = when { + dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { + val context = LocalContext.current + if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) + } + + darkTheme -> DarkColorScheme + else -> LightColorScheme + } + + MaterialTheme( + colorScheme = colorScheme, + typography = Typography, + content = content + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/zywl/test1229/ui/theme/Type.kt b/app/src/main/java/com/zywl/test1229/ui/theme/Type.kt new file mode 100644 index 0000000..2d94231 --- /dev/null +++ b/app/src/main/java/com/zywl/test1229/ui/theme/Type.kt @@ -0,0 +1,34 @@ +package com.zywl.test1229.ui.theme + +import androidx.compose.material3.Typography +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.sp + +// Set of Material typography styles to start with +val Typography = Typography( + bodyLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 16.sp, + lineHeight = 24.sp, + letterSpacing = 0.5.sp + ) + /* Other default text styles to override + titleLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 22.sp, + lineHeight = 28.sp, + letterSpacing = 0.sp + ), + labelSmall = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Medium, + fontSize = 11.sp, + lineHeight = 16.sp, + letterSpacing = 0.5.sp + ) + */ +) \ No newline at end of file diff --git a/app/src/main/java/com/zywl/test1229/utils/ExcelUtils.kt b/app/src/main/java/com/zywl/test1229/utils/ExcelUtils.kt new file mode 100644 index 0000000..39b0dde --- /dev/null +++ b/app/src/main/java/com/zywl/test1229/utils/ExcelUtils.kt @@ -0,0 +1,188 @@ +package com.zywl.test1229.utils + +import android.content.Context +import android.util.Log +import com.zywl.test1229.bean.Constant +import com.zywl.test1229.bean.LineInfo +import com.zywl.test1229.bean.PointInfo +import com.zywl.test1229.bean.StakeInfo +import org.apache.poi.hssf.usermodel.HSSFWorkbook +import org.apache.poi.ss.usermodel.Cell +import org.apache.poi.ss.usermodel.CellType +import java.io.File +import java.io.FileInputStream +import java.time.LocalDate + + +class ExcelUtils { + fun parseExcel(path:String):MutableList{ + val list:MutableList = mutableListOf() + var file=File(path) + if (!file.exists()) + return list + var fileByte=FileInputStream(file) + val workbook=HSSFWorkbook(fileByte) + val sheet=workbook.getSheetAt(0); + for (rowIndex in 1 until sheet.physicalNumberOfRows) { + val row = sheet.getRow(rowIndex) + var index3=0.0 + var index4=0.0 + var index5=0.0 + try { + index3=getCellData(row.getCell(9)).toDouble(); + } catch (e: NumberFormatException) { + index3=0.0 + } + try { + index4=getCellData(row.getCell(10)).toDouble(); + } catch (e: NumberFormatException) { + index4=0.0 + } + try { + index5=getCellData(row.getCell(10)).toDouble(); + } catch (e: NumberFormatException) { + index5=0.0 + } + // 跳过空行 + if (row == null) continue + var stakeInfo=StakeInfo( + getCellData(row.getCell(1)), + getCellData(row.getCell(0)), + getCellData(row.getCell(2)), + index3, + index4, + index5, + getCellData(row.getCell(6)), + getCellData(row.getCell(7)), + getCellData(row.getCell(8)), + getCellData(row.getCell(9)), + getCellData(row.getCell(10)), + getCellData(row.getCell(11)), + getCellData(row.getCell(12)), + ) + list.add(stakeInfo) + } + return list; + } + fun getCellData(cell:Cell):String{ + val cellValue = when (cell.cellType) { + CellType.STRING -> cell.stringCellValue + CellType.NUMERIC -> cell.numericCellValue.toString() + CellType.BOOLEAN -> cell.booleanCellValue.toString() + else -> "Unknown" + } + return cellValue + } + fun produceExcel(context: Context?,array:List,isbackUp: Boolean=false){ + val primeExlPFixedSizeWidth = JsonUils.parseJSONListDouble( + JsonUils.loadJSONFromAssets("pile_data.json", context), + "primeExlPFixedSizeWidth" + ) + val primeExlFixedHeight = JsonUils.parseJSONListDouble( + JsonUils.loadJSONFromAssets("pile_data.json", context), + "primeExlFixedHeight" + ) + // softexportPrimeDataP(m_excelFiledNameP,m_pointListGroup); + + var listMain= mutableListOf>() + for (index in array){ + var list = mutableListOf() + list.add(index.pipeLine) + list.add(index.tempNo) + list.add(index.stakeType) + list.add("${index.latitude}") + list.add("${index.longitude}") + list.add("${index.z}") + list.add(index.pipeDepth) + list.add(index.mileage) + list.add(index.buryTech) + list.add(index.isInPoint) + list.add(index.terrain) + list.add(index.imageName) + list.add(index.collectDate) + listMain.add(list) + } + //获得json文件数据 + val parseJSONprimeExlP: List = + JsonUils.parseJSONList( + JsonUils.loadJSONFromAssets("pile_data.json", context), + "primeExlP" + ) + var directory="" + var date=LocalDate.now() + if (!isbackUp){ + var pointTitleInfo=Tools.getDataClassFieldNames(PointInfo()) + var lineTitleInfo=Tools.getDataClassFieldNames(LineInfo()) + var pointInfos = Tools.getDataClassFieldNamesAndValueForMap(collectPoints(array)) + var points=Tools.getDataClassFieldNamesAndValuesForList(pointTitleInfo,pointInfos) + directory=Constant.SDCARD+"/"+Constant.projectName+"/tables" + FileUtils.mkDir(directory) + var fileNum = FileUtils.getFileCountInDirectory(directory, ".xls")/2+1 + ExcelUtilsOfPoi.initExcelPrime( + "$directory/桩表_${date}_${fileNum}.xls", + parseJSONprimeExlP, "桩表", primeExlPFixedSizeWidth, primeExlFixedHeight + ) + ExcelUtilsOfPoi.initExcel("$directory/桩表PC_${date}_${fileNum}.xls",pointTitleInfo,lineTitleInfo,"P_ALL", "L_All") + + ExcelUtilsOfPoi.writeObjListToExcelPrime( + listMain, "$directory/桩表_${date}_${fileNum}.xls", + primeExlFixedHeight, primeExlPFixedSizeWidth + ) + ExcelUtilsOfPoi.writeObjListToExcel(0,points,"$directory/桩表PC_${date}_${fileNum}.xls") + }else{ + directory=Constant.SDCARD+"/"+Constant.projectName+"/backup" + FileUtils.mkDir(directory) + ExcelUtilsOfPoi.initExcelPrime( + "$directory/main.xls", + parseJSONprimeExlP, "桩表", primeExlPFixedSizeWidth, primeExlFixedHeight + ) + ExcelUtilsOfPoi.writeObjListToExcelPrime( + listMain, "$directory/main.xls", + primeExlFixedHeight, primeExlPFixedSizeWidth + ) + } + Log.d("MainActivity","produceExcel") + } + fun collectPoints(data:List):List{ + var list:MutableList = mutableListOf() + var point = PointInfo() + var index=1; + data.forEach { item-> + point.buryTech=item.buryTech + point.collectDate=item.collectDate + point.exp_Date=item.collectDate + point.exp_Num="RQa$index" + point.id="RQa$index" + point.isInPoint=item.isInPoint + point.latitude=item.latitude.toString() + point.longitude=item.longitude.toString() + point.mileage=item.mileage + point.pipeDepth=item.pipeDepth + point.pipeLine=item.pipeLine + point.serialNum=index.toString() + point.situation="T-正常" + point.stakeType=item.stakeType + point.state="新测" + point.subsid=item.stakeType + point.symbol="探测点" + point.symbolExpression="RQ-探测点" + point.symbolID="472" + point.symbolSizeX="4.0" + point.symbolSizeY="4.0" + point.tempNo=item.tempNo + point.terrain=item.terrain + point.code="RQ" + point.pipeLine="燃气-RQ" + point.rangeExpression="3.5" + point.shortCode="RQ" + point.sysId=index.toString() + point.type="Type_None" + list.add(point) + } + return list + } + fun collectLines(data:List):List{ + var list:MutableList = mutableListOf() + return list + } +} \ No newline at end of file diff --git a/app/src/main/java/com/zywl/test1229/utils/ExcelUtilsOfPoi.java b/app/src/main/java/com/zywl/test1229/utils/ExcelUtilsOfPoi.java new file mode 100644 index 0000000..e58a3d1 --- /dev/null +++ b/app/src/main/java/com/zywl/test1229/utils/ExcelUtilsOfPoi.java @@ -0,0 +1,437 @@ +package com.zywl.test1229.utils; + +import android.util.SparseArray; + +import org.apache.poi.hssf.usermodel.HSSFCellStyle; +import org.apache.poi.hssf.usermodel.HSSFFont; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.usermodel.BorderStyle; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.FillPatternType; +import org.apache.poi.ss.usermodel.Font; +import org.apache.poi.ss.usermodel.Footer; +import org.apache.poi.ss.usermodel.Header; +import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.ss.usermodel.IndexedColors; +import org.apache.poi.ss.usermodel.PrintSetup; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.VerticalAlignment; +import org.apache.poi.ss.usermodel.Workbook; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class ExcelUtilsOfPoi { + private static Workbook createWorkbook() { + //xls + return new HSSFWorkbook(); + } + + private static Font creatFont(Workbook workbook) { + Font font = workbook.createFont(); + font.setColor(Font.COLOR_NORMAL); + return font; + } + + private static SparseArray createBorderedStyle(Workbook workbook) { + SparseArray array = new SparseArray<>(); + //第一 二 三行标题 + CellStyle cellStyle0 = workbook.createCellStyle(); + Font font0 = creatFont(workbook); + font0.setFontHeightInPoints((short) 14); + font0.setFontName("黑体"); + cellStyle0.setFont(font0); + cellStyle0.setAlignment(HorizontalAlignment.CENTER); + cellStyle0.setVerticalAlignment(VerticalAlignment.CENTER); + array.put(0, cellStyle0); + + //第 五 六 七 八 十行 + CellStyle cellStyle1 = workbook.createCellStyle(); + Font font1 = creatFont(workbook); + font1.setFontName("宋体"); + font1.setFontHeightInPoints((short) 10); + cellStyle1.setFont(font1); + cellStyle1.setAlignment(HorizontalAlignment.LEFT); + cellStyle1.setVerticalAlignment(VerticalAlignment.CENTER); + cellStyle1.setWrapText(true); + setCellStyle(cellStyle1); + array.put(1, cellStyle1); + + //第九行 + CellStyle cellStyle2 = workbook.createCellStyle(); + Font font2 = creatFont(workbook); + font2.setFontName("宋体"); + font2.setFontHeightInPoints((short) 10); + cellStyle2.setFont(font2); + cellStyle2.setAlignment(HorizontalAlignment.CENTER); + cellStyle2.setVerticalAlignment(VerticalAlignment.CENTER); + cellStyle2.setWrapText(true); + setCellStyle(cellStyle2); + array.put(2, cellStyle2); + + //第十一行 + CellStyle cellStyle3 = workbook.createCellStyle(); + //对齐 + cellStyle3.setAlignment(HorizontalAlignment.CENTER); + cellStyle3.setVerticalAlignment(VerticalAlignment.CENTER); +// cellStyle3.setAlignment(HorizontalAlignment.CENTER); +// cellStyle3.setVerticalAlignment(VerticalAlignment.CENTER); + Font font3 = workbook.createFont(); + font3.setFontName("宋体"); + font3.setColor(Font.COLOR_NORMAL); + cellStyle3.setFont(font3); + cellStyle3.setWrapText(true); + setCellStyle(cellStyle3); + array.put(3, cellStyle3); + + //第 五 行 + CellStyle cellStyle4 = workbook.createCellStyle(); + Font font4 = creatFont(workbook); + font4.setFontHeightInPoints((short) 10); + font4.setFontName("宋体"); + cellStyle4.setFont(font1); + cellStyle4.setAlignment(HorizontalAlignment.LEFT); + cellStyle4.setVerticalAlignment(VerticalAlignment.CENTER); + cellStyle4.setWrapText(true); + array.put(4, cellStyle4); + + //第 五 行 + CellStyle cellStyle5 = workbook.createCellStyle(); + cellStyle5.setBottomBorderColor((short) 13); + cellStyle5.setWrapText(true); + cellStyle5.setAlignment(HorizontalAlignment.LEFT); + cellStyle5.setVerticalAlignment(VerticalAlignment.CENTER); + cellStyle5.setFillPattern(FillPatternType.SOLID_FOREGROUND); +// cellStyle5.setFillPattern(FillPatternType.SOLID_FOREGROUND); + array.put(5, cellStyle5); + + Font font5 = workbook.createFont(); + font5.setFontName("黑体"); // 设置字体为黑体 + font5.setFontHeightInPoints((short) 9); // 设置字体大小为9 + CellStyle cellStyle6 = workbook.createCellStyle(); + cellStyle6.setFont(font5); // 将字体设置到样式中 + cellStyle6.setAlignment(HorizontalAlignment.CENTER); + cellStyle6.setVerticalAlignment(VerticalAlignment.CENTER); + // 设置边框 + cellStyle6.setBorderTop(BorderStyle.THIN); // 上边框 + cellStyle6.setBorderBottom(BorderStyle.THIN); // 下边框 + cellStyle6.setBorderLeft(BorderStyle.THIN); // 左边框 + cellStyle6.setBorderRight(BorderStyle.THIN); // 右边框 + + // 设置边框颜色 + cellStyle6.setTopBorderColor(IndexedColors.BLACK.getIndex()); + cellStyle6.setBottomBorderColor(IndexedColors.BLACK.getIndex()); + cellStyle6.setLeftBorderColor(IndexedColors.BLACK.getIndex()); + cellStyle6.setRightBorderColor(IndexedColors.BLACK.getIndex()); + + array.put(6,cellStyle6); + Font font6 = workbook.createFont(); + font6.setFontName("宋体"); // 设置字体为黑体 + font6.setFontHeightInPoints((short) 9); // 设置字体大小为9 + CellStyle cellStyle7 = workbook.createCellStyle(); + cellStyle7.setFont(font6); // 将字体设置到样式中 + cellStyle7.setAlignment(HorizontalAlignment.CENTER); + cellStyle7.setVerticalAlignment(VerticalAlignment.CENTER); + cellStyle7.setBorderTop(BorderStyle.THIN); // 上边框 + cellStyle7.setBorderBottom(BorderStyle.THIN); // 下边框 + cellStyle7.setBorderLeft(BorderStyle.THIN); // 左边框 + cellStyle7.setBorderRight(BorderStyle.THIN); // 右边框 + + // 设置边框颜色 + cellStyle7.setTopBorderColor(IndexedColors.BLACK.getIndex()); + cellStyle7.setBottomBorderColor(IndexedColors.BLACK.getIndex()); + cellStyle7.setLeftBorderColor(IndexedColors.BLACK.getIndex()); + cellStyle7.setRightBorderColor(IndexedColors.BLACK.getIndex()); + array.put(7,cellStyle7); + + return array; + } + + /** + * 设置单元格格式 + * + * @Params : + * @author :HaiRun + * @date :2019/7/2 17:34 + */ + private static void setCellStyle(CellStyle cellStyle3) { + //重新设置单元格的四边颜色 +// BorderStyle thin = BorderStyle.THIN; + short blackColor_Index = IndexedColors.BLACK.getIndex(); + cellStyle3.setBottomBorderColor(blackColor_Index); + cellStyle3.setBorderBottom(BorderStyle.THIN); + cellStyle3.setTopBorderColor(blackColor_Index); + cellStyle3.setBorderTop(BorderStyle.THIN); + cellStyle3.setRightBorderColor(blackColor_Index); + cellStyle3.setBorderRight(BorderStyle.THIN); + cellStyle3.setRightBorderColor(blackColor_Index); + cellStyle3.setBorderLeft(BorderStyle.THIN); + } + public static void writeObjListToExcelPrime(List list, String fileName,List height,List width) { + FileInputStream is = null; + FileOutputStream os = null; + Workbook wb = null; + String extString = fileName.substring(fileName.lastIndexOf(".")); + try { + is = new FileInputStream(new File(fileName)); + if (".xls".equals(extString)) { + wb = new HSSFWorkbook(is); + } else if (".xlsx".equals(extString)) { + + } else { + wb = null; + } + if (wb != null) { + SparseArray borderedStyle = createBorderedStyle(wb); + Sheet sheet = wb.getSheetAt(0); + int numTotal=0; + int size = list.size(); + for (int i=0;i)list.get(i)).size(); + setHeaderFooter(sheet,numTotal); + ArrayList list1 = null; + + for (int i = 0; i < size; i++) { + list1 = (ArrayList) list.get(i); + int size2 = list1.size(); + //当前行宽行数默认是2 + int rowMaxHNum=2; + Row row = sheet.createRow(i + 1); + int[] maxColumnWidths = new int[size2]; + + for (int j = 0; j < size2; j++) { + int rowHeight=list1.get(j).getBytes().length; + int columnWidthSheet=(sheet.getColumnWidth(j)-512); + //限制为12个字节为值列宽的最大数,不然太宽了 + int cellWidth = Math.min(rowHeight,12) * 256; + //如果当前计算过的列宽大过之前的列宽,覆盖掉之前的列宽 + maxColumnWidths[j]=Math.max(cellWidth,columnWidthSheet); + rowMaxHNum=Math.max(rowMaxHNum,rowHeight%12); + + Cell cell = row.createCell(j); + cell.setCellStyle(borderedStyle.get(7)); + cell.setCellValue(list1.get(j)); + } + if (width.isEmpty()){ + for (int colIndex=0;colIndex colNameP, String pointName, + List pWidth,List height) { + + FileOutputStream outputStream = null; + int[] maxColumnWidthPs=new int[colNameP.size()]; + Workbook workbook = null; + try { + workbook = createWorkbook(); + //设置表格的样式 + SparseArray borderedStyle = createBorderedStyle(workbook); + + //建立新的point sheet对象 excel表单 P_ALL + Sheet sheetPoint = workbook.createSheet(pointName); + //在sheet里创建第一行,参数为行索引 0~65535直接 + Row row1 = sheetPoint.createRow(0); + if (height.size()==2) { + row1.setHeight((short) (height.get(0)*20)); + } + //创建单元格 0~255 + for (int i = 0; i < colNameP.size(); i++) { + Cell cell = row1.createCell(i); + cell.setCellStyle(borderedStyle.get(6)); + cell.setCellValue(colNameP.get(i)); + int cellWidth=Math.min(colNameP.get(i).getBytes().length*256,9*256); + maxColumnWidthPs[i]=Math.max(maxColumnWidthPs[i],cellWidth); + } + + if (pWidth.isEmpty()) + for (int colIndex=0;colIndex colNameP, List colNameL, String pointName, String lineName) { + FileOutputStream outputStream = null; + int[] maxColumnWidthPs=new int[colNameP.size()]; + int[] maxColumnWidthLs=new int[colNameL.size()]; + Workbook workbook = null; + try { + workbook = createWorkbook(); + //设置表格的样式 + SparseArray borderedStyle = createBorderedStyle(workbook); + + //建立新的point sheet对象 excel表单 P_ALL + Sheet sheetPoint = workbook.createSheet(pointName); + //在sheet里创建第一行,参数为行索引 0~65535直接 + Row row1 = sheetPoint.createRow(0); + //创建单元格 0~255 + for (int i = 0; i < colNameP.size(); i++) { + Cell cell = row1.createCell(i); + cell.setCellStyle(borderedStyle.get(2)); + cell.setCellValue(colNameP.get(i)); + + int cellWidth=Math.min(colNameP.get(i).getBytes().length*256,9*256); + maxColumnWidthPs[i]=Math.max(maxColumnWidthPs[i],cellWidth); + + } + //建立新的point sheet对象 excel表单 L_ALL + Sheet sheetLine = workbook.createSheet(lineName); + //在sheet里创建第一行,参数为行索引 0~65535直接 + Row row = sheetLine.createRow(0); + //创建单元格 0~255 + for (int i = 0; i < colNameL.size(); i++) { + Cell cell = row.createCell(i); + cell.setCellStyle(borderedStyle.get(2)); + cell.setCellValue(colNameL.get(i)); + + int cellWidth=Math.min(colNameL.get(i).getBytes().length*256,9*256); + maxColumnWidthLs[i]=Math.max(maxColumnWidthLs[i],cellWidth); + } + + for (int colIndex=0;colIndex void writeObjListToExcel(int sheetIndex, List list, String fileName) { + FileInputStream is = null; + FileOutputStream os = null; + Workbook wb = null; + String extString = fileName.substring(fileName.lastIndexOf(".")); + try { + is = new FileInputStream(new File(fileName)); + if (".xls".equals(extString)) { + wb = new HSSFWorkbook(is); + } else if (".xlsx".equals(extString)) { + + } else { + wb = null; + } + if (wb != null) { + SparseArray borderedStyle = createBorderedStyle(wb); + Sheet sheet = wb.getSheetAt(sheetIndex); + ArrayList list1 = null; + int size = list.size(); + for (int i = 0; i < size; i++) { + list1 = (ArrayList) list.get(i); + int size2 = list1.size(); + Row row = sheet.createRow(i + 1); + for (int j = 0; j < size2; j++) { + Cell cell = row.createCell(j); + cell.setCellStyle(borderedStyle.get(3)); + cell.setCellValue(list1.get(j)); + } + } + } + os = new FileOutputStream(fileName); + wb.write(os); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (os != null) { + os.close(); + } + + } catch (IOException e) { + e.printStackTrace(); + } + + } + } +} diff --git a/app/src/main/java/com/zywl/test1229/utils/FileUtils.kt b/app/src/main/java/com/zywl/test1229/utils/FileUtils.kt new file mode 100644 index 0000000..83e9856 --- /dev/null +++ b/app/src/main/java/com/zywl/test1229/utils/FileUtils.kt @@ -0,0 +1,37 @@ +package com.zywl.test1229.utils + +import java.io.File + +class FileUtils { + companion object{ + fun getFileCountInDirectory(directoryPath: String?, vararg types: String?): Int { + val directory = File(directoryPath) + var num = 0 + // 检查是否为有效目录 + if (directory.exists() && directory.isDirectory) { + // 获取目录下所有文件和子目录 + val files = directory.listFiles() + if (types.size == 0) // 返回文件的数量,如果目录为空则返回 0 + return files?.size ?: 0 + for (file in files!!) { + if (file.isDirectory) { + num++ + continue + } + for (str in types) if (file.name.endsWith(str!!)) { + num++ + } + } + return num + } else { + // 如果路径不是目录或不存在 + return num + } + } + fun mkDir(path:String){ + var file=File(path) + if (!file.exists()) + file.mkdir() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/zywl/test1229/utils/JsonUils.kt b/app/src/main/java/com/zywl/test1229/utils/JsonUils.kt new file mode 100644 index 0000000..308085d --- /dev/null +++ b/app/src/main/java/com/zywl/test1229/utils/JsonUils.kt @@ -0,0 +1,61 @@ +package com.zywl.test1229.utils + +import android.content.Context +import org.json.JSONException +import org.json.JSONObject +import java.io.BufferedReader +import java.io.InputStream +import java.io.InputStreamReader + +class JsonUils { + companion object{ + fun parseJSONListDouble(exceFiledJson: String?, type: String?): List { + val list: MutableList = ArrayList() + var jsonObject: JSONObject? = null + try { + jsonObject = JSONObject(exceFiledJson) + val primeExlPObject = jsonObject.getJSONObject(type) + val keys = primeExlPObject.keys() + while (keys.hasNext()) { + val key = keys.next() + list.add(primeExlPObject.getDouble(key)) + } + } catch (e: JSONException) { + throw RuntimeException(e) + } + return list + } + fun loadJSONFromAssets(fileName: String?,context: Context?): String? { + val jsonString = StringBuilder() + try { + val inputStream: InputStream = context!!.assets.open(fileName!!) + val bufferedReader = BufferedReader(InputStreamReader(inputStream)) + var line: String? + while ((bufferedReader.readLine().also { line = it }) != null) { + jsonString.append(line) + } + bufferedReader.close() + } catch (e: Exception) { + e.printStackTrace() + return null + } + return jsonString.toString() + } + fun parseJSONList(exceFiledJson: String?, type: String?): List { + val list: MutableList = java.util.ArrayList() + var jsonObject: JSONObject? = null + try { + jsonObject = JSONObject(exceFiledJson) + val primeExlPObject = jsonObject.getJSONObject(type) + val keys = primeExlPObject.keys() + while (keys.hasNext()) { + val key = keys.next() + list.add(primeExlPObject.getString(key)) + } + } catch (e: JSONException) { + throw java.lang.RuntimeException(e) + } + return list + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/zywl/test1229/utils/Tools.kt b/app/src/main/java/com/zywl/test1229/utils/Tools.kt new file mode 100644 index 0000000..e9b18b1 --- /dev/null +++ b/app/src/main/java/com/zywl/test1229/utils/Tools.kt @@ -0,0 +1,44 @@ +package com.zywl.test1229.utils + +import android.util.Log +import com.zywl.test1229.bean.PointInfo +import kotlin.reflect.full.declaredMemberProperties +import kotlin.reflect.full.memberProperties + +class Tools { + companion object{ + fun getDataClassFieldNames(clazz: Any): List { + return clazz::class.memberProperties.map { it.name } + } + fun getDataClassFieldNamesAndValue(clazz: Any):Map{ + return clazz.javaClass.kotlin.declaredMemberProperties.associate { it-> + it.name to it.get(clazz).toString() + } + } + fun getDataClassFieldNamesAndValueForMap(list:List): List> { + var maps:MutableList> = mutableListOf() + list.forEach { + var map = getDataClassFieldNamesAndValue(it) + if (map.isNotEmpty())maps.add(map) + } + return maps + } + fun getDataClassFieldNamesAndValuesForList(names:List, + maps: List>):List>{ + var listMain:MutableList> = mutableListOf() + for (map in maps){ + var list= mutableListOf() + names.forEach { + for (key in map.keys){ + if (key.equals(it)){ + map.get(key)?.let { it1 -> list.add(it1) } + return@forEach + } + } + } + if (list.isNotEmpty())listMain.add(list) + } + return listMain + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/zywl/test1229/view/DropdownMenu.kt b/app/src/main/java/com/zywl/test1229/view/DropdownMenu.kt new file mode 100644 index 0000000..3f82cc2 --- /dev/null +++ b/app/src/main/java/com/zywl/test1229/view/DropdownMenu.kt @@ -0,0 +1,257 @@ + +package com.zywl.test1229.view +import android.util.Log +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.text.KeyboardOptions + +import androidx.compose.material3.DatePicker +import androidx.compose.material3.DatePickerDialog +import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.ExposedDropdownMenuBox +import androidx.compose.material3.ExposedDropdownMenuDefaults +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.material3.TextField +import androidx.compose.material3.TextFieldDefaults +import androidx.compose.material3.rememberDatePickerState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue + + +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.input.KeyboardType + +import androidx.compose.ui.unit.sp +import com.zywl.test1229.utils.ExcelUtils +import com.zywl.test1229.bean.StakeInfo +import com.zywl.test1229.data.SimpleViewModel +import kotlinx.coroutines.delay +import java.text.SimpleDateFormat +import java.util.Date +import java.util.Locale + + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun EditableExposedDropdownMenuSample(options:List, + label:String, + content:String, + onPipeLineChanged: (String) -> Unit,modifier: Modifier=Modifier) { + var expanded by remember { mutableStateOf(false) } + ExposedDropdownMenuBox( + //是否列出列表 + expanded = expanded, + onExpandedChange = { + expanded = !expanded + }, + ) { + TextField( + value = content, + onValueChange = { + onPipeLineChanged(it) + }, + label = { Text(label) }, + trailingIcon = { + ExposedDropdownMenuDefaults.TrailingIcon( + expanded = expanded + ) + }, + colors = TextFieldDefaults.colors(focusedContainerColor = Color.Transparent, unfocusedContainerColor = Color.Transparent ), + modifier = modifier.menuAnchor() + ) + val filteringOptions = + options.filter { it.contains(content, ignoreCase = true) } + if (filteringOptions.isNotEmpty()) { + ExposedDropdownMenu( + expanded = expanded, + onDismissRequest = { + expanded = false + } + ) { + filteringOptions.forEach { selectionOption -> + DropdownMenuItem( + text = { + Text(text = selectionOption) + }, + onClick = { + onPipeLineChanged(selectionOption) + expanded = false + } + ) + } + } + } + } +} +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun ExposedDropdownMenuSample(label:String, + content:String, + onPipeLineChanged: (String) -> Unit,modifier: Modifier=Modifier) { + val options = listOf("否", "是") + var expanded by remember { mutableStateOf(false) } + ExposedDropdownMenuBox( + expanded = expanded, + onExpandedChange = { + expanded = !expanded + } + ) { + TextField( + readOnly = true, + value = content, + onValueChange = { }, + label = { Text(label) }, + trailingIcon = { + ExposedDropdownMenuDefaults.TrailingIcon( + //这里使用了 ExposedDropdownMenuDefaults.TrailingIcon 组件作为右侧图标。 + //这个图标会根据 expanded 的状态变化,通常用于表示下拉菜单的打开或关闭状态 + expanded = expanded + ) + }, + colors = TextFieldDefaults.colors(focusedContainerColor = Color.Transparent, unfocusedContainerColor = Color.Transparent ), + modifier = modifier.menuAnchor() + ) + + ExposedDropdownMenu( + expanded = expanded, + onDismissRequest = { + expanded = false + }, + ) { + options.forEach { selectionOption -> + DropdownMenuItem( + text = { + Text(selectionOption) + }, + onClick = { + onPipeLineChanged(selectionOption) + expanded = false + } + ) + } + } + } +} +@Composable +fun EditableTextField(label:String, + content:String, + onPipeLineChanged: (String) -> Unit,modifier: Modifier=Modifier){ + TextField( + modifier = modifier, + value =content, + onValueChange = { + onPipeLineChanged(it) + }, + singleLine = true, + label = { + Text(label) + }, + colors = TextFieldDefaults.colors(focusedContainerColor = Color.Transparent, unfocusedContainerColor = Color.Transparent ) + ) +} +@Composable +fun EditableTextFieldInt(label:String, + content:String, + onPipeLineChanged: (Double) -> Unit,modifier: Modifier=Modifier){ + TextField( + modifier = modifier, + value =content, + onValueChange = { + val newValue = it.toDoubleOrNull() // 将输入的字符串转换为 Double + if (newValue != null) { + onPipeLineChanged(newValue) // 如果转换成功,调用 onPipeLineChanged + } + }, + singleLine = true, + label = { + Text(label) + }, + keyboardOptions = KeyboardOptions.Default.copy( + keyboardType = KeyboardType.Number, // 设置为数字键盘 + imeAction = ImeAction.Done + ), + colors = TextFieldDefaults.colors(focusedContainerColor = Color.Transparent, unfocusedContainerColor = Color.Transparent ) + ) +} +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun EditableTime(label:String, + date:String, + onPipeLineChanged: (String) -> Unit,modifier: Modifier=Modifier){ + var content=date + if(content.isEmpty()) { + content="**-**-**" + } + + Row(modifier = modifier, horizontalArrangement = Arrangement.SpaceBetween) { + var showTimePicker by remember { mutableStateOf(false) } + Text(text = label) + Text(text = content, + style = TextStyle( + fontSize = 14.sp, + fontWeight = FontWeight.Bold + ), + modifier = Modifier.clickable { + showTimePicker = true + } + ) + val datePickerState = rememberDatePickerState() + if (showTimePicker) { + DatePickerDialog( + onDismissRequest = { showTimePicker=false; }, + confirmButton = { + TextButton(onClick = { + val formattedDate = datePickerState.selectedDateMillis?.let { + val date = Date(it) + val format = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()) // 设置日期格式 + format.format(date) + } ?: content + onPipeLineChanged(formattedDate) + Log.d("DatePickerDialog",formattedDate) + showTimePicker=false; + }) { + Text("OK") + } + }, + dismissButton = { + TextButton(onClick = {showTimePicker=false;}) { + Text("Cancel") + } + } + ) { + DatePicker(state = datePickerState) + } + } + } +} +@Composable +fun PeriodicTaskForDataSave(viewModel: SimpleViewModel>){ + var context = LocalContext.current + LaunchedEffect(key1 = Unit) { + while (true){ + delay(10_000) + var data=viewModel.stateFlow.value.data + Log.d("MainActivity","PeriodicTaskForDataSave") + if (data!=null){ + if (data.isNotEmpty()) + ExcelUtils().produceExcel(context,data,true) + else + Log.d("MainActivity","PeriodicTaskForDataSave is Empty") + }else{ + Log.d("MainActivity","PeriodicTaskForDataSave is null") + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/zywl/test1229/view/FilesScreen.kt b/app/src/main/java/com/zywl/test1229/view/FilesScreen.kt new file mode 100644 index 0000000..f03d346 --- /dev/null +++ b/app/src/main/java/com/zywl/test1229/view/FilesScreen.kt @@ -0,0 +1,304 @@ +package com.zywl.test1229.view + +import android.annotation.SuppressLint +import android.content.Context +import android.content.Intent +import android.os.Environment +import android.util.Log +import androidx.activity.compose.BackHandler +import androidx.compose.foundation.Image +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Done +import androidx.compose.material.icons.rounded.ArrowBack +import androidx.compose.material.icons.rounded.Clear +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.ListItem +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.input.nestedscroll.nestedScroll +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp +import androidx.core.content.FileProvider +import androidx.navigation.NavController +import com.zywl.test1229.utils.ExcelUtils +import com.zywl.test1229.R +import com.zywl.test1229.bean.StakeInfo +import com.zywl.test1229.data.SimpleViewModel +import java.io.File +import java.nio.file.Files + +@SuppressLint("UnrememberedGetBackStackEntry") +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun FilesScreen(navController:NavController,viewModel: SimpleViewModel>){ + val context = LocalContext.current + val fileState = remember { FileState() } + val action = remember { mutableStateOf(FileAction.None) } + + //设置copy或者select里的parentfile路径 + LaunchedEffect(fileState.current) { + fileState.onContentChange() + } + //按下返回健且条件满足时 + BackHandler(fileState.current != fileState.root) { + fileState.goToParent() + } + val listState = rememberLazyListState() + val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior() + var isLoading by remember { mutableStateOf(false) } + var filePath by remember { mutableStateOf(null) } + LaunchedEffect(filePath) { + filePath?.let { + isLoading = true + var excelUtils= ExcelUtils() + var excelData=excelUtils.parseExcel(filePath!!) + isLoading = false + viewModel.setData(excelData); + navController.popBackStack() + } + } + Scaffold( + topBar = { + TopAppBar( + title = { + Text(text = action.value.topBarTitle, maxLines = 1) + }, navigationIcon = { + action.value.navigation?.let { + IconButton( + onClick = { + it.second.invoke(action.value) + } + ) { + Icon(imageVector = it.first, contentDescription = null) + } + } + }, actions = { + action.value.actions.forEach { item -> + IconButton( + onClick = item.second + ) { + Icon(imageVector = item.first, contentDescription = null) + } + } + }, scrollBehavior = scrollBehavior + ) + } + +// floatingActionButton = { +// AnimatedVisibility( + //当下拉到底时不显示 +// visible = listState.canScrollForward, +// enter = slideInVertically(initialOffsetY = { it }) + fadeIn(), +// exit = slideOutVertically(targetOffsetY = { it }) + fadeOut() +// ) { +// FloatingActionButton( +// onClick = { +// +// } +// ) { +// Icon(imageVector = Icons.Rounded.Add, contentDescription = null) +// } +// } +// } + ,modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection) + ){ innerPadding -> + LazyColumn( + state = listState, + contentPadding = innerPadding + ) { + if (fileState.parent != null) item { + ListItem( + headlineContent = { + Text(text = "..") + }, modifier = Modifier.clickable { + fileState.goToParent() + }, leadingContent = { + Icon(imageVector = Icons.Rounded.ArrowBack, contentDescription = null) + } + ) + } + items(fileState.items) { item -> + ListItem( + headlineContent = { + Text(text = item.name) + }, leadingContent = { + if (item.isDirectory) { + Image( + painter = painterResource(R.mipmap.directory), + contentDescription = "Vector Image", + modifier = Modifier.size(30.dp) // 控制图片的大小 + ) + } + if (item.isFile) { + Image( + painter = painterResource(R.mipmap.file), + contentDescription = "Vector Image", + modifier = Modifier.size(30.dp) // 控制图片的大小 + ) + } + }, +// trailingContent = { +// val expanded = remember { mutableStateOf(false) } +// IconButton( +// onClick = { +// expanded.value = true +// } +// ) { +// Icon(imageVector = Icons.Rounded.MoreVert, contentDescription = null) +// } +// } + modifier = Modifier.clickable { + if (item.isDirectory) fileState.current = item.path + if (item.isFile) { + var fileActionCopy: FileAction.Select = FileAction.Select( + source = item, + onPasteResult = { str -> + filePath=str + //返回数据 +// action.value = FileAction.None +// navController.previousBackStackEntry?.savedStateHandle?.set("resultKey", str) +// navController.popBackStack() +// isLoading = true +// +// var excelUtils=ExcelUtils() +// var excelData=excelUtils.parseExcel(str) +// +// isLoading = false +// viewModel.setData(excelData); +// navController.popBackStack() + + }, onCancel = { + action.value = FileAction.None + } + ) + action.value = fileActionCopy + } + } + ) + } + } + } + ProgressDialogView(isLoading) +} +fun Context.openExternal(file: File) { + if (file.isDirectory) return + val contentType = Files.probeContentType(file.toPath()) + val uri = FileProvider.getUriForFile(this, "$packageName.provider", file) + val intent = Intent().apply { + action = Intent.ACTION_VIEW + addCategory(Intent.CATEGORY_DEFAULT) + addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) + setDataAndType(uri, contentType) + } + startActivity(intent) +} +class FileState { + var items by mutableStateOf(emptyList()) + var root: String by mutableStateOf(Environment.getExternalStorageDirectory().path) + var current: String by mutableStateOf(root) + var parent: String? by mutableStateOf(null) + val listener = mutableListOf<(String) -> Unit>() + + fun onContentChange() { + listener.forEach { + it(current) + } + val file = File(current) +// val files = (file.listFiles() ?: arrayOf()) +// .groupBy { it.isDirectory } +// .flatMap { +// it.value.sortedBy { it.name } +// } + val files = (file.listFiles() ?: arrayOf()) + .sortedBy { it.name } // 按文件名排序 + .flatMap { + // 先获取所有文件夹,再获取所有后缀为 .xls 的文件 + when { + it.isDirectory -> listOf(it) // 如果是目录,添加到列表中 + it.extension.equals("xls", ignoreCase = true) -> listOf(it) // 如果是 .xls 文件,添加到列表中 + else -> emptyList() // 否则不做任何处理 + } + } + parent = if (current == root) null else file.parentFile?.path + items = files + } + + fun goToParent() { + parent?.let { current = it } + } +} +sealed interface FileAction { + val topBarTitle: String + val navigation: Pair Unit>? + val actions: List Unit>> + + data object None : FileAction { + override val topBarTitle: String = "文件选择" + override val navigation: Pair Unit>? = null + override val actions: List Unit>> = emptyList() + } + + class Select( + val source: File, + val onPasteResult: (String) -> Unit, + val onCancel: FileAction.() -> Unit + ):FileAction{ + fun sure() { + Log.d("MainActivity","${source.path} ${source.name}") + onPasteResult(source.path); + } + override val topBarTitle: String = "已经选中 ${source.name} " + override val navigation: Pair Unit>? = + Icons.Rounded.Clear to onCancel + override val actions: List Unit>> = listOf( + Icons.Default.Done to ::sure + ) + } + + class Copy( + val source: File, + val onPasteResult: (Boolean, String) -> Unit, + val onCancel: FileAction.() -> Unit + ) : FileAction { + private var targetDir: File = source.parentFile + fun onTargetDirChange(it: String) { + targetDir = File(it) + } + + fun paste() { + val filename = source.name + val target = File(targetDir, filename) + if (target.exists()) { + onPasteResult(false, "文件已存在") + } else { + source.copyRecursively(target) + onPasteResult(true, "复制成功") + } + } + + override val topBarTitle: String = "复制 ${source.name} 到.." + override val navigation: Pair Unit>? = + Icons.Rounded.Clear to onCancel + override val actions: List Unit>> = listOf( + Icons.Default.Done to ::paste + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/zywl/test1229/view/HomePager.kt b/app/src/main/java/com/zywl/test1229/view/HomePager.kt new file mode 100644 index 0000000..03ea3c4 --- /dev/null +++ b/app/src/main/java/com/zywl/test1229/view/HomePager.kt @@ -0,0 +1,331 @@ +package com.zywl.test1229.view + +import android.net.Uri +import android.util.Log +import android.widget.Toast +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.fadeIn +import androidx.compose.animation.slideInVertically +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.gestures.detectTapGestures +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.itemsIndexed +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ArrowBack +import androidx.compose.material3.Button +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.FloatingActionButton +import androidx.compose.material3.FloatingActionButtonDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.SideEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ImageBitmap +import androidx.compose.ui.input.pointer.pointerInput +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.imageResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.navigation.NavController +import com.google.gson.Gson +import com.zywl.test1229.utils.ExcelUtils +import com.zywl.test1229.MainActivity +import com.zywl.test1229.R +import com.zywl.test1229.bean.Constant +import com.zywl.test1229.bean.StakeInfo +import com.zywl.test1229.data.SimpleViewModel +import kotlinx.coroutines.delay + + +@Composable +fun FloatingButtonS(navController: NavController,viewModel: SimpleViewModel>){ +// var viewModel= viewModel(); + var isShow by remember { mutableStateOf(false) } + var isShowDialog by remember { mutableStateOf(false) } + val context = LocalContext.current +// val result = navController.currentBackStackEntry?.savedStateHandle?.get("resultKey") +// SideEffect { +// Log.d("mainPager","stakeInfoView $result") +// } + Column(modifier = Modifier.padding(end = 16.dp,bottom = 8.dp)) { + AnimatedVisibility( + visible = isShow, + enter = fadeIn() + slideInVertically(initialOffsetY = { it }) // Animation for appearing + ) { + Column( + verticalArrangement = Arrangement.spacedBy(8.dp), + modifier = Modifier.padding(bottom = 8.dp) + ) { + FloatingActionButton( + elevation = FloatingActionButtonDefaults.elevation(0.dp), + shape = CircleShape, + onClick = { + navController.navigate("files") + }, + modifier = Modifier.size(66.dp), + ) { + Text("导入", color = Color.White) + } + FloatingActionButton( + elevation = FloatingActionButtonDefaults.elevation(0.dp), + shape = CircleShape, + onClick = { + isShowDialog=true + var excelUtils = ExcelUtils() + var data=viewModel.stateFlow.value.data + if (data!=null){ + if (data.isNotEmpty()){ + excelUtils.produceExcel(context,data) + Toast.makeText(context, "导出成功", Toast.LENGTH_SHORT).show() + } + else{ + Toast.makeText(context, "导出失败,没有数据", Toast.LENGTH_SHORT).show() + } + }else{ + Toast.makeText(context, "导出失败,没有数据", Toast.LENGTH_SHORT).show() + } + isShowDialog=false + }, + modifier = Modifier.size(66.dp), + ) { + Text("导出", color = Color.White) + } + + FloatingActionButton( + elevation = FloatingActionButtonDefaults.elevation(0.dp), + shape = CircleShape, + onClick = { + navController.navigate("info") + }, + modifier = Modifier.size(66.dp), + ) { + Text("新增", color = Color.White) + } + } + } + FloatingActionButton( + elevation = FloatingActionButtonDefaults.elevation(0.dp), + shape = CircleShape, + onClick = { + isShow=!isShow + }, + modifier = Modifier.size(66.dp), + containerColor = Color.Blue + ) { + var str=if (isShow) "-" else "+" + Text(str, color = Color.White, style = TextStyle(fontSize = 26.sp)) + } + } + ProgressDialogView(isShowDialog) +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun TopBar(activity: MainActivity){ + // 设置两次点击之间的间隔时间为 2 秒 + var showExitMessage by remember { mutableStateOf(false) } + + if (showExitMessage) { + Toast.makeText(LocalContext.current, "再按一次退出", Toast.LENGTH_SHORT).show() + LaunchedEffect(Unit) { + delay(activity.backPressInterval) + showExitMessage = false // 2 秒后隐藏提示 + } + } + TopAppBar( + title = { Text(text = "桩管理") }, + colors = TopAppBarDefaults.mediumTopAppBarColors( + containerColor = Color.Cyan + ), + navigationIcon = { + IconButton(onClick = { + val currentTime = System.currentTimeMillis() + if (currentTime - activity.lastBackPressedTime < activity.backPressInterval) { + // 如果两次点击的时间间隔小于规定的时间(2000ms),退出应用 + activity.finish() // 或者使用 `exitProcess(0)` 来退出应用 + } else { + // 否则显示提示信息并记录当前时间 + activity.lastBackPressedTime = currentTime + showExitMessage = true + } + + }) { + Icon(imageVector = Icons.Default.ArrowBack, contentDescription = "Back") + } + } + ) +} +var outerItems:MutableList = mutableListOf() +@Composable +fun mainPager(navController: NavController, viewModel: SimpleViewModel>, modifier: Modifier = Modifier){ + // 订阅 stateFlow 以获取数据 + val result = viewModel.stateFlow.collectAsState() + val dataList = result.value.data + PeriodicTaskForDataSave(viewModel) + SideEffect { + Log.d("sss","mainPager outerItems") + dataList?.let { + outerItems= dataList as MutableList + } + } + Box(modifier= modifier + .fillMaxSize() + .padding(start = 36.dp, end = 36.dp)){ + LazyColumn(modifier=Modifier.fillMaxSize()) { + itemsIndexed(dataList?:ArrayList()){ + index, item -> + var expanded by remember { mutableStateOf(false) } + var stakeInfo by remember { + mutableStateOf(item) + } + SideEffect { + outerItems[index] = stakeInfo + } + Column(modifier = Modifier + .fillParentMaxWidth() + .padding(top = 16.dp), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center) { + Row(modifier = Modifier + .fillMaxWidth() + .height(26.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween) { + Text(text = "${index+1}", style = TextStyle( + fontSize = 16.sp, + fontWeight = FontWeight.Bold, + ), modifier = Modifier.padding(start = 6.dp) + ) + Text(text = "测绘临时编号:${item.tempNo}",style = TextStyle( + fontSize = 14.sp, + fontWeight = FontWeight.Bold + ), modifier = Modifier + .padding(start = 26.dp) + .clickable { + navController.navigate("info/${Uri.encode(Gson().toJson(item))}") + } + ) + Icon(bitmap = ImageBitmap.imageResource( id = (if (!expanded) R.mipmap.downdraw else R.mipmap.updraw)), + contentDescription = null,modifier= Modifier + .size(16.dp) + .padding(end = 6.dp) + .clickable { + expanded = !expanded + } + ) + } + StakeInfoView(isShow = expanded, stakeInfo = stakeInfo, + onPipeLineChanged = { newStakeInfo-> + stakeInfo=newStakeInfo + }, + onDeleteItem = { + + } + ) + Box(modifier = Modifier.padding(top = 6.dp)) { + Spacer(modifier = Modifier + .fillMaxWidth() + .height(1.dp) + .background(Color.Blue)) + } + } + } + } + Button( + onClick = { /* Handle Click */ }, + modifier = Modifier + .align(Alignment.BottomStart) // 设置它在Box中的右下角 + .padding(bottom = 36.dp) + ) { + Text("设置点的线") + } + } +} +@Composable +fun StakeInfoView(isShow:Boolean, stakeInfo: StakeInfo, onPipeLineChanged:(StakeInfo)->Unit,onDeleteItem:()->Unit){ + if (!isShow){ + return + } + Surface( + shape = RoundedCornerShape(8.dp), + shadowElevation = 10.dp, + ){ + Column { + EditableTextField("管线",stakeInfo.pipeLine, modifier = Modifier.fillMaxWidth(), onPipeLineChanged = { + onPipeLineChanged(stakeInfo.copy(pipeLine = it)) + }) + EditableExposedDropdownMenuSample(Constant.stakeTypeArray,"桩类型",stakeInfo.stakeType,modifier = Modifier.fillMaxWidth(),onPipeLineChanged = { + onPipeLineChanged(stakeInfo.copy(stakeType = it)) + }) + EditableExposedDropdownMenuSample(Constant.depthArray,"管中埋深(米)",stakeInfo.pipeDepth,modifier = Modifier.fillMaxWidth(),onPipeLineChanged = { + onPipeLineChanged(stakeInfo.copy(pipeDepth = it)) + }) + EditableTextField("里程",stakeInfo.mileage, modifier = Modifier.fillMaxWidth(), onPipeLineChanged = { + onPipeLineChanged(stakeInfo.copy(mileage = it)) + }) + EditableExposedDropdownMenuSample(Constant.BuriedTechnologyArray,"埋设工艺",stakeInfo.buryTech,modifier = Modifier.fillMaxWidth(),onPipeLineChanged = { + onPipeLineChanged(stakeInfo.copy(buryTech = it)) + }) + ExposedDropdownMenuSample("是否出入土点",stakeInfo.isInPoint, modifier = Modifier.fillMaxWidth(), onPipeLineChanged = { + onPipeLineChanged(stakeInfo.copy(isInPoint = it)) + }) + EditableExposedDropdownMenuSample(Constant.terrainArray,"地形",stakeInfo.terrain,modifier = Modifier.fillMaxWidth(),onPipeLineChanged = { + onPipeLineChanged(stakeInfo.copy(terrain = it)) + }) + Row { + EditableTextFieldInt("经度","${stakeInfo.latitude}", modifier = Modifier + .fillMaxWidth() + .weight(1f), onPipeLineChanged = { + onPipeLineChanged(stakeInfo.copy(latitude = it)) + }) + EditableTextFieldInt("维度","${stakeInfo.longitude}", modifier = Modifier + .fillMaxWidth() + .weight(1f), onPipeLineChanged = { + onPipeLineChanged(stakeInfo.copy(longitude = it)) + }) + } + EditableTextFieldInt("Z(85高程,桩根部)","${stakeInfo.z}", modifier = Modifier + .fillMaxWidth(), onPipeLineChanged = { + onPipeLineChanged(stakeInfo.copy(z = it)) + }) + EditableTime("采集时间",stakeInfo.collectDate, modifier = Modifier + .fillMaxWidth() + .padding(start = 6.dp, end = 6.dp, top = 18.dp, bottom = 12.dp), onPipeLineChanged = { + onPipeLineChanged(stakeInfo.copy(collectDate = it)) + }) + Row (modifier = Modifier.fillMaxSize(),horizontalArrangement = Arrangement.Center){ + Button(onClick = { + onDeleteItem() + }) { + Text(text = "删除") + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/zywl/test1229/view/SimpleDialog.kt b/app/src/main/java/com/zywl/test1229/view/SimpleDialog.kt new file mode 100644 index 0000000..c3e025f --- /dev/null +++ b/app/src/main/java/com/zywl/test1229/view/SimpleDialog.kt @@ -0,0 +1,112 @@ +package com.zywl.test1229.view + + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.material3.TextField +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.unit.dp +import java.awt.Color + + +@Composable +fun SimpleDialogView(showDialog : Boolean, + dialogTitle: String, + dialogText: String, + onDismissRequest: () -> Unit, + onConfirmation: () -> Unit){ + if (showDialog) { + AlertDialog( + onDismissRequest = { + onDismissRequest() + }, + title = { + Text(dialogTitle) + }, + text = { + Text(dialogText) + }, + confirmButton = { + TextButton( + onClick = { + onConfirmation() + } + ) { + Text("确定") + } + }, + dismissButton = { + TextButton( + onClick = { + onDismissRequest() + } + ) { + Text("取消") + } + } + ) + } +} +@Composable +fun PermissionDialog( + visible: Boolean, + onConfirm: () -> Unit, + onDismissRequest: () -> Unit, +) { + if (visible) AlertDialog( + title = { + Text(text = "管理所有文件") + }, text = { + Text(text = "授予app管理存储设备上的所有文件的权限") + }, + confirmButton = { + TextButton( + onClick = { + onConfirm() + onDismissRequest() + } + ) { + Text(text = "确定") + } + }, dismissButton = { + TextButton( + onClick = onDismissRequest + ) { + Text(text = "取消") + } + }, onDismissRequest = onDismissRequest + ) +} +@Composable +fun ProgressDialogView(visible: Boolean){ + if (visible) + AlertDialog( + onDismissRequest = { }, + title = { + Text(text = "正在处理...") + }, + text = { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + CircularProgressIndicator( + modifier = Modifier.width(64.dp), + color = MaterialTheme.colorScheme.secondary, + trackColor = MaterialTheme.colorScheme.surfaceVariant, + ) + } + }, + confirmButton = { + + } + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/zywl/test1229/view/StakeInfoViewPager.kt b/app/src/main/java/com/zywl/test1229/view/StakeInfoViewPager.kt new file mode 100644 index 0000000..cd59b29 --- /dev/null +++ b/app/src/main/java/com/zywl/test1229/view/StakeInfoViewPager.kt @@ -0,0 +1,154 @@ +package com.zywl.test1229.view +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.Button +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import androidx.navigation.NavController +import com.zywl.test1229.bean.Constant +import com.zywl.test1229.bean.StakeInfo +import com.zywl.test1229.bean.User +import com.zywl.test1229.data.SimpleViewModel + +class StakeInfoViewPager { + @Composable + fun MainView(navController: NavController, + viewModel: SimpleViewModel>, + stakeInfo: StakeInfo? =null, + modifier: Modifier=Modifier){ + val result = viewModel.stateFlow.collectAsState() + val dataList = result.value.data as MutableList + val scrollState = rememberScrollState() + var index=-1 + + var dataTmp=StakeInfo("","","",0.0,0.0,0.0, + "","","","","","","") + var data by remember { mutableStateOf(dataTmp) } + stakeInfo?.let { + data=stakeInfo + dataList?.let{ + index= dataList.indexOf(stakeInfo) ?: -1 + } + } + + Scaffold( + modifier = Modifier.fillMaxSize().padding(start = 26.dp, end = 26.dp), + ) { innerPadding -> + Column(modifier = Modifier.fillMaxSize().padding(innerPadding).verticalScroll(scrollState)) { + EditableTextField( + "桩号", + data.tempNo, + modifier = Modifier.fillMaxWidth(), + onPipeLineChanged = { + data=data.copy(tempNo = it) + }) + EditableTextField( + "管线", + data.pipeLine, + modifier = Modifier.fillMaxWidth(), + onPipeLineChanged = { + data=data.copy(pipeLine = it) + }) + EditableExposedDropdownMenuSample( + Constant.stakeTypeArray, + "桩类型", + data.stakeType, + modifier = Modifier.fillMaxWidth(), + onPipeLineChanged = { + data=data.copy(stakeType = it) + }) + EditableExposedDropdownMenuSample( + Constant.depthArray, + "管中埋深(米)", + data.pipeDepth, + modifier = Modifier.fillMaxWidth(), + onPipeLineChanged = { + data=data.copy(pipeDepth = it) + }) + EditableTextField( + "里程", + data.mileage, + modifier = Modifier.fillMaxWidth(), + onPipeLineChanged = { + data=data.copy(mileage = it) + }) + EditableExposedDropdownMenuSample( + Constant.BuriedTechnologyArray, + "埋设工艺", + data.buryTech , + modifier = Modifier.fillMaxWidth(), + onPipeLineChanged = { + data=data.copy(buryTech = it) + }) + ExposedDropdownMenuSample( + "是否出入土点", + data.isInPoint, + modifier = Modifier.fillMaxWidth(), + onPipeLineChanged = { + data=data.copy(isInPoint = it) + }) + EditableExposedDropdownMenuSample( + Constant.terrainArray, + "地形", + data.terrain, + modifier = Modifier.fillMaxWidth(), + onPipeLineChanged = { + data=data.copy(terrain = it) + }) + Row { + EditableTextFieldInt("经度", (data.latitude).toString(), modifier = Modifier + .fillMaxWidth() + .weight(1f), onPipeLineChanged = { + data=data.copy(latitude = it) + }) + EditableTextFieldInt("维度", (data.longitude).toString(), modifier = Modifier + .fillMaxWidth() + .weight(1f), onPipeLineChanged = { + data=data.copy(longitude = it) + }) + } + EditableTime("采集时间", + data.collectDate, + modifier = Modifier + .fillMaxWidth() + .padding(start = 6.dp, end = 6.dp, top = 18.dp, bottom = 12.dp), + onPipeLineChanged = { + data=data.copy(collectDate = it) + }) + Row(horizontalArrangement = Arrangement.Center, modifier = Modifier.fillMaxWidth()) { + Button(modifier = Modifier.padding(end = 16.dp),onClick = { + dataList?.let { + if (index>=0) + dataList[index]=data + else + dataList.add(data) + viewModel.setData(dataList) + } + navController.popBackStack() + }) { + Text(text = "确定") + } + Button(modifier = Modifier.padding(start = 16.dp),onClick = { + navController.popBackStack() + }) { + Text(text = "取消") + } + } + } + } + } +} diff --git a/app/src/main/java/java/awt/Color.java b/app/src/main/java/java/awt/Color.java new file mode 100644 index 0000000..c2d7475 --- /dev/null +++ b/app/src/main/java/java/awt/Color.java @@ -0,0 +1,461 @@ +package java.awt; + +import java.io.Serializable; + +/** + * @author GEEK + */ +public class Color implements Serializable { + public static final Color white = new Color(255, 255, 255); + public static final Color WHITE; + public static final Color lightGray; + public static final Color LIGHT_GRAY; + public static final Color gray; + public static final Color GRAY; + public static final Color darkGray; + public static final Color DARK_GRAY; + public static final Color black; + public static final Color BLACK; + public static final Color red; + public static final Color RED; + public static final Color pink; + public static final Color PINK; + public static final Color orange; + public static final Color ORANGE; + public static final Color yellow; + public static final Color YELLOW; + public static final Color green; + public static final Color GREEN; + public static final Color magenta; + public static final Color MAGENTA; + public static final Color cyan; + public static final Color CYAN; + public static final Color blue; + public static final Color BLUE; + private static final long serialVersionUID = 118526816881161077L; + private static final double FACTOR = 0.7D; + + static { + WHITE = white; + lightGray = new Color(192, 192, 192); + LIGHT_GRAY = lightGray; + gray = new Color(128, 128, 128); + GRAY = gray; + darkGray = new Color(64, 64, 64); + DARK_GRAY = darkGray; + black = new Color(0, 0, 0); + BLACK = black; + red = new Color(255, 0, 0); + RED = red; + pink = new Color(255, 175, 175); + PINK = pink; + orange = new Color(255, 200, 0); + ORANGE = orange; + yellow = new Color(255, 255, 0); + YELLOW = yellow; + green = new Color(0, 255, 0); + GREEN = green; + magenta = new Color(255, 0, 255); + MAGENTA = magenta; + cyan = new Color(0, 255, 255); + CYAN = cyan; + blue = new Color(0, 0, 255); + BLUE = blue; + } + + int value; + private float[] frgbvalue; + private float[] fvalue; + private float falpha; + + public Color(int var1, int var2, int var3) { + this(var1, var2, var3, 255); + } + + public Color(int var1, int var2, int var3, int var4) { + this.frgbvalue = null; + this.fvalue = null; + this.falpha = 0.0F; + this.value = (var4 & 255) << 24 | (var1 & 255) << 16 | (var2 & 255) << 8 | (var3 & 255) << 0; + testColorValueRange(var1, var2, var3, var4); + } + + public Color(int var1) { + this.frgbvalue = null; + this.fvalue = null; + this.falpha = 0.0F; + this.value = -16777216 | var1; + } + + public Color(int var1, boolean var2) { + this.frgbvalue = null; + this.fvalue = null; + this.falpha = 0.0F; + if (var2) { + this.value = var1; + } else { + this.value = -16777216 | var1; + } + + } + + public Color(float var1, float var2, float var3) { + this((int) ((double) (var1 * 255.0F) + 0.5D), (int) ((double) (var2 * 255.0F) + 0.5D), (int) ((double) (var3 * 255.0F) + 0.5D)); + testColorValueRange(var1, var2, var3, 1.0F); + this.frgbvalue = new float[3]; + this.frgbvalue[0] = var1; + this.frgbvalue[1] = var2; + this.frgbvalue[2] = var3; + this.falpha = 1.0F; + this.fvalue = this.frgbvalue; + } + + public Color(float var1, float var2, float var3, float var4) { + this((int) ((double) (var1 * 255.0F) + 0.5D), (int) ((double) (var2 * 255.0F) + 0.5D), (int) ((double) (var3 * 255.0F) + 0.5D), (int) ((double) (var4 * 255.0F) + 0.5D)); + this.frgbvalue = new float[3]; + this.frgbvalue[0] = var1; + this.frgbvalue[1] = var2; + this.frgbvalue[2] = var3; + this.falpha = var4; + this.fvalue = this.frgbvalue; + } + + private static void testColorValueRange(int var0, int var1, int var2, int var3) { + boolean var4 = false; + String var5 = ""; + if (var3 < 0 || var3 > 255) { + var4 = true; + var5 = var5 + " Alpha"; + } + + if (var0 < 0 || var0 > 255) { + var4 = true; + var5 = var5 + " Red"; + } + + if (var1 < 0 || var1 > 255) { + var4 = true; + var5 = var5 + " Green"; + } + + if (var2 < 0 || var2 > 255) { + var4 = true; + var5 = var5 + " Blue"; + } + + if (var4) { + throw new IllegalArgumentException("Color parameter outside of expected range:" + var5); + } + } + + private static void testColorValueRange(float var0, float var1, float var2, float var3) { + boolean var4 = false; + String var5 = ""; + if ((double) var3 < 0.0D || (double) var3 > 1.0D) { + var4 = true; + var5 = var5 + " Alpha"; + } + + if ((double) var0 < 0.0D || (double) var0 > 1.0D) { + var4 = true; + var5 = var5 + " Red"; + } + + if ((double) var1 < 0.0D || (double) var1 > 1.0D) { + var4 = true; + var5 = var5 + " Green"; + } + + if ((double) var2 < 0.0D || (double) var2 > 1.0D) { + var4 = true; + var5 = var5 + " Blue"; + } + + if (var4) { + throw new IllegalArgumentException("Color parameter outside of expected range:" + var5); + } + } + + public static Color decode(String var0) throws NumberFormatException { + Integer var1 = Integer.decode(var0); + int var2 = var1; + return new Color(var2 >> 16 & 255, var2 >> 8 & 255, var2 & 255); + } + + public static Color getColor(String var0) { + return getColor(var0, (Color) null); + } + + public static Color getColor(String var0, Color var1) { + Integer var2 = Integer.getInteger(var0); + if (var2 == null) { + return var1; + } else { + int var3 = var2; + return new Color(var3 >> 16 & 255, var3 >> 8 & 255, var3 & 255); + } + } + + public static Color getColor(String var0, int var1) { + Integer var2 = Integer.getInteger(var0); + int var3 = var2 != null ? var2 : var1; + return new Color(var3 >> 16 & 255, var3 >> 8 & 255, var3 >> 0 & 255); + } + + public static int HSBtoRGB(float var0, float var1, float var2) { + int var3 = 0; + int var4 = 0; + int var5 = 0; + if (var1 == 0.0F) { + var3 = var4 = var5 = (int) (var2 * 255.0F + 0.5F); + } else { + float var6 = (var0 - (float) Math.floor((double) var0)) * 6.0F; + float var7 = var6 - (float) Math.floor((double) var6); + float var8 = var2 * (1.0F - var1); + float var9 = var2 * (1.0F - var1 * var7); + float var10 = var2 * (1.0F - var1 * (1.0F - var7)); + switch ((int) var6) { + case 0: + var3 = (int) (var2 * 255.0F + 0.5F); + var4 = (int) (var10 * 255.0F + 0.5F); + var5 = (int) (var8 * 255.0F + 0.5F); + break; + case 1: + var3 = (int) (var9 * 255.0F + 0.5F); + var4 = (int) (var2 * 255.0F + 0.5F); + var5 = (int) (var8 * 255.0F + 0.5F); + break; + case 2: + var3 = (int) (var8 * 255.0F + 0.5F); + var4 = (int) (var2 * 255.0F + 0.5F); + var5 = (int) (var10 * 255.0F + 0.5F); + break; + case 3: + var3 = (int) (var8 * 255.0F + 0.5F); + var4 = (int) (var9 * 255.0F + 0.5F); + var5 = (int) (var2 * 255.0F + 0.5F); + break; + case 4: + var3 = (int) (var10 * 255.0F + 0.5F); + var4 = (int) (var8 * 255.0F + 0.5F); + var5 = (int) (var2 * 255.0F + 0.5F); + break; + case 5: + var3 = (int) (var2 * 255.0F + 0.5F); + var4 = (int) (var8 * 255.0F + 0.5F); + var5 = (int) (var9 * 255.0F + 0.5F); + } + } + + return -16777216 | var3 << 16 | var4 << 8 | var5 << 0; + } + + public static float[] RGBtoHSB(int var0, int var1, int var2, float[] var3) { + if (var3 == null) { + var3 = new float[3]; + } + + int var7 = var0 > var1 ? var0 : var1; + if (var2 > var7) { + var7 = var2; + } + + int var8 = var0 < var1 ? var0 : var1; + if (var2 < var8) { + var8 = var2; + } + + float var6 = (float) var7 / 255.0F; + float var5; + if (var7 != 0) { + var5 = (float) (var7 - var8) / (float) var7; + } else { + var5 = 0.0F; + } + + float var4; + if (var5 == 0.0F) { + var4 = 0.0F; + } else { + float var9 = (float) (var7 - var0) / (float) (var7 - var8); + float var10 = (float) (var7 - var1) / (float) (var7 - var8); + float var11 = (float) (var7 - var2) / (float) (var7 - var8); + if (var0 == var7) { + var4 = var11 - var10; + } else if (var1 == var7) { + var4 = 2.0F + var9 - var11; + } else { + var4 = 4.0F + var10 - var9; + } + + var4 /= 6.0F; + if (var4 < 0.0F) { + ++var4; + } + } + + var3[0] = var4; + var3[1] = var5; + var3[2] = var6; + return var3; + } + + public static Color getHSBColor(float var0, float var1, float var2) { + return new Color(HSBtoRGB(var0, var1, var2)); + } + + public int getRed() { + return this.getRGB() >> 16 & 255; + } + + public int getGreen() { + return this.getRGB() >> 8 & 255; + } + + public int getBlue() { + return this.getRGB() >> 0 & 255; + } + + public int getAlpha() { + return this.getRGB() >> 24 & 255; + } + + public int getRGB() { + return this.value; + } + + public Color brighter() { + int var1 = this.getRed(); + int var2 = this.getGreen(); + int var3 = this.getBlue(); + int var4 = this.getAlpha(); + byte var5 = 3; + if (var1 == 0 && var2 == 0 && var3 == 0) { + return new Color(var5, var5, var5, var4); + } else { + if (var1 > 0 && var1 < var5) { + var1 = var5; + } + + if (var2 > 0 && var2 < var5) { + var2 = var5; + } + + if (var3 > 0 && var3 < var5) { + var3 = var5; + } + + return new Color(Math.min((int) ((double) var1 / 0.7D), 255), Math.min((int) ((double) var2 / 0.7D), 255), Math.min((int) ((double) var3 / 0.7D), 255), var4); + } + } + + public Color darker() { + return new Color(Math.max((int) ((double) this.getRed() * 0.7D), 0), Math.max((int) ((double) this.getGreen() * 0.7D), 0), Math.max((int) ((double) this.getBlue() * 0.7D), 0), this.getAlpha()); + } + + public int hashCode() { + return this.value; + } + + public boolean equals(Object var1) { + return var1 instanceof Color && ((Color) var1).getRGB() == this.getRGB(); + } + + public String toString() { + return this.getClass().getName() + "[r=" + this.getRed() + ",g=" + this.getGreen() + ",b=" + this.getBlue() + "]"; + } + + public float[] getRGBComponents(float[] var1) { + float[] var2; + if (var1 == null) { + var2 = new float[4]; + } else { + var2 = var1; + } + + if (this.frgbvalue == null) { + var2[0] = (float) this.getRed() / 255.0F; + var2[1] = (float) this.getGreen() / 255.0F; + var2[2] = (float) this.getBlue() / 255.0F; + var2[3] = (float) this.getAlpha() / 255.0F; + } else { + var2[0] = this.frgbvalue[0]; + var2[1] = this.frgbvalue[1]; + var2[2] = this.frgbvalue[2]; + var2[3] = this.falpha; + } + + return var2; + } + + public float[] getRGBColorComponents(float[] var1) { + float[] var2; + if (var1 == null) { + var2 = new float[3]; + } else { + var2 = var1; + } + + if (this.frgbvalue == null) { + var2[0] = (float) this.getRed() / 255.0F; + var2[1] = (float) this.getGreen() / 255.0F; + var2[2] = (float) this.getBlue() / 255.0F; + } else { + var2[0] = this.frgbvalue[0]; + var2[1] = this.frgbvalue[1]; + var2[2] = this.frgbvalue[2]; + } + + return var2; + } + + public float[] getComponents(float[] var1) { + if (this.fvalue == null) { + return this.getRGBComponents(var1); + } else { + int var3 = this.fvalue.length; + float[] var2; + if (var1 == null) { + var2 = new float[var3 + 1]; + } else { + var2 = var1; + } + + for (int var4 = 0; var4 < var3; ++var4) { + var2[var4] = this.fvalue[var4]; + } + + var2[var3] = this.falpha; + return var2; + } + } + + public float[] getColorComponents(float[] var1) { + if (this.fvalue == null) { + return this.getRGBColorComponents(var1); + } else { + int var3 = this.fvalue.length; + float[] var2; + if (var1 == null) { + var2 = new float[var3]; + } else { + var2 = var1; + } + + for (int var4 = 0; var4 < var3; ++var4) { + var2[var4] = this.fvalue[var4]; + } + + return var2; + } + } + + public int getTransparency() { + int var1 = this.getAlpha(); + if (var1 == 255) { + return 1; + } else { + return var1 == 0 ? 2 : 3; + } + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi/ic_launcher.xml b/app/src/main/res/mipmap-anydpi/ic_launcher.xml new file mode 100644 index 0000000..6f3b755 --- /dev/null +++ b/app/src/main/res/mipmap-anydpi/ic_launcher.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml new file mode 100644 index 0000000..6f3b755 --- /dev/null +++ b/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/app_icon.png b/app/src/main/res/mipmap-hdpi/app_icon.png new file mode 100644 index 0000000..dfadb32 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/app_icon.png differ diff --git a/app/src/main/res/mipmap-hdpi/directory.png b/app/src/main/res/mipmap-hdpi/directory.png new file mode 100644 index 0000000..fe55a03 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/directory.png differ diff --git a/app/src/main/res/mipmap-hdpi/downdraw.png b/app/src/main/res/mipmap-hdpi/downdraw.png new file mode 100644 index 0000000..59a8ede Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/downdraw.png differ diff --git a/app/src/main/res/mipmap-hdpi/file.png b/app/src/main/res/mipmap-hdpi/file.png new file mode 100644 index 0000000..e2ae1e1 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/file.png differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/app/src/main/res/mipmap-hdpi/ic_launcher.webp new file mode 100644 index 0000000..c209e78 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp new file mode 100644 index 0000000..b2dfe3d Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-hdpi/updraw.png b/app/src/main/res/mipmap-hdpi/updraw.png new file mode 100644 index 0000000..091cf65 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/updraw.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/app/src/main/res/mipmap-mdpi/ic_launcher.webp new file mode 100644 index 0000000..4f0f1d6 Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp new file mode 100644 index 0000000..62b611d Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp new file mode 100644 index 0000000..948a307 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..1b9a695 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp new file mode 100644 index 0000000..28d4b77 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..9287f50 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp new file mode 100644 index 0000000..aa7d642 Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..9126ae3 Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..f8c6127 --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,10 @@ + + + #FFBB86FC + #FF6200EE + #FF3700B3 + #FF03DAC5 + #FF018786 + #FF000000 + #FFFFFFFF + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..58920a7 --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + 桩表e + \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml new file mode 100644 index 0000000..b5e04ad --- /dev/null +++ b/app/src/main/res/values/themes.xml @@ -0,0 +1,5 @@ + + + +