You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

346 lines
11 KiB

package com.gyf.csams.association.ui
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.gyf.csams.R
import com.gyf.csams.association.model.*
import com.gyf.csams.uikit.*
/**
* 题库管理
*
*/
class ExamActivity : ComponentActivity() {
lateinit var activityType: ExamActivityType
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
activityType = intent?.getSerializableExtra(ExamActivityType::name.name) as ExamActivityType
setContent {
Body { scaffoldState ->
MainFrame(background = { Background(image = BackgroundImage.Exam, alpha = 0.6F) }) {
Spacer(modifier = Modifier.weight(0.1F))
Title(modifier = Modifier.weight(0.1F))
Exam(modifier = Modifier.weight(0.8F))
ShowSnackbar(scaffoldState = scaffoldState)
}
}
}
}
/**
* 底部按钮
*
*/
@Composable
private fun BottomButton(
modifier: Modifier = Modifier,
model: ExamViewModel = viewModel(),
scaffoldModel: ScaffoldModel = viewModel()
) {
val context = LocalContext.current as ExamActivity
Row(modifier = modifier, horizontalArrangement = Arrangement.Center) {
when (context.activityType) {
ExamActivityType.SET_EXAM -> OutlinedButton(onClick = {
model.updateExam { scaffoldModel.update(message = it) }
}, modifier = Modifier.background(color = MaterialTheme.colors.primary)) {
Text(text = model.updateExam)
}
ExamActivityType.JOIN_Association -> OutlinedButton(onClick = {
model.postAnswer { scaffoldModel.update(message = it) }
}, modifier = Modifier.background(color = MaterialTheme.colors.primary)) {
Text(text = model.postAnswer)
}
}
Spacer(modifier = Modifier.width(10.dp))
OutlinedButton(onClick = {
context.onBackPressed()
}, modifier = Modifier.background(color = MaterialTheme.colors.secondary)) {
Text(text = model.back)
}
}
}
/**
* 标题
*
* @param modifier
*/
@Composable
private fun Title(modifier: Modifier = Modifier) {
val context = LocalContext.current as ExamActivity
Row(horizontalArrangement = Arrangement.Center, modifier = modifier.fillMaxWidth()) {
Text(text = context.activityType.menuName, style = MaterialTheme.typography.h4)
}
}
@Composable
private fun ExamChild(it: Exam, examHeight: Dp, isAdd: Boolean = false) {
val questionWeight = 0.3F
when (it) {
is OpenQuestionsVo -> ExamOQ(
openQuestionsVo = it,
modifier = Modifier.height(examHeight * questionWeight),
isAdd = isAdd
)
is ChoiceQuestionVo -> ExamCQ(
choiceQuestionVo = it,
modifier = Modifier.height(examHeight),
questionWeight = questionWeight,
isAdd = isAdd
)
}
}
/**
* 题目列表
*
* @param modifier
* @param model
*/
@Composable
private fun Exam(
modifier: Modifier = Modifier,
model: ExamViewModel = viewModel(),
scaffoldModel: ScaffoldModel = viewModel(),
examHeight: Dp = 350.dp
) {
val listState = rememberLazyListState()
val data by model.data.observeAsState()
val newExam by model.newExam.observeAsState()
LazyColumn(state = listState, modifier = modifier) {
data?.forEach {
item {
ExamChild(it = it, examHeight = examHeight)
Spacer(modifier = Modifier.height(20.dp))
}
}
newExam?.let {
item {
Column {
OutlinedButton(onClick = { model.switchType(it) }) {
Text(text = "切换到${if (newExam is ChoiceQuestionVo) "开放题" else "选择题"}")
}
ExamChild(it = it, examHeight = examHeight, isAdd = true)
}
}
}
item {
Column {
Divider(color = MaterialTheme.colors.background)
Spacer(modifier = Modifier.height(30.dp))
BottomButton(modifier = Modifier.fillMaxWidth())
}
}
}
if (listState.layoutInfo.totalItemsCount - listState.firstVisibleItemIndex == model.initSize / 2 - 1) {
model.loadMore { scaffoldModel.update(message = it) }
}
}
/**
* 问题
*
* @param modifier
* @param exam
*/
@Composable
private fun Question(modifier: Modifier = Modifier, exam: Exam) {
BaseTextField(
form = exam.question,
modifier = modifier
.fillMaxSize()
.background(color = MaterialTheme.colors.background)
)
}
/**
* 操作按钮
*
*/
@Composable
private fun ActionButton(
modifier: Modifier = Modifier, isAdd: Boolean,
model: ExamViewModel = viewModel(),
scaffoldModel: ScaffoldModel = viewModel(),
exam: Exam
) {
val list by model.data.observeAsState()
val newExam by model.newExam.observeAsState()
Box(
contentAlignment = Alignment.Center,
modifier = modifier
) {
IconButton(onClick = {
if (isAdd) {
if ((newExam?.question?.formValue?.value ?: "").isNotEmpty()) {
scaffoldModel.update(
message = model.addTip,
actionLabel = model.actionLabel
) {
model.addQuestion()
}
} else {
scaffoldModel.update(message = model.questionIsNull)
}
} else {
if (list?.size == 1) {
scaffoldModel.update(model.deleteLeastOne)
} else {
scaffoldModel.update(
message = model.deleteTip,
actionLabel = model.actionLabel
) {
model.deleteQuestion(exam = exam)
}
}
}
}) {
Icon(
painter = painterResource(id = if (isAdd) R.drawable.ic_add_select else R.drawable.ic_sami_select),
contentDescription = null
)
}
}
}
/**
* 开放题
*
* @param openQuestionsVo
*/
@Composable
private fun ExamOQ(
modifier: Modifier = Modifier,
openQuestionsVo: OpenQuestionsVo,
isAdd: Boolean = false
) {
Row(modifier = modifier) {
val context = LocalContext.current as ExamActivity
Question(
exam = openQuestionsVo, modifier =
if (context.activityType == ExamActivityType.SET_EXAM)
Modifier
.weight(0.8F)
.fillMaxHeight()
else
Modifier
)
if (context.activityType == ExamActivityType.SET_EXAM) {
ActionButton(
modifier = Modifier
.weight(0.2F)
.fillMaxHeight(),
isAdd = isAdd,
exam = openQuestionsVo
)
}
}
}
/**
* 选择题
*
* @param choiceQuestionVo
*/
@Composable
private fun ExamCQ(
modifier: Modifier = Modifier,
choiceQuestionVo: ChoiceQuestionVo,
isAdd: Boolean = false,
model: ExamViewModel = viewModel(),
questionWeight: Float
) {
Row(modifier = modifier) {
val context = LocalContext.current as ExamActivity
Column(
modifier = if (context.activityType == ExamActivityType.SET_EXAM)
Modifier
.weight(0.8F)
.fillMaxHeight()
else
Modifier
) {
Question(
exam = choiceQuestionVo,
modifier = Modifier
.fillMaxWidth()
.weight(questionWeight)
)
Card(
backgroundColor = MaterialTheme.colors.secondaryVariant,
modifier = Modifier
.fillMaxWidth()
.weight(1 - questionWeight)
) {
choiceQuestionVo.answers.apply {
Column {
forEach {
Row(
modifier = Modifier
.fillMaxWidth()
.weight(1F / ANSWER_SIZE)
) {
val answerIndex: Int = indexOf(it)
val click = {
model.update(
oldExam = choiceQuestionVo,
newExam = choiceQuestionVo.copy(rightAnswer = answerIndex)
)
}
val isRightAnswer =
choiceQuestionVo.rightAnswer == answerIndex
RadioButton(selected = isRightAnswer, onClick = click)
BaseTextField(form = it)
}
}
}
}
}
}
if (context.activityType == ExamActivityType.SET_EXAM) {
ActionButton(
modifier = Modifier
.weight(0.2F)
.fillMaxHeight(),
isAdd = isAdd,
exam = choiceQuestionVo
)
}
}
}
}