diff --git a/app/src/main/java/com/gyf/csams/association/model/AssociationViewModel.kt b/app/src/main/java/com/gyf/csams/association/model/AssociationViewModel.kt index e5bbc14..0768cfb 100644 --- a/app/src/main/java/com/gyf/csams/association/model/AssociationViewModel.kt +++ b/app/src/main/java/com/gyf/csams/association/model/AssociationViewModel.kt @@ -11,12 +11,41 @@ import com.orhanobut.logger.Logger import kotlinx.coroutines.launch class AssociationViewModel:ViewModel() { + /** + * 当前菜单 + */ private val _currentMenu=MutableLiveData() val currentMenu:LiveData = _currentMenu + /** + * 下拉菜单状态 + */ + private val _expanded=MutableLiveData(false) + val expanded:LiveData = _expanded + + /** + * 切换顶部菜单 + * + * @param menu + */ fun clickMenu(menu:AssociationMenu){ _currentMenu.value=menu } + + /** + * 切换下拉菜单状态 + * + */ + fun switchType(){ + _expanded.value?.let { + _expanded.value = !it + } + } + + fun close(){ + _expanded.value=false + } + } data class MemberVo(val name:String) diff --git a/app/src/main/java/com/gyf/csams/association/model/ExamViewModel.kt b/app/src/main/java/com/gyf/csams/association/model/ExamViewModel.kt index c913936..fae7464 100644 --- a/app/src/main/java/com/gyf/csams/association/model/ExamViewModel.kt +++ b/app/src/main/java/com/gyf/csams/association/model/ExamViewModel.kt @@ -6,15 +6,26 @@ import com.gyf.csams.uikit.ScrollList import com.gyf.csams.uikit.StringForm import kotlin.random.Random +/** + * 题库界面类型 + * + */ +enum class ExamActivityType(val menuName:String){ + //入团题库 + SET_EXAM("入团题库"), + //入团申请表 + JOIN_Association("入团申请表") +} + /** * 题型 * */ enum class ExamType(val type:String){ //选择题 - cq("选择题"), + CQ("选择题"), //开放题 - oq("开放题") + OQ("开放题") } sealed class Exam{ @@ -30,7 +41,7 @@ sealed class Exam{ * @property question 问题 */ data class OpenQuestionsVo( - override val examType: ExamType = ExamType.oq, override val question: StringForm + override val examType: ExamType = ExamType.OQ, override val question: StringForm ) : Exam() @@ -42,7 +53,7 @@ data class OpenQuestionsVo( * @property rightAnswer 正确答案 * @property question 问题 */ -data class ChoiceQuestionVo(override val examType: ExamType = ExamType.cq, +data class ChoiceQuestionVo(override val examType: ExamType = ExamType.CQ, val answers:List, val rightAnswer:Int, override val question: StringForm @@ -77,8 +88,8 @@ class ExamViewModel:ScrollList() { val questionIsNull: String = "问题不能为空" val deleteLeastOne: String="至少保留一道题目" val updateExam="更新题库" + val postAnswer="提交答案" val back="返回" - val menuName="入团题库" val deleteTip="确定删除此题目?" val addTip="确定添加此题目?" val actionLabel="确定" @@ -87,7 +98,7 @@ class ExamViewModel:ScrollList() { override val initSize = 10 - private val _newExam:MutableLiveData = MutableLiveData(createExam(ExamType.cq)) + private val _newExam:MutableLiveData = MutableLiveData(createExam(ExamType.CQ)) val newExam:LiveData = _newExam init { @@ -99,7 +110,7 @@ class ExamViewModel:ScrollList() { * */ fun switchType(exam: Exam){ - if(exam is ChoiceQuestionVo) _newExam.value=createExam(ExamType.oq) else _newExam.value=createExam(ExamType.cq) + if(exam is ChoiceQuestionVo) _newExam.value=createExam(ExamType.OQ) else _newExam.value=createExam(ExamType.CQ) } @@ -112,12 +123,12 @@ class ExamViewModel:ScrollList() { private fun createExam(type: ExamType): Exam { val question=StringForm(formDesc = "问题",textLength = QUESTION_TEXT_LENGTH) return when(type){ - ExamType.cq-> ChoiceQuestionVo( + ExamType.CQ-> ChoiceQuestionVo( answers = ('A'..'D').map { StringForm(formDesc = "选项",textLength = ANSWER_TEXT_LENGTH,value = "选项$it") }, rightAnswer = 0, question = question ) - ExamType.oq-> OpenQuestionsVo(question = question) + ExamType.OQ-> OpenQuestionsVo(question = question) } } @@ -147,7 +158,15 @@ class ExamViewModel:ScrollList() { */ fun updateExam(callback: (message: String) -> Unit){ callback("功能尚未实现,敬请期待") + } + /** + * TODO 提交答案 + * + * @param callback + */ + fun postAnswer(callback: (message: String) -> Unit){ + callback("功能尚未实现,敬请期待") } /** @@ -208,7 +227,7 @@ class ExamViewModel:ScrollList() { list.add(it) _data.postValue(list) } - _newExam.value=createExam(ExamType.cq) + _newExam.value=createExam(ExamType.CQ) } } diff --git a/app/src/main/java/com/gyf/csams/association/ui/AssociationActivity.kt b/app/src/main/java/com/gyf/csams/association/ui/AssociationActivity.kt index 6f825ad..aa75f73 100644 --- a/app/src/main/java/com/gyf/csams/association/ui/AssociationActivity.kt +++ b/app/src/main/java/com/gyf/csams/association/ui/AssociationActivity.kt @@ -1,5 +1,6 @@ package com.gyf.csams.association.ui +import android.content.Intent import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent @@ -18,7 +19,9 @@ import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.DpOffset import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.PopupProperties import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable @@ -26,6 +29,7 @@ import com.gyf.csams.R import com.gyf.csams.association.model.* import com.gyf.csams.uikit.* import com.gyf.csams.uikit.theme.CSAMSTheme +import com.orhanobut.logger.Logger /** * 社团界面 @@ -42,11 +46,74 @@ class AssociationActivity: ComponentActivity() { val model:AssociationViewModel= viewModel() val startMenu=AssociationMenu.main val menu:AssociationMenu by model.currentMenu.observeAsState(startMenu) + val intent=Intent(context,ExamActivity::class.java) + val expanded by model.expanded.observeAsState(false) Column { - AssociationAppBar(menu = menu,nav = nav,back = { context.onBackPressed() }){ - //TODO 显示下拉菜单 + Logger.i("expanded=$expanded") + AssociationAppBar(menu = menu,nav = nav,back = { context.onBackPressed() },dropMenu = {model.switchType()}){ + Row{ + DropdownMenu(expanded = expanded, + onDismissRequest = { /*TODO*/ }, + offset = DpOffset.Zero.copy(x=50.dp), + properties = PopupProperties() + ) { + DropdownMenuItem(onClick = { + model.close() + }) { + Row(verticalAlignment = Alignment.CenterVertically){ + Text(text = "申请活动") + Icon(painter = painterResource(id = R.drawable.ic_add_fill), contentDescription = null) + } + } + DropdownMenuItem(onClick = { + intent.apply { + putExtra(ExamActivityType::name.name, ExamActivityType.SET_EXAM) + } + context.startActivity(intent) + model.close() + }) { + Row(verticalAlignment = Alignment.CenterVertically) { + Text(text = "设置题库") + Icon(painter = painterResource(id = R.drawable.ic_editor), contentDescription = null) + } + } + DropdownMenuItem(onClick = { + context.startActivity(Intent(context,ReNameActivity::class.java)) + model.close() + }) { + Row(verticalAlignment = Alignment.CenterVertically) { + Text(text = "社团命名") + Icon(painter = painterResource(id = R.drawable.ic_exchange_rate), contentDescription = null) + } + } + DropdownMenuItem(onClick = { + intent.apply { + putExtra(ExamActivityType::name.name, ExamActivityType.JOIN_Association) + } + context.startActivity(intent) + model.close() + }) { + Row(verticalAlignment = Alignment.CenterVertically) { + Text(text = "申请入团") + Icon(painter = painterResource(id = R.drawable.ic_add_account), contentDescription = null) + } + } + DropdownMenuItem(onClick = { + model.close() + }) { + Row(verticalAlignment = Alignment.CenterVertically) { + Icon(painter = painterResource(id = R.drawable.ic_arrow_up), contentDescription = null, + modifier = Modifier + .height(30.dp) + .fillMaxWidth()) + } + } + } + } + } + NavHost(navController = nav, startDestination = startMenu.name) { composable(AssociationMenu.member.name){ model.clickMenu(AssociationMenu.member) diff --git a/app/src/main/java/com/gyf/csams/association/ui/ExamActivity.kt b/app/src/main/java/com/gyf/csams/association/ui/ExamActivity.kt index a16279d..9c5b263 100644 --- a/app/src/main/java/com/gyf/csams/association/ui/ExamActivity.kt +++ b/app/src/main/java/com/gyf/csams/association/ui/ExamActivity.kt @@ -22,13 +22,21 @@ 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) }) { @@ -42,6 +50,8 @@ class ExamActivity : ComponentActivity() { } } + + /** * 底部按钮 * @@ -53,12 +63,21 @@ private fun BottomButton( scaffoldModel: ScaffoldModel = viewModel() ) { val context = LocalContext.current as ExamActivity + Row(modifier = modifier, horizontalArrangement = Arrangement.Center) { - OutlinedButton(onClick = { - model.updateExam { scaffoldModel.update(message=it) } - }, modifier = Modifier.background(color = MaterialTheme.colors.primary)) { - Text(text = model.updateExam) + 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() @@ -72,12 +91,12 @@ private fun BottomButton( * 标题 * * @param modifier - * @param model */ @Composable -private fun Title(modifier: Modifier = Modifier, model: ExamViewModel = viewModel()) { +private fun Title(modifier: Modifier = Modifier) { + val context= LocalContext.current as ExamActivity Row(horizontalArrangement = Arrangement.Center, modifier = modifier.fillMaxWidth()) { - Text(text = model.menuName, style = MaterialTheme.typography.h4) + Text(text = context.activityType.menuName, style = MaterialTheme.typography.h4) } } @@ -223,18 +242,23 @@ private fun ExamOQ( isAdd: Boolean = false ) { Row(modifier = modifier) { + val context= LocalContext.current as ExamActivity Question( - exam = openQuestionsVo, modifier = Modifier - .weight(0.8F) - .fillMaxHeight() - ) - ActionButton( - modifier = Modifier - .weight(0.2F) - .fillMaxHeight(), - isAdd = isAdd, - exam = openQuestionsVo + 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 + ) + } } } @@ -252,10 +276,12 @@ private fun ExamCQ( questionWeight:Float ) { Row(modifier = modifier) { + val context= LocalContext.current as ExamActivity Column( - modifier = Modifier - .weight(0.8F) - .fillMaxHeight() + modifier = if(context.activityType==ExamActivityType.SET_EXAM) + Modifier.weight(0.8F).fillMaxHeight() + else + Modifier ) { Question( exam = choiceQuestionVo, @@ -294,13 +320,15 @@ private fun ExamCQ( } } - ActionButton( - modifier = Modifier - .weight(0.2F) - .fillMaxHeight(), - isAdd = isAdd, - exam = choiceQuestionVo - ) + if(context.activityType==ExamActivityType.SET_EXAM) { + ActionButton( + modifier = Modifier + .weight(0.2F) + .fillMaxHeight(), + isAdd = isAdd, + exam = choiceQuestionVo + ) + } } } \ No newline at end of file diff --git a/app/src/main/java/com/gyf/csams/uikit/BaseView.kt b/app/src/main/java/com/gyf/csams/uikit/BaseView.kt index 2482c64..eb05fab 100644 --- a/app/src/main/java/com/gyf/csams/uikit/BaseView.kt +++ b/app/src/main/java/com/gyf/csams/uikit/BaseView.kt @@ -148,45 +148,47 @@ fun AssociationAppBar( menu: AssociationMenu, nav: NavHostController, back: () -> Unit, - dropMenu: () -> Unit + dropMenu: () -> Unit, + content:@Composable () -> Unit ) { TopAppBar(backgroundColor = MaterialTheme.colors.secondary) { - Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) { - IconButton(onClick = back, modifier = Modifier.weight(0.1F)) { - Icon( - painter = painterResource(id = R.drawable.ic_arrow_left), - contentDescription = null - ) - } - Row( - modifier = Modifier - .weight(0.8F) - .fillMaxHeight(), - horizontalArrangement = Arrangement.Center, - verticalAlignment = Alignment.CenterVertically - ) { - val menus = AssociationMenu.values() - menus.forEach { - Row( - modifier = Modifier - .weight(1F / menus.size) - .clickable(onClick = { nav.navigate(it.name) }), - horizontalArrangement = Arrangement.Center - ) { - Text( - text = it.menuName, - color = if (menu == it) MaterialTheme.colors.primary else MaterialTheme.colors.onBackground - ) + Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) { + IconButton(onClick = back, modifier = Modifier.weight(0.1F)) { + Icon( + painter = painterResource(id = R.drawable.ic_arrow_left), + contentDescription = null + ) + } + Row( + modifier = Modifier + .weight(0.8F) + .fillMaxHeight(), + horizontalArrangement = Arrangement.Center, + verticalAlignment = Alignment.CenterVertically + ) { + val menus = AssociationMenu.values() + menus.forEach { + Row( + modifier = Modifier + .weight(1F / menus.size) + .clickable(onClick = { nav.navigate(it.name) }), + horizontalArrangement = Arrangement.Center + ) { + Text( + text = it.menuName, + color = if (menu == it) MaterialTheme.colors.primary else MaterialTheme.colors.onBackground + ) + } } } + IconButton(onClick = dropMenu, modifier = Modifier.weight(0.1F)) { + Icon( + painter = painterResource(id = R.drawable.ic_configuration), + contentDescription = null + ) + } } - IconButton(onClick = dropMenu, modifier = Modifier.weight(0.1F)) { - Icon( - painter = painterResource(id = R.drawable.ic_configuration), - contentDescription = null - ) - } - } + content() } } diff --git a/app/src/main/java/com/gyf/csams/util/GsonUtil.kt b/app/src/main/java/com/gyf/csams/util/GsonUtil.kt index 45f0d0d..08df781 100644 --- a/app/src/main/java/com/gyf/csams/util/GsonUtil.kt +++ b/app/src/main/java/com/gyf/csams/util/GsonUtil.kt @@ -100,9 +100,9 @@ class ExamDeserializer:JsonDeserializer{ val type=root?.get("examType")?.asString return when (gson.fromJson(type, ExamType::class.java)) { - ExamType.cq -> gson.fromJson(json, + ExamType.CQ -> gson.fromJson(json, object : TypeToken() {}.type) - ExamType.oq -> gson.fromJson(json, + ExamType.OQ -> gson.fromJson(json, object : TypeToken() {}.type) null->throw NullPointerException("无法识别题目类型!") } diff --git a/app/src/main/res/drawable/ic_add_account.xml b/app/src/main/res/drawable/ic_add_account.xml new file mode 100644 index 0000000..084a778 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_account.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_arrow_up.xml b/app/src/main/res/drawable/ic_arrow_up.xml new file mode 100644 index 0000000..6b223aa --- /dev/null +++ b/app/src/main/res/drawable/ic_arrow_up.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_editor.xml b/app/src/main/res/drawable/ic_editor.xml new file mode 100644 index 0000000..8c3535b --- /dev/null +++ b/app/src/main/res/drawable/ic_editor.xml @@ -0,0 +1,9 @@ + + +