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