Compare commits

..

2 Commits
main ... lab2

Author SHA1 Message Date
0e04a5eba1 Загрузка отчета по лабораторной 2. 2023-12-23 10:26:13 +04:00
ksenianeva
86be093a35 2nd lab 2023-11-21 23:50:31 +04:00
14 changed files with 493 additions and 4 deletions

View File

@ -47,11 +47,12 @@ android {
}
dependencies {
implementation("androidx.core:core-ktx:1.9.0")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.1")
implementation("androidx.activity:activity-compose:1.7.0")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
implementation("androidx.activity:activity-compose:1.7.2")
implementation(platform("androidx.compose:compose-bom:2023.03.00"))
implementation("androidx.navigation:navigation-compose:2.6.0")
implementation("io.coil-kt:coil-compose:2.4.0")
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-graphics")
implementation("androidx.compose.ui:ui-tooling-preview")

View File

@ -10,6 +10,7 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.example.myapplication.composeui.navigation.MainNavbar
import com.example.myapplication.ui.theme.MyApplicationTheme
class MainActivity : ComponentActivity() {
@ -19,7 +20,7 @@ class MainActivity : ComponentActivity() {
MyApplicationTheme {
// A surface container using the 'background' color from the theme
Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) {
Greeting("World")
MainNavbar()
}
}
}

View File

@ -0,0 +1,47 @@
package com.example.myapplication.category.composeui
import android.content.res.Configuration
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
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.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import com.example.myapplication.category.model.getTestCategory
import com.example.myapplication.ui.theme.MyApplicationTheme
@Composable
fun CategoriesList(navController: NavController?) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.padding(all = 10.dp)
.verticalScroll(rememberScrollState())) {
getTestCategory().forEachIndexed() { _, category ->
Row(Modifier.padding(all = 20.dp)) {
Text(category.category_name)
}
}
}
}
@Preview(name = "Light Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO)
@Preview(name = "Dark Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
fun CategoryPreview() {
MyApplicationTheme {
Surface(
color = MaterialTheme.colorScheme.background
) {
CategoriesList(navController = null)
}
}
}

View File

@ -0,0 +1,15 @@
package com.example.myapplication.category.model
import java.io.Serializable
data class Category(
val category_name: String,
) : Serializable
fun getTestCategory(): List<Category> {
return listOf(
Category("Отжимания"),
Category("Кардио"),
Category("Силовые")
)
}

View File

@ -0,0 +1,19 @@
package com.example.myapplication.challenge.model
import com.example.myapplication.category.model.Category
import java.io.Serializable
data class Challenge(
val challenge_name: String,
val challenge_status: Boolean,
val category: Category,
) : Serializable
fun getTestChallenge(): List<Challenge> {
val сategory = Category("Отжимания")
return listOf(
Challenge("Сделать 20 отжиманий", false, сategory),
Challenge("Сделать 10 отжиманий", false, сategory),
Challenge("Сделать 5 отжиманий", false, сategory),
)
}

View File

@ -0,0 +1,46 @@
package com.example.myapplication.composeui
import android.content.res.Configuration
import android.widget.TextView
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import com.example.myapplication.ui.theme.MyApplicationTheme
import com.example.myapplication.R;
@Composable
fun About() {
val localContext = LocalContext.current
val aboutText = localContext.resources.getText(R.string.about_text)
Column(Modifier.padding(all = 10.dp)) {
AndroidView(
modifier = Modifier
.fillMaxWidth(),
factory = { context -> TextView(context) },
update = { it.text = aboutText }
)
}
}
@Preview(name = "Light Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO)
@Preview(name = "Dark Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
fun AboutPreview() {
MyApplicationTheme {
Surface(
color = MaterialTheme.colorScheme.background
) {
About()
}
}
}

View File

@ -0,0 +1,154 @@
package com.example.myapplication.composeui.navigation
import android.content.res.Configuration
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.Scaffold
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.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.navigation.NavDestination
import androidx.navigation.NavDestination.Companion.hierarchy
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavHostController
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import com.example.myapplication.R
import com.example.myapplication.category.composeui.CategoriesList
import com.example.myapplication.composeui.About
import com.example.myapplication.ui.theme.MyApplicationTheme
import com.example.myapplication.user.composeui.UserView
import com.example.myapplication.user.composeui.UsersList
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun Topbar(
navController: NavHostController,
currentScreen: Screen?
) {
TopAppBar(
colors = TopAppBarDefaults.smallTopAppBarColors(
containerColor = MaterialTheme.colorScheme.primary,
titleContentColor = MaterialTheme.colorScheme.onPrimary,
),
title = {
Text(stringResource(currentScreen?.resourceId ?: R.string.app_name))
},
navigationIcon = {
if (
navController.previousBackStackEntry != null
&& (currentScreen == null || !currentScreen.showInBottomBar)
) {
IconButton(onClick = { navController.navigateUp() }) {
Icon(
imageVector = Icons.Filled.ArrowBack,
contentDescription = null,
tint = MaterialTheme.colorScheme.onPrimary
)
}
}
}
)
}
@Composable
fun Navbar(
navController: NavHostController,
currentDestination: NavDestination?,
modifier: Modifier = Modifier
) {
NavigationBar(modifier) {
Screen.bottomBarItems.forEach { screen ->
NavigationBarItem(
icon = { Icon(screen.icon, contentDescription = null) },
label = { Text(stringResource(screen.resourceId)) },
selected = currentDestination?.hierarchy?.any { it.route == screen.route } == true,
onClick = {
navController.navigate(screen.route) {
popUpTo(navController.graph.findStartDestination().id) {
saveState = true
}
launchSingleTop = true
restoreState = true
}
}
)
}
}
}
@Composable
fun Navhost(
navController: NavHostController,
innerPadding: PaddingValues, modifier:
Modifier = Modifier
) {
NavHost(
navController,
startDestination = Screen.About.route,
modifier.padding(innerPadding)
) {
composable(Screen.CategoryList.route) { CategoriesList(navController)}
composable(Screen.About.route) { About() }
composable(Screen.UserList.route) { UsersList(navController)}
composable(
Screen.UserView.route,
arguments = listOf(navArgument("id") { type = NavType.IntType })
) { backStackEntry ->
backStackEntry.arguments?.let { UserView(it.getInt("id")) }
}
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainNavbar() {
val navController = rememberNavController()
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentDestination = navBackStackEntry?.destination
val currentScreen = currentDestination?.route?.let { Screen.getItem(it) }
Scaffold(
topBar = {
Topbar(navController, currentScreen)
},
bottomBar = {
if (currentScreen == null || currentScreen.showInBottomBar) {
Navbar(navController, currentDestination)
}
}
) { innerPadding ->
Navhost(navController, innerPadding)
}
}
@Preview(name = "Light Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO)
@Preview(name = "Dark Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
fun MainNavbarPreview() {
MyApplicationTheme {
Surface(
color = MaterialTheme.colorScheme.background
) {
MainNavbar()
}
}
}

View File

@ -0,0 +1,43 @@
package com.example.myapplication.composeui.navigation
import androidx.annotation.StringRes
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material.icons.filled.Info
import androidx.compose.material.icons.filled.List
import androidx.compose.material.icons.filled.Person
import androidx.compose.ui.graphics.vector.ImageVector
import com.example.myapplication.R
enum class Screen(
val route: String,
@StringRes val resourceId: Int,
val icon: ImageVector = Icons.Filled.Favorite,
val showInBottomBar: Boolean = true
) {
CategoryList(
"categories-list", R.string.categories_list, Icons.Filled.List
),
UserList(
"users-list", R.string.user_list, Icons.Filled.Person
),
About(
"about", R.string.about_main_title, Icons.Filled.Info
),
UserView(
"user-view/{id}", R.string.user_view_title, showInBottomBar = false
);
companion object {
val bottomBarItems = listOf(
CategoryList,
UserList,
About,
)
fun getItem(route: String): Screen? {
val findRoute = route.split("/").first()
return values().find { value -> value.route.startsWith(findRoute) }
}
}
}

View File

@ -0,0 +1,69 @@
package com.example.myapplication.user.composeui
import android.content.res.Configuration
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
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.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
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.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.example.myapplication.user.model.getTestUser
import com.example.myapplication.ui.theme.MyApplicationTheme
import com.example.myapplication.R
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun UserView(id: Int) {
var user = getTestUser()[id]
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.padding(all = 10.dp)
.verticalScroll(rememberScrollState())) {
OutlinedTextField(modifier = Modifier.fillMaxWidth(), value = user.login, onValueChange = {}, readOnly = true,
label = {
Text(stringResource(id = R.string.user_login))
}
)
OutlinedTextField(modifier = Modifier.fillMaxWidth(), value = user.fio, onValueChange = {}, readOnly = true,
label = {
Text(stringResource(id = R.string.user_fio))
}
)
user.challenges.forEachIndexed() { _, challenge ->
Row {
Text(text = challenge.challenge_name)
if (challenge.challenge_status) {
Text(text = " - Выполнено")
}
else {
Text(text = " - В процессе")
}
}
}
}
}
@Preview(name = "Light Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO)
@Preview(name = "Dark Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
fun PerformanceViewPreview() {
MyApplicationTheme {
Surface(
color = MaterialTheme.colorScheme.background
) {
UserView(id = 0)
}
}
}

View File

@ -0,0 +1,57 @@
package com.example.myapplication.user.composeui
import android.content.res.Configuration
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
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.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.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import com.example.myapplication.composeui.navigation.Screen
import com.example.myapplication.user.model.getTestUser
import com.example.myapplication.ui.theme.MyApplicationTheme
@Composable
fun UsersList(navController: NavController?) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.padding(all = 10.dp)
.verticalScroll(rememberScrollState())) {
getTestUser().forEachIndexed() { _, user ->
val userId = Screen.UserView.route.replace("{id}", (user.id).toString())
Row(Modifier.padding(all = 10.dp)) {
Button(
modifier = Modifier
.fillMaxWidth()
.padding(all = 10.dp),
onClick = { navController?.navigate(userId) }) {
Text(user.fio)
}
}
}
}
}
@Preview(name = "Light Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO)
@Preview(name = "Dark Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
fun UserPreview() {
MyApplicationTheme {
Surface(
color = MaterialTheme.colorScheme.background
) {
UsersList(navController = null)
}
}
}

View File

@ -0,0 +1,22 @@
package com.example.myapplication.user.model
import com.example.myapplication.challenge.model.Challenge
import com.example.myapplication.challenge.model.getTestChallenge
import java.io.Serializable
data class User(
val id: Int,
val login: String,
val password: String,
val fio: String,
val challenges: List<Challenge>,
) : Serializable
fun getTestUser(): List<User> {
val challenges = getTestChallenge()
return listOf(
User(0,"user1", "1234", "ivanov ivan", challenges),
User(1,"user2", "1234", "vasiliev ivan", challenges),
User(2,"user3", "1234", "listov ivan", challenges),
)
}

View File

@ -1,3 +1,18 @@
<resources>
<string name="app_name">My Application</string>
<string name="about_main_title">О нас</string>
<string name="user_list">Пользователи</string>
<string name="categories_list">Категории</string>
<string name="about_text">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Volutpat odio facilisis
mauris sit amet massa vitae. Arcu dui vivamus arcu felis bibendum ut tristique.
Leo in vitae turpis massa sed elementum. Tristique sollicitudin nibh sit amet commodo.
Donec ultrices tincidunt arcu non sodales neque sodales. Convallis aenean et tortor at.
Nisi est sit amet facilisis magna etiam tempor orci. Dignissim diam quis enim lobortis.
Lacus laoreet non curabitur gravida. Netus et malesuada fames ac turpis egestas maecenas.
Ornare aenean euismod elementum nisi quis eleifend. Elit sed vulputate mi sit. Sit amet
justo donec enim diam vulputate ut. Laoreet non curabitur gravida arcu.</string>
<string name="user_login">Логин</string>
<string name="user_fio">ФИО</string>
<string name="user_view_title">Пользователь</string>
</resources>

Binary file not shown.

BIN
Лаб2_Отчет.docx Normal file

Binary file not shown.