Correction finale
This commit is contained in:
@@ -26,13 +26,15 @@ fun ArticleActivityPage() {
|
|||||||
val navController = rememberNavController();
|
val navController = rememberNavController();
|
||||||
|
|
||||||
var viewModel = ListArticleViewModel();
|
var viewModel = ListArticleViewModel();
|
||||||
|
var detailViewModel = DetailArticleViewModel();
|
||||||
|
|
||||||
NavHost(
|
NavHost(
|
||||||
navController = navController,
|
navController = navController,
|
||||||
startDestination = "list_article"
|
startDestination = "list_article"
|
||||||
) {
|
) {
|
||||||
composable("list_article") { ListArticleFragmentPage(viewModel, navController) }
|
composable("list_article") { ListArticleFragmentPage(viewModel, detailViewModel, navController) }
|
||||||
composable("article_form") { ArticleFormFragmentPage(viewModel, navController) }
|
composable("article_form") { ArticleFormFragmentPage(viewModel, navController) }
|
||||||
|
composable("article_detail") { DetailArticleFragmentPage(detailViewModel) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
package com.example.tpfilrouge.article
|
||||||
|
|
||||||
|
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.layout.width
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.text.TextStyle
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
import androidx.navigation.NavController
|
||||||
|
import coil.compose.AsyncImage
|
||||||
|
import com.example.tpfilrouge.R
|
||||||
|
import com.example.tpfilrouge.ui.theme.EniPage
|
||||||
|
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun DetailArticleFragmentPage(
|
||||||
|
viewModel: DetailArticleViewModel
|
||||||
|
) {
|
||||||
|
// Ecouter les changements de la liste d'article dans le ViewModel
|
||||||
|
val articleState by viewModel.article.collectAsState();
|
||||||
|
|
||||||
|
EniPage {
|
||||||
|
Column(
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
modifier = Modifier.padding(40.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = articleState.title,
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
style = TextStyle(color = Color.White, fontSize = 28.sp)
|
||||||
|
)
|
||||||
|
Row(modifier = Modifier
|
||||||
|
.padding(10.dp)
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(vertical = 14.dp)) {
|
||||||
|
AsyncImage(
|
||||||
|
model = articleState.imgPath,
|
||||||
|
contentDescription = "",
|
||||||
|
modifier = Modifier
|
||||||
|
.width(82.dp)
|
||||||
|
.padding(horizontal = 5.dp),
|
||||||
|
placeholder = painterResource(R.drawable.reset_password_ic),
|
||||||
|
)
|
||||||
|
Column(modifier = Modifier.padding(start = 5.dp)) {
|
||||||
|
Text(articleState.desc, style = TextStyle(color = Color.White, fontSize = 20.sp))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview(
|
||||||
|
showBackground = true,
|
||||||
|
)
|
||||||
|
@Composable
|
||||||
|
fun DetailArticleFragmentPreview() {
|
||||||
|
var viewModel = DetailArticleViewModel();
|
||||||
|
DetailArticleFragmentPage(viewModel)
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package com.example.tpfilrouge.article
|
||||||
|
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
|
||||||
|
class DetailArticleViewModel {
|
||||||
|
|
||||||
|
var article = MutableStateFlow<Article>(Article("", "", ""));
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,13 +1,18 @@
|
|||||||
package com.example.tpfilrouge.article
|
package com.example.tpfilrouge.article
|
||||||
|
|
||||||
|
import androidx.compose.foundation.Image
|
||||||
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Delete
|
import androidx.compose.material.icons.filled.Delete
|
||||||
import androidx.compose.material.icons.filled.Edit
|
import androidx.compose.material.icons.filled.Edit
|
||||||
@@ -22,7 +27,9 @@ import androidx.compose.runtime.collectAsState
|
|||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Brush
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.layout.ContentScale
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.TextStyle
|
import androidx.compose.ui.text.TextStyle
|
||||||
@@ -39,52 +46,63 @@ import com.example.tpfilrouge.ui.theme.EniPage
|
|||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ArticleCard(article: Article, viewModel: ListArticleViewModel, navController: NavController?=null){
|
fun ArticleCard(article: Article, viewModel: ListArticleViewModel, detailViewModel: DetailArticleViewModel, navController: NavController?=null){
|
||||||
ElevatedCard(
|
ElevatedCard(
|
||||||
elevation = CardDefaults.cardElevation(defaultElevation = 6.dp),
|
elevation = CardDefaults.cardElevation(defaultElevation = 6.dp),
|
||||||
|
shape = RoundedCornerShape(0.dp),
|
||||||
modifier = Modifier.fillMaxWidth().padding(vertical = 14.dp)
|
modifier = Modifier.fillMaxWidth().padding(vertical = 14.dp)
|
||||||
) {
|
) {
|
||||||
Row(modifier = Modifier.padding(10.dp)) {
|
Box(Modifier.background(brush = Brush.linearGradient(listOf(
|
||||||
AsyncImage(
|
Color(0xFF3a3b5d),
|
||||||
model = article.imgPath,
|
Color(0xFF535479),
|
||||||
contentDescription = "",
|
))).fillMaxSize()) {
|
||||||
modifier = Modifier.width(82.dp).padding(horizontal = 5.dp),
|
Row(modifier = Modifier.padding(10.dp)) {
|
||||||
placeholder = painterResource(R.drawable.reset_password_ic),
|
AsyncImage(
|
||||||
)
|
model = article.imgPath,
|
||||||
Column(modifier = Modifier.padding(start = 5.dp)) {
|
contentDescription = "",
|
||||||
Text(article.title,
|
modifier = Modifier.width(82.dp).padding(horizontal = 5.dp),
|
||||||
style = TextStyle(fontWeight = FontWeight.Bold, fontSize = 15.sp))
|
placeholder = painterResource(R.drawable.reset_password_ic),
|
||||||
Text(article.desc)
|
)
|
||||||
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.End) {
|
Column(modifier = Modifier.padding(start = 5.dp)) {
|
||||||
IconButton(onClick = {
|
Text(article.title,
|
||||||
}) {
|
style = TextStyle(fontWeight = FontWeight.Bold, fontSize = 15.sp, color = Color.White))
|
||||||
Icon(imageVector = Icons.Filled.Info, contentDescription = "Voir")
|
Text(article.desc, style = TextStyle(color = Color.White))
|
||||||
}
|
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.End) {
|
||||||
IconButton(onClick = {
|
IconButton(onClick = {
|
||||||
// Dire au viewmodel qu'on va être en mode édition
|
|
||||||
viewModel.isEdit.value = true;
|
detailViewModel.article.value = article;
|
||||||
// Dire au viewmodel quel article on va modifier
|
navController!!.navigate("article_detail");
|
||||||
viewModel.editedArticle = article;
|
|
||||||
// Dire au viewmodel quel Id d'article en cours de proccessus
|
}) {
|
||||||
viewModel.editedArticleId = article.id;
|
Icon(imageVector = Icons.Filled.Info, tint = Color.White, contentDescription = "Voir")
|
||||||
// naviguer dans le formulaire
|
}
|
||||||
navController!!.navigate("article_form")
|
IconButton(onClick = {
|
||||||
}) {
|
// Dire au viewmodel qu'on va être en mode édition
|
||||||
Icon(imageVector = Icons.Filled.Edit, contentDescription = "Edit")
|
viewModel.isEdit.value = true;
|
||||||
}
|
// Dire au viewmodel quel article on va modifier
|
||||||
IconButton(onClick = {
|
viewModel.editedArticle = article;
|
||||||
viewModel.callDeleteArticleApi(article.id);
|
// Dire au viewmodel quel Id d'article en cours de proccessus
|
||||||
}) {
|
viewModel.editedArticleId = article.id;
|
||||||
Icon(imageVector = Icons.Filled.Delete, contentDescription = "Delete")
|
// naviguer dans le formulaire
|
||||||
|
navController!!.navigate("article_form")
|
||||||
|
}) {
|
||||||
|
Icon(imageVector = Icons.Filled.Edit, tint = Color.White, contentDescription = "Edit")
|
||||||
|
}
|
||||||
|
IconButton(onClick = {
|
||||||
|
viewModel.callDeleteArticleApi(article.id);
|
||||||
|
}) {
|
||||||
|
Icon(imageVector = Icons.Filled.Delete, tint = Color.White, contentDescription = "Delete")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ListArticleFragmentPage(viewModel: ListArticleViewModel, navController: NavController? = null) {
|
fun ListArticleFragmentPage(viewModel: ListArticleViewModel, detailViewModel: DetailArticleViewModel, navController: NavController? = null) {
|
||||||
// Ecouter les changements de la liste d'article dans le ViewModel
|
// Ecouter les changements de la liste d'article dans le ViewModel
|
||||||
val articlesState by viewModel.articles.collectAsState();
|
val articlesState by viewModel.articles.collectAsState();
|
||||||
|
|
||||||
@@ -98,6 +116,9 @@ fun ListArticleFragmentPage(viewModel: ListArticleViewModel, navController: NavC
|
|||||||
textAlign = TextAlign.Center,
|
textAlign = TextAlign.Center,
|
||||||
style = TextStyle(color = Color.White, fontSize = 28.sp))
|
style = TextStyle(color = Color.White, fontSize = 28.sp))
|
||||||
EniButton("Ajouter un Article") {
|
EniButton("Ajouter un Article") {
|
||||||
|
// Passer le edit à false pour revenir en mode ajout dans le form
|
||||||
|
viewModel.isEdit.value = false;
|
||||||
|
|
||||||
navController!!.navigate("article_form")
|
navController!!.navigate("article_form")
|
||||||
}
|
}
|
||||||
EniButton("Rafraichir") {
|
EniButton("Rafraichir") {
|
||||||
@@ -106,7 +127,7 @@ fun ListArticleFragmentPage(viewModel: ListArticleViewModel, navController: NavC
|
|||||||
}
|
}
|
||||||
LazyColumn {
|
LazyColumn {
|
||||||
items(articlesState) { article ->
|
items(articlesState) { article ->
|
||||||
ArticleCard(article, viewModel, navController)
|
ArticleCard(article, viewModel, detailViewModel, navController)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -119,10 +140,11 @@ fun ListArticleFragmentPage(viewModel: ListArticleViewModel, navController: NavC
|
|||||||
@Composable
|
@Composable
|
||||||
fun ListArticleActivityPreview() {
|
fun ListArticleActivityPreview() {
|
||||||
var viewModel = ListArticleViewModel();
|
var viewModel = ListArticleViewModel();
|
||||||
|
var detailViewModel = DetailArticleViewModel();
|
||||||
viewModel.articles = MutableStateFlow(listOf(
|
viewModel.articles = MutableStateFlow(listOf(
|
||||||
Article("Teletubies", "Meilleur série du monde", "https://avatar.iran.liara.run/public"),
|
Article("Teletubies", "Meilleur série du monde", "https://avatar.iran.liara.run/public"),
|
||||||
Article("Velocipastor", "Meilleur film du monde, gros budget", "https://avatar.iran.liara.run/public"),
|
Article("Velocipastor", "Meilleur film du monde, gros budget", "https://avatar.iran.liara.run/public"),
|
||||||
Article("Photo mouton béret paille ?", "Pourquoi", "https://avatar.iran.liara.run/public")
|
Article("Photo mouton béret paille ?", "Pourquoi", "https://avatar.iran.liara.run/public")
|
||||||
));
|
));
|
||||||
ListArticleFragmentPage(viewModel)
|
ListArticleFragmentPage(viewModel, detailViewModel)
|
||||||
}
|
}
|
||||||
BIN
app/src/main/res/drawable/card_bg.png
Normal file
BIN
app/src/main/res/drawable/card_bg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
Reference in New Issue
Block a user