Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
0e04a5eba1 | |||
|
86be093a35 |
@ -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")
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
@ -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("Силовые")
|
||||
)
|
||||
}
|
@ -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),
|
||||
)
|
||||
}
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
@ -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) }
|
||||
}
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
@ -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),
|
||||
)
|
||||
}
|
@ -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>
|
BIN
Лаб1_Отчет.docx
BIN
Лаб1_Отчет.docx
Binary file not shown.
BIN
Лаб2_Отчет.docx
Normal file
BIN
Лаб2_Отчет.docx
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user