diff --git a/.DS_Store b/.DS_Store index 9d97825..0993ce3 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml new file mode 100644 index 0000000..1c29f31 --- /dev/null +++ b/.idea/deploymentTargetDropDown.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/arithmetic/kotlin/com/leoleo/androidapptemplate/ui/quiz/Quiz.kt b/app/src/arithmetic/kotlin/com/leoleo/androidapptemplate/ui/quiz/Quiz.kt index 5df84cf..50e221a 100644 --- a/app/src/arithmetic/kotlin/com/leoleo/androidapptemplate/ui/quiz/Quiz.kt +++ b/app/src/arithmetic/kotlin/com/leoleo/androidapptemplate/ui/quiz/Quiz.kt @@ -13,17 +13,17 @@ internal enum class Quiz( listOf( QuestionData( messageResId = R.string.quiz_01_question_01, - answers = listOf("2", "3", "4", "5", "6"), + answerResId = R.array.quiz_01_question_01_answers, answerIndex = 0 ), QuestionData( messageResId = R.string.quiz_01_question_02, - answers = listOf("12", "16", "18"), + answerResId = R.array.quiz_01_question_02_answers, answerIndex = 1 ), QuestionData( messageResId = R.string.quiz_01_question_03, - answers = listOf("155", "152", "151", "150"), + answerResId = R.array.quiz_01_question_03_answers, answerIndex = 2 ), ) @@ -34,17 +34,17 @@ internal enum class Quiz( listOf( QuestionData( messageResId = R.string.quiz_02_question_01, - answers = listOf("2", "8", "1", "0"), + answerResId = R.array.quiz_02_question_01_answers, answerIndex = 3 ), QuestionData( messageResId = R.string.quiz_02_question_02, - answers = listOf("2", "0", "1", "8"), + answerResId = R.array.quiz_02_question_02_answers, answerIndex = 1 ), QuestionData( messageResId = R.string.quiz_02_question_03, - answers = listOf("-92", "90", "95", "-95"), + answerResId = R.array.quiz_02_question_03_answers, answerIndex = 3 ), ) @@ -54,17 +54,17 @@ internal enum class Quiz( listOf( QuestionData( messageResId = R.string.quiz_03_question_01, - answers = listOf("2", "8", "1", "0"), + answerResId = R.array.quiz_03_question_01_answers, answerIndex = 2 ), QuestionData( messageResId = R.string.quiz_03_question_02, - answers = listOf("2", "64", "1", "8"), + answerResId = R.array.quiz_03_question_02_answers, answerIndex = 1 ), QuestionData( messageResId = R.string.quiz_03_question_03, - answers = listOf("3440", "3442", "3444", "3448"), + answerResId = R.array.quiz_03_question_03_answers, answerIndex = 2 ), ) diff --git a/app/src/arithmetic/res/values/strings.xml b/app/src/arithmetic/res/values/strings.xml index 064511a..c4de3d8 100644 --- a/app/src/arithmetic/res/values/strings.xml +++ b/app/src/arithmetic/res/values/strings.xml @@ -10,4 +10,58 @@ 1 X 1 = ? 8 X 8 = ? 28 X 123 = ? + + 2 + 3 + 4 + 5 + 6 + + + 12 + 16 + 18 + + + 155 + 152 + 151 + 150 + + + 2 + 8 + 1 + 0 + + + 2 + 0 + 1 + 8 + + + -92 + 90 + 95 + -95 + + + 2 + 8 + 1 + 0 + + + 2 + 64 + 1 + 8 + + + 3440 + 3442 + 3444 + 3448 + \ No newline at end of file diff --git a/app/src/main/kotlin/com/leoleo/androidapptemplate/ui/quiz/CompactMainScreen.kt b/app/src/main/kotlin/com/leoleo/androidapptemplate/ui/quiz/CompactMainScreen.kt index cab466e..83d272e 100644 --- a/app/src/main/kotlin/com/leoleo/androidapptemplate/ui/quiz/CompactMainScreen.kt +++ b/app/src/main/kotlin/com/leoleo/androidapptemplate/ui/quiz/CompactMainScreen.kt @@ -41,6 +41,8 @@ internal fun CompactMainScreen( viewModel.changeUiState(throwable.message ?: "error.") } + val title = stringResource(id = viewModel.uiState.selectedQuestion.titleResId) + CompactMainScreenStateless( modifier = modifier, snackbarHostState = snackbarHostState, @@ -60,7 +62,7 @@ internal fun CompactMainScreen( }, onClickAnswerButton = { index -> scope.launch(coroutineExceptionHandler) { - viewModel.changeUiState(pagerState.currentPage, index) + viewModel.changeUiState(pagerState.currentPage, index, title) val msg = if (viewModel.uiState.selectedQuestion.data[pagerState.currentPage].answerIndex == index) { "Is the correct answer!" diff --git a/app/src/main/kotlin/com/leoleo/androidapptemplate/ui/quiz/ExpandedMainScreen.kt b/app/src/main/kotlin/com/leoleo/androidapptemplate/ui/quiz/ExpandedMainScreen.kt index 4cbd3d9..05a5478 100644 --- a/app/src/main/kotlin/com/leoleo/androidapptemplate/ui/quiz/ExpandedMainScreen.kt +++ b/app/src/main/kotlin/com/leoleo/androidapptemplate/ui/quiz/ExpandedMainScreen.kt @@ -3,7 +3,9 @@ package com.leoleo.androidapptemplate.ui.quiz import android.widget.Toast import androidx.activity.compose.BackHandler import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.ScrollState import androidx.compose.foundation.layout.* +import androidx.compose.foundation.pager.PagerState import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll @@ -17,6 +19,7 @@ import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import com.leoleo.androidapptemplate.ui.component.AppSurface import com.leoleo.androidapptemplate.ui.component.ErrorContent +import com.leoleo.androidapptemplate.ui.preview.PreviewTabletDevice import kotlinx.coroutines.CoroutineExceptionHandler import kotlinx.coroutines.launch @@ -28,14 +31,61 @@ internal fun ExpandedMainScreen( ) { val drawerState = rememberDrawerState(DrawerValue.Closed) val pagerState = rememberPagerState() - val pagerScrollState = rememberScrollState() val scope = rememberCoroutineScope() val coroutineExceptionHandler = CoroutineExceptionHandler { _, throwable -> viewModel.changeUiState(throwable.message ?: "error.") } val context = LocalContext.current + val title = stringResource(id = viewModel.uiState.selectedQuestion.titleResId) BackHandler(enabled = drawerState.isOpen) { scope.launch { drawerState.close() } } + ExpandedMainScreenStateless( + modifier = modifier, + drawerState = drawerState, + uiState = viewModel.uiState, + pagerState = pagerState, + onClickDrawerItem = { index -> + viewModel.changeUiState(index) + scope.launch { + drawerState.close() + pagerState.scrollToPage(page = 0) + } + }, + onClickResetButton = { + scope.launch(coroutineExceptionHandler) { + viewModel.resetUiState() + pagerState.scrollToPage(page = 0) + } + }, + onClickAnswerButton = { index -> + scope.launch(coroutineExceptionHandler) { + viewModel.changeUiState(pagerState.currentPage, index, title) + val msg = + if (viewModel.uiState.selectedQuestion.data[pagerState.currentPage].answerIndex == index) { + "Is the correct answer!" + } else { + "Incorrect!" + } + pagerState.scrollToPage(page = pagerState.currentPage + 1) + // TODO: できれば Android ViewのToastを辞めたい + Toast.makeText(context, msg, Toast.LENGTH_SHORT).show() + } + } + ) +} + +@OptIn(ExperimentalFoundationApi::class) +@Composable +private fun ExpandedMainScreenStateless( + modifier: Modifier = Modifier, + drawerState: DrawerState, + uiState: QuizUiState, + pagerScrollState: ScrollState = rememberScrollState(), + pagerState: PagerState, + onClickDrawerItem: (Int) -> Unit, + onClickResetButton: () -> Unit, + onClickAnswerButton: (Int) -> Unit, +) { AppSurface(modifier) { DismissibleNavigationDrawer(drawerState = drawerState, drawerContent = { DismissibleDrawerSheet { @@ -43,57 +93,61 @@ internal fun ExpandedMainScreen( Quiz.values().forEachIndexed { index, quiz -> NavigationDrawerItem( label = { Text(stringResource(id = quiz.titleResId)) }, - selected = quiz == viewModel.uiState.selectedQuestion, - onClick = { - viewModel.changeUiState(index) - scope.launch { - drawerState.close() - pagerState.scrollToPage(page = 0) - } - }, + selected = quiz == uiState.selectedQuestion, + onClick = { onClickDrawerItem(index) }, modifier = Modifier.padding(horizontal = 12.dp) ) } } }, content = { - if (viewModel.uiState.errorMessage.isNullOrBlank()) { + if (uiState.errorMessage.isNullOrBlank()) { MainContent(modifier = Modifier .fillMaxSize() .padding(8.dp) .verticalScroll(pagerScrollState), pagerState = pagerState, - selectedQuestion = viewModel.uiState.selectedQuestion, - isFinishedQuiz = viewModel.uiState.isFinishedQuiz, - collectAnswerCount = viewModel.uiState.collectAnswerCount, - onClickResetButton = { - scope.launch(coroutineExceptionHandler) { - viewModel.resetUiState() - pagerState.scrollToPage(page = 0) - } - }, - onClickAnswerButton = { index -> - scope.launch(coroutineExceptionHandler) { - viewModel.changeUiState(pagerState.currentPage, index) - val msg = - if (viewModel.uiState.selectedQuestion.data[pagerState.currentPage].answerIndex == index) { - "Is the correct answer!" - } else { - "Incorrect!" - } - pagerState.scrollToPage(page = pagerState.currentPage + 1) - // TODO: できれば Android ViewのToastを辞めたい - Toast.makeText(context, msg, Toast.LENGTH_SHORT).show() - } - }) + selectedQuestion = uiState.selectedQuestion, + isFinishedQuiz = uiState.isFinishedQuiz, + collectAnswerCount = uiState.collectAnswerCount, + onClickResetButton = { onClickResetButton() }, + onClickAnswerButton = { index -> onClickAnswerButton(index) }) } else { ErrorContent( modifier = Modifier .fillMaxSize() .wrapContentSize() .padding(8.dp), - errorMessage = viewModel.uiState.errorMessage ?: "error.", + errorMessage = uiState.errorMessage, ) } }) } +} + +@OptIn(ExperimentalFoundationApi::class) +@PreviewTabletDevice +@Composable +fun Prev_ExpandedMainScreen_Initial() { + ExpandedMainScreenStateless( + drawerState = rememberDrawerState(DrawerValue.Closed), + uiState = QuizUiState(), + pagerState = rememberPagerState(), + onClickDrawerItem = {}, + onClickResetButton = { }, + onClickAnswerButton = {}, + ) +} + +@OptIn(ExperimentalFoundationApi::class) +@PreviewTabletDevice +@Composable +fun Prev_ExpandedMainScreen_Error() { + ExpandedMainScreenStateless( + drawerState = rememberDrawerState(DrawerValue.Closed), + uiState = QuizUiState(errorMessage = "error..."), + pagerState = rememberPagerState(), + onClickDrawerItem = {}, + onClickResetButton = { }, + onClickAnswerButton = {}, + ) } \ No newline at end of file diff --git a/app/src/main/kotlin/com/leoleo/androidapptemplate/ui/quiz/MainContent.kt b/app/src/main/kotlin/com/leoleo/androidapptemplate/ui/quiz/MainContent.kt index 3463a3c..6dad88a 100644 --- a/app/src/main/kotlin/com/leoleo/androidapptemplate/ui/quiz/MainContent.kt +++ b/app/src/main/kotlin/com/leoleo/androidapptemplate/ui/quiz/MainContent.kt @@ -23,14 +23,13 @@ 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.stringArrayResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -import androidx.hilt.navigation.compose.hiltViewModel import com.leoleo.androidapptemplate.R import com.leoleo.androidapptemplate.ui.component.AppSurface -import com.leoleo.androidapptemplate.ui.component.ErrorContent import com.leoleo.androidapptemplate.ui.preview.PreviewPhoneDevice @OptIn(ExperimentalFoundationApi::class) @@ -43,7 +42,6 @@ internal fun MainContent( collectAnswerCount: Int, onClickResetButton: () -> Unit, onClickAnswerButton: (Int) -> Unit, - viewModel: MainContentViewModel = hiltViewModel() ) { Column( @@ -70,25 +68,24 @@ internal fun MainContent( } } - viewModel.uiState.errorMessage?.let { - ErrorContent( - modifier = Modifier - .wrapContentSize() - .padding(12.dp), errorMessage = it - ) - } - AnimatedVisibility(isFinishedQuiz) { Column(horizontalAlignment = Alignment.CenterHorizontally) { if (collectAnswerCount == selectedQuestion.data.size) { - Text(stringResource(id = R.string.completed_msg), style = MaterialTheme.typography.titleLarge) - viewModel.addCompleteData(stringResource(id = selectedQuestion.titleResId)) + Text( + stringResource(id = R.string.completed_msg), + style = MaterialTheme.typography.titleLarge + ) } - Text(stringResource(id = R.string.format_finished_msg, formatArgs = arrayOf(collectAnswerCount))) + Text( + stringResource( + id = R.string.format_finished_msg, + formatArgs = arrayOf(collectAnswerCount) + ) + ) Button(onClick = { onClickResetButton() }) { Text(stringResource(id = R.string.retry)) } } } - selectedQuestion.data[pagerState.currentPage].answers.forEachIndexed { index, answerText -> + stringArrayResource(id = selectedQuestion.data[pagerState.currentPage].answerResId).forEachIndexed { index, answerText -> Button( onClick = { onClickAnswerButton(index) }, modifier = Modifier.fillMaxWidth(), enabled = !isFinishedQuiz, diff --git a/app/src/main/kotlin/com/leoleo/androidapptemplate/ui/quiz/MainContentUiState.kt b/app/src/main/kotlin/com/leoleo/androidapptemplate/ui/quiz/MainContentUiState.kt deleted file mode 100644 index a1ef2fc..0000000 --- a/app/src/main/kotlin/com/leoleo/androidapptemplate/ui/quiz/MainContentUiState.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.leoleo.androidapptemplate.ui.quiz - -import androidx.compose.runtime.Immutable - -@Immutable -data class MainContentUiState(val errorMessage: String? = null) diff --git a/app/src/main/kotlin/com/leoleo/androidapptemplate/ui/quiz/MainContentViewModel.kt b/app/src/main/kotlin/com/leoleo/androidapptemplate/ui/quiz/MainContentViewModel.kt deleted file mode 100644 index b781fcc..0000000 --- a/app/src/main/kotlin/com/leoleo/androidapptemplate/ui/quiz/MainContentViewModel.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.leoleo.androidapptemplate.ui.quiz - -import android.util.Log -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.setValue -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import com.leoleo.androidapptemplate.domain.repository.QuizRepository -import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.CoroutineExceptionHandler -import kotlinx.coroutines.launch -import java.util.Date -import javax.inject.Inject - -@HiltViewModel -internal class MainContentViewModel @Inject constructor( - private val repository: QuizRepository, -) : ViewModel() { - var uiState by mutableStateOf(MainContentUiState()) - private set - private val coroutineExceptionHandler = CoroutineExceptionHandler { _, throwable -> - uiState = uiState.copy(errorMessage = throwable.message ?: "error.") - } - - init { - Log.d(TAG, "call init") - } - - override fun onCleared() { - super.onCleared() - Log.d(TAG, "call onCleared") - } - - fun addCompleteData(title: String) { - viewModelScope.launch(coroutineExceptionHandler) { - repository.addCompleteData(title, Date().time) - } - } - - companion object { - private const val TAG = "MainContentViewModel" - } -} \ No newline at end of file diff --git a/app/src/main/kotlin/com/leoleo/androidapptemplate/ui/quiz/MediumMainScreen.kt b/app/src/main/kotlin/com/leoleo/androidapptemplate/ui/quiz/MediumMainScreen.kt index 0ad0f69..43a4499 100644 --- a/app/src/main/kotlin/com/leoleo/androidapptemplate/ui/quiz/MediumMainScreen.kt +++ b/app/src/main/kotlin/com/leoleo/androidapptemplate/ui/quiz/MediumMainScreen.kt @@ -2,7 +2,9 @@ package com.leoleo.androidapptemplate.ui.quiz import android.widget.Toast import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.ScrollState import androidx.compose.foundation.layout.* +import androidx.compose.foundation.pager.PagerState import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll @@ -21,6 +23,7 @@ import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import com.leoleo.androidapptemplate.ui.component.AppSurface import com.leoleo.androidapptemplate.ui.component.ErrorContent +import com.leoleo.androidapptemplate.ui.preview.PreviewFoldableDevice import kotlinx.coroutines.CoroutineExceptionHandler import kotlinx.coroutines.launch @@ -31,13 +34,55 @@ internal fun MediumMainScreen( viewModel: QuizViewModel = hiltViewModel(), ) { val pagerState = rememberPagerState() - val pagerScrollState = rememberScrollState() val scope = rememberCoroutineScope() val coroutineExceptionHandler = CoroutineExceptionHandler { _, throwable -> viewModel.changeUiState(throwable.message ?: "error.") } val context = LocalContext.current + val title = stringResource(id = viewModel.uiState.selectedQuestion.titleResId) + MediumMainScreenStateless( + modifier = modifier, + uiState = viewModel.uiState, + pagerState = pagerState, + onClickRailItem = { index -> + viewModel.changeUiState(index) + scope.launch { pagerState.scrollToPage(page = 0) } + }, + onClickResetButton = { + scope.launch(coroutineExceptionHandler) { + viewModel.resetUiState() + pagerState.scrollToPage(page = 0) + } + }, + onClickAnswerButton = { index -> + scope.launch(coroutineExceptionHandler) { + viewModel.changeUiState(pagerState.currentPage, index, title) + val msg = + if (viewModel.uiState.selectedQuestion.data[pagerState.currentPage].answerIndex == index) { + "Is the correct answer!" + } else { + "Incorrect!" + } + pagerState.scrollToPage(page = pagerState.currentPage + 1) + // TODO: できれば Android ViewのToastを辞めたい + Toast.makeText(context, msg, Toast.LENGTH_SHORT).show() + } + } + ) +} + +@OptIn(ExperimentalFoundationApi::class) +@Composable +private fun MediumMainScreenStateless( + modifier: Modifier = Modifier, + uiState: QuizUiState, + pagerScrollState: ScrollState = rememberScrollState(), + pagerState: PagerState, + onClickRailItem: (Int) -> Unit, + onClickResetButton: () -> Unit, + onClickAnswerButton: (Int) -> Unit, +) { AppSurface(modifier) { Row { NavigationRail { @@ -50,54 +95,59 @@ internal fun MediumMainScreen( ) }, label = { Text(stringResource(id = item.titleResId)) }, - selected = viewModel.uiState.selectedQuestion == item, - onClick = { - viewModel.changeUiState(index) - scope.launch { pagerState.scrollToPage(page = 0) } - }, + selected = uiState.selectedQuestion == item, + onClick = { onClickRailItem(index) }, modifier = Modifier.padding(12.dp) ) } } - if (viewModel.uiState.errorMessage.isNullOrBlank()) { + if (uiState.errorMessage.isNullOrBlank()) { MainContent(modifier = Modifier .fillMaxSize() .padding(8.dp) .verticalScroll(pagerScrollState), pagerState = pagerState, - selectedQuestion = viewModel.uiState.selectedQuestion, - isFinishedQuiz = viewModel.uiState.isFinishedQuiz, - collectAnswerCount = viewModel.uiState.collectAnswerCount, - onClickResetButton = { - scope.launch(coroutineExceptionHandler) { - viewModel.resetUiState() - pagerState.scrollToPage(page = 0) - } - }, - onClickAnswerButton = { index -> - scope.launch(coroutineExceptionHandler) { - viewModel.changeUiState(pagerState.currentPage, index) - val msg = - if (viewModel.uiState.selectedQuestion.data[pagerState.currentPage].answerIndex == index) { - "Is the correct answer!" - } else { - "Incorrect!" - } - pagerState.scrollToPage(page = pagerState.currentPage + 1) - // TODO: できれば Android ViewのToastを辞めたい - Toast.makeText(context, msg, Toast.LENGTH_SHORT).show() - } - }) + selectedQuestion = uiState.selectedQuestion, + isFinishedQuiz = uiState.isFinishedQuiz, + collectAnswerCount = uiState.collectAnswerCount, + onClickResetButton = { onClickResetButton() }, + onClickAnswerButton = { index -> onClickAnswerButton(index) }) } else { ErrorContent( modifier = Modifier .fillMaxSize() .wrapContentSize() .padding(8.dp), - errorMessage = viewModel.uiState.errorMessage ?: "error.", + errorMessage = uiState.errorMessage, ) } } } +} + +@OptIn(ExperimentalFoundationApi::class) +@PreviewFoldableDevice +@Composable +private fun Prev_MediumMainScreen_Init() { + MediumMainScreenStateless( + uiState = QuizUiState(), + pagerState = rememberPagerState(), + onClickRailItem = {}, + onClickResetButton = { }, + onClickAnswerButton = {}, + ) +} + +@OptIn(ExperimentalFoundationApi::class) +@PreviewFoldableDevice +@Composable +private fun Prev_MediumMainScreen_Error() { + MediumMainScreenStateless( + uiState = QuizUiState(errorMessage = "error..."), + pagerState = rememberPagerState(), + onClickRailItem = {}, + onClickResetButton = { }, + onClickAnswerButton = {}, + ) } \ No newline at end of file diff --git a/app/src/main/kotlin/com/leoleo/androidapptemplate/ui/quiz/QuestionData.kt b/app/src/main/kotlin/com/leoleo/androidapptemplate/ui/quiz/QuestionData.kt index 0d0a22c..7eac8b0 100644 --- a/app/src/main/kotlin/com/leoleo/androidapptemplate/ui/quiz/QuestionData.kt +++ b/app/src/main/kotlin/com/leoleo/androidapptemplate/ui/quiz/QuestionData.kt @@ -4,7 +4,7 @@ import androidx.compose.runtime.Immutable @Immutable internal data class QuestionData( - val messageResId: Int, - val answers: List, + val messageResId: Int, // TODO R.string.xxxx + val answerResId: Int, // TODO R.array.xxxx val answerIndex: Int ) \ No newline at end of file diff --git a/app/src/main/kotlin/com/leoleo/androidapptemplate/ui/quiz/QuizViewModel.kt b/app/src/main/kotlin/com/leoleo/androidapptemplate/ui/quiz/QuizViewModel.kt index bbcf135..35a76bf 100644 --- a/app/src/main/kotlin/com/leoleo/androidapptemplate/ui/quiz/QuizViewModel.kt +++ b/app/src/main/kotlin/com/leoleo/androidapptemplate/ui/quiz/QuizViewModel.kt @@ -4,12 +4,14 @@ import android.util.Log import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue +import androidx.compose.ui.res.stringResource import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.leoleo.androidapptemplate.domain.repository.QuizRepository import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.CoroutineExceptionHandler import kotlinx.coroutines.launch +import java.util.Date import javax.inject.Inject @HiltViewModel @@ -31,12 +33,6 @@ internal class QuizViewModel @Inject constructor( Log.d(TAG, "call onCleared") } - fun getCompletedQuizList() { - viewModelScope.launch(coroutineExceptionHandler) { - repository.getCompletedQuizList() - } - } - fun changeUiState(errorMessage: String) { viewModelScope.launch(coroutineExceptionHandler) { uiState = uiState.copy(errorMessage = errorMessage) @@ -62,18 +58,35 @@ internal class QuizViewModel @Inject constructor( } } - fun changeUiState(currentPage: Int, index: Int) { + fun changeUiState(currentPage: Int, index: Int, title: String) { viewModelScope.launch(coroutineExceptionHandler) { + + val isFinishedQuiz = uiState.selectedQuestion.data.size <= currentPage + 1 + val collectAnswerCount = + if (uiState.selectedQuestion.data[currentPage].answerIndex == index) { + uiState.collectAnswerCount + 1 + } else { + uiState.collectAnswerCount + } + + if (collectAnswerCount == uiState.selectedQuestion.data.size) { + addCompleteData(title) + } + uiState = uiState.copy( errorMessage = null, - isFinishedQuiz = uiState.selectedQuestion.data.size <= currentPage + 1, - collectAnswerCount = - if (uiState.selectedQuestion.data[currentPage].answerIndex == index) - uiState.collectAnswerCount + 1 else uiState.collectAnswerCount + isFinishedQuiz = isFinishedQuiz, + collectAnswerCount = collectAnswerCount ) } } + private fun addCompleteData(title: String) { + viewModelScope.launch(coroutineExceptionHandler) { + repository.addCompleteData(title, Date().time) + } + } + companion object { private const val TAG = "QuizViewModel" } diff --git a/app/src/trivia/kotlin/com/leoleo/androidapptemplate/ui/quiz/Quiz.kt b/app/src/trivia/kotlin/com/leoleo/androidapptemplate/ui/quiz/Quiz.kt index 5cfed7c..e43702b 100644 --- a/app/src/trivia/kotlin/com/leoleo/androidapptemplate/ui/quiz/Quiz.kt +++ b/app/src/trivia/kotlin/com/leoleo/androidapptemplate/ui/quiz/Quiz.kt @@ -13,23 +13,17 @@ internal enum class Quiz( listOf( QuestionData( messageResId = R.string.quiz_01_question_01, - answers = listOf( - "George Washington", - "John Adams", - "John Quincy Adams", - "Andrew Johnson", - "Donald John Trump" - ), + answerResId = R.array.quiz_01_question_01_answers, answerIndex = 0 ), QuestionData( messageResId = R.string.quiz_01_question_02, - answers = listOf("Chicago", "Louisiana", "Michigan", "Georgia", "Washington D.C."), + answerResId = R.array.quiz_01_question_02_answers, answerIndex = 4 ), QuestionData( messageResId = R.string.quiz_01_question_03, - answers = listOf("Japanese fencing", "McDonald\'s", "Sumo", "MLB"), + answerResId = R.array.quiz_01_question_03_answers, answerIndex = 3 ), ) @@ -39,17 +33,17 @@ internal enum class Quiz( listOf( QuestionData( messageResId = R.string.quiz_02_question_01, - answers = listOf("190", "200", "201", "192", "198", "188"), + answerResId = R.array.quiz_02_question_01_answers, answerIndex = 4 ), QuestionData( messageResId = R.string.quiz_02_question_02, - answers = listOf("190", "200", "206", "192", "198", "188", "210"), + answerResId = R.array.quiz_02_question_02_answers, answerIndex = 2 ), QuestionData( messageResId = R.string.quiz_02_question_03, - answers = listOf("193", "200", "185"), + answerResId = R.array.quiz_02_question_03_answers, answerIndex = 0 ), ), @@ -59,17 +53,17 @@ internal enum class Quiz( listOf( QuestionData( messageResId = R.string.quiz_03_question_01, - answers = listOf("Google", "Apple", "Microsoft", "Amazon", "Meta", "Yahoo", "Sony"), + answerResId = R.array.quiz_03_question_common_answers, answerIndex = 0 ), QuestionData( messageResId = R.string.quiz_03_question_02, - answers = listOf("Google", "Apple", "Microsoft", "Amazon", "Meta", "Yahoo", "Sony"), + answerResId = R.array.quiz_03_question_common_answers, answerIndex = 1 ), QuestionData( messageResId = R.string.quiz_03_question_03, - answers = listOf("Google", "Apple", "Microsoft", "Amazon", "Meta", "Yahoo", "Sony"), + answerResId = R.array.quiz_03_question_common_answers, answerIndex = 2 ), ), diff --git a/app/src/trivia/res/values/strings.xml b/app/src/trivia/res/values/strings.xml index cde6039..a2cf0ad 100644 --- a/app/src/trivia/res/values/strings.xml +++ b/app/src/trivia/res/values/strings.xml @@ -1,13 +1,65 @@ TriviaQuizApp - アメリカの初代大統領は? - アメリカの首都は? - アメリカ発祥のスポーツは? - マイケルジョーダンの身長は(cm)? - レブロンジェームズの身長は(cm)? - ロジャー・クレメンスの身長は(cm)? - Androidを開発している会社は? - iOSを開発している会社は? - windowsを開発している会社は? + Which was America\'s first president? + Which is the capital of America? + Which sports originated in America? + How tall is Michael Jordan (cm)? + How tall is LeBron James (cm)? + How tall is Roger Clemens (cm)? + Which company develops Android? + Which company develops iOS? + Which company develops windows? + + + George Washington + John Adams + John Quincy Adams + Andrew Johnson + Donald John Trump + + + Chicago + Louisiana + Michigan + Georgia + Washington D.C. + + + Japanese fencing + McDonald\'s + Sumo + MLB + + + 190 + 200 + 201 + 192 + 198 + 188 + + + 190 + 200 + 206 + 192 + 198 + 188 + 210 + + + 193 + 200 + 185 + + + Google + Apple + Microsoft + Amazon + Meta + Yahoo + Sony + \ No newline at end of file