MainActivity.kt
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.example.infoapp.ui.theme.InfoAppTheme
import com.example.infoapp.ui_components.InfoScreen
import com.example.infoapp.ui_components.MainScreen
import com.example.infoapp.utils.ListItem
import com.example.infoapp.utils.Routes
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
val navController = rememberNavController()
var item: ListItem? = null
InfoAppTheme {
NavHost(
navController = navController,
startDestination = Routes.MAIN_SCREEN
){
composable(Routes.MAIN_SCREEN){
MainScreen(context = this@MainActivity){ listItem ->
item = listItem
navController.navigate(Routes.INFO_SCREEN)
}
}
composable(Routes.INFO_SCREEN){
InfoScreen(item = item!!)
}
}
}
}
}
}
InfoScreen.kt
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.compose.foundation.layout.Column
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.foundation.shape.RoundedCornerShape
import androidx.compose.material.Card
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import com.example.infoapp.utils.ListItem
@Composable
fun InfoScreen(item: ListItem) {
Card(
modifier = Modifier
.fillMaxSize()
.padding(5.dp),
shape = RoundedCornerShape(10.dp)
) {
Column(
modifier = Modifier
.fillMaxSize()
) {
AssetImage(
imageName = item.imageName,
contentDescription = item.title,
modifier = Modifier
.fillMaxWidth()
.height(200.dp)
)
HtmlLoader(htmlName = item.htmlName)
}
}
}
@Composable
fun HtmlLoader(htmlName: String){
val context = LocalContext.current
val assetManger = context.assets
val inputStream = assetManger.open("html/$htmlName")
val size = inputStream.available()
val buffer = ByteArray(size)
inputStream.read(buffer)
val htmlString = String(buffer)
AndroidView(factory = {
WebView(it).apply {
webViewClient = WebViewClient()
loadData(htmlString, "text/html", "utf-8")
}
})
}
Routes.kt
object Routes {
const val MAIN_SCREEN = "main_screen"
const val INFO_SCREEN = "info_screen"
}
MainScreen.kt
import android.annotation.SuppressLint
import android.content.Context
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.Scaffold
import androidx.compose.material.rememberScaffoldState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import com.example.infoapp.utils.DrawerEvents
import com.example.infoapp.utils.IdArrayList
import com.example.infoapp.utils.ListItem
import kotlinx.coroutines.launch
@SuppressLint("UnusedMaterialScaffoldPaddingParameter")
@Composable
fun MainScreen(context: Context, onClick: (ListItem) -> Unit) {
val scaffoldState = rememberScaffoldState()
val coroutineScope = rememberCoroutineScope()
val mainList = remember {
mutableStateOf(getListItemsByIndex(0, context))
}
val topBarTitle = remember {
mutableStateOf("Грибы")
}
Scaffold(
scaffoldState = scaffoldState,
topBar = {
MainTopBar(
title = topBarTitle.value,
scaffoldState
)
},
drawerContent = {
DrawerMenu(){ event ->
when(event){
is DrawerEvents.OnItemClick -> {
topBarTitle.value = event.title
mainList.value = getListItemsByIndex(
event.index, context)
}
}
coroutineScope.launch {
scaffoldState.drawerState.close()
}
}
}
) {
LazyColumn(modifier = Modifier.fillMaxSize()){
items(mainList.value){ item ->
MainListItem(item = item){ listItem ->
onClick(listItem)
}
}
}
}
}
private fun getListItemsByIndex(index: Int, context: Context): List<ListItem>{
val list = ArrayList<ListItem>()
val arrayList = context.resources.getStringArray(IdArrayList.listId[index])
arrayList.forEach { item ->
val itemArray = item.split("|")
list.add(
ListItem(
itemArray[0],
itemArray[1],
itemArray[2]
)
)
}
return list
}
MainListItem.kt
import android.graphics.BitmapFactory
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Card
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import com.example.infoapp.R
import com.example.infoapp.ui.theme.MainRed
import com.example.infoapp.utils.ListItem
@Composable
fun MainListItem(item: ListItem, onClick: (ListItem) -> Unit) {
Card(
modifier = Modifier
.fillMaxWidth()
.height(250.dp)
.padding(5.dp)
.clickable {
onClick(item)
}
,
shape = RoundedCornerShape(10.dp),
border = BorderStroke(1.dp, MainRed)
) {
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.BottomCenter
) {
AssetImage(
imageName = item.imageName,
contentDescription = item.title,
modifier = Modifier.fillMaxSize()
)
Text(
text = item.title,
modifier = Modifier
.fillMaxWidth()
.background(MainRed)
.padding(10.dp),
textAlign = TextAlign.Center,
fontWeight = FontWeight.Bold,
color = Color.White
)
}
}
}
@Composable
fun AssetImage(imageName: String, contentDescription: String, modifier: Modifier){
val context = LocalContext.current
val assetManger = context.assets
val inputStream = assetManger.open(imageName)
val bitMap = BitmapFactory.decodeStream(inputStream)
Image(
bitmap = bitMap.asImageBitmap(),
contentDescription = contentDescription,
contentScale = ContentScale.Crop,
modifier = modifier
)
}
ListItem.kt
data class ListItem(
val title: String,
val imageName: String,
val htmlName: String
)
main_array.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="drawer_list">
<item>Грибы</item>
<item>Лечебные травы</item>
<item>Деревья</item>
<item>Фрукты</item>
<item>Овощи</item>
</string-array>
<string-array name="mushrooms">
<item>Лисичка|lesichka.png|lisichka.html</item>
<item>Мухамор|muhamor.png|lisichka.html</item>
</string-array>
<string-array name="medicinal_herbs">
<item>Ромашка|romashka.png|lisichka.html</item>
<item>Крапива|krapiva.png|lisichka.html</item>
</string-array>
<string-array name="trees">
<item>Тополь|topol.png|lisichka.html</item>
<item>Дуб|dub.png|lisichka.html</item>
</string-array>
<string-array name="fruits">
<item>Апельсин|apelsin.png|lisichka.html</item>
<item>Яблоко|yabloco.png|lisichka.html</item>
</string-array>
<string-array name="vegetables">
<item>Капуста|kapusta.png|lisichka.html</item>
<item>Свекла|svekla.png|lisichka.html</item>
</string-array>
</resources>
Зависимости Navigation:
def nav_version = "2.5.3"
implementation("androidx.navigation:navigation-compose:$nav_version")
Здравствуйте, при добавлении зависимостей выдает ошибку. Подскажите как исправить?
Уберите это строку: def nav_version = “2.5.3”
Версию пропишите без переменной: implementation(“androidx.navigation:navigation-compose:2.5.3”)
Благодарю за урок. Есть вопрос, а как сохранить состояние данных при повороте экрана на странице InfoScreen?