Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //#################################
- //MainActivity.kt
- //#################################
- package com.thevals.lab3
- import android.os.Bundle
- import androidx.activity.ComponentActivity
- import androidx.activity.compose.setContent
- import androidx.compose.foundation.layout.Arrangement
- import androidx.compose.foundation.layout.fillMaxSize
- import androidx.compose.material3.MaterialTheme
- import androidx.compose.material3.Surface
- import androidx.compose.material3.Text
- import androidx.compose.material3.Button
- import androidx.compose.foundation.layout.Column
- //import androidx.compose.foundation.layout.Spacer
- import androidx.compose.runtime.Composable
- import androidx.compose.ui.Alignment
- import androidx.compose.ui.Modifier
- import androidx.compose.ui.tooling.preview.Preview
- import androidx.navigation.NavController
- import androidx.navigation.compose.rememberNavController
- import androidx.navigation.compose.NavHost
- import androidx.navigation.compose.composable
- import com.thevals.lab3.ui.theme.Lab3Theme
- class MainActivity : ComponentActivity() {
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContent {
- Lab3Theme {
- // A surface container using the 'background' color from the theme
- Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) {
- App()
- }
- }
- }
- }
- }
- @Composable
- fun App(){
- val appNavController = rememberNavController()
- NavHost(navController = appNavController, startDestination = "main"){
- composable("main") { MainScreen(navController = appNavController)}
- composable("t1") { T1Screen(navController = appNavController)}
- composable("t2") { T2Screen(navController = appNavController)}
- composable("t3") { T3Screen(navController = appNavController)}
- }
- }
- @Composable
- fun MainScreen(navController:NavController){
- Column(
- modifier = Modifier.fillMaxSize(),
- verticalArrangement = Arrangement.Center,
- horizontalAlignment = Alignment.CenterHorizontally
- ) {
- Button(onClick = { navController.navigate("t1") }) {
- Text("T1: ФИО")
- }
- Button(onClick = { navController.navigate("t2") }) {
- Text("T2: REST API")
- }
- Button(onClick = { navController.navigate("t3") }) {
- Text("T3: БД")
- }
- }
- }
- @Composable
- @Preview
- fun PreviewApp(){
- App()
- }
- //#################################
- //T1Screen.kt
- //#################################
- package com.thevals.lab3
- import androidx.compose.foundation.layout.Arrangement
- import androidx.compose.foundation.layout.Column
- import androidx.compose.foundation.layout.fillMaxSize
- import androidx.compose.material3.Button
- import androidx.compose.material3.Text
- import androidx.compose.runtime.Composable
- import androidx.compose.ui.Alignment
- import androidx.compose.ui.Modifier
- import androidx.navigation.NavController
- @Composable
- fun T1Screen(navController: NavController){
- Column(
- modifier = Modifier.fillMaxSize(),
- verticalArrangement = Arrangement.Center,
- horizontalAlignment = Alignment.CenterHorizontally
- ) {
- Text("Волков Сергей Алексеевич")
- Button(onClick = {navController.navigate("main")}){
- Text("Back")
- }
- }
- }
- //#################################
- //T2Screen.kt
- //#################################
- package com.thevals.lab3
- import androidx.compose.foundation.layout.Column
- import androidx.compose.foundation.layout.fillMaxSize
- import androidx.compose.foundation.layout.Arrangement
- import androidx.compose.foundation.layout.fillMaxWidth
- import androidx.compose.foundation.layout.height
- import androidx.compose.foundation.layout.width
- import androidx.compose.foundation.layout.padding
- import androidx.compose.foundation.shape.RoundedCornerShape
- import androidx.compose.foundation.Image
- import coil.compose.rememberImagePainter
- import androidx.compose.ui.unit.dp
- import androidx.compose.ui.layout.ContentScale
- import androidx.compose.ui.graphics.painter.Painter
- import androidx.compose.material3.Button
- import androidx.compose.material3.Text
- import androidx.compose.runtime.Composable
- import androidx.compose.ui.Alignment
- import androidx.compose.ui.Modifier
- import androidx.compose.material3.Card
- import androidx.compose.material3.MaterialTheme
- import androidx.navigation.NavController
- import androidx.compose.material3.TextField
- import androidx.compose.runtime.getValue
- import androidx.compose.runtime.setValue
- import androidx.compose.runtime.remember
- import androidx.compose.runtime.mutableStateOf
- import kotlinx.coroutines.Dispatchers
- import androidx.compose.runtime.rememberCoroutineScope
- import androidx.compose.ui.window.Dialog
- import kotlinx.coroutines.launch
- import kotlinx.serialization.Serializable
- import kotlinx.serialization.decodeFromString
- import kotlinx.serialization.json.Json
- import kotlinx.coroutines.withContext
- import okhttp3.OkHttpClient
- import okhttp3.Request
- //Задаем сериализацию для JSON результата
- @Serializable
- data class PokemonForm(
- val name: String
- )
- @Serializable
- data class PokemonInfo(
- val id: Int,
- val forms: List<PokemonForm>
- )
- @Serializable
- data class PokemonFormInfo(
- val id: Int,
- val types: List<PokemonType>,
- val version_group: VersionGroup,
- val sprites: Sprites,
- val name: String
- )
- @Serializable
- data class PokemonType(
- val type: Type
- )
- @Serializable
- data class Type(
- val name: String
- )
- @Serializable
- data class VersionGroup(
- val name: String
- )
- @Serializable
- data class Sprites(
- val front_default: String
- )
- //Основная активность в Compose колонне
- @Composable
- fun T2Screen(navController: NavController) {
- val coroutineScope = rememberCoroutineScope()
- var pokemonInfo by remember { mutableStateOf<PokemonFormInfo?>(null) }
- var showDialog by remember {mutableStateOf(false)}
- var isError by remember {mutableStateOf(false)}
- Column(
- modifier = Modifier.fillMaxSize(),
- verticalArrangement = Arrangement.Center,
- horizontalAlignment = Alignment.CenterHorizontally
- ) {
- var text by remember {mutableStateOf("")}
- Text("REST API")
- TextField(
- value = text,
- onValueChange = { text = it },
- label = { Text("Enter Pokemon name")},
- supportingText = {
- if(isError){
- Text("Error! No Pokemon with this name in API", color = MaterialTheme.colorScheme.error)
- }
- }
- )
- Button(onClick={
- showDialog = true
- isError = false
- if(text != "") {
- coroutineScope.launch {
- val pokemonQuery = getPokemonInfo(text)
- if (pokemonQuery == "") {
- isError = true
- } else {
- pokemonInfo = json.decodeFromString<PokemonFormInfo>(pokemonQuery)
- }
- }
- } else isError = true
- }){
- Text("Get info")
- }
- Button(onClick = { navController.navigate("main") }) {
- Text("Back")
- }
- }
- if(showDialog && pokemonInfo != null) {
- val painter = rememberImagePainter(pokemonInfo!!.sprites.front_default)
- var cardText = "ID: " + pokemonInfo!!.id + "\nName: " +
- pokemonInfo!!.name + "\nVersion: " + pokemonInfo!!.version_group.name + "\nTypes: "
- for(type in pokemonInfo!!.types){
- cardText+=type.type.name
- cardText+=","
- }
- cardText = cardText.dropLast(1)
- InfoDialog(
- onDismissRequest = {
- showDialog = false
- pokemonInfo = null
- },
- painter = painter,
- imageDescription = "sprite",
- cardText = cardText
- )
- }
- }
- @Composable
- fun InfoDialog(
- onDismissRequest: () -> Unit,
- painter: Painter,
- imageDescription: String,
- cardText: String,
- ) {
- Dialog(onDismissRequest = { onDismissRequest() }) {
- // Draw a rectangle shape with rounded corners inside the dialog
- Card(
- modifier = Modifier
- .fillMaxWidth()
- .height(375.dp)
- .padding(16.dp),
- shape = RoundedCornerShape(16.dp),
- ) {
- Column(
- modifier = Modifier
- .fillMaxSize(),
- verticalArrangement = Arrangement.Center,
- horizontalAlignment = Alignment.CenterHorizontally,
- ) {
- Image(
- painter = painter,
- contentDescription = imageDescription,
- contentScale = ContentScale.FillBounds,
- modifier = Modifier
- .height(160.dp)
- .width(160.dp)
- )
- Text(
- text = cardText,
- modifier = Modifier.padding(16.dp),
- )
- Button(
- onClick = { onDismissRequest() },
- modifier = Modifier.padding(8.dp)
- ){
- Text("Close")
- }
- }
- }
- }
- }
- private val json: Json = Json { ignoreUnknownKeys = true }
- suspend fun getPokemonInfo(pokemonNameInput: String):String{
- //создаём запрос к общей информации о покемоне
- var pokemonName = pokemonNameInput.replaceFirstChar {
- if (it.isUpperCase()) it.lowercase() else it.toString()
- }
- pokemonName = pokemonName.trimEnd()
- val url = "https://pokeapi.co/api/v2/pokemon/$pokemonName"
- val request = Request.Builder().url(url).build()
- var formResponseBody = ""
- withContext(Dispatchers.IO) {
- val client = OkHttpClient()
- val response = client.newCall(request).execute()
- var responseBody = response.body?.string() ?: ""
- if(response.code == 404) responseBody = ""
- if(responseBody != "") {
- val pokemonInfo = json.decodeFromString<PokemonInfo>(responseBody)
- //из полученной информации делаем запрос с получением подробной информации о первой
- //форме покемона
- val formRequest = Request.Builder()
- .url("https://pokeapi.co/api/v2/pokemon-form/${pokemonInfo.forms[0].name}").build()
- val formResponse = client.newCall(formRequest).execute()
- formResponseBody = formResponse.body?.string() ?: ""
- }
- }
- return formResponseBody
- }
- //#################################
- //T3Screen.kt
- //#################################
- package com.thevals.lab3
- import androidx.compose.foundation.layout.Arrangement
- import androidx.compose.foundation.layout.Column
- import androidx.compose.foundation.layout.Row
- import androidx.compose.foundation.layout.fillMaxSize
- import androidx.compose.material3.Button
- import androidx.compose.material3.Icon
- import androidx.compose.material3.IconButton
- import androidx.compose.material3.MaterialTheme
- import androidx.compose.material3.Text
- import androidx.compose.material3.TextField
- import androidx.compose.runtime.remember
- import androidx.compose.runtime.LaunchedEffect
- import androidx.compose.runtime.rememberCoroutineScope
- import androidx.compose.runtime.mutableStateOf
- import androidx.compose.ui.Alignment
- import androidx.compose.ui.Modifier
- import androidx.compose.ui.res.painterResource
- import androidx.compose.ui.platform.LocalContext
- import androidx.compose.runtime.getValue
- import androidx.compose.runtime.setValue
- import androidx.compose.runtime.Composable
- import androidx.navigation.NavController
- import android.widget.Toast
- import kotlinx.coroutines.withContext
- import okhttp3.OkHttpClient
- import okhttp3.Request
- import kotlinx.coroutines.launch
- import kotlinx.coroutines.Dispatchers
- import okhttp3.MediaType.Companion.toMediaType
- import okhttp3.RequestBody.Companion.toRequestBody
- @Composable
- fun T3Screen(navController: NavController) {
- val coroutineScope = rememberCoroutineScope()
- var rating by remember { mutableStateOf(0) }
- var isError by remember { mutableStateOf(false) }
- var cnt by remember { mutableStateOf(0) }
- var feedback by remember { mutableStateOf("") }
- val context = LocalContext.current
- Column(
- modifier = Modifier.fillMaxSize(),
- verticalArrangement = Arrangement.Center,
- horizontalAlignment = Alignment.CenterHorizontally
- ) {
- Text("Feedback")
- Row {
- for (i in 1..5) {
- IconButton(onClick = { rating = i }) {
- Icon(
- painter = if (i <= rating) painterResource(id = R.drawable.round_star_24) else painterResource(
- id = R.drawable.round_star_border_24
- ), contentDescription = null
- )
- }
- }
- }
- TextField(
- value = feedback,
- onValueChange = { feedback = it },
- label = { Text("Feedback") },
- supportingText = {
- if (isError) {
- Text("API returned error", color = MaterialTheme.colorScheme.error)
- }
- }
- )
- Button(onClick = {
- coroutineScope.launch {
- val json = """
- {
- "title": "$rating",
- "body": "$feedback",
- "userId": $cnt
- }
- """.trimIndent()
- val client = OkHttpClient()
- val mediaType = "application/json; charset=utf-8".toMediaType()
- val requestBody = json.toRequestBody(mediaType)
- val request = Request.Builder()
- .url("https://jsonplaceholder.typicode.com/posts")
- .post(requestBody)
- .build()
- withContext(Dispatchers.IO) {
- val response = client.newCall(request).execute()
- if (response.code == 201 && rating > 0) {
- cnt++
- isError = false
- } else isError = true
- }
- }
- }) {
- Text("Send")
- }
- Button(onClick = { navController.navigate("main") }) {
- Text("Back")
- }
- if (cnt > 0) LaunchedEffect(key1 = cnt) {
- if (!isError) {
- Toast.makeText(
- context,
- "Feedback sent successfully! Thank you!",
- Toast.LENGTH_LONG
- ).show()
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement