Лаб 2 выглядит как предварительный конец 2 лабы

This commit is contained in:
Kate 2023-10-12 09:00:15 +04:00
parent 16d85c07d0
commit b20055a9c7
22 changed files with 554 additions and 115 deletions

Binary file not shown.

View File

@ -9,38 +9,28 @@
<option name="autoReloadType" value="NONE" />
</component>
<component name="ChangeListManager">
<list default="true" id="dc3793c7-c725-42e8-8eda-044c95f334c1" name="Changes" comment="Лаб 2 нало работы с пользователем">
<change afterPath="$PROJECT_DIR$/.idea/inspectionProfiles/Project_Default.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/composeui/CreatePet.kt" afterDir="false" />
<change afterPath="$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/models/user/composeui/PetList.kt" afterDir="false" />
<change afterPath="$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/models/user/model/Pet.kt" afterDir="false" />
<change afterPath="$PROJECT_DIR$/app/src/main/res/drawable/pet1.jpg" afterDir="false" />
<change afterPath="$PROJECT_DIR$/app/src/main/res/drawable/pet2.jpg" afterDir="false" />
<change afterPath="$PROJECT_DIR$/app/src/main/res/drawable/pet3.jpg" afterDir="false" />
<change afterPath="$PROJECT_DIR$/app/src/main/res/drawable/pet4.jpg" afterDir="false" />
<change afterPath="$PROJECT_DIR$/app/src/main/res/drawable/pet5.jpg" afterDir="false" />
<change afterPath="$PROJECT_DIR$/app/src/main/res/drawable/pet6.jpg" afterDir="false" />
<change afterPath="$PROJECT_DIR$/app/src/main/res/drawable/pet7.jpg" afterDir="false" />
<change afterPath="$PROJECT_DIR$/app/src/main/res/drawable/pet8.jpg" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.gradle/8.0/checksums/checksums.lock" beforeDir="false" afterPath="$PROJECT_DIR$/.gradle/8.0/checksums/checksums.lock" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.gradle/8.0/checksums/md5-checksums.bin" beforeDir="false" afterPath="$PROJECT_DIR$/.gradle/8.0/checksums/md5-checksums.bin" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.gradle/8.0/checksums/sha1-checksums.bin" beforeDir="false" afterPath="$PROJECT_DIR$/.gradle/8.0/checksums/sha1-checksums.bin" afterDir="false" />
<list default="true" id="dc3793c7-c725-42e8-8eda-044c95f334c1" name="Changes" comment="Лаб 2 питомцы просто добавлены">
<change afterPath="$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/composeui/EditPet.kt" afterDir="false" />
<change afterPath="$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/composeui/PlayPet.kt" afterDir="false" />
<change afterPath="$PROJECT_DIR$/app/src/main/res/drawable/avatar.jpg" afterDir="false" />
<change afterPath="$PROJECT_DIR$/report/~$Lab1.docx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.gradle/8.0/executionHistory/executionHistory.bin" beforeDir="false" afterPath="$PROJECT_DIR$/.gradle/8.0/executionHistory/executionHistory.bin" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.gradle/8.0/executionHistory/executionHistory.lock" beforeDir="false" afterPath="$PROJECT_DIR$/.gradle/8.0/executionHistory/executionHistory.lock" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.gradle/8.0/fileHashes/fileHashes.bin" beforeDir="false" afterPath="$PROJECT_DIR$/.gradle/8.0/fileHashes/fileHashes.bin" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.gradle/8.0/fileHashes/fileHashes.lock" beforeDir="false" afterPath="$PROJECT_DIR$/.gradle/8.0/fileHashes/fileHashes.lock" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.gradle/8.0/fileHashes/resourceHashesCache.bin" beforeDir="false" afterPath="$PROJECT_DIR$/.gradle/8.0/fileHashes/resourceHashesCache.bin" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.gradle/buildOutputCleanup/buildOutputCleanup.lock" beforeDir="false" afterPath="$PROJECT_DIR$/.gradle/buildOutputCleanup/buildOutputCleanup.lock" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.gradle/buildOutputCleanup/outputFiles.bin" beforeDir="false" afterPath="$PROJECT_DIR$/.gradle/buildOutputCleanup/outputFiles.bin" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.gradle/file-system.probe" beforeDir="false" afterPath="$PROJECT_DIR$/.gradle/file-system.probe" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/build.gradle.kts" beforeDir="false" afterPath="$PROJECT_DIR$/app/build.gradle.kts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/composeui/CreatePet.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/composeui/CreatePet.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/composeui/Home.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/composeui/Home.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/composeui/Profile.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/composeui/Profile.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/composeui/navigation/MyPage.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/composeui/navigation/MyPage.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/composeui/navigation/Screen.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/composeui/navigation/Screen.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/models/user/composeui/UserList.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/models/user/composeui/UserList.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/models/user/model/Student.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/models/user/model/User.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/models/user/composeui/PetList.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/models/user/composeui/PetList.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/models/user/model/Pet.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/models/user/model/Pet.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/models/user/model/User.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/models/user/model/User.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/res/values/strings.xml" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/res/values/strings.xml" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
@ -95,8 +85,8 @@
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="Kotlin Class" />
<option value="Kotlin File" />
<option value="Kotlin Class" />
</list>
</option>
</component>
@ -112,7 +102,7 @@
<option name="stateVersion" value="1" />
</component>
<component name="ProblemsViewState">
<option name="selectedTabId" value="CurrentFile" />
<option name="selectedTabId" value="ProjectErrors" />
</component>
<component name="ProjectId" id="2WToW0mvjPzND9QiCAmC6MXKLwF" />
<component name="ProjectLevelVcsManager">
@ -131,17 +121,20 @@
"SHARE_PROJECT_CONFIGURATION_FILES": "true",
"cidr.known.project.marker": "true",
"com.android.tools.idea.devicemanager.tab": "Physical",
"last_opened_file_path": "C:/Users/Kate/AndroidStudioProjects/Ihonkina_PIbd-31_PMU/app/src/main/java/com/example/pmuapp/models/user/composeui",
"last_opened_file_path": "C:/Users/Kate/AndroidStudioProjects/Ihonkina_PIbd-31_PMU/app/src/main/java/com/example/pmuapp/composeui/navigation",
"settings.editor.selected.configurable": "experimental"
}
}]]></component>
<component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS">
<recent name="C:\Users\Kate\AndroidStudioProjects\Ihonkina_PIbd-31_PMU\app\src\main\java\com\example\pmuapp\composeui\navigation" />
<recent name="C:\Users\Kate\AndroidStudioProjects\Ihonkina_PIbd-31_PMU\app\src\main\java\com\example\pmuapp\models\user\composeui" />
<recent name="C:\Users\Kate\AndroidStudioProjects\Ihonkina_PIbd-31_PMU\app\src\main\java\com\example\pmuapp\composeui" />
<recent name="C:\Users\Kate\AndroidStudioProjects\Ihonkina_PIbd-31_PMU\app\src\main\res\drawable" />
<recent name="C:\Users\Kate\AndroidStudioProjects\Ihonkina_PIbd-31_PMU\app\src\main\java\com\example\pmuapp" />
<recent name="C:\Users\Kate\AndroidStudioProjects\Ihonkina_PIbd-31_PMU" />
</key>
<key name="MoveFile.RECENT_KEYS">
<recent name="C:\Users\Kate\AndroidStudioProjects\Ihonkina_PIbd-31_PMU\app\src\main\java\com\example\pmuapp\composeui" />
</key>
<key name="MoveKotlinTopLevelDeclarationsDialog.RECENTS_KEY">
<recent name="com.example.pmuapp.composeui" />
@ -255,7 +248,14 @@
<option name="project" value="LOCAL" />
<updated>1697041852651</updated>
</task>
<option name="localTasksCounter" value="5" />
<task id="LOCAL-00005" summary="Лаб 2 питомцы просто добавлены">
<created>1697054812374</created>
<option name="number" value="00005" />
<option name="presentableId" value="LOCAL-00005" />
<option name="project" value="LOCAL" />
<updated>1697054812374</updated>
</task>
<option name="localTasksCounter" value="6" />
<servers />
</component>
<component name="Vcs.Log.Tabs.Properties">
@ -287,17 +287,7 @@
<MESSAGE value="добавление отчета лаб 1" />
<MESSAGE value="Лаб 2 начало" />
<MESSAGE value="Лаб 2 нало работы с пользователем" />
<option name="LAST_COMMIT_MESSAGE" value="Лаб 2 нало работы с пользователем" />
</component>
<component name="XDebuggerManager">
<breakpoint-manager>
<breakpoints>
<line-breakpoint enabled="true" type="kotlin-line">
<url>file://$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/composeui/CreatePet.kt</url>
<line>73</line>
<option name="timeStamp" value="1" />
</line-breakpoint>
</breakpoints>
</breakpoint-manager>
<MESSAGE value="Лаб 2 питомцы просто добавлены" />
<option name="LAST_COMMIT_MESSAGE" value="Лаб 2 питомцы просто добавлены" />
</component>
</project>

View File

@ -5,12 +5,13 @@ plugins {
android {
namespace = "com.example.pmuapp"
compileSdk = 33
compileSdk = 34
defaultConfig {
applicationId = "com.example.pmuapp"
minSdk = 24
targetSdk = 33
targetSdk = 34
versionCode = 1
versionName = "1.0"
@ -50,6 +51,7 @@ android {
}
dependencies {
implementation ("io.coil-kt:coil-compose:1.4.0")
implementation("androidx.core:core-ktx:1.9.0")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
@ -62,6 +64,7 @@ dependencies {
implementation("androidx.compose.material3:material3")
implementation("com.google.android.engage:engage-core:1.3.0")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("androidx.compose.ui:ui-graphics-android:1.5.3")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")

View File

@ -10,13 +10,14 @@ import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import com.example.pmuapp.R
import com.example.pmuapp.models.user.model.Pet
import com.example.pmuapp.models.user.model.User
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun CreatePet(onSaveClick: (Pet) -> Unit) {
fun CreatePet(navController: NavController, onSaveClick: (Pet) -> Unit) {
var selectedImage by remember { mutableStateOf(R.drawable.pet1) }
var petName by remember { mutableStateOf("") }
@ -72,10 +73,13 @@ fun CreatePet(onSaveClick: (Pet) -> Unit) {
Button(
onClick = {
if (petName.isNotEmpty()) {
val newPet = Pet(0, petName, selectedImage)
val newPet = Pet(0, petName, selectedImage, "")
onSaveClick(newPet)
petName = ""
selectedImage = R.drawable.pet1
// Навигация назад на предыдущую страницу
navController.popBackStack()
}
},
modifier = Modifier.fillMaxWidth()

View File

@ -0,0 +1,117 @@
package com.example.pmuapp.composeui
import android.os.Build
import android.os.Build.*
import androidx.annotation.RequiresApi
import androidx.compose.foundation.Image
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.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.Composable
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.res.painterResource
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.example.pmuapp.composeui.navigation.Screen
import com.example.pmuapp.models.user.model.AuthViewModel
import com.example.pmuapp.models.user.model.PetViewModel
import com.example.pmuapp.models.user.model.UserViewModel
@RequiresApi(VERSION_CODES.O)
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun EditPet(navController: NavController ,authViewModel: AuthViewModel, petViewModel: PetViewModel, userViewModel: UserViewModel, petId: Int) {
val pet = (authViewModel.currentUser?.petId ?: emptyList()).find { it.id == petId }
var petName by remember { mutableStateOf(pet?.name ?: "") }
var petNotes by remember { mutableStateOf(pet?.notes ?: "") }
Column(
modifier = Modifier
.fillMaxSize()
.padding(10.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
// Отображение изображения (здесь предполагается, что у вас есть доступ к `availablePetImages` по индексу)
val imageResId = pet?.imageResId ?: 0
Image(
painter = painterResource(id = imageResId),
contentDescription = null,
modifier = Modifier
.fillMaxWidth()
.height(200.dp)
)
// Поле ввода имени
OutlinedTextField(
value = petName,
onValueChange = { petName = it },
label = { Text("Имя питомца") },
modifier = Modifier
.fillMaxWidth()
.padding(top = 8.dp)
)
// Текст "Заметка о питомце"
Text(
text = "Заметка о питомце",
style = TextStyle(fontSize = 16.sp),
modifier = Modifier.padding(top = 8.dp)
)
// Поле ввода заметок
TextField(
value = petNotes,
onValueChange = { petNotes = it },
label = { Text("Заметки") },
modifier = Modifier
.fillMaxWidth()
.padding(top = 8.dp)
.heightIn(max = 200.dp) // Заметка будет растянута до конца экрана
.padding(16.dp),
readOnly = false // Сделаем его доступным для редактирования
)
Spacer(modifier = Modifier.weight(1f)) // Заполнитель для размещения кнопки внизу
// Кнопка "Изменить"
// Кнопка "Сохранить"
val editedPetId = Screen.PlayPet.route.replace("{id}", pet?.id.toString())
Button(
onClick = {
// Создаем обновленную версию питомца с введенными данными
val updatedPet = pet?.copy(name = petName, notes = petNotes) ?: return@Button
// Вызываем функцию для обновления питомца в вашей ViewModel (в данном случае, в petViewModel)
petViewModel.updatePet(updatedPet)
userViewModel.updatePetOnUser(authViewModel.currentUser?.id ?: -1, updatedPet)
authViewModel.currentUser=userViewModel.getUser(authViewModel.currentUser?.id ?: -1)
// Дополнительные действия после обновления, например, переход на другой экран
val petId = Screen.EditPet.route.replace("{id}", pet.id.toString())
navController?.navigate(editedPetId)
},
modifier = Modifier.padding(16.dp)
) {
Text("Сохранить")
}
}
}

View File

@ -1,39 +1,25 @@
package com.example.pmuapp.composeui
import android.content.Intent
import android.content.res.Configuration
import android.net.Uri
import android.provider.ContactsContract.Profile
import android.widget.TextView
import androidx.compose.foundation.clickable
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.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.navigation.NavController
import com.example.pmuapp.R
import com.example.pmuapp.composeui.navigation.Screen
import com.example.pmuapp.models.user.composeui.PetList
import com.example.pmuapp.models.user.model.AuthViewModel
import com.example.pmuapp.ui.theme.PMUappTheme
import com.example.pmuapp.models.user.model.PetViewModel
import com.example.pmuapp.models.user.model.UserViewModel
@Composable
fun Home(navController: NavController, authViewModel: AuthViewModel) {
fun Home(navController: NavController, authViewModel: AuthViewModel, petViewModel:PetViewModel, userViewModel:UserViewModel) {
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
@ -51,7 +37,7 @@ fun Home(navController: NavController, authViewModel: AuthViewModel) {
Spacer(modifier = Modifier.height(16.dp))
// Вывод списка питомцев
PetList(navController, authViewModel)
PetList(navController,authViewModel, petViewModel, userViewModel, authViewModel.currentUser?.id ?: -1)
}
}

View File

@ -0,0 +1,96 @@
package com.example.pmuapp.composeui
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column
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.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
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.example.pmuapp.composeui.navigation.Screen
import com.example.pmuapp.models.user.model.AuthViewModel
import com.example.pmuapp.models.user.model.PetViewModel
import com.example.pmuapp.models.user.model.UserViewModel
@RequiresApi(Build.VERSION_CODES.O)
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun PlayPet(navController: NavController,authViewModel: AuthViewModel, petViewModel: PetViewModel, userViewModel: UserViewModel, petId: Int) {
val pet = (authViewModel.currentUser?.petId ?: emptyList()).find { it.id == petId }
Column(
modifier = Modifier
.fillMaxSize()
.padding(10.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
// Отображение изображения (здесь предполагается, что у вас есть доступ к `availablePetImages` по индексу)
val imageResId = pet?.imageResId ?: 0
Image(
painter = painterResource(id = imageResId),
contentDescription = null,
modifier = Modifier
.fillMaxWidth()
.height(200.dp)
)
// Отображение имени
Text(
text = pet?.name ?: "",
style = TextStyle(fontWeight = FontWeight.Bold, fontSize = 24.sp),
modifier = Modifier.padding(top = 8.dp)
)
// Текст "Заметка о питомце"
Text(
text = "Заметка о питомце",
style = TextStyle(fontSize = 16.sp),
modifier = Modifier.padding(top = 8.dp)
)
// Отображение заметок
TextField(
value = pet?.notes ?: "",
onValueChange = { /* Обработка изменения текста, если необходимо */ },
modifier = Modifier
.fillMaxWidth()
.padding(top = 8.dp)
.heightIn(max = 200.dp) // Заметка будет растянута до конца экрана
.padding(16.dp),
readOnly = true
)
Spacer(modifier = Modifier.weight(1f)) // Заполнитель для размещения кнопки внизу
val petId = Screen.EditPet.route.replace("{id}", pet?.id.toString())
// Кнопка "Изменить"
Button(
onClick = {
// Перейти на страницу "играть" с передачей petId как аргумент
navController?.navigate(petId)
// Обработка нажатия кнопки "Изменить"
},
modifier = Modifier.padding(16.dp)
) {
Text("Изменить")
}
}
}

View File

@ -1,36 +1,26 @@
package com.example.pmuapp.composeui
import android.annotation.SuppressLint
import android.content.Intent
import android.content.res.Configuration
import android.net.Uri
import android.provider.ContactsContract.Profile
import android.widget.TextView
import androidx.compose.foundation.clickable
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.Image
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.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import com.example.pmuapp.R
import coil.compose.rememberImagePainter
import com.example.pmuapp.models.user.model.User
import com.example.pmuapp.ui.theme.PMUappTheme
@OptIn(ExperimentalMaterial3Api::class)
@SuppressLint("RememberReturnType")
@ -45,6 +35,38 @@ fun Profile(currentUser: User?, onSaveClick: (User) -> Unit) {
.fillMaxSize()
.padding(16.dp)
) {
currentUser?.let { user ->
Image(
painter = rememberImagePainter(data = user.imageResId),
contentDescription = null,
modifier = Modifier
.fillMaxWidth()
.height(200.dp)
)
}
// State to hold the selected image URI
val selectedImageUri = remember { mutableStateOf<Uri?>(null) }
// Create an ActivityResultLauncher to handle image selection
val imagePickerLauncher = rememberLauncherForActivityResult(ActivityResultContracts.GetContent()) { result: Uri? ->
result?.let { uri ->
selectedImageUri.value = uri
}
}
// Button to open the image picker
Button(
onClick = {
// Request permission to access the device's storage
// Open the image picker
imagePickerLauncher.launch("image/*")
},
modifier = Modifier.fillMaxWidth()
) {
Text("Загрузить фото")
}
TextField(
value = nameState.value,
onValueChange = { nameState.value = it },
@ -67,7 +89,6 @@ fun Profile(currentUser: User?, onSaveClick: (User) -> Unit) {
value = passwordState.value,
onValueChange = { passwordState.value = it },
label = { Text("Password") },
visualTransformation = PasswordVisualTransformation(),
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 16.dp)
@ -80,7 +101,8 @@ fun Profile(currentUser: User?, onSaveClick: (User) -> Unit) {
nameState.value,
loginState.value,
passwordState.value,
currentUser?.petId ?: emptyList()
currentUser?.petId ?: emptyList(),
selectedImageUri.value?.toString() ?: "", // Use the selected image URI
)
onSaveClick(updatedUser) // Вызывает функцию updateUser в UserViewModel
},
@ -88,7 +110,5 @@ fun Profile(currentUser: User?, onSaveClick: (User) -> Unit) {
) {
Text("Сохранить")
}
}
}

View File

@ -2,7 +2,11 @@ package com.example.pmuapp.composeui.navigation
import CreatePet
import android.content.res.Configuration
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
@ -20,6 +24,7 @@ import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
@ -34,13 +39,15 @@ import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import com.example.pmuapp.R
import com.example.pmuapp.composeui.EditPet
import com.example.pmuapp.composeui.Home
import com.example.pmuapp.composeui.Login
import com.example.pmuapp.composeui.PlayPet
import com.example.pmuapp.composeui.Profile
import com.example.pmuapp.models.user.composeui.StudentView
import com.example.pmuapp.models.user.composeui.PetList
import com.example.pmuapp.models.user.composeui.UserList
import com.example.pmuapp.models.user.model.AuthViewModel
import com.example.pmuapp.models.user.model.User
import com.example.pmuapp.models.user.model.PetViewModel
import com.example.pmuapp.models.user.model.UserViewModel
import com.example.pmuapp.ui.theme.PMUappTheme
@ -59,14 +66,27 @@ fun Topbar(
Text(stringResource(currentScreen?.resourceId ?: R.string.app_name))
},
navigationIcon = {
if (
if (currentScreen == Screen.PlayPet) {
IconButton(
onClick = {
// Перейти на главный экран
navController.navigate(Screen.Home.route)
}
) {
Icon(
imageVector = Icons.Default.ArrowBack,
contentDescription = "Back",
tint = MaterialTheme.colorScheme.onPrimary
)
}
} else if (
navController.previousBackStackEntry != null
&& (currentScreen == null || !currentScreen.showInBottomBar)
) {
IconButton(onClick = { navController.navigateUp() }) {
Icon(
imageVector = Icons.Filled.ArrowBack,
contentDescription = null,
imageVector = Icons.Default.ArrowBack,
contentDescription = "Back",
tint = MaterialTheme.colorScheme.onPrimary
)
}
@ -101,12 +121,14 @@ fun Navbar(
}
}
@RequiresApi(Build.VERSION_CODES.O)
@Composable
fun NavHost(
navController: NavHostController,
innerPadding: PaddingValues,
authViewModel: AuthViewModel, // Передайте AuthViewModel как параметр
userViewModel: UserViewModel // Передайте UserViewModel как параметр
userViewModel: UserViewModel,
petViewModel: PetViewModel// Передайте UserViewModel как параметр
) {
NavHost(
navController = navController,
@ -124,6 +146,7 @@ userViewModel: UserViewModel // Передайте UserViewModel как пара
onSaveClick = { updatedUser ->
userViewModel.updateUser(updatedUser)
authViewModel.currentUser = updatedUser
navController.navigate(Screen.Profile.route)
}
)
} else {
@ -132,11 +155,12 @@ userViewModel: UserViewModel // Передайте UserViewModel как пара
}
composable(Screen.UserList.route) { UserList(navController, userViewModel) }
composable(Screen.Home.route) { Home(navController, authViewModel) }
composable(Screen.Home.route) { Home(navController, authViewModel,petViewModel,userViewModel) }
composable(Screen.CreatePet.route) {
val currentUser = authViewModel.currentUser ?: userViewModel.getUsers().firstOrNull()
CreatePet ( onSaveClick = { newPet ->
userViewModel.addPetToUser(currentUser?.id ?:0, newPet)
CreatePet ( navController, onSaveClick = { newPet ->
var adedPet = petViewModel.createPet(newPet)
userViewModel.addPetToUser(currentUser?.id ?:0, adedPet)
authViewModel.currentUser = userViewModel.getUser(currentUser?.id ?:0)
}
)
@ -147,8 +171,32 @@ userViewModel: UserViewModel // Передайте UserViewModel как пара
Screen.UserView.route,
arguments = listOf(navArgument("id") { type = NavType.IntType })
) { backStackEntry ->
backStackEntry.arguments?.let { StudentView(userViewModel.getUsers()[it.getInt("id")]) }
val userId = backStackEntry.arguments?.getInt("id") ?: -1
Box(
contentAlignment = Alignment.TopCenter, // Центрировать содержимое по горизонтали и сверху
modifier = Modifier.fillMaxSize()
) {
PetList(navController,authViewModel, petViewModel, userViewModel, userId)
}
}
composable(
Screen.PlayPet.route,
arguments = listOf(navArgument("id") { type = NavType.IntType })
) { backStackEntry ->
val petId = backStackEntry.arguments?.getInt("id") ?: -1
PlayPet(navController,authViewModel, petViewModel, userViewModel, petId)
}
composable(
Screen.EditPet.route,
arguments = listOf(navArgument("id") { type = NavType.IntType })
) { backStackEntry ->
val petId = backStackEntry.arguments?.getInt("id") ?: -1
EditPet(navController,authViewModel, petViewModel, userViewModel, petId)
}
}
}
@ -158,6 +206,7 @@ fun MainNavbar() {
val navController = rememberNavController()
val authViewModel = remember { AuthViewModel() }
val userViewModel =remember {UserViewModel() }// Создайте экземпляр AuthViewModel
val petViewModel = remember {PetViewModel()}
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentDestination = navBackStackEntry?.destination
val currentScreen = currentDestination?.route?.let { Screen.getItem(it) }
@ -172,7 +221,7 @@ fun MainNavbar() {
}
}
) { innerPadding ->
NavHost(navController, innerPadding, authViewModel, userViewModel)
NavHost(navController, innerPadding, authViewModel, userViewModel, petViewModel )
}
}

View File

@ -27,15 +27,22 @@ enum class Screen(
"profile", R.string.user_my_title, Icons.Filled.Person
),
UserView(
"student-view/{id}", R.string.user_view_title, showInBottomBar = false
"user-view/{id}", R.string.user_view_title, showInBottomBar = false
),
Login(
"login", R.string.login_title, showInBottomBar = false
),
CreatePet(
"createpet", R.string.create_pet_title, showInBottomBar = false
),
PlayPet(
"playpet/{id}", R.string.play_pet_title,showInBottomBar = false
),
EditPet(
"editpet/{id}", R.string.edit_pet_title,showInBottomBar = false
);
companion object {
val bottomBarItems = listOf(
UserList,

View File

@ -1,55 +1,72 @@
package com.example.pmuapp.models.user.composeui
import android.content.res.Configuration
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
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.example.pmuapp.composeui.navigation.Screen
import com.example.pmuapp.models.user.model.AuthViewModel
import com.example.pmuapp.models.user.model.PetViewModel
import com.example.pmuapp.models.user.model.User
import com.example.pmuapp.models.user.model.UserViewModel
import com.example.pmuapp.ui.theme.PMUappTheme
@OptIn(ExperimentalFoundationApi::class, ExperimentalLayoutApi::class)
@Composable
fun PetList(navController: NavController?, authViewModel: AuthViewModel) {
val currentUser = authViewModel.currentUser
val pets = currentUser?.petId.orEmpty()
fun PetList(navController: NavController, authViewModel: AuthViewModel, petViewModel: PetViewModel, userViewModel: UserViewModel, userId: Int) {
val currentUser = userViewModel.getUser(userId)
var pets = currentUser.petId
LazyColumn(
verticalArrangement = Arrangement.Center, // Центрировать элементы по вертикали
horizontalAlignment = Alignment.CenterHorizontally // Центрировать элементы по горизонтали
) {
if (userId != authViewModel.currentUser?.id ?: -1) {
item {
// Добавляем большой текст с именем пользователя
Text(
text = currentUser?.name + " (" + currentUser.login + ")",
style = TextStyle(
fontSize = 24.sp,
fontWeight = FontWeight.Bold
),
modifier = Modifier.padding(16.dp)
)
}
}
LazyColumn {
item {
FlowRow(
) {
FlowRow() {
pets.forEach { pet ->
val imageId = pet.imageResId
val petName = pet.name
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.padding(8.dp)
modifier = Modifier.padding(8.dp)
) {
Image(
painter = painterResource(id = imageId),
@ -61,6 +78,43 @@ fun PetList(navController: NavController?, authViewModel: AuthViewModel) {
text = petName,
modifier = Modifier.padding(top = 4.dp)
)
if (userId == authViewModel.currentUser?.id ?: -1) {
val petId = Screen.PlayPet.route.replace("{id}", pet.id.toString())
Button(
onClick = {
// Перейти на страницу "играть" с передачей petId как аргумент
navController?.navigate(petId)
},
// modifier = Modifier.fillMaxWidth()
) {
Text("Играть")
}
// Кнопка удаления питомца
IconButton(
onClick = {
// Вызывает функцию удаления питомца из PetViewModel
petViewModel.deletePet(pet)
userViewModel.deletePet(
currentUser?.id
?: 0,
pet.id
)
authViewModel.currentUser =
userViewModel.getUser(
currentUser?.id
?: 0
)
}
) {
Icon(
imageVector = Icons.Default.Delete,
contentDescription = "Удалить"
)
}
}
}
}
}

View File

@ -4,13 +4,65 @@ import android.media.Image
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import com.example.pmuapp.R
import java.io.Serializable
data class Pet(
val id: Int,
var id: Int,
val name: String,
val imageResId: Int
val imageResId: Int,
val notes: String
) : Serializable
class PetViewModel : ViewModel() {
var pets: MutableState<List<Pet>> = mutableStateOf(
emptyList()
)
val availablePetImages: List<Int> = listOf(
R.drawable.pet1,
R.drawable.pet2,
R.drawable.pet3,
R.drawable.pet4,
R.drawable.pet5,
R.drawable.pet6,
R.drawable.pet7,
R.drawable.pet8,
)
fun createPet(newPet: Pet): Pet {
newPet.id = pets.value.size.toInt()
val updatedPets = pets.value.toMutableList()
updatedPets.add(newPet)
pets.value = updatedPets
return newPet
}
fun deletePet(pet: Pet) {
val updatedPets = pets.value.toMutableList()
updatedPets.remove(pet)
pets.value = updatedPets
}
fun updatePet(updatedPet: Pet) {
val updatedPets = pets.value.toMutableList()
val index = updatedPets.indexOfFirst { it.id == updatedPet.id }
if (index != -1) {
updatedPets[index] = updatedPet
pets.value = updatedPets
}
}
}
// fun updateUser(updatedUser: User) {
// val updatedUsers = users.value.toMutableList()
// val index = updatedUsers.indexOfFirst { it.login == updatedUser.login }
// if (index != -1) {
// updatedUsers[index] = updatedUser
// users.value = updatedUsers
// }
// }

View File

@ -1,5 +1,6 @@
package com.example.pmuapp.models.user.model
import android.net.Uri
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
@ -11,15 +12,19 @@ data class User(
val name: String,
val login: String,
val password: String,
val petId: List<Pet>
val petId: List<Pet>,
val imageResId: String // Добавляем поле для хранения ID ресурса изображения пользователя
) : Serializable
class UserViewModel : ViewModel() {
val imageUri: Uri = Uri.parse("android.resource://com.example.pmuapp/${R.drawable.avatar}")
var users: MutableState<List<User>> = mutableStateOf(
listOf(
User(0,"Иван", "ivan", "111111", emptyList()),
User(1,"Анна", "ann", "111111", emptyList()),
User(2,"Лиза", "liza", "111111",emptyList())
User(0,"Иван", "ivan", "111111", emptyList(),imageUri.toString()),
User(1,"Анна", "ann", "111111", emptyList(),imageUri.toString()),
User(2,"Лиза", "liza", "111111",emptyList(),imageUri.toString())
)
)
val availablePetImages: List<Int> = listOf(
@ -56,6 +61,58 @@ class UserViewModel : ViewModel() {
users.value = updatedUsers
}
}
fun deletePet(userId: Int, petIdToDelete: Int) {
val updatedUsers = users.value.toMutableList()
// Найдем пользователя по userId
val user = updatedUsers.find { it.id == userId }
user?.let { user ->
val updatedPets = user.petId.toMutableList()
// Найдем питомца по petId и удалим его из списка питомцев
val petToDelete = updatedPets.find { it.id == petIdToDelete }
petToDelete?.let { pet ->
updatedPets.remove(pet)
}
// Обновим пользователя с обновленным списком питомцев
val updatedUser = user.copy(petId = updatedPets)
// Обновим список пользователей
val userIndex = updatedUsers.indexOf(user)
updatedUsers[userIndex] = updatedUser
users.value = updatedUsers
}
}
fun updatePetOnUser(userId: Int, updatedPet: Pet) {
val updatedUsers = users.value.toMutableList()
// Найдем пользователя по userId
val user = updatedUsers.find { it.id == userId }
user?.let { user ->
val updatedPets = user.petId.toMutableList()
// Найдем питомца по petId и обновим его
val petToUpdate = updatedPets.find { it.id == updatedPet.id }
petToUpdate?.let { pet ->
val petIndex = updatedPets.indexOf(pet)
updatedPets[petIndex] = updatedPet
}
// Обновим пользователя с обновленным списком питомцев
val updatedUser = user.copy(petId = updatedPets)
// Обновим список пользователей
val userIndex = updatedUsers.indexOf(user)
updatedUsers[userIndex] = updatedUser
users.value = updatedUsers
}
}
fun updateUser(updatedUser: User) {
val updatedUsers = users.value.toMutableList()

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

@ -9,12 +9,16 @@
<string name="user_my_title">Мой профиль</string>
<string name="login_title">Авторизация</string>
<string name="create_pet_title">Создание питомца</string>
<string name="pet_notes">Заметка питомца</string>
<string name="play_pet_title">Мой питомец</string>
<string name="edit_pet_title">Изменение питомца</string>
<string name="about_text">
<p>Это текст <b>о нас</b>!</p>\n\n
<p>Здесь могла быть Ваша реклама!</p>\n\n
<p>Наш сайт <a href="https://ulstu.ru">ulstu.ru</a></p>
</string>
<string-array name="available_pet_images">
<item>@drawable/avatar</item>
<item>@drawable/pet1</item>
<item>@drawable/pet2</item>
<item>@drawable/pet3</item>

BIN
report/~$Lab1.docx Normal file

Binary file not shown.