Лаб 2 начало

This commit is contained in:
Kate 2023-10-11 19:32:32 +04:00
parent 24d223cdff
commit 555dca89be
22 changed files with 757 additions and 26 deletions

Binary file not shown.

View File

@ -7,7 +7,13 @@
<option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" />
<option name="gradleJvm" value="jbr-17" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>

View File

@ -1,6 +1,6 @@
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager">
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

View File

@ -1,31 +1,99 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AndroidLayouts">
<shared>
<config />
</shared>
</component>
<component name="AutoImportSettings">
<option name="autoReloadType" value="NONE" />
</component>
<component name="ChangeListManager">
<list default="true" id="dc3793c7-c725-42e8-8eda-044c95f334c1" name="Changes" comment=оммит1" />
<list default="true" id="dc3793c7-c725-42e8-8eda-044c95f334c1" name="Changes" comment="добавление отчета лаб 1">
<change afterPath="$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/composeui/Home.kt" afterDir="false" />
<change afterPath="$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/composeui/Login.kt" afterDir="false" />
<change afterPath="$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/composeui/Profile.kt" afterDir="false" />
<change afterPath="$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/composeui/navigation/MyPage.kt" afterDir="false" />
<change afterPath="$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/composeui/navigation/Screen.kt" afterDir="false" />
<change afterPath="$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/models/user/composeui/StudentView.kt" afterDir="false" />
<change afterPath="$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/models/user/composeui/UserList.kt" afterDir="false" />
<change afterPath="$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/models/user/model/Student.kt" 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/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/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$/.idea/gradle.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/gradle.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/misc.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/misc.xml" 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/AndroidManifest.xml" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/AndroidManifest.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/MainActivity.kt" beforeDir="false" afterPath="$PROJECT_DIR$/app/src/main/java/com/example/pmuapp/MainComposeActivity.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" />
<change beforePath="$PROJECT_DIR$/gradle.properties" beforeDir="false" afterPath="$PROJECT_DIR$/gradle.properties" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="ExecutionTargetManager" SELECTED_TARGET="device_and_snapshot_combo_box_target[adb-RF8N601QWVE-2InjWs._adb-tls-connect._tcp]" />
<component name="ExternalProjectsData">
<projectState path="$PROJECT_DIR$">
<ProjectState />
</projectState>
</component>
<component name="ExternalProjectsManager">
<system id="GRADLE">
<state>
<task path="$PROJECT_DIR$/app">
<activation />
</task>
<projects_view>
<tree_state>
<expand />
<expand>
<path>
<item name="" type="6a2764b6:ExternalProjectsStructure$RootNode" />
<item name="PMUapp" type="f1a62948:ProjectNode" />
</path>
<path>
<item name="" type="6a2764b6:ExternalProjectsStructure$RootNode" />
<item name="PMUapp" type="f1a62948:ProjectNode" />
<item name="app" type="2d1252cf:ModuleNode" />
</path>
<path>
<item name="" type="6a2764b6:ExternalProjectsStructure$RootNode" />
<item name="PMUapp" type="f1a62948:ProjectNode" />
<item name="app" type="2d1252cf:ModuleNode" />
<item name="Tasks" type="e4a08cd1:TasksNode" />
</path>
<path>
<item name="" type="6a2764b6:ExternalProjectsStructure$RootNode" />
<item name="PMUapp" type="f1a62948:ProjectNode" />
<item name="app" type="2d1252cf:ModuleNode" />
<item name="Tasks" type="e4a08cd1:TasksNode" />
<item name="other" type="c8890929:TasksNode$1" />
</path>
</expand>
<select />
</tree_state>
</projects_view>
</state>
</system>
</component>
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="Kotlin File" />
<option value="Kotlin Class" />
</list>
</option>
</component>
<component name="Git.Settings">
<option name="RECENT_BRANCH_BY_REPOSITORY">
<map>
<entry key="$PROJECT_DIR$" value="main" />
<entry key="$PROJECT_DIR$" value="Lab1" />
</map>
</option>
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
@ -47,9 +115,94 @@
"RunOnceActivity.OpenProjectViewOnStart": "true",
"RunOnceActivity.ShowReadmeOnStart": "true",
"RunOnceActivity.cidr.known.project.marker": "true",
"cidr.known.project.marker": "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/composeui",
"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" />
<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" />
<recent name="C:\Users\Kate\AndroidStudioProjects\Ihonkina_PIbd-31_PMU\app\src\main\res\values" />
</key>
<key name="MoveKotlinTopLevelDeclarationsDialog.RECENTS_KEY">
<recent name="com.example.pmuapp.composeui" />
</key>
<key name="CopyKotlinDeclarationDialog.RECENTS_KEY">
<recent name="com.example.pmuapp.composeui.navigation" />
</key>
</component>
<component name="RunManager">
<configuration name="app" type="AndroidRunConfigurationType" factoryName="Android App">
<module name="PMUapp.app.main" />
<option name="DEPLOY" value="true" />
<option name="DEPLOY_APK_FROM_BUNDLE" value="false" />
<option name="DEPLOY_AS_INSTANT" value="false" />
<option name="ARTIFACT_NAME" value="" />
<option name="PM_INSTALL_OPTIONS" value="" />
<option name="ALL_USERS" value="false" />
<option name="ALWAYS_INSTALL_WITH_PM" value="false" />
<option name="CLEAR_APP_STORAGE" value="false" />
<option name="ACTIVITY_EXTRA_FLAGS" value="" />
<option name="MODE" value="default_activity" />
<option name="CLEAR_LOGCAT" value="false" />
<option name="SHOW_LOGCAT_AUTOMATICALLY" value="false" />
<option name="INSPECTION_WITHOUT_ACTIVITY_RESTART" value="false" />
<option name="TARGET_SELECTION_MODE" value="DEVICE_AND_SNAPSHOT_COMBO_BOX" />
<option name="SELECTED_CLOUD_MATRIX_CONFIGURATION_ID" value="-1" />
<option name="SELECTED_CLOUD_MATRIX_PROJECT_ID" value="" />
<option name="DEBUGGER_TYPE" value="Auto" />
<Auto>
<option name="USE_JAVA_AWARE_DEBUGGER" value="false" />
<option name="SHOW_STATIC_VARS" value="true" />
<option name="WORKING_DIR" value="" />
<option name="TARGET_LOGGING_CHANNELS" value="lldb process:gdb-remote packets" />
<option name="SHOW_OPTIMIZED_WARNING" value="true" />
<option name="ATTACH_ON_WAIT_FOR_DEBUGGER" value="false" />
<option name="DEBUG_SANDBOX_SDK" value="false" />
</Auto>
<Hybrid>
<option name="USE_JAVA_AWARE_DEBUGGER" value="false" />
<option name="SHOW_STATIC_VARS" value="true" />
<option name="WORKING_DIR" value="" />
<option name="TARGET_LOGGING_CHANNELS" value="lldb process:gdb-remote packets" />
<option name="SHOW_OPTIMIZED_WARNING" value="true" />
<option name="ATTACH_ON_WAIT_FOR_DEBUGGER" value="false" />
<option name="DEBUG_SANDBOX_SDK" value="false" />
</Hybrid>
<Java>
<option name="ATTACH_ON_WAIT_FOR_DEBUGGER" value="false" />
<option name="DEBUG_SANDBOX_SDK" value="false" />
</Java>
<Native>
<option name="USE_JAVA_AWARE_DEBUGGER" value="false" />
<option name="SHOW_STATIC_VARS" value="true" />
<option name="WORKING_DIR" value="" />
<option name="TARGET_LOGGING_CHANNELS" value="lldb process:gdb-remote packets" />
<option name="SHOW_OPTIMIZED_WARNING" value="true" />
<option name="ATTACH_ON_WAIT_FOR_DEBUGGER" value="false" />
<option name="DEBUG_SANDBOX_SDK" value="false" />
</Native>
<Profilers>
<option name="ADVANCED_PROFILING_ENABLED" value="false" />
<option name="STARTUP_PROFILING_ENABLED" value="false" />
<option name="STARTUP_CPU_PROFILING_ENABLED" value="false" />
<option name="STARTUP_CPU_PROFILING_CONFIGURATION_NAME" value="Java/Kotlin Method Sample (legacy)" />
<option name="STARTUP_NATIVE_MEMORY_PROFILING_ENABLED" value="false" />
<option name="NATIVE_MEMORY_SAMPLE_RATE_BYTES" value="2048" />
</Profilers>
<option name="DEEP_LINK" value="" />
<option name="ACTIVITY_CLASS" value="" />
<option name="SEARCH_ACTIVITY_IN_GLOBAL_SCOPE" value="false" />
<option name="SKIP_ACTIVITY_VALIDATION" value="false" />
<method v="2">
<option name="Android.Gradle.BeforeRunTask" enabled="true" />
</method>
</configuration>
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
@ -66,7 +219,14 @@
<option name="project" value="LOCAL" />
<updated>1696766359976</updated>
</task>
<option name="localTasksCounter" value="2" />
<task id="LOCAL-00002" summary="добавление отчета лаб 1">
<created>1696766847352</created>
<option name="number" value="00002" />
<option name="presentableId" value="LOCAL-00002" />
<option name="project" value="LOCAL" />
<updated>1696766847352</updated>
</task>
<option name="localTasksCounter" value="3" />
<servers />
</component>
<component name="Vcs.Log.Tabs.Properties">
@ -95,6 +255,7 @@
<component name="VcsManagerConfiguration">
<option name="ADD_EXTERNAL_FILES_SILENTLY" value="true" />
<MESSAGE value=оммит1" />
<option name="LAST_COMMIT_MESSAGE" value=оммит1" />
<MESSAGE value="добавление отчета лаб 1" />
<option name="LAST_COMMIT_MESSAGE" value="добавление отчета лаб 1" />
</component>
</project>

View File

@ -55,6 +55,7 @@ dependencies {
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("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-graphics")
implementation("androidx.compose.ui:ui-tooling-preview")

View File

@ -13,7 +13,7 @@
android:theme="@style/Theme.PMUapp"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:name=".MainComposeActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.PMUapp">

View File

@ -1,46 +1,43 @@
package com.example.pmuapp
import android.content.res.Configuration
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
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.pmuapp.composeui.navigation.MainNavbar
import com.example.pmuapp.ui.theme.PMUappTheme
class MainActivity : ComponentActivity() {
class MainComposeActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
PMUappTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
Greeting("Android")
MainNavbar()
}
}
}
}
}
@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 Greeting(name: String, modifier: Modifier = Modifier) {
Text(
text = "Hello $name!",
modifier = modifier
)
}
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
fun MainNavbarPreview() {
PMUappTheme {
Greeting("Android")
Surface(
color = MaterialTheme.colorScheme.background
) {
MainNavbar()
}
}
}

View File

@ -0,0 +1,55 @@
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.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
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.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 com.example.pmuapp.R
import com.example.pmuapp.ui.theme.PMUappTheme
@Composable
fun Home() {
val localContext = LocalContext.current
val aboutText = localContext.resources.getText(R.string.about_text)
val urlOnClick = {
val openURL = Intent(Intent.ACTION_VIEW)
openURL.data = Uri.parse("https://ulstu.ru/")
localContext.startActivity(openURL)
}
Column(Modifier.padding(all = 10.dp)) {
AndroidView(
modifier = Modifier
.fillMaxWidth()
.clickable(onClick = urlOnClick),
factory = { context -> TextView(context) },
update = { it.text = aboutText }
)
Spacer(Modifier.padding(bottom = 10.dp))
Button(
modifier = Modifier.fillMaxWidth(),
onClick = urlOnClick
) {
Text(stringResource(id = R.string.user_my_title))
}
}
}

View File

@ -0,0 +1,106 @@
package com.example.pmuapp.composeui
import android.content.Intent
import android.content.res.Configuration
import android.net.Uri
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.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.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.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 androidx.navigation.NavController
import com.example.pmuapp.R
import com.example.pmuapp.composeui.navigation.Screen
import com.example.pmuapp.models.user.model.getStudents
import com.example.pmuapp.ui.theme.PMUappTheme
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun Login(navController: NavController) {
var username by remember { mutableStateOf("") }
var password by remember { mutableStateOf("") }
val users = getStudents()
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
TextField(
value = username,
onValueChange = { username = it },
label = { Text("Username") },
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 16.dp)
)
TextField(
value = password,
onValueChange = { password = it },
label = { Text("Password") },
visualTransformation = PasswordVisualTransformation(),
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 16.dp)
)
Button(
onClick = {
// Check if the entered username and password match a user
val authenticatedUser = users.find { it.login == username && it.password == password }
if (authenticatedUser != null) {
// Navigate to the Home screen if authentication is successful
navController.navigate(Screen.Home.route)
} else {
// Show an error message or handle authentication failure
// For example, display a Toast or Text message
// For simplicity, we'll just print a message
println("Authentication failed")
}
},
modifier = Modifier.fillMaxWidth()
) {
Text("Login")
}
}
}
//@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 LoginPreview() {
// PMUappTheme {
// Surface(
// color = MaterialTheme.colorScheme.background
// ) {
// Login()
// }
// }
//}

View File

@ -0,0 +1,52 @@
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.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
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.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 com.example.pmuapp.R
import com.example.pmuapp.models.user.model.User
import com.example.pmuapp.ui.theme.PMUappTheme
@Composable
fun Profile(user: User) {
val localContext = LocalContext.current
val urlOnClick = {
val openURL = Intent(Intent.ACTION_VIEW)
openURL.data = Uri.parse("https://ulstu.ru/")
localContext.startActivity(openURL)
}
Column(Modifier.padding(all = 10.dp)) {
Text("Name: ${user.name}")
Text("Login: ${user.login}")
Text("Password: ${user.password}")
Spacer(Modifier.padding(bottom = 10.dp))
AndroidView(
modifier = Modifier
.fillMaxWidth()
.clickable(onClick = urlOnClick),
factory = { context -> TextView(context) },
update = { it.text = R.string.app_name.toString() }
)
}
}

View File

@ -0,0 +1,165 @@
package com.example.pmuapp.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.pmuapp.R
import com.example.pmuapp.composeui.Home
import com.example.pmuapp.composeui.Login
import com.example.pmuapp.composeui.Profile
import com.example.pmuapp.models.user.composeui.UserList
import com.example.pmuapp.models.user.composeui.StudentView
import com.example.pmuapp.models.user.model.User
import com.example.pmuapp.ui.theme.PMUappTheme
@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.Login.route,
modifier.padding(innerPadding)
) {
composable(Screen.UserList.route) { UserList(navController) }
composable(Screen.Home.route) { Home() }
composable(Screen.Profile.route + "/{name}/{username}/{password}") { backStackEntry ->
val name = backStackEntry.arguments?.getString("name")
val username = backStackEntry.arguments?.getString("username")
val password = backStackEntry.arguments?.getString("password")
if (name != null && username != null && password != null) {
val user = User(name, username, password)
Profile(user)
}
}
composable(Screen.Login.route) { Login(navController) }
composable(
Screen.UserView.route,
arguments = listOf(navArgument("id") { type = NavType.IntType })
) { backStackEntry ->
backStackEntry.arguments?.let { StudentView(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() {
PMUappTheme {
Surface(
color = MaterialTheme.colorScheme.background
) {
MainNavbar()
}
}
}

View File

@ -0,0 +1,48 @@
package com.example.pmuapp.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.Home
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.pmuapp.R
enum class Screen(
val route: String,
@StringRes val resourceId: Int,
val icon: ImageVector = Icons.Filled.Favorite,
val showInBottomBar: Boolean = true
) {
UserList(
"user-list", R.string.users_title, Icons.Filled.List
),
Home(
"home", R.string.home_title, Icons.Filled.Home
),
Profile(
"profile", R.string.user_my_title, Icons.Filled.Person
),
UserView(
"student-view/{id}", R.string.user_view_title, showInBottomBar = false
),
Login(
"login", R.string.login_title, showInBottomBar = false
);
companion object {
val bottomBarItems = listOf(
UserList,
Home,
Profile,
)
fun getItem(route: String): Screen? {
val findRoute = route.split("/").first()
return values().find { value -> value.route.startsWith(findRoute) }
}
}
}

View File

@ -0,0 +1,62 @@
package com.example.pmuapp.models.user.composeui
import android.content.res.Configuration
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
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.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.example.pmuapp.R
import com.example.pmuapp.models.user.model.getStudents
import com.example.pmuapp.ui.theme.PMUappTheme
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun StudentView(id: Int) {
val student = getStudents()[id]
Column(
Modifier
.fillMaxWidth()
.padding(all = 10.dp)
) {
OutlinedTextField(modifier = Modifier.fillMaxWidth(),
value = student.name, onValueChange = {}, readOnly = true,
label = {
Text(stringResource(id = R.string.user_name))
}
)
OutlinedTextField(modifier = Modifier.fillMaxWidth(),
value = student.login, onValueChange = {}, readOnly = true,
label = {
Text(stringResource(id = R.string.user_login))
}
)
OutlinedTextField(modifier = Modifier.fillMaxWidth(),
value = student.password, onValueChange = {}, readOnly = true,
label = {
Text(stringResource(id = R.string.user_login))
}
)
}
}
@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 StudentViewPreview() {
PMUappTheme {
Surface(
color = MaterialTheme.colorScheme.background
) {
StudentView(id = 0)
}
}
}

View File

@ -0,0 +1,47 @@
package com.example.pmuapp.models.user.composeui
import android.content.res.Configuration
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
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.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import com.example.pmuapp.composeui.navigation.Screen
import com.example.pmuapp.models.user.model.getStudents
import com.example.pmuapp.ui.theme.PMUappTheme
@Composable
fun UserList(navController: NavController?) {
Column(Modifier.padding(all = 10.dp)) {
getStudents().forEachIndexed() { index, student ->
val studentId = Screen.UserView.route.replace("{id}", index.toString())
Button(
modifier = Modifier
.fillMaxWidth()
.padding(all = 10.dp),
onClick = { navController?.navigate(studentId) }) {
Text("${student.login}")
}
}
}
}
@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 StudentListPreview() {
PMUappTheme {
Surface(
color = MaterialTheme.colorScheme.background
) {
UserList(navController = null)
}
}
}

View File

@ -0,0 +1,17 @@
package com.example.pmuapp.models.user.model
import java.io.Serializable
data class User(
val name: String,
val login: String,
val password: String,
) : Serializable
fun getStudents(): List<User> {
return listOf(
User("Иван", "ivan", "111111"),
User("Анна", "ann", "111111"),
User("Лиза", "liza", "111111")
)
}

View File

@ -1,3 +1,16 @@
<resources>
<string name="app_name">PMUapp</string>
<string name="app_name">Мой питомец</string>
<string name="user_name">Имя</string>
<string name="user_login">Логин</string>
<string name="user_password">Пароль</string>
<string name="users_title">Пользователи</string>
<string name="user_view_title">Профиль пользователя</string>
<string name="home_title">Мой дом</string>
<string name="user_my_title">Мой профиль</string>
<string name="login_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>
</resources>

View File

@ -21,3 +21,4 @@ kotlin.code.style=official
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true
android.overridePathCheck=true