基本视图完成,引入ObjectBox 还没有完成

dev
rayc 2024-03-02 17:25:54 +08:00
parent fce70dcda8
commit 783d2921f0
7 changed files with 265 additions and 40 deletions

View File

@ -1,6 +1,7 @@
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("io.objectbox")
}
android {
@ -67,5 +68,14 @@ dependencies {
debugImplementation("androidx.compose.ui:ui-tooling")
debugImplementation("androidx.compose.ui:ui-test-manifest")
// google fonts 感觉有些字体用不了
implementation("androidx.compose.ui:ui-text-google-fonts:1.6.1")
// implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.6.1")
// implementation("androidx.compose.runtime:runtime-livedata:1.7.0")
// implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1")
// view model
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1")
}

View File

@ -3,6 +3,7 @@
xmlns:tools="http://schemas.android.com/tools">
<application
android:name=".WeightTrackApp"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"

View File

@ -1,30 +1,42 @@
package com.eacenic.weighttrack
import android.annotation.SuppressLint
import android.os.Build
import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.annotation.RequiresApi
import androidx.compose.foundation.background
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.fillMaxHeight
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.layout.wrapContentHeight
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
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.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
@ -32,18 +44,22 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.eacenic.weighttrack.ui.theme.WeightTrackTheme
import kotlinx.coroutines.launch
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
class MainActivity : ComponentActivity() {
@RequiresApi(Build.VERSION_CODES.O)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
WeightTrackTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
@ -55,73 +71,93 @@ class MainActivity : ComponentActivity() {
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun WeightTrackLayout() {
@RequiresApi(Build.VERSION_CODES.O)
private val dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
val scope = rememberCoroutineScope()
@SuppressLint("StateFlowValueCalledInComposition")
@RequiresApi(Build.VERSION_CODES.O)
@Composable
fun WeightTrackLayout(
weightTrackViewModel: WeightTrackViewModel = viewModel()
) {
val weightRecords by weightTrackViewModel.historyData.collectAsState()
var openBottomSheet by rememberSaveable { mutableStateOf(false) }
var bottomSheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
Surface(
modifier = Modifier.fillMaxSize(),
color = Color.Gray
color = Color.White
) {
Column {
Row {
CurrentWeight()
Column(
modifier = Modifier.padding(horizontal = 20.dp)
) {
CurrentWeight(62.6f, Modifier.padding(top = 20.dp))
LazyColumn(
modifier = Modifier.fillMaxHeight(0.9f)
) {
this.items(weightRecords) {
// Text(text = "${it.weight}")
WeightRecordItem(weightRecord = it)
}
Button(onClick = {
openBottomSheet = true
}) {
Text(text = "添加")
}
EditButton(onClick = { openBottomSheet = true })
}
if (openBottomSheet) {
ModalBottomSheet(
onDismissRequest = { openBottomSheet = false },
sheetState = bottomSheetState
) {
Row {
Button(
onClick = {
scope.launch { bottomSheetState.hide() }.invokeOnCompletion {
if (!bottomSheetState.isVisible) {
BottomSheetEditor(
expandBottomSheet = openBottomSheet,
onDismiss = {
openBottomSheet = false
}
}
}
) {
Text(text = "关闭")
}
}
}
}
)
}
}
@RequiresApi(Build.VERSION_CODES.O)
@Composable
fun CurrentWeight() {
Row (
fun WeightRecordItem(weightRecord: WeightRecord) {
Box(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.padding(vertical = 5.dp)
) {
Text(
text = "${weightRecord.weight}",
modifier = Modifier.align(Alignment.CenterStart),
fontFamily = doodleShadowFontFamily,
fontSize = 36.sp,
)
Text(
text = dateTimeFormatter.format(weightRecord.date),
modifier = Modifier.align(Alignment.CenterEnd),
fontFamily = doodleShadowFontFamily,
fontSize = 18.sp
)
}
}
@Composable
fun CurrentWeight(
currentWeight: Float,
modifier: Modifier = Modifier
) {
Row (
modifier = modifier
.wrapContentHeight()
.padding(20.dp)
.fillMaxWidth(),
horizontalArrangement = Arrangement.Center
) {
Box(
modifier = Modifier
.fillMaxWidth(0.9f)
.fillMaxWidth()
.height(120.dp)
.clip(RoundedCornerShape(10.dp))
.background(Color.Cyan)
) {
Text(
text = "62.6",
text = "$currentWeight",
modifier = Modifier.align(Alignment.Center),
fontSize = 80.sp,
fontFamily = doodleShadowFontFamily
@ -129,3 +165,115 @@ fun CurrentWeight() {
}
}
}
@Composable
fun EditButton(
onClick: () -> Unit
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center,
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
) {
Button(
modifier = Modifier
.height(48.dp)
.fillMaxWidth(),
shape = RoundedCornerShape(5.dp),
colors = ButtonDefaults.buttonColors(Color.Cyan),
onClick = onClick,
) {
Text(text = "ADD", color = Color.Black, fontSize = 36.sp, fontFamily = doodleShadowFontFamily)
}
}
}
@RequiresApi(Build.VERSION_CODES.O)
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun BottomSheetEditor(
expandBottomSheet: Boolean = false,
onDismiss: () -> Unit,
weightTrackViewModel: WeightTrackViewModel = viewModel()
) {
val context = LocalContext.current
val scope = rememberCoroutineScope()
val bottomSheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
var text by remember { mutableStateOf("") }
var clickable by remember { mutableStateOf(false) }
if (expandBottomSheet) {
ModalBottomSheet(
onDismissRequest = onDismiss,
sheetState = bottomSheetState
) {
Column(
modifier = Modifier
.wrapContentHeight()
.fillMaxWidth()
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 20.dp)
) {
OutlinedTextField(
value = text,
modifier = Modifier.fillMaxWidth(),
onValueChange = {
val newVal = it.toFloatOrNull()
if ((it.isNotEmpty() && newVal == null) || (newVal !=null && newVal > 1000f)) {
Toast.makeText(context, "只能输入数字且要求数字小于1000", Toast.LENGTH_SHORT).show()
return@OutlinedTextField
}
text = it
clickable = text.isNotEmpty()
},
)
}
Spacer(modifier = Modifier
.height(20.dp)
.fillMaxWidth())
Row(
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.fillMaxWidth()
) {
Button(
onClick = {
scope.launch { bottomSheetState.hide() }.invokeOnCompletion {
if (!bottomSheetState.isVisible) {
onDismiss()
}
}
}
) {
Text(text = "CANCEL", fontSize = 18.sp, fontFamily = doodleShadowFontFamily)
}
Spacer(modifier = Modifier.size(60.dp))
Button(
onClick = {
Toast.makeText(context, "save weight", Toast.LENGTH_SHORT).show()
weightTrackViewModel.addWeightRecord(WeightRecord(text.toFloat(), LocalDateTime.now()))
text = ""
onDismiss()
},
enabled = clickable
) {
Text(text = "CONFIRM", fontSize = 18.sp, fontFamily = doodleShadowFontFamily)
}
}
Spacer(modifier = Modifier
.height(40.dp)
.fillMaxWidth())
}
}
}
}

View File

@ -0,0 +1,14 @@
package com.eacenic.weighttrack
import io.objectbox.annotation.Entity
import io.objectbox.annotation.Id
import java.time.LocalDateTime
@Entity
data class WeightRecord(
@Id
var id: Long = 0,
var weight: Float,
var date: LocalDateTime,
var isDeleted: Boolean = false
)

View File

@ -0,0 +1,11 @@
package com.eacenic.weighttrack
import android.app.Application
class WeightTrackApp: Application() {
override fun onCreate() {
super.onCreate()
}
}

View File

@ -0,0 +1,32 @@
package com.eacenic.weighttrack
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.lifecycle.ViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import java.time.LocalDateTime
const val TAG = "WeightTrackViewModel"
class WeightTrackViewModel: ViewModel() {
@RequiresApi(Build.VERSION_CODES.O)
private var _historyData = MutableStateFlow<List<WeightRecord>>(mutableListOf<WeightRecord>(
WeightRecord(62.6f, LocalDateTime.now()),
WeightRecord(63.6f, LocalDateTime.now()),
WeightRecord(65.6f, LocalDateTime.now())
))
@RequiresApi(Build.VERSION_CODES.O)
val historyData: StateFlow<List<WeightRecord>> = _historyData
@RequiresApi(Build.VERSION_CODES.O)
fun addWeightRecord(newRecord: WeightRecord) {
val newRecords = _historyData.value.toMutableList()
newRecords.add(newRecord)
_historyData.value = newRecords
Log.e(TAG, "$newRecord")
Log.e(TAG, "${_historyData.value}")
}
}

View File

@ -1,4 +1,13 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("io.objectbox:objectbox-gradle-plugin:3.8.0")
}
}
plugins {
id("com.android.application") version "8.2.2" apply false
id("org.jetbrains.kotlin.android") version "1.9.0" apply false