增加活动详情界面

master
pan 4 years ago
parent 31e1d9fd92
commit 4ee124d927
  1. 2
      app/src/androidTest/java/com/gyf/csams/ExampleInstrumentedTest.kt
  2. 9
      app/src/androidTest/java/com/gyf/csams/MainActivityTest.kt
  3. 5
      app/src/main/AndroidManifest.xml
  4. 13
      app/src/main/java/com/gyf/csams/Api.kt
  5. 7
      app/src/main/java/com/gyf/csams/InitActivity.kt
  6. 290
      app/src/main/java/com/gyf/csams/activity/model/ActivityDetailViewModel.kt
  7. 491
      app/src/main/java/com/gyf/csams/activity/ui/ActivityDetailActivity.kt
  8. 26
      app/src/main/java/com/gyf/csams/association/model/AssociationViewModel.kt
  9. 7
      app/src/main/java/com/gyf/csams/association/model/ExamViewModel.kt
  10. 3
      app/src/main/java/com/gyf/csams/association/model/RegAssociationViewModel.kt
  11. 3
      app/src/main/java/com/gyf/csams/association/model/RenameViewModel.kt
  12. 138
      app/src/main/java/com/gyf/csams/association/ui/AssociationActivity.kt
  13. 73
      app/src/main/java/com/gyf/csams/association/ui/ExamActivity.kt
  14. 42
      app/src/main/java/com/gyf/csams/association/ui/ReNameActivity.kt
  15. 42
      app/src/main/java/com/gyf/csams/association/ui/RegAssociationActivity.kt
  16. 7
      app/src/main/java/com/gyf/csams/main/model/MainViewModel.kt
  17. 114
      app/src/main/java/com/gyf/csams/main/ui/MainActivity.kt
  18. 210
      app/src/main/java/com/gyf/csams/uikit/BaseView.kt
  19. 55
      app/src/main/java/com/gyf/csams/util/RandomUtil.kt
  20. 9
      app/src/main/res/drawable/ic_upload.xml
  21. 15
      app/src/test/java/com/gyf/csams/ExampleUnitTest.kt

@ -18,7 +18,5 @@ class ExampleInstrumentedTest {
// Context of the app under test. // Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.gyf.csams", appContext.packageName) assertEquals("com.gyf.csams", appContext.packageName)
} }
} }

@ -0,0 +1,9 @@
package com.gyf.csams
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class MainActivityTest {
}

@ -62,6 +62,11 @@
<activity android:name=".association.ui.ExamActivity" <activity android:name=".association.ui.ExamActivity"
android:exported="true"> android:exported="true">
</activity> </activity>
<!--活动详情-->
<activity android:name=".activity.ui.ActivityDetailActivity"
android:exported="true">
</activity>
</application> </application>
</manifest> </manifest>

@ -5,6 +5,11 @@ interface UrlPath{
fun build():String fun build():String
} }
/**
* 帐号接口
*
* @property path
*/
enum class AccountApi(val path: String):UrlPath{ enum class AccountApi(val path: String):UrlPath{
register("/register"), register("/register"),
checkId("/register/checkId"), checkId("/register/checkId"),
@ -17,7 +22,10 @@ enum class AccountApi(val path: String):UrlPath{
} }
} }
/**
* 构建服务端请求接口地址
*
*/
class Api { class Api {
companion object{ companion object{
fun buildUrl(urlPath: UrlPath):String{ fun buildUrl(urlPath: UrlPath):String{
@ -26,3 +34,6 @@ class Api {
} }
} }
const val NOT_IMPL_TIP="功能尚未实现!"

@ -37,10 +37,10 @@ class InitActivity : ComponentActivity() {
} }
} }
} }
}
@Composable
private fun Init(initViewModel:InitViewModel= viewModel()){ @Composable
private fun Init(initViewModel:InitViewModel= viewModel()){
Logger.i("初始化。。。。") Logger.i("初始化。。。。")
val context= LocalContext.current val context= LocalContext.current
//后台检查token //后台检查token
@ -53,4 +53,5 @@ private fun Init(initViewModel:InitViewModel= viewModel()){
true -> context.startActivity(Intent(context, MainActivity::class.java)) true -> context.startActivity(Intent(context, MainActivity::class.java))
} }
}
} }

@ -0,0 +1,290 @@
package com.gyf.csams.activity.model
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.gyf.csams.NOT_IMPL_TIP
import com.gyf.csams.uikit.ActivityDetailMenu
import com.gyf.csams.uikit.ScrollList
import com.gyf.csams.uikit.StringForm
import com.gyf.csams.uikit.TopMenuInterface
import com.gyf.csams.util.randomChinese
import com.gyf.csams.util.randomDateTime
import com.gyf.csams.util.randomNum
import com.orhanobut.logger.Logger
import kotlinx.coroutines.launch
import java.util.*
/**
* 活动详情菜单通用状态
*
*/
class ActivityDetailViewModel:ViewModel(), TopMenuInterface<ActivityDetailMenu> {
override val _currentMenu: MutableLiveData<ActivityDetailMenu> = MutableLiveData()
override val currentMenu: LiveData<ActivityDetailMenu> = _currentMenu
}
/**
* TODO
*
* @property associationName 社团名字
* @property activityName 活动名
* @property activityTime 活动时间
* @property activityLocation 活动地点
* @property activityDesc 活动介绍
*/
data class ActivityDetailVo(val associationName:String,val activityName:String,
val activityTime:Date,val activityLocation:String,
val activityDesc:String)
/**
* 活动信息
*
*/
class ActivityInfoViewModel:ViewModel(){
private val _activityDetailVo=MutableLiveData<ActivityDetailVo>()
val activityDetailVo:LiveData<ActivityDetailVo> = _activityDetailVo
val like = "点赞"
val collect="收藏"
init {
loadInfo()
}
/**
* TODO 点赞
*
* @param callback
*/
fun like(callback:(message:String)->Unit){
callback(NOT_IMPL_TIP)
}
/**
* TODO 收藏
*
* @param callback
*/
fun collect(callback:(message:String)->Unit){
callback(NOT_IMPL_TIP)
}
private fun loadInfo(){
viewModelScope.launch {
_activityDetailVo.value = ActivityDetailVo(
activityName = randomChinese(4),
associationName = randomChinese(4),
activityTime = randomDateTime(),
activityLocation = randomChinese(3),
activityDesc = randomChinese(500)
)
}
}
}
/**
* 图片
* @property name 文件名
* @property size 文件大小
* @property url 文件路径
* @property md5 文件hash
* @property createTime 文件创建时间
* @property studentId 文件上传人
*/
data class ActivityPhotoVo(val name:String, val size:Long, val url:String, val md5:String, val createTime: Date, val studentId:String)
/**
* 活动相册数据状态管理
*
*/
class ActivityPhotoViewModel:ScrollList<ActivityPhotoVo>(){
override val initSize: Int = 10
init {
load()
}
fun upload(callback: (message: String) -> Unit){
callback(NOT_IMPL_TIP)
}
/**
* TODO 加载相册
*
*/
override fun load() {
viewModelScope.launch {
_data.value?.apply {
repeat(initSize){
add(ActivityPhotoVo(name=randomChinese(3),
size= randomNum(3).toLong(),
url="",
md5 = "",
createTime = randomDateTime(),
studentId = ""))
}
}
}
}
/**
* TODO 加载更多相册
*
* @param callback
*/
override fun loadMore(callback: (message: String) -> Unit) {
Logger.i("加载更多")
viewModelScope.launch {
_data.value?.apply {
val list= mutableListOf<ActivityPhotoVo>()
list.addAll(this)
repeat(initSize){
add(ActivityPhotoVo(name=randomChinese(3),
size= randomNum(3).toLong(),
url="",
md5 = "",
createTime = randomDateTime(),
studentId = ""))
}
_data.postValue(list)
callback("成功加载更多相册")
}
}
}
}
data class ActivityMemberVo(val studentId: String,val name:String)
data class ActivityMembersVo(val organizer:ActivityMemberVo, val participant:MutableList<ActivityMemberVo>?)
class ActivityMemberViewModel:ScrollList<ActivityMemberVo>(){
override val initSize: Int = 10
private val _allMember=MutableLiveData<ActivityMembersVo>()
val allMember:LiveData<ActivityMembersVo> = _allMember
init {
load()
}
/**
* TODO 加载活动成员
*
*/
override fun load() {
viewModelScope.launch {
_data.value?.apply {
repeat(initSize){
add(ActivityMemberVo(studentId = randomNum(),name = randomChinese(3)))
}
_allMember.value= ActivityMembersVo(organizer = ActivityMemberVo(studentId = randomNum(),name = randomChinese(3)),participant = _data.value)
}
}
}
/**
* TODO 加载更多活动成员
*
* @param callback
*/
override fun loadMore(callback: (message: String) -> Unit) {
viewModelScope.launch {
_data.value?.apply {
val list= mutableListOf<ActivityMemberVo>()
list.addAll(this)
repeat(initSize){
add(ActivityMemberVo(studentId = randomNum(),name = randomChinese(3)))
}
_allMember.value?.apply {
_data.postValue(list)
_allMember.postValue(ActivityMembersVo(organizer=organizer,participant=list))
callback("成功加载更多活动参与者")
}
}
}
}
}
data class BBSVo(val studentId:String,val name:String,val createTime:Date,val content:String)
/**
* 交流区数据状态管理
*
*/
class BBSViewModel:ScrollList<BBSVo>(){
override val initSize: Int = 10
val title="发送评论"
val newContent = StringForm(formDesc = "评论内容",textLength = 80)
private val _openDialog=MutableLiveData<Boolean>()
val openDialog:LiveData<Boolean> = _openDialog
init {
load()
}
/**
* 打开评论弹窗
*
*/
fun openDialog(){
_openDialog.value=true
}
fun closeDialog(){
_openDialog.value=false
}
/**
* TODO 发送评论
*
* @param callback
*/
fun send(callback: (message: String) -> Unit){
callback(NOT_IMPL_TIP)
}
/**
* TODO 加载评论
*
*/
override fun load() {
viewModelScope.launch {
_data.value?.apply {
repeat(initSize){
add(BBSVo(studentId = randomNum(),createTime = randomDateTime(),content = randomChinese(50),name = randomChinese(3)))
}
}
}
}
/**
* TODO 加载更多评论
*
* @param callback
*/
override fun loadMore(callback: (message: String) -> Unit) {
viewModelScope.launch {
_data.value?.apply {
repeat(initSize){
val list= mutableListOf<BBSVo>()
list.addAll(this)
repeat(initSize){
add(BBSVo(studentId = randomNum(),name = randomChinese(3),createTime = randomDateTime(),content = randomChinese(50)))
}
_data.postValue(list)
callback("成功加载更多评论")
}
}
}
}
}

@ -0,0 +1,491 @@
package com.gyf.csams.activity.ui
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.Image
import androidx.compose.foundation.border
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.res.painterResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import com.gyf.csams.R
import com.gyf.csams.activity.model.*
import com.gyf.csams.uikit.*
import com.gyf.csams.util.format
/**
* 活动详情
*
*/
class ActivityDetailActivity : ComponentActivity() {
@ExperimentalMaterialApi
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Body { nav, scaffoldState ->
val model: ActivityDetailViewModel = viewModel()
val currentMenuName by model.currentMenu.observeAsState(ActivityDetailMenu.startMenu)
Column {
TextTopAppBar(
nav = nav,
currentMenuName = currentMenuName.menuName,
menuNames = ActivityDetailMenu.values()
)
NavHost(
navController = nav,
startDestination = ActivityDetailMenu.startMenu.name
) {
composable(ActivityDetailMenu.Info.name) {
Info()
ShowSnackbar(scaffoldState = scaffoldState)
model.clickMenu(ActivityDetailMenu.Info)
}
composable(ActivityDetailMenu.Photo.name) {
Photo()
ShowSnackbar(scaffoldState = scaffoldState)
model.clickMenu(ActivityDetailMenu.Photo)
}
composable(ActivityDetailMenu.Member.name) {
Member()
ShowSnackbar(scaffoldState = scaffoldState)
model.clickMenu(ActivityDetailMenu.Member)
}
composable(ActivityDetailMenu.BBS.name) {
BBS()
ShowSnackbar(scaffoldState = scaffoldState)
model.clickMenu(ActivityDetailMenu.BBS)
}
}
}
}
}
}
/**
* 底部按钮
*
* @param modifier
*/
@Composable
private fun BottomButton(
modifier: Modifier = Modifier,
model: ActivityInfoViewModel = viewModel(),
scaffoldModel: ScaffoldModel = viewModel()
) {
Row(modifier = modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceEvenly) {
OutlinedButton(onClick = { model.like { scaffoldModel.update(message = it) } }) {
Text(text = model.like)
}
OutlinedButton(onClick = { model.collect { scaffoldModel.update(message = it) } }) {
Text(text = model.collect)
}
}
}
/**
* 活动信息
*
*/
@Composable
private fun Info() {
MainFrame(background = { Background(image = BackgroundImage.ActivityInfo, alpha = 0.7F) }) {
RectList(modifier = Modifier.weight(0.4F))
ActivityDesc(modifier = Modifier.weight(0.4F))
Spacer(modifier = Modifier.weight(0.05F))
BottomButton()
Spacer(modifier = Modifier.weight(0.05F))
}
}
/**
* 活动基础信息
*
*/
@Composable
private fun RectList(
modifier: Modifier = Modifier,
model: ActivityInfoViewModel = viewModel()
) {
val activityDetailVo by model.activityDetailVo.observeAsState()
activityDetailVo?.let {
Card(modifier = modifier, backgroundColor = MaterialTheme.colors.background) {
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.SpaceAround
) {
RectListItem(text = it.associationName)
RectListItem(text = it.activityName)
RectListItem(text = it.activityTime.format())
RectListItem(text = it.activityLocation)
}
}
}
}
/**
* 列表项
*
* @param text
*/
@Composable
private fun RectListItem(text: String) {
Row(modifier = Modifier.fillMaxWidth()) {
val color = MaterialTheme.colors.secondaryVariant
val canvasSize = 30.dp
Box(modifier = Modifier.weight(0.5F), contentAlignment = Alignment.Center) {
Canvas(modifier = Modifier.size(canvasSize)) {
drawCircle(color = color)
}
}
Text(text = text, style = MaterialTheme.typography.h5, modifier = Modifier.weight(0.5F))
}
}
/**
* 活动介绍
*
* @param modifier
* @param model
*/
@Composable
private fun ActivityDesc(
modifier: Modifier = Modifier,
model: ActivityInfoViewModel = viewModel()
) {
Column(modifier = modifier) {
val activityDetailVo by model.activityDetailVo.observeAsState()
activityDetailVo?.let {
DescCard(modifier = Modifier.weight(0.5F), content = it.activityDesc)
}
}
}
/**
* 相册
*
*/
@Composable
private fun Photo(
model: ActivityPhotoViewModel = viewModel(),
scaffoldModel: ScaffoldModel = viewModel()
) {
MainFrame(background = {
Background(
image = BackgroundImage.ActivityPhoto,
alpha = 0.7F
)
}) {
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.End) {
IconButton(onClick = { model.upload { scaffoldModel.update(message = it) } }) {
Icon(
painter = painterResource(id = R.drawable.ic_upload),
contentDescription = null
)
}
}
Spacer(modifier = Modifier.height(10.dp))
Box(
modifier = Modifier
.fillMaxSize()
.padding(10.dp)
.border(
width = 1.dp,
color = MaterialTheme.colors.background
)
) {
val listState = rememberLazyListState()
val photos by model.data.observeAsState()
photos?.let {
LazyColumn(state = listState) {
it.chunked(2).forEach {
item {
Spacer(modifier = Modifier.height(20.dp))
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceEvenly
) {
Spacer(modifier = Modifier.weight(0.05F))
PhotoItem(vo = it[0], modifier = Modifier.weight(0.4F))
Spacer(modifier = Modifier.weight(0.1F))
if (it.size == 2) {
PhotoItem(vo = it[1], modifier = Modifier.weight(0.4F))
} else {
Spacer(modifier = Modifier.weight(0.4F))
}
Spacer(modifier = Modifier.weight(0.05F))
}
Spacer(modifier = Modifier.height(20.dp))
}
}
}
// Logger.i("totalItemsCount=${listState.layoutInfo.totalItemsCount},firstVisibleItemIndex=${listState.firstVisibleItemIndex}")
if (listState.layoutInfo.totalItemsCount - listState.firstVisibleItemIndex == model.initSize / 2 - 1) {
model.loadMore { scaffoldModel.update(message = it) }
}
}
}
}
}
@Composable
private fun PhotoItem(modifier: Modifier = Modifier, vo: ActivityPhotoVo) {
Box(
modifier = modifier.border(width = 1.dp, color = MaterialTheme.colors.background),
contentAlignment = Alignment.Center
) {
Image(
painter = painterResource(id = R.drawable.ic_launcher_foreground),
contentDescription = null,
)
}
}
/**
* 活动成员
*
*/
@Composable
private fun Member(
model: ActivityMemberViewModel = viewModel(),
scaffoldModel: ScaffoldModel = viewModel()
) {
MainFrame(background = {
Background(
image = BackgroundImage.ActivityMember,
alpha = 0.7F
)
}) {
val data by model.allMember.observeAsState()
data?.apply {
Spacer(modifier = Modifier.height(5.dp))
Row(
modifier = Modifier
.fillMaxWidth()
.weight(0.2F), horizontalArrangement = Arrangement.Center
) {
Box(contentAlignment = Alignment.Center) {
Image(
painter = painterResource(id = R.drawable.persion_name_border),
contentDescription = null
)
Text(text = organizer.name)
}
}
Spacer(modifier = Modifier.height(5.dp))
Box(
modifier = Modifier
.fillMaxWidth()
.weight(0.8F)
.padding(10.dp)
.border(width = 1.dp, color = MaterialTheme.colors.background)
) {
val listState = rememberLazyListState()
participant?.let {
LazyColumn(state = listState) {
it.chunked(2).forEach {
item {
Spacer(modifier = Modifier.height(10.dp))
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceEvenly
) {
Spacer(modifier = Modifier.weight(0.05F))
Participant(vo = it[0], modifier = Modifier.weight(0.4F))
Spacer(modifier = Modifier.weight(0.1F))
if (it.size == 2) {
Participant(
vo = it[1],
modifier = Modifier.weight(0.4F)
)
} else {
Spacer(modifier = Modifier.weight(0.4F))
}
Spacer(modifier = Modifier.weight(0.05F))
}
Spacer(modifier = Modifier.height(10.dp))
}
}
}
// Logger.i("totalItemsCount=${listState.layoutInfo.totalItemsCount},firstVisibleItemIndex=${listState.firstVisibleItemIndex}")
if (listState.layoutInfo.totalItemsCount - listState.firstVisibleItemIndex == model.initSize / 2 - 1) {
model.loadMore { scaffoldModel.update(message = it) }
}
}
}
}
}
}
@Composable
private fun Participant(modifier: Modifier = Modifier, vo: ActivityMemberVo) {
Box(modifier = modifier, contentAlignment = Alignment.Center) {
Image(
painter = painterResource(id = R.drawable.participant_border),
contentDescription = null,
// contentScale = ContentScale.FillBounds,
// modifier = Modifier.fillMaxSize()
)
Text(text = vo.name)
}
}
/**
* 交流区
*
*/
@ExperimentalMaterialApi
@Composable
private fun BBS(model: BBSViewModel = viewModel(), scaffoldModel: ScaffoldModel = viewModel()) {
MainFrame(background = { Background(image = BackgroundImage.ActivityBBS, alpha = 0.7F) }) {
// val drawerState = rememberBottomDrawerState(BottomDrawerValue.Closed)
val openDialog=model.openDialog.observeAsState()
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 10.dp),
horizontalArrangement = Arrangement.End,
verticalAlignment = Alignment.CenterVertically
) {
// IconToggleButton(checked = false, onCheckedChange = { /*TODO*/ }) {
// Row(horizontalArrangement = Arrangement.SpaceEvenly) {
// Icon(painter = painterResource(id = R.drawable.ic_configuration), contentDescription = null)
// }
// }
// Text(text = "")
IconButton(onClick = { model.openDialog() }) {
Icon(
painter = painterResource(id = R.drawable.ic_editor),
contentDescription = null
)
}
}
if(openDialog.value ==true) {
AlertDialog(onDismissRequest = { /*TODO*/ },
buttons = {
Row(
modifier = Modifier
.padding(10.dp)
.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceEvenly
) {
OutlinedButton(onClick = {
model.send { scaffoldModel.update(message = it) }
}) {
Text(text = "发送")
}
OutlinedButton(onClick = {
model.closeDialog()
}) {
Text(text = "关闭")
}
}
}, text = {
Column(modifier = Modifier.padding(10.dp)) {
Card(
backgroundColor = MaterialTheme.colors.background,
modifier = Modifier.padding(10.dp)
) {
BaseTextField(
form = model.newContent, modifier = Modifier
.fillMaxWidth()
.height(200.dp)
)
}
}
})
}
Box(
modifier = Modifier
.weight(0.9F)
.padding(10.dp)
.border(width = 1.dp, color = MaterialTheme.colors.background)
) {
val listState = rememberLazyListState()
val data by model.data.observeAsState()
LazyColumn(state = listState) {
data?.forEach {
item {
BBSItem(vo = it)
Spacer(modifier = Modifier.height(5.dp))
Divider(color = MaterialTheme.colors.onBackground)
}
}
}
// Logger.i("totalItemsCount=${listState.layoutInfo.totalItemsCount},firstVisibleItemIndex=${listState.firstVisibleItemIndex}")
if (listState.layoutInfo.totalItemsCount - listState.firstVisibleItemIndex == model.initSize / 2 - 1) {
model.loadMore { scaffoldModel.update(message = it) }
}
}
}
}
@Composable
private fun BBSItem(vo: BBSVo) {
Column {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(10.dp)
) {
Card(
backgroundColor = MaterialTheme.colors.secondaryVariant,
modifier = Modifier.weight(0.5F)
) {
Column(
modifier = Modifier.height(50.dp),
verticalArrangement = Arrangement.SpaceEvenly
) {
Text(text = vo.name)
Text(text = vo.createTime.format())
}
}
Spacer(modifier = Modifier.weight(0.5F))
}
Card(
backgroundColor = MaterialTheme.colors.background,
modifier = Modifier.padding(10.dp)
) {
Text(
text = vo.content, modifier = Modifier
.fillMaxWidth()
.height(100.dp)
)
}
}
}
}

@ -4,18 +4,19 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.gyf.csams.NOT_IMPL_TIP
import com.gyf.csams.uikit.AssociationMenu import com.gyf.csams.uikit.AssociationMenu
import com.gyf.csams.uikit.ScrollList import com.gyf.csams.uikit.ScrollList
import com.gyf.csams.uikit.StringForm import com.gyf.csams.uikit.StringForm
import com.gyf.csams.uikit.TopMenuInterface
import com.orhanobut.logger.Logger import com.orhanobut.logger.Logger
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class AssociationViewModel:ViewModel() {
/** class AssociationViewModel:ViewModel(),TopMenuInterface<AssociationMenu>{
* 当前菜单
*/ override val _currentMenu: MutableLiveData<AssociationMenu> = MutableLiveData()
private val _currentMenu=MutableLiveData<AssociationMenu>() override val currentMenu: LiveData<AssociationMenu> = _currentMenu
val currentMenu:LiveData<AssociationMenu> = _currentMenu
/** /**
* 下拉菜单状态 * 下拉菜单状态
@ -23,14 +24,7 @@ class AssociationViewModel:ViewModel() {
private val _expanded=MutableLiveData(false) private val _expanded=MutableLiveData(false)
val expanded:LiveData<Boolean> = _expanded val expanded:LiveData<Boolean> = _expanded
/**
* 切换顶部菜单
*
* @param menu
*/
fun clickMenu(menu:AssociationMenu){
_currentMenu.value=menu
}
/** /**
* 切换下拉菜单状态 * 切换下拉菜单状态
@ -113,7 +107,7 @@ class MemberViewModel:ScrollList<MemberVo>(){
*/ */
fun search(callback: (value: String) -> Unit){ fun search(callback: (value: String) -> Unit){
Logger.i("搜索条件[成员姓名:${name.formValue.value}]") Logger.i("搜索条件[成员姓名:${name.formValue.value}]")
callback("功能尚未实现,敬请期待") callback(NOT_IMPL_TIP)
} }
} }
@ -131,6 +125,7 @@ class HistoryActViewModel: ScrollList<HistoryActVo>() {
} }
override fun load() { override fun load() {
viewModelScope.launch {
_data.value?.apply { _data.value?.apply {
repeat(initSize){ repeat(initSize){
add(HistoryActVo(name = "活动${size+1}")) add(HistoryActVo(name = "活动${size+1}"))
@ -138,6 +133,7 @@ class HistoryActViewModel: ScrollList<HistoryActVo>() {
Logger.i("初始化活动数量:${size}") Logger.i("初始化活动数量:${size}")
} }
} }
}
override fun loadMore(callback:(message:String) -> Unit) { override fun loadMore(callback:(message:String) -> Unit) {
_data.value?.apply { _data.value?.apply {

@ -3,6 +3,7 @@ package com.gyf.csams.association.model
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.gyf.csams.NOT_IMPL_TIP
import com.gyf.csams.uikit.ScrollList import com.gyf.csams.uikit.ScrollList
import com.gyf.csams.uikit.StringForm import com.gyf.csams.uikit.StringForm
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -159,7 +160,7 @@ class ExamViewModel:ScrollList<Exam>() {
* @param callback * @param callback
*/ */
fun updateExam(callback: (message: String) -> Unit){ fun updateExam(callback: (message: String) -> Unit){
callback("功能尚未实现,敬请期待") callback(NOT_IMPL_TIP)
} }
/** /**
@ -168,7 +169,7 @@ class ExamViewModel:ScrollList<Exam>() {
* @param callback * @param callback
*/ */
fun postAnswer(callback: (message: String) -> Unit){ fun postAnswer(callback: (message: String) -> Unit){
callback("功能尚未实现,敬请期待") callback(NOT_IMPL_TIP)
} }
/** /**
@ -220,7 +221,7 @@ class ExamViewModel:ScrollList<Exam>() {
// callback("成功加载更多题目") // callback("成功加载更多题目")
// } // }
// callback("功能尚未实现,敬请期待") // callback(NOT_IMPL_TIP)
} }
fun addQuestion() { fun addQuestion() {

@ -4,6 +4,7 @@ import android.net.Uri
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import com.gyf.csams.NOT_IMPL_TIP
import com.gyf.csams.uikit.StringForm import com.gyf.csams.uikit.StringForm
@ -39,7 +40,7 @@ class RegAssociationViewModel : ViewModel() {
* @param callback * @param callback
*/ */
fun register(callback: (value: String) -> Unit){ fun register(callback: (value: String) -> Unit){
callback("功能尚未实现,敬请期待") callback(NOT_IMPL_TIP)
} }
} }

@ -1,6 +1,7 @@
package com.gyf.csams.association.model package com.gyf.csams.association.model
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import com.gyf.csams.NOT_IMPL_TIP
import com.gyf.csams.uikit.StringForm import com.gyf.csams.uikit.StringForm
/** /**
@ -22,6 +23,6 @@ class RenameViewModel:ViewModel() {
* *
*/ */
fun post(callback:(message:String) -> Unit){ fun post(callback:(message:String) -> Unit){
callback("功能尚未实现,敬请期待") callback(NOT_IMPL_TIP)
} }
} }

@ -19,7 +19,6 @@ import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.PopupProperties import androidx.compose.ui.window.PopupProperties
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
@ -29,8 +28,11 @@ import com.gyf.csams.R
import com.gyf.csams.association.model.* import com.gyf.csams.association.model.*
import com.gyf.csams.uikit.* import com.gyf.csams.uikit.*
import com.gyf.csams.uikit.theme.CSAMSTheme import com.gyf.csams.uikit.theme.CSAMSTheme
import com.gyf.csams.util.randomChinese
import com.orhanobut.logger.Logger import com.orhanobut.logger.Logger
/** /**
* 社团界面 * 社团界面
* *
@ -44,18 +46,20 @@ class AssociationActivity: ComponentActivity() {
nav, scaffoldState -> nav, scaffoldState ->
val context= LocalContext.current as AssociationActivity val context= LocalContext.current as AssociationActivity
val model:AssociationViewModel= viewModel() val model:AssociationViewModel= viewModel()
val startMenu=AssociationMenu.main val currentMenuName:AssociationMenu by model.currentMenu.observeAsState(AssociationMenu.startMenu)
val menu:AssociationMenu by model.currentMenu.observeAsState(startMenu)
val intent=Intent(context,ExamActivity::class.java) val intent=Intent(context,ExamActivity::class.java)
val expanded by model.expanded.observeAsState(false) val expanded by model.expanded.observeAsState(false)
Column { Column {
Logger.i("expanded=$expanded") Logger.i("expanded=$expanded")
AssociationAppBar(menu = menu,nav = nav,back = { context.onBackPressed() },dropMenu = {model.switchType()}){ TextTopAppBar(nav = nav,
currentMenuName= currentMenuName.menuName,
menuNames = AssociationMenu.values(),
iconMenu = {model.switchType()}){
Row{ Row{
DropdownMenu(expanded = expanded, DropdownMenu(expanded = expanded,
onDismissRequest = { /*TODO*/ }, onDismissRequest = { /*TODO*/ },
offset = DpOffset.Zero.copy(x=50.dp), // offset = DpOffset.Zero.copy(x=50.dp),
properties = PopupProperties() properties = PopupProperties()
) { ) {
DropdownMenuItem(onClick = { DropdownMenuItem(onClick = {
@ -111,22 +115,21 @@ class AssociationActivity: ComponentActivity() {
} }
} }
} }
} }
NavHost(navController = nav, startDestination = startMenu.name) { NavHost(navController = nav, startDestination = AssociationMenu.startMenu.name) {
composable(AssociationMenu.member.name){ composable(AssociationMenu.Member.name){
model.clickMenu(AssociationMenu.member) model.clickMenu(AssociationMenu.Member)
Member() Member()
ShowSnackbar(scaffoldState = scaffoldState) ShowSnackbar(scaffoldState = scaffoldState)
} }
composable(AssociationMenu.main.name){ composable(AssociationMenu.Main.name){
model.clickMenu(AssociationMenu.main) model.clickMenu(AssociationMenu.Main)
Main() Main()
ShowSnackbar(scaffoldState = scaffoldState) ShowSnackbar(scaffoldState = scaffoldState)
} }
composable(AssociationMenu.list.name){ composable(AssociationMenu.ActivityList.name){
model.clickMenu(AssociationMenu.list) model.clickMenu(AssociationMenu.ActivityList)
AssociationList() AssociationList()
ShowSnackbar(scaffoldState = scaffoldState) ShowSnackbar(scaffoldState = scaffoldState)
} }
@ -137,15 +140,15 @@ class AssociationActivity: ComponentActivity() {
} }
} }
} }
}
/**
/**
* 社团成员 * 社团成员
* *
*/ */
@Composable @Composable
private fun Member(){ private fun Member(){
MainFrame(background = { Background(image = BackgroundImage.association_main) }) { MainFrame(background = { Background(image = BackgroundImage.AssociationMain) }) {
val searchWeight=0.2F val searchWeight=0.2F
Search(modifier = Modifier Search(modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
@ -155,14 +158,14 @@ private fun Member(){
.weight(1 - searchWeight)) .weight(1 - searchWeight))
} }
} }
/** /**
* 检索成员 * 检索成员
* *
*/ */
@Composable @Composable
private fun Search(modifier:Modifier=Modifier, model: MemberViewModel= viewModel(), scaffoldModel: ScaffoldModel= viewModel()){ private fun Search(modifier:Modifier=Modifier, model: MemberViewModel= viewModel(), scaffoldModel: ScaffoldModel= viewModel()){
Column(modifier = modifier.fillMaxSize()) { Column(modifier = modifier.fillMaxSize()) {
Spacer(modifier = Modifier.weight(0.5F)) Spacer(modifier = Modifier.weight(0.5F))
Row(modifier = Modifier Row(modifier = Modifier
@ -181,14 +184,14 @@ private fun Search(modifier:Modifier=Modifier, model: MemberViewModel= viewModel
Spacer(modifier = Modifier.weight(spaceWeight)) Spacer(modifier = Modifier.weight(spaceWeight))
} }
} }
} }
/** /**
* 成员列表 * 成员列表
* *
*/ */
@Composable @Composable
private fun MemberList(modifier: Modifier=Modifier, model: MemberViewModel=viewModel(), scaffoldModel: ScaffoldModel= viewModel()){ private fun MemberList(modifier: Modifier=Modifier, model: MemberViewModel=viewModel(), scaffoldModel: ScaffoldModel= viewModel()){
val list:MutableList<MemberVo>? by model.memberList.observeAsState() val list:MutableList<MemberVo>? by model.memberList.observeAsState()
val listState= rememberLazyListState() val listState= rememberLazyListState()
LazyColumn(state = listState,modifier = modifier) { LazyColumn(state = listState,modifier = modifier) {
@ -223,16 +226,16 @@ private fun MemberList(modifier: Modifier=Modifier, model: MemberViewModel=viewM
} }
} }
} }
/** /**
* 社团主页 * 社团主页
* *
*/ */
@Composable @Composable
private fun Main(){ private fun Main(){
MainFrame(background = { MainFrame(background = {
Background(image = BackgroundImage.association_main,alpha = 0.7F) Background(image = BackgroundImage.AssociationMain,alpha = 0.7F)
}) { }) {
val nameW=0.1F val nameW=0.1F
val cardW=0.66F*0.4F val cardW=0.66F*0.4F
@ -242,22 +245,23 @@ private fun Main(){
DescCard( DescCard(
modifier = Modifier modifier = Modifier
.weight(cardW) .weight(cardW)
.fillMaxWidth() .fillMaxWidth(),
content = randomChinese(500)
) )
Commander( Commander(
modifier = Modifier.weight(cardW) modifier = Modifier.weight(cardW)
) )
Showcase(modifier = Modifier.weight(1F-nameW-cardW-cardW)) Showcase(modifier = Modifier.weight(1F-nameW-cardW-cardW))
} }
} }
/** /**
* 社团名字 * 社团名字
* *
* @param modifier * @param modifier
*/ */
@Composable @Composable
private fun Name(modifier: Modifier){ private fun Name(modifier: Modifier){
Box(modifier = modifier) { Box(modifier = modifier) {
Image( Image(
painter = painterResource(id = R.drawable.association_name_border), painter = painterResource(id = R.drawable.association_name_border),
@ -276,48 +280,48 @@ private fun Name(modifier: Modifier){
Spacer(modifier = Modifier.weight(0.3F / 3)) Spacer(modifier = Modifier.weight(0.3F / 3))
} }
} }
} }
/** /**
* 团长名字 * 团长名字
* *
* @param modifier * @param modifier
*/ */
@Composable @Composable
private fun Commander(modifier: Modifier){ private fun Commander(modifier: Modifier){
Box(modifier=modifier,contentAlignment = Alignment.Center){ Box(modifier=modifier,contentAlignment = Alignment.Center){
Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.Center) { Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.Center) {
Image(painter = painterResource(id = R.drawable.association_persion_name_border), Image(painter = painterResource(id = R.drawable.persion_name_border),
contentDescription = null contentDescription = null
) )
} }
Text(text = "团长") Text(text = "团长")
} }
} }
/** /**
* 风采展示区 * 风采展示区
* *
* @param modifier * @param modifier
*/ */
@Composable @Composable
private fun Showcase(modifier: Modifier){ private fun Showcase(modifier: Modifier){
Box(modifier = modifier,contentAlignment = Alignment.Center) { Box(modifier = modifier,contentAlignment = Alignment.Center) {
Image(painter = painterResource(id = R.drawable.showcase_border), Image(painter = painterResource(id = R.drawable.showcase_border),
contentDescription = null, contentDescription = null,
modifier=Modifier.fillMaxSize()) modifier=Modifier.fillMaxSize())
Image(painter = painterResource(id = R.drawable.ic_launcher_foreground), contentDescription = null) Image(painter = painterResource(id = R.drawable.ic_launcher_foreground), contentDescription = null)
} }
} }
/** /**
* 活动列表 * 活动列表
* *
*/ */
@Composable @Composable
private fun AssociationList(){ private fun AssociationList(){
MainFrame(background = { Background(image = BackgroundImage.association_main,alpha = 07F) }) { MainFrame(background = { Background(image = BackgroundImage.AssociationMain,alpha = 07F) }) {
val onGoWeight=0.3F val onGoWeight=0.3F
OngoingActivity(modifier = Modifier OngoingActivity(modifier = Modifier
.weight(onGoWeight) .weight(onGoWeight)
@ -327,14 +331,14 @@ private fun AssociationList(){
.weight(1 - onGoWeight) .weight(1 - onGoWeight)
.border(width = 1.dp, color = MaterialTheme.colors.onBackground)) .border(width = 1.dp, color = MaterialTheme.colors.onBackground))
} }
} }
/** /**
* 进行中的活动 * 进行中的活动
* *
*/ */
@Composable @Composable
private fun OngoingActivity(modifier: Modifier=Modifier){ private fun OngoingActivity(modifier: Modifier=Modifier){
Row(modifier = modifier,horizontalArrangement = Arrangement.Center) { Row(modifier = modifier,horizontalArrangement = Arrangement.Center) {
val weight=0.5F val weight=0.5F
val spaceWeight=(1-0.5F)/2 val spaceWeight=(1-0.5F)/2
@ -343,15 +347,15 @@ private fun OngoingActivity(modifier: Modifier=Modifier){
Spacer(modifier = Modifier.weight(spaceWeight)) Spacer(modifier = Modifier.weight(spaceWeight))
} }
} }
/** /**
* 历史活动列表 * 历史活动列表
* *
* @param modifier * @param modifier
*/ */
@Composable @Composable
private fun HistoryActivityList(modifier: Modifier,model:HistoryActViewModel= viewModel(),scaffoldModel: ScaffoldModel= viewModel()){ private fun HistoryActivityList(modifier: Modifier,model:HistoryActViewModel= viewModel(),scaffoldModel: ScaffoldModel= viewModel()){
val listState= rememberLazyListState() val listState= rememberLazyListState()
val list by model.data.observeAsState() val list by model.data.observeAsState()
LazyColumn(state = listState,modifier = modifier) { LazyColumn(state = listState,modifier = modifier) {
@ -371,15 +375,15 @@ private fun HistoryActivityList(modifier: Modifier,model:HistoryActViewModel= vi
if(listState.layoutInfo.totalItemsCount-listState.firstVisibleItemIndex==model.initSize/2-1){ if(listState.layoutInfo.totalItemsCount-listState.firstVisibleItemIndex==model.initSize/2-1){
model.loadMore { scaffoldModel.update(message=it) } model.loadMore { scaffoldModel.update(message=it) }
} }
} }
/** /**
* 历史活动 * 历史活动
* *
* @param modifier * @param modifier
*/ */
@Composable @Composable
private fun HistoryActivity(modifier: Modifier,historyActVo: HistoryActVo){ private fun HistoryActivity(modifier: Modifier,historyActVo: HistoryActVo){
Box(modifier=modifier,contentAlignment = Alignment.Center){ Box(modifier=modifier,contentAlignment = Alignment.Center){
Image(painter = painterResource(id = R.drawable.history_activity_border), Image(painter = painterResource(id = R.drawable.history_activity_border),
contentDescription = null, contentDescription = null,
@ -390,12 +394,14 @@ private fun HistoryActivity(modifier: Modifier,historyActVo: HistoryActVo){
Text(text = historyActVo.name) Text(text = historyActVo.name)
} }
} }
@Preview @Preview
@Composable @Composable
fun NamePreview(){ fun NamePreview(){
Divider(color = MaterialTheme.colors.background) Divider(color = MaterialTheme.colors.background)
}
} }

@ -39,7 +39,7 @@ class ExamActivity : ComponentActivity() {
setContent { setContent {
Body { scaffoldState -> Body { scaffoldState ->
MainFrame(background = { Background(image = BackgroundImage.exam) }) { MainFrame(background = { Background(image = BackgroundImage.Exam,alpha = 0.6F) }) {
Spacer(modifier = Modifier.weight(0.1F)) Spacer(modifier = Modifier.weight(0.1F))
Title(modifier = Modifier.weight(0.1F)) Title(modifier = Modifier.weight(0.1F))
Exam(modifier = Modifier.weight(0.8F)) Exam(modifier = Modifier.weight(0.8F))
@ -48,20 +48,20 @@ class ExamActivity : ComponentActivity() {
} }
} }
} }
}
/**
/**
* 底部按钮 * 底部按钮
* *
*/ */
@Composable @Composable
private fun BottomButton( private fun BottomButton(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
model: ExamViewModel = viewModel(), model: ExamViewModel = viewModel(),
scaffoldModel: ScaffoldModel = viewModel() scaffoldModel: ScaffoldModel = viewModel()
) { ) {
val context = LocalContext.current as ExamActivity val context = LocalContext.current as ExamActivity
Row(modifier = modifier, horizontalArrangement = Arrangement.Center) { Row(modifier = modifier, horizontalArrangement = Arrangement.Center) {
@ -85,23 +85,23 @@ private fun BottomButton(
Text(text = model.back) Text(text = model.back)
} }
} }
} }
/** /**
* 标题 * 标题
* *
* @param modifier * @param modifier
*/ */
@Composable @Composable
private fun Title(modifier: Modifier = Modifier) { private fun Title(modifier: Modifier = Modifier) {
val context= LocalContext.current as ExamActivity val context= LocalContext.current as ExamActivity
Row(horizontalArrangement = Arrangement.Center, modifier = modifier.fillMaxWidth()) { Row(horizontalArrangement = Arrangement.Center, modifier = modifier.fillMaxWidth()) {
Text(text = context.activityType.menuName, style = MaterialTheme.typography.h4) Text(text = context.activityType.menuName, style = MaterialTheme.typography.h4)
} }
} }
@Composable @Composable
private fun ExamChild(it:Exam,examHeight: Dp,isAdd: Boolean=false){ private fun ExamChild(it:Exam,examHeight: Dp,isAdd: Boolean=false){
val questionWeight=0.3F val questionWeight=0.3F
when (it) { when (it) {
is OpenQuestionsVo -> ExamOQ( is OpenQuestionsVo -> ExamOQ(
@ -116,21 +116,21 @@ private fun ExamChild(it:Exam,examHeight: Dp,isAdd: Boolean=false){
isAdd = isAdd isAdd = isAdd
) )
} }
} }
/** /**
* 题目列表 * 题目列表
* *
* @param modifier * @param modifier
* @param model * @param model
*/ */
@Composable @Composable
private fun Exam( private fun Exam(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
model: ExamViewModel = viewModel(), model: ExamViewModel = viewModel(),
scaffoldModel: ScaffoldModel = viewModel(), scaffoldModel: ScaffoldModel = viewModel(),
examHeight: Dp = 350.dp examHeight: Dp = 350.dp
) { ) {
val listState = rememberLazyListState() val listState = rememberLazyListState()
val data by model.data.observeAsState() val data by model.data.observeAsState()
val newExam by model.newExam.observeAsState() val newExam by model.newExam.observeAsState()
@ -167,16 +167,16 @@ private fun Exam(
} }
} }
/** /**
* 问题 * 问题
* *
* @param modifier * @param modifier
* @param exam * @param exam
*/ */
@Composable @Composable
private fun Question(modifier: Modifier = Modifier, exam: Exam) { private fun Question(modifier: Modifier = Modifier, exam: Exam) {
BaseTextField( BaseTextField(
form = exam.question, form = exam.question,
modifier = modifier modifier = modifier
@ -184,14 +184,14 @@ private fun Question(modifier: Modifier = Modifier, exam: Exam) {
.background(color = MaterialTheme.colors.background) .background(color = MaterialTheme.colors.background)
) )
} }
/** /**
* 操作按钮 * 操作按钮
* *
*/ */
@Composable @Composable
private fun ActionButton(modifier: Modifier = Modifier, isAdd: Boolean, private fun ActionButton(modifier: Modifier = Modifier, isAdd: Boolean,
model: ExamViewModel= viewModel(), model: ExamViewModel= viewModel(),
scaffoldModel: ScaffoldModel= viewModel(), scaffoldModel: ScaffoldModel= viewModel(),
exam: Exam) { exam: Exam) {
@ -227,20 +227,20 @@ private fun ActionButton(modifier: Modifier = Modifier, isAdd: Boolean,
) )
} }
} }
} }
/** /**
* 开放题 * 开放题
* *
* @param openQuestionsVo * @param openQuestionsVo
*/ */
@Composable @Composable
private fun ExamOQ( private fun ExamOQ(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
openQuestionsVo: OpenQuestionsVo, openQuestionsVo: OpenQuestionsVo,
isAdd: Boolean = false isAdd: Boolean = false
) { ) {
Row(modifier = modifier) { Row(modifier = modifier) {
val context= LocalContext.current as ExamActivity val context= LocalContext.current as ExamActivity
Question( Question(
@ -260,21 +260,21 @@ private fun ExamOQ(
) )
} }
} }
} }
/** /**
* 选择题 * 选择题
* *
* @param choiceQuestionVo * @param choiceQuestionVo
*/ */
@Composable @Composable
private fun ExamCQ( private fun ExamCQ(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
choiceQuestionVo: ChoiceQuestionVo, choiceQuestionVo: ChoiceQuestionVo,
isAdd: Boolean = false, isAdd: Boolean = false,
model: ExamViewModel = viewModel(), model: ExamViewModel = viewModel(),
questionWeight:Float questionWeight:Float
) { ) {
Row(modifier = modifier) { Row(modifier = modifier) {
val context= LocalContext.current as ExamActivity val context= LocalContext.current as ExamActivity
Column( Column(
@ -331,4 +331,5 @@ private fun ExamCQ(
} }
} }
}
} }

@ -26,7 +26,7 @@ class ReNameActivity: ComponentActivity() {
setContent { setContent {
Body { Body {
scaffoldState -> scaffoldState ->
MainFrame(background = { Background(image = BackgroundImage.rename) }) { MainFrame(background = { Background(image = BackgroundImage.Rename) }) {
Spacer( Spacer(
modifier = Modifier modifier = Modifier
.weight(0.2F) .weight(0.2F)
@ -48,54 +48,53 @@ class ReNameActivity: ComponentActivity() {
} }
} }
} }
}
/** /**
* 标题 * 标题
* *
*/ */
@Composable @Composable
private fun Title(modifier: Modifier=Modifier,model:RenameViewModel= viewModel()){ private fun Title(modifier: Modifier=Modifier,model:RenameViewModel= viewModel()){
Row(modifier = modifier.fillMaxWidth(),horizontalArrangement = Arrangement.Center) { Row(modifier = modifier.fillMaxWidth(),horizontalArrangement = Arrangement.Center) {
Text(text = model.menuName,style = MaterialTheme.typography.h4) Text(text = model.menuName,style = MaterialTheme.typography.h4)
} }
} }
/** /**
* 社团原名 * 社团原名
* *
*/ */
@Composable @Composable
private fun OldName(modifier: Modifier=Modifier,model:RenameViewModel= viewModel()){ private fun OldName(modifier: Modifier=Modifier,model:RenameViewModel= viewModel()){
BaseTextField(form = model.oldName,modifier = modifier.fillMaxWidth(),singeLine = true) BaseTextField(form = model.oldName,modifier = modifier.fillMaxWidth(),singeLine = true)
} }
/** /**
* 社团新名 * 社团新名
* *
*/ */
@Composable @Composable
private fun NewName(modifier: Modifier=Modifier,model:RenameViewModel= viewModel()){ private fun NewName(modifier: Modifier=Modifier,model:RenameViewModel= viewModel()){
BaseTextField(form = model.newName,modifier = modifier.fillMaxWidth(),singeLine = true) BaseTextField(form = model.newName,modifier = modifier.fillMaxWidth(),singeLine = true)
} }
/** /**
* 换名原因 * 换名原因
* *
*/ */
@Composable @Composable
private fun Cause(modifier: Modifier=Modifier,model:RenameViewModel= viewModel()){ private fun Cause(modifier: Modifier=Modifier,model:RenameViewModel= viewModel()){
BaseTextField(form = model.cause,modifier = modifier.fillMaxWidth()) BaseTextField(form = model.cause,modifier = modifier.fillMaxWidth())
} }
/** /**
* 操作按钮 * 操作按钮
* *
* @param modifier * @param modifier
* @param model * @param model
*/ */
@Composable @Composable
private fun BottomButton(modifier: Modifier=Modifier,model:RenameViewModel= viewModel(),scaffoldModel: ScaffoldModel= viewModel()){ private fun BottomButton(modifier: Modifier=Modifier,model:RenameViewModel= viewModel(),scaffoldModel: ScaffoldModel= viewModel()){
Row(modifier = modifier.fillMaxWidth()) { Row(modifier = modifier.fillMaxWidth()) {
val weight=(1-0.5F)/2 val weight=(1-0.5F)/2
val context= LocalContext.current as ReNameActivity val context= LocalContext.current as ReNameActivity
@ -111,4 +110,5 @@ private fun BottomButton(modifier: Modifier=Modifier,model:RenameViewModel= view
} }
Spacer(modifier = Modifier.weight(weight)) Spacer(modifier = Modifier.weight(weight))
} }
}
} }

@ -50,7 +50,7 @@ class RegAssociationActivity: ComponentActivity(){
CSAMSTheme { CSAMSTheme {
Body { Body {
scaffoldState -> scaffoldState ->
MainFrame(background = { Background(BackgroundImage.reg_association,alpha = 0.5F) }) { MainFrame(background = { Background(BackgroundImage.RegAssociation,alpha = 0.5F) }) {
Spacer( Spacer(
modifier = Modifier modifier = Modifier
.weight(0.1F) .weight(0.1F)
@ -79,15 +79,14 @@ class RegAssociationActivity: ComponentActivity(){
} }
} }
}
/** /**
* 社团Logo * 社团Logo
* *
* @param modifier * @param modifier
*/ */
@Composable @Composable
private fun Logo(model:RegAssociationViewModel= viewModel(),modifier: Modifier) { private fun Logo(model:RegAssociationViewModel= viewModel(),modifier: Modifier) {
val photoIntent=Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI) val photoIntent=Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
photoIntent.type = "image/*" photoIntent.type = "image/*"
val uri:Uri? by model.picture.observeAsState() val uri:Uri? by model.picture.observeAsState()
@ -172,10 +171,10 @@ private fun Logo(model:RegAssociationViewModel= viewModel(),modifier: Modifier)
} }
} }
@Composable @Composable
private fun BottomButton(modifier: Modifier=Modifier,scaffoldModel: ScaffoldModel= viewModel(),model:RegAssociationViewModel= viewModel()){ private fun BottomButton(modifier: Modifier=Modifier,scaffoldModel: ScaffoldModel= viewModel(),model:RegAssociationViewModel= viewModel()){
val context= LocalContext.current as RegAssociationActivity val context= LocalContext.current as RegAssociationActivity
Row(modifier = modifier,horizontalArrangement = Arrangement.Center) { Row(modifier = modifier,horizontalArrangement = Arrangement.Center) {
OutlinedButton(onClick = { OutlinedButton(onClick = {
@ -191,33 +190,36 @@ private fun BottomButton(modifier: Modifier=Modifier,scaffoldModel: ScaffoldMode
} }
} }
} }
/** /**
* 菜单标题 * 菜单标题
* *
*/ */
@Composable @Composable
private fun Title(model:RegAssociationViewModel= viewModel()){ private fun Title(model:RegAssociationViewModel= viewModel()){
Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.Center) { Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.Center) {
Text(text = model.frameDesc,style = MaterialTheme.typography.h4) Text(text = model.frameDesc,style = MaterialTheme.typography.h4)
} }
} }
/** /**
* 社团名称 * 社团名称
* @param model * @param model
*/ */
@Composable @Composable
private fun Name(model:RegAssociationViewModel= viewModel()){ private fun Name(model:RegAssociationViewModel= viewModel()){
BaseTextField(form = model.name,singeLine = true,modifier = Modifier.fillMaxWidth()) BaseTextField(form = model.name,singeLine = true,modifier = Modifier.fillMaxWidth())
} }
/** /**
* 社团简介 * 社团简介
* @param model * @param model
*/ */
@Composable @Composable
private fun Desc(model:RegAssociationViewModel= viewModel(),modifier:Modifier){ private fun Desc(model:RegAssociationViewModel= viewModel(),modifier:Modifier){
BaseTextField(form = model.desc,modifier = modifier) BaseTextField(form = model.desc,modifier = modifier)
}
} }

@ -4,6 +4,7 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.gyf.csams.NOT_IMPL_TIP
import com.gyf.csams.R import com.gyf.csams.R
import com.gyf.csams.uikit.ScrollList import com.gyf.csams.uikit.ScrollList
import com.gyf.csams.uikit.StringForm import com.gyf.csams.uikit.StringForm
@ -85,7 +86,7 @@ class MainViewModel:ViewModel(){
* *
*/ */
fun sendMessage(callback: (value: String) -> Unit){ fun sendMessage(callback: (value: String) -> Unit){
callback("功能尚未实现,敬请期待") callback(NOT_IMPL_TIP)
} }
/** /**
@ -94,7 +95,7 @@ class MainViewModel:ViewModel(){
* @param callback * @param callback
*/ */
fun openNotification(callback: (value: String) -> Unit){ fun openNotification(callback: (value: String) -> Unit){
callback("功能尚未实现,敬请期待") callback(NOT_IMPL_TIP)
} }
} }
@ -125,7 +126,7 @@ class ListViewModel: ScrollList<AssociationDto>() {
*/ */
fun search(callback: (value: String) -> Unit){ fun search(callback: (value: String) -> Unit){
Logger.i("搜索条件[社团名称:${name.formValue.value},社团简介:${desc.formValue.value}]") Logger.i("搜索条件[社团名称:${name.formValue.value},社团简介:${desc.formValue.value}]")
callback("功能尚未实现,敬请期待") callback(NOT_IMPL_TIP)
} }
override val initSize: Int = 10 override val initSize: Int = 10

@ -32,6 +32,7 @@ import com.gyf.csams.association.ui.RegAssociationActivity
import com.gyf.csams.main.model.* import com.gyf.csams.main.model.*
import com.gyf.csams.uikit.* import com.gyf.csams.uikit.*
import com.gyf.csams.uikit.theme.CSAMSTheme import com.gyf.csams.uikit.theme.CSAMSTheme
import com.gyf.csams.util.randomChinese
/** /**
@ -66,15 +67,14 @@ class MainActivity : ComponentActivity() {
} }
}
/** /**
* 个人中心 * 个人中心
* *
*/ */
@Composable @Composable
private fun Center(model:CenterViewModel= viewModel(), scaffoldModel: ScaffoldModel= viewModel(), navController: NavHostController){ private fun Center(model:CenterViewModel= viewModel(), scaffoldModel: ScaffoldModel= viewModel(), navController: NavHostController){
MainFrame(background = { Background(image = BackgroundImage.center,alpha = 0.5F) }, mainMenu = MainMenu.Center, nav = navController) { MainFrame(background = { Background(image = BackgroundImage.Center,alpha = 0.5F) }, mainMenu = MainMenu.Center, nav = navController) {
Column(modifier = Modifier Column(modifier = Modifier
.weight(0.33F) .weight(0.33F)
.fillMaxWidth(),verticalArrangement = Arrangement.Bottom) { .fillMaxWidth(),verticalArrangement = Arrangement.Bottom) {
@ -104,14 +104,14 @@ private fun Center(model:CenterViewModel= viewModel(), scaffoldModel: ScaffoldMo
.weight(0.66F) .weight(0.66F)
.fillMaxWidth()) .fillMaxWidth())
} }
} }
/** /**
* 主界面 * 主界面
*/ */
@Composable @Composable
private fun Main(navController: NavHostController) { private fun Main(navController: NavHostController) {
MainFrame(background = { Background(image = BackgroundImage.main) }, mainMenu = MainMenu.Main, nav = navController) { MainFrame(background = { Background(image = BackgroundImage.Main) }, mainMenu = MainMenu.Main, nav = navController) {
Column(modifier = Modifier.weight(0.33F)) { Column(modifier = Modifier.weight(0.33F)) {
Notification() Notification()
MessageBoard() MessageBoard()
@ -123,18 +123,18 @@ private fun Main(navController: NavHostController) {
PosterWithDesc() PosterWithDesc()
} }
} }
} }
/** /**
* 社团列表 * 社团列表
* *
* @param navController * @param navController
*/ */
@Composable @Composable
private fun AssociationList(navController: NavHostController) { private fun AssociationList(navController: NavHostController) {
MainFrame( MainFrame(
background = { Background(image = BackgroundImage.list) }, background = { Background(image = BackgroundImage.AssociationList) },
mainMenu = MainMenu.List, mainMenu = MainMenu.List,
nav = navController nav = navController
) { ) {
@ -142,14 +142,14 @@ private fun AssociationList(navController: NavHostController) {
AssociationSearch() AssociationSearch()
AssociationListBody() AssociationListBody()
} }
} }
/** /**
* 注册社团按钮 * 注册社团按钮
* *
*/ */
@Composable @Composable
private fun RegisterAssociation() { private fun RegisterAssociation() {
val context= LocalContext.current val context= LocalContext.current
Row( Row(
horizontalArrangement = Arrangement.End, horizontalArrangement = Arrangement.End,
@ -167,14 +167,14 @@ private fun RegisterAssociation() {
) )
} }
} }
} }
/** /**
* 社团列表 * 社团列表
* *
*/ */
@Composable @Composable
private fun AssociationListBody(model: ListViewModel = viewModel(),scaffoldModel: ScaffoldModel= viewModel()) { private fun AssociationListBody(model: ListViewModel = viewModel(),scaffoldModel: ScaffoldModel= viewModel()) {
val associationList: MutableList<AssociationDto>? by model.associationDto.observeAsState() val associationList: MutableList<AssociationDto>? by model.associationDto.observeAsState()
val listState = rememberLazyListState() val listState = rememberLazyListState()
@ -208,10 +208,10 @@ private fun AssociationListBody(model: ListViewModel = viewModel(),scaffoldModel
if(listState.layoutInfo.totalItemsCount-listState.firstVisibleItemIndex==model.associationListSize/2-1){ if(listState.layoutInfo.totalItemsCount-listState.firstVisibleItemIndex==model.associationListSize/2-1){
model.loadMore { scaffoldModel.update(message=it) } model.loadMore { scaffoldModel.update(message=it) }
} }
} }
@Composable @Composable
private fun Association(associationDto: AssociationDto) { private fun Association(associationDto: AssociationDto) {
val context= LocalContext.current val context= LocalContext.current
Card(modifier = Modifier.clickable(onClick = { context.startActivity(Intent(context,AssociationActivity::class.java)) })) { Card(modifier = Modifier.clickable(onClick = { context.startActivity(Intent(context,AssociationActivity::class.java)) })) {
Image( Image(
@ -225,14 +225,14 @@ private fun Association(associationDto: AssociationDto) {
} }
} }
/** /**
* 社团检索 * 社团检索
* *
*/ */
@Composable @Composable
private fun AssociationSearch(model: ListViewModel = viewModel(),scaffoldModel: ScaffoldModel= viewModel()) { private fun AssociationSearch(model: ListViewModel = viewModel(),scaffoldModel: ScaffoldModel= viewModel()) {
Card(modifier = Modifier.padding(horizontal = 50.dp, vertical = 10.dp)) { Card(modifier = Modifier.padding(horizontal = 50.dp, vertical = 10.dp)) {
Column { Column {
@ -254,14 +254,14 @@ private fun AssociationSearch(model: ListViewModel = viewModel(),scaffoldModel:
} }
} }
/** /**
* 通知 * 通知
* *
*/ */
@Composable @Composable
private fun Notification(mainViewModel: MainViewModel= viewModel(),scaffoldModel: ScaffoldModel= viewModel()) { private fun Notification(mainViewModel: MainViewModel= viewModel(),scaffoldModel: ScaffoldModel= viewModel()) {
Row( Row(
horizontalArrangement = Arrangement.End, horizontalArrangement = Arrangement.End,
modifier = Modifier modifier = Modifier
@ -278,14 +278,14 @@ private fun Notification(mainViewModel: MainViewModel= viewModel(),scaffoldModel
} }
} }
} }
/** /**
* 圆角矩形边框 * 圆角矩形边框
* *
*/ */
@Composable @Composable
private fun MyBorder(content: @Composable BoxScope.() -> Unit) { private fun MyBorder(content: @Composable BoxScope.() -> Unit) {
Box(modifier = Modifier.padding(horizontal = 15.dp)) { Box(modifier = Modifier.padding(horizontal = 15.dp)) {
Box( Box(
modifier = Modifier modifier = Modifier
@ -298,14 +298,14 @@ private fun MyBorder(content: @Composable BoxScope.() -> Unit) {
content() content()
} }
} }
} }
/** /**
* 留言板 * 留言板
* *
*/ */
@Composable @Composable
private fun MessageBoard(model: MarqueeViewModel = viewModel(),mainViewModel:MainViewModel= viewModel(),scaffoldModel: ScaffoldModel= viewModel()) { private fun MessageBoard(model: MarqueeViewModel = viewModel(),mainViewModel:MainViewModel= viewModel(),scaffoldModel: ScaffoldModel= viewModel()) {
MyBorder { MyBorder {
Row( Row(
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
@ -333,14 +333,14 @@ private fun MessageBoard(model: MarqueeViewModel = viewModel(),mainViewModel:Mai
} }
} }
} }
/** /**
* 活动标题 * 活动标题
* *
*/ */
@Composable @Composable
private fun ClubActivitiesTitle() { private fun ClubActivitiesTitle() {
MyBorder { MyBorder {
Row( Row(
modifier = Modifier modifier = Modifier
@ -357,15 +357,15 @@ private fun ClubActivitiesTitle() {
) )
} }
} }
} }
/** /**
* 带介绍活动海报 * 带介绍活动海报
* *
*/ */
@Composable @Composable
private fun PosterWithDesc(model: CarouselViewModel = viewModel()) { private fun PosterWithDesc(model: CarouselViewModel = viewModel()) {
Carousel(model = model) { Carousel(model = model) {
Column { Column {
Poster(modifier = Modifier Poster(modifier = Modifier
@ -374,21 +374,25 @@ private fun PosterWithDesc(model: CarouselViewModel = viewModel()) {
DescCard( DescCard(
modifier = Modifier modifier = Modifier
.weight(0.4F) .weight(0.4F)
.fillMaxWidth() .fillMaxWidth(),
content = randomChinese(500)
) )
} }
} }
} }
@Preview(showBackground = true) @Preview(showBackground = true)
@Composable @Composable
fun DefaultPreview() { fun DefaultPreview() {
CSAMSTheme { CSAMSTheme {
Text(text = "666") Text(text = "666")
} }
}
} }

@ -1,19 +1,18 @@
package com.gyf.csams.uikit package com.gyf.csams.uikit
import android.app.Activity
import androidx.annotation.DrawableRes import androidx.annotation.DrawableRes
import androidx.compose.animation.Crossfade import androidx.compose.animation.Crossfade
import androidx.compose.animation.animateColor import androidx.compose.animation.animateColor
import androidx.compose.animation.core.* import androidx.compose.animation.core.*
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.* import androidx.compose.material.*
import androidx.compose.runtime.Composable import androidx.compose.runtime.*
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@ -27,6 +26,8 @@ import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import androidx.navigation.compose.navigate import androidx.navigation.compose.navigate
@ -35,7 +36,6 @@ import com.gyf.csams.APP
import com.gyf.csams.R import com.gyf.csams.R
import com.gyf.csams.main.model.CarouselViewModel import com.gyf.csams.main.model.CarouselViewModel
import com.gyf.csams.main.model.MarqueeViewModel import com.gyf.csams.main.model.MarqueeViewModel
import com.gyf.csams.uikit.theme.CSAMSTheme
import com.orhanobut.logger.Logger import com.orhanobut.logger.Logger
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -90,7 +90,7 @@ enum class MainMenu(
* @param onClick * @param onClick
*/ */
@Composable @Composable
fun MenuIconButton(_menu: MainMenu, menu: MainMenu, modifier: Modifier, onClick: () -> Unit) { fun MenuIconButton(_menu: MainMenu, menu: MainMenu, modifier: Modifier=Modifier, onClick: () -> Unit) {
Row( Row(
modifier = modifier, horizontalArrangement = Arrangement.Center modifier = modifier, horizontalArrangement = Arrangement.Center
) { ) {
@ -113,30 +113,74 @@ fun MenuIconButton(_menu: MainMenu, menu: MainMenu, modifier: Modifier, onClick:
@Composable @Composable
fun MainBottomAppBar(menu: MainMenu, nav: NavHostController, modifier: Modifier = Modifier) { fun MainBottomAppBar(menu: MainMenu, nav: NavHostController, modifier: Modifier = Modifier) {
BottomAppBar(backgroundColor = MaterialTheme.colors.background, modifier = modifier) { BottomAppBar(backgroundColor = MaterialTheme.colors.background, modifier = modifier) {
//图标宽度平等分 Row(Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.SpaceBetween) {
MenuIconButton(_menu = menu, menu = MainMenu.Main,
val weight = 1 / (MainMenu.values().size * 1.0f)
Row(Modifier.fillMaxWidth()) {
MenuIconButton(_menu = menu, menu = MainMenu.Main, Modifier.weight(weight),
onClick = { nav.navigate(MainMenu.Main.name) }) onClick = { nav.navigate(MainMenu.Main.name) })
MenuIconButton(_menu = menu, menu = MainMenu.List, Modifier.weight(weight), MenuIconButton(_menu = menu, menu = MainMenu.List,
onClick = { nav.navigate(MainMenu.List.name) }) onClick = { nav.navigate(MainMenu.List.name) })
MenuIconButton(_menu = menu, menu = MainMenu.Center, Modifier.weight(weight), MenuIconButton(_menu = menu, menu = MainMenu.Center,
onClick = { nav.navigate(MainMenu.Center.name) }) onClick = { nav.navigate(MainMenu.Center.name) })
} }
} }
} }
/**
* 顶部菜单
*
*/
interface TopMenuInterface<T:TopBarMenu>{
/**
* 当前菜单
*/
val _currentMenu: MutableLiveData<T>
val currentMenu: LiveData<T>
/**
* 切换顶部菜单
*
* @param menu
*/
fun clickMenu(menu:T){
_currentMenu.value=menu
}
}
interface TopBarMenu{
val menuName:String
val name:String
}
interface StartMenu<T>{
val startMenu:T
}
/** /**
* 社团菜单 * 社团菜单
* *
*/ */
enum class AssociationMenu(val menuName: String) { enum class AssociationMenu(override val menuName: String):TopBarMenu {
member("社团成员"), Member("社团成员"),
main("社团主页"), Main("社团主页"),
list("活动列表") ActivityList("活动列表");
companion object Menu:StartMenu<AssociationMenu>{
override val startMenu: AssociationMenu = Main
}
}
enum class ActivityDetailMenu(override val menuName:String):TopBarMenu{
Info("活动信息"),
Photo("相册"),
Member("活动成员"),
BBS("交流区");
companion object Menu:StartMenu<ActivityDetailMenu>{
override val startMenu: ActivityDetailMenu = Info
}
} }
/** /**
@ -144,16 +188,18 @@ enum class AssociationMenu(val menuName: String) {
* *
*/ */
@Composable @Composable
fun AssociationAppBar( fun TextTopAppBar(
menu: AssociationMenu, nav:NavHostController,
nav: NavHostController, currentMenuName:String,
back: () -> Unit, menuNames:Array<out TopBarMenu>,
dropMenu: () -> Unit, iconMenu: (() -> Unit)? = null,
content:@Composable () -> Unit @DrawableRes icon:Int = R.drawable.ic_configuration,
dropMenuContent:@Composable () -> Unit = {},
) { ) {
TopAppBar(backgroundColor = MaterialTheme.colors.secondary) { TopAppBar(backgroundColor = MaterialTheme.colors.secondary) {
Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) { Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
IconButton(onClick = back, modifier = Modifier.weight(0.1F)) { val context= LocalContext.current as Activity
IconButton(onClick = {context.onBackPressed()}, modifier = Modifier.weight(0.1F)) {
Icon( Icon(
painter = painterResource(id = R.drawable.ic_arrow_left), painter = painterResource(id = R.drawable.ic_arrow_left),
contentDescription = null contentDescription = null
@ -163,32 +209,35 @@ fun AssociationAppBar(
modifier = Modifier modifier = Modifier
.weight(0.8F) .weight(0.8F)
.fillMaxHeight(), .fillMaxHeight(),
horizontalArrangement = Arrangement.Center, horizontalArrangement = Arrangement.SpaceAround,
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
val menus = AssociationMenu.values() menuNames.forEach {
menus.forEach {
Row( Row(
modifier = Modifier modifier = Modifier
.weight(1F / menus.size) .weight(1F / menuNames.size)
.clickable(onClick = { nav.navigate(it.name) }), .clickable(onClick = { nav.navigate(it.name) }),
horizontalArrangement = Arrangement.Center horizontalArrangement = Arrangement.Center
) { ) {
Text( Text(
text = it.menuName, text = it.menuName,
color = if (menu == it) MaterialTheme.colors.primary else MaterialTheme.colors.onBackground color = if (currentMenuName == it.menuName) MaterialTheme.colors.primary else MaterialTheme.colors.onBackground
) )
} }
} }
} }
IconButton(onClick = dropMenu, modifier = Modifier.weight(0.1F)) { if(iconMenu!=null) {
IconButton(onClick = iconMenu, modifier = Modifier.weight(0.1F)) {
Icon( Icon(
painter = painterResource(id = R.drawable.ic_configuration), painter = painterResource(id = icon),
contentDescription = null contentDescription = null
) )
} }
}else{
Spacer(modifier = Modifier.weight(0.1F))
}
} }
content() if(iconMenu!=null) dropMenuContent()
} }
} }
@ -383,26 +432,34 @@ fun ShowSnackbar(model: ScaffoldModel = viewModel(), scaffoldState: ScaffoldStat
*/ */
enum class BackgroundImage(@DrawableRes val id: Int) { enum class BackgroundImage(@DrawableRes val id: Int) {
//主页 //主页
main(R.drawable.mb_bg_fb_08), Main(R.drawable.mb_bg_fb_08),
//社团列表 //社团列表
list(R.drawable.mb_bg_fb_07), AssociationList(R.drawable.mb_bg_fb_07),
//个人中心 //个人中心
center(R.drawable.mb_bg_fb_28), Center(R.drawable.mb_bg_fb_28),
//注册社团 //注册社团
reg_association(R.drawable.mb_bg_fb_06), RegAssociation(R.drawable.mb_bg_fb_06),
//社团主界面 //社团主界面
association_main(R.drawable.mb_bg_fb_25_180), AssociationMain(R.drawable.mb_bg_fb_25_180),
//社团重命名 //社团重命名
rename(R.drawable.mb_bg_fb_27), Rename(R.drawable.mb_bg_fb_27),
//社团题库管理 //社团题库管理
exam(R.drawable.mb_bg_fb_02) Exam(R.drawable.mb_bg_fb_09),
//活动信息
ActivityInfo(R.drawable.mb_bg_fb_01),
//活动相册
ActivityPhoto(R.drawable.mb_bg_fb_02),
//活动成员
ActivityMember(R.drawable.mb_bg_fb_03),
//交流区
ActivityBBS(R.drawable.mb_bg_fb_04)
} }
/** /**
@ -493,47 +550,78 @@ fun Poster(modifier: Modifier = Modifier, @DrawableRes id: Int) {
* *
*/ */
@Composable @Composable
fun DescCard(modifier: Modifier) { fun DescCard(modifier: Modifier,content:String) {
Card( Card(
modifier = modifier, modifier = modifier,
backgroundColor = Color.Transparent backgroundColor = Color.Transparent
) { ) {
Box {
Image( Image(
painter = painterResource(id = R.drawable.hot_activity_desc_background), painter = painterResource(id = R.drawable.hot_activity_desc_background),
contentDescription = null contentDescription = null,
contentScale = ContentScale.FillBounds,
modifier = Modifier.fillMaxSize()
) )
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 10.dp)) {
Row(modifier = Modifier.fillMaxWidth()) { Spacer(modifier = Modifier.weight(0.15F))
Spacer(modifier = Modifier.weight(0.2F))
Column(
modifier = Modifier
.weight(0.5F)
) {
Spacer(modifier = Modifier.weight(0.1F))
Text( Text(
text = "文字对任何界面都属于核心内容,而利用 Jetpack Compose 可以更轻松地显示或写入文字。Compose 可以充分利用其构建块的组合,这意味着您无需覆盖各种属性和方法,也无需扩展大型类,即可拥有特定的可组合项设计以及按您期望的方式运行的逻辑。" modifier = Modifier.weight(0.65F),
.repeat(10), overflow = TextOverflow.Ellipsis, text = content,
modifier = Modifier.weight(0.8F) overflow = TextOverflow.Ellipsis
) )
Spacer(modifier = Modifier.weight(0.1F)) Spacer(modifier = Modifier.weight(0.15F))
} }
Spacer(modifier = Modifier.weight(0.2F))
} }
} }
} }
//@Preview
@Preview
@Composable @Composable
fun AnimationTextPreview() { fun AnimationTextPreview() {
AnimationText(text = "6666") AnimationText(text = "6666")
} }
//@Preview @Preview
@Composable @Composable
fun MyBottomAppBarPreview() { fun MyBottomAppBarPreview() {
CSAMSTheme { val arr:List<Arrangement.Horizontal> = listOf(
Arrangement.Start,
Arrangement.End,
Arrangement.Center,
Arrangement.SpaceBetween,
Arrangement.SpaceAround,
Arrangement.SpaceEvenly
)
var i by remember {
mutableStateOf(3)
}
Column(modifier = Modifier.fillMaxSize()) {
Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.SpaceEvenly) {
OutlinedButton(onClick = { i += 1 }) {
Text(text = "添加元素")
}
if(i>1) {
OutlinedButton(onClick = { i -= 1 }) {
Text(text = "删除元素")
}
}
}
arr.forEach {
Column(modifier = Modifier
.weight(1F / arr.size)
.border(width = 1.dp, color = MaterialTheme.colors.background)) {
Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.Center) {
Text(text = "$it",style = MaterialTheme.typography.h5)
}
Row(modifier = Modifier.fillMaxSize(),
horizontalArrangement = it,
verticalAlignment = Alignment.CenterVertically) {
repeat(i) {
Text(text = "$it", style = MaterialTheme.typography.h3)
}
}
}
}
} }
} }

@ -0,0 +1,55 @@
package com.gyf.csams.util
import okhttp3.internal.toHexString
import java.text.SimpleDateFormat
import java.util.*
fun randomNum(length:Int=8):String{
return List(length) {('0' .. '9').random()}.joinToString("")
}
fun encode(char: Char) = "\\u${char.toInt().toHexString()}"
//String ->unicode
fun String.encodeUnicode(text: String) = text
.toCharArray().joinToString(separator = "", truncated = "") { encode(it) }
//unicode ->String
fun String.decodeUnicode(): String {
fun decode1(unicode: String) = unicode.toInt(16).toChar()
val unicodes = this.split("\\u").mapNotNull { if (it.isNotBlank()) decode1(it) else null }
return String(unicodes.toCharArray())
}
val CHINESE_UNICODE_AREA=0X4e00..0X9fa5
/**
* 随机中文
*
* @param length
* @return
*/
fun randomChinese(length:Int=8):String{
return List(length){ "\\u${CHINESE_UNICODE_AREA.random().toHexString()}".decodeUnicode() }.joinToString("")
}
const val DATETIME_FORMAT="yyyy-MM-dd HH:mm"
const val START_TIME="2021-01-01 00:00"
val FORMAT=SimpleDateFormat(DATETIME_FORMAT,Locale.US)
val startUnix= FORMAT.parse(START_TIME)?.time
fun randomDateTime():Date{
if (startUnix != null) {
return Date("${(startUnix..Date().time).random()}".toLong())
}else{
throw IllegalArgumentException("生成随机失败,无法获取起始时间")
}
}
fun Date.format():String{
return FORMAT.format(this)
}

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="200dp"
android:height="200dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="#FF000000"
android:pathData="M704,341.33h64a64,64 0,0 1,64 64v362.67a64,64 0,0 1,-64 64H256a64,64 0,0 1,-64 -64V405.33a64,64 0,0 1,64 -64h64v64h-64v362.67h512V405.33h-64v-64zM517.65,124.63l150.83,150.83 -45.23,45.27 -74.03,-74.01v304.77h-64V247.62l-73.17,73.13 -45.25,-45.25 150.83,-150.85z"/>
</vector>

@ -3,6 +3,7 @@ package com.gyf.csams
import com.google.gson.Gson import com.google.gson.Gson
import com.google.gson.reflect.TypeToken import com.google.gson.reflect.TypeToken
import com.gyf.csams.util.ApiResponse import com.gyf.csams.util.ApiResponse
import com.gyf.csams.util.randomChinese
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Test import org.junit.Test
@ -32,16 +33,16 @@ class ExampleUnitTest {
println(e.body) println(e.body)
} }
@Test
fun testYear(){
repeat(10,{
println(it)
})
}
@Test @Test
fun testCharRange(){ fun testCharRange(){
println(('A'..'D').map { "选项$it" }) repeat(100){
println(randomChinese())
}
// println(java.time.format.DateTimeFormatter.ISO_INSTANT
// .format(java.time.Instant.ofEpochMilli(1532358895000)))
} }
} }

Loading…
Cancel
Save