界面逻辑封装

完善社团界面
master
pan 3 years ago
parent 743486211b
commit 3234ec2974
  1. 2
      app/src/main/java/com/gyf/csams/APP.kt
  2. 56
      app/src/main/java/com/gyf/csams/association/model/AssociationViewModel.kt
  3. 87
      app/src/main/java/com/gyf/csams/association/ui/AssociationActivity.kt
  4. 42
      app/src/main/java/com/gyf/csams/main/model/MainViewModel.kt
  5. 28
      app/src/main/java/com/gyf/csams/main/ui/MainActivity.kt
  6. 25
      app/src/main/java/com/gyf/csams/uikit/BaseView.kt
  7. 29
      app/src/main/java/com/gyf/csams/uikit/ViewModel.kt

@ -14,6 +14,8 @@ import com.orhanobut.logger.Logger
class APP : Application() {
private lateinit var memoryCache: LruCache<BackgroundImage, Bitmap>
// Get max available VM memory, exceeding this amount will throw an
// OutOfMemory exception. Stored in kilobytes as LruCache takes an

@ -5,6 +5,7 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.gyf.csams.uikit.AssociationMenu
import com.gyf.csams.uikit.ScrollList
import com.gyf.csams.uikit.StringForm
import com.orhanobut.logger.Logger
import kotlinx.coroutines.launch
@ -24,7 +25,7 @@ data class MemberVo(val name:String)
* 社团会员
*
*/
class MemberViewModel:ViewModel(){
class MemberViewModel:ScrollList<MemberVo>(){
val name=StringForm(formDesc = "姓名关键字",5)
val search="搜索"
@ -33,30 +34,34 @@ class MemberViewModel:ViewModel(){
val memberList=_memberList
override val initSize: Int = 10
init {
initMemberList()
load()
}
/**
* 初始化成员
*
*/
private fun initMemberList(){
override fun load() {
viewModelScope.launch {
_memberList.value?.apply {
repeat(10) {
add(MemberVo(name = "成员${it+1}"))
repeat(initSize) {
add(MemberVo(name = "成员${size+1}"))
}
Logger.i("初始化社团成员size=$size")
}
Logger.i("初始化社团成员size=${_memberList.value?.size}")
}
}
/**
* 加载更多成员
*
*/
fun loadMore(){
override fun loadMore(callback: (message: String) -> Unit) {
viewModelScope.launch {
_memberList.value?.let {
val t= mutableListOf<MemberVo>()
@ -81,4 +86,41 @@ class MemberViewModel:ViewModel(){
Logger.i("搜索条件[成员姓名:${name.formValue.value}]")
callback("功能尚未实现,敬请期待")
}
}
data class HistoryActVo(val name: String)
/**
* 历史活动
*
*/
class HistoryActViewModel: ScrollList<HistoryActVo>() {
override val initSize = 10
init {
load()
}
override fun load() {
_data.value?.apply {
repeat(initSize){
add(HistoryActVo(name = "活动${size+1}"))
}
Logger.i("初始化活动数量:${size}")
}
}
override fun loadMore(callback:(message:String) -> Unit) {
_data.value?.apply {
val t= mutableListOf<HistoryActVo>()
t.addAll(this)
t.apply {
repeat(10){
add(HistoryActVo(name = "活动${t.size+1}"))
}
}
_data.postValue(t)
callback("成功加载更多活动")
}
}
}

@ -4,6 +4,7 @@ import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
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
@ -22,9 +23,7 @@ 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.association.model.AssociationViewModel
import com.gyf.csams.association.model.MemberViewModel
import com.gyf.csams.association.model.MemberVo
import com.gyf.csams.association.model.*
import com.gyf.csams.uikit.*
import com.gyf.csams.uikit.theme.CSAMSTheme
@ -46,7 +45,7 @@ class AssociationActivity: ComponentActivity() {
Column {
AssociationAppBar(menu = menu,nav = nav,back = { context.onBackPressed() }){
//TODO 显示下拉菜单
}
NavHost(navController = nav, startDestination = startMenu.name) {
composable(AssociationMenu.member.name){
@ -122,8 +121,8 @@ private fun Search(modifier:Modifier=Modifier, model: MemberViewModel= viewModel
*
*/
@Composable
private fun MemberList(modifier: Modifier=Modifier,viewModel: MemberViewModel=viewModel()){
val list:MutableList<MemberVo>? by viewModel.memberList.observeAsState()
private fun MemberList(modifier: Modifier=Modifier, model: MemberViewModel=viewModel(), scaffoldModel: ScaffoldModel= viewModel()){
val list:MutableList<MemberVo>? by model.memberList.observeAsState()
val listState= rememberLazyListState()
LazyColumn(state = listState,modifier = modifier) {
list?.forEach {
@ -148,7 +147,9 @@ private fun MemberList(modifier: Modifier=Modifier,viewModel: MemberViewModel=vi
}
item {
Row(horizontalArrangement = Arrangement.Center,modifier = Modifier.fillMaxWidth()) {
IconButton(onClick = { viewModel.loadMore() }) {
IconButton(onClick = { model.loadMore{
scaffoldModel.update(it)
} }) {
Icon(painter = painterResource(id = R.drawable.ic_arrow_down), contentDescription = null)
}
}
@ -250,7 +251,77 @@ private fun Showcase(modifier: Modifier){
@Composable
private fun AssociationList(){
MainFrame(background = { Background(image = BackgroundImage.association_main,alpha = 07F) }) {
Text(text = "活动列表")
val onGoWeight=0.3F
OngoingActivity(modifier = Modifier
.weight(onGoWeight)
.fillMaxWidth())
HistoryActivityList(modifier = Modifier
.fillMaxWidth()
.weight(1 - onGoWeight)
.border(width = 1.dp, color = MaterialTheme.colors.onBackground))
}
}
/**
* 进行中的活动
*
*/
@Composable
private fun OngoingActivity(modifier: Modifier=Modifier){
Row(modifier = modifier,horizontalArrangement = Arrangement.Center) {
val weight=0.5F
val spaceWeight=(1-0.5F)/2
Spacer(modifier = Modifier.weight(spaceWeight))
Poster(id = R.drawable.ic_launcher_foreground,modifier = Modifier.weight(weight))
Spacer(modifier = Modifier.weight(spaceWeight))
}
}
/**
* 历史活动列表
*
* @param modifier
*/
@Composable
private fun HistoryActivityList(modifier: Modifier,model:HistoryActViewModel= viewModel(),scaffoldModel: ScaffoldModel= viewModel()){
val listState= rememberLazyListState()
val list by model.data.observeAsState()
LazyColumn(state = listState,modifier = modifier) {
list?.chunked(2)?.forEach {
item {
Row(modifier=Modifier.fillMaxWidth()) {
HistoryActivity(modifier = Modifier.weight(0.4F),it[0])
Spacer(modifier = Modifier.weight(0.2F))
if (it.size==2) HistoryActivity(modifier = Modifier.weight(0.4F),it[1])
else Box(modifier = Modifier.weight(0.4F))
}
Spacer(modifier = Modifier.height(10.dp))
Divider(color = MaterialTheme.colors.background)
}
}
}
if(listState.layoutInfo.totalItemsCount-listState.firstVisibleItemIndex==model.initSize/2-1){
model.loadMore { scaffoldModel.update(it) }
}
}
/**
* 历史活动
*
* @param modifier
*/
@Composable
private fun HistoryActivity(modifier: Modifier,historyActVo: HistoryActVo){
Box(modifier=modifier,contentAlignment = Alignment.Center){
Image(painter = painterResource(id = R.drawable.history_activity_border),
contentDescription = null,
modifier = Modifier.fillMaxSize())
Image(painter = painterResource(id = R.drawable.ic_launcher_foreground),
contentDescription = null,
modifier = Modifier.fillMaxSize())
Text(text = historyActVo.name)
}
}

@ -5,6 +5,7 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.gyf.csams.R
import com.gyf.csams.uikit.ScrollList
import com.gyf.csams.uikit.StringForm
import com.orhanobut.logger.Logger
import kotlinx.coroutines.Job
@ -101,7 +102,7 @@ class MainViewModel:ViewModel(){
* 社团列表
*
*/
class ListViewModel:ViewModel(){
class ListViewModel: ScrollList<AssociationDto>() {
val name = StringForm(formDesc = "社团名称",textLength = 5)
val desc = StringForm(formDesc = "社团简介",textLength = 10)
@ -115,9 +116,7 @@ class ListViewModel:ViewModel(){
val searchDesc="搜索"
init {
loadAssociation()
}
/**
* TODO 社团检索
@ -129,12 +128,18 @@ class ListViewModel:ViewModel(){
callback("功能尚未实现,敬请期待")
}
override val initSize: Int = 10
init {
load()
}
/**
* 加载社团列表
*
*/
private fun loadAssociation(){
override fun load() {
viewModelScope.launch {
_associationList.value?.apply {
repeat(10
@ -145,35 +150,28 @@ class ListViewModel:ViewModel(){
}
Logger.i("初始化社团列表size=${_associationList.value?.size}")
}
}
/**
* 加载更多社团列表
*
*/
fun addMore(callback:(message:String) -> Unit){
override fun loadMore(callback: (message: String) -> Unit) {
viewModelScope.launch {
val c = _associationList.value
if(c!=null){
val t=mutableListOf<AssociationDto>()
t.addAll(c)
t.apply {
repeat(10
) {
add(AssociationDto(name = "社团${t.size}"))
_associationList.value?.apply {
val list= mutableListOf<AssociationDto>()
list.addAll(this)
list.apply {
repeat(10){
add(AssociationDto(name = "社团${size}"))
}
}
Logger.i("t.size=${t.size}")
_associationList.postValue(t)
Logger.i("t.size=${size}")
_associationList.postValue(list)
Logger.i("加载更多社团size=${_associationList.value?.size}")
callback("成功加载更多社团")
}
}
}
}

@ -17,7 +17,6 @@ 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.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextOverflow
@ -121,7 +120,7 @@ private fun Main(navController: NavHostController) {
Spacer(modifier = Modifier.height(10.dp))
}
Column(modifier = Modifier.weight(0.66F)) {
ClubActivitiesImage()
PosterWithDesc()
}
}
}
@ -207,7 +206,7 @@ private fun AssociationListBody(model: ListViewModel = viewModel(),scaffoldModel
}
if(listState.layoutInfo.totalItemsCount-listState.firstVisibleItemIndex==model.associationListSize/2-1){
model.addMore { scaffoldModel.update(it) }
model.loadMore { scaffoldModel.update(it) }
}
}
@ -362,29 +361,16 @@ private fun ClubActivitiesTitle() {
/**
* 活动海报
* 带介绍活动海报
*
*/
@Composable
private fun ClubActivitiesImage(model: CarouselViewModel = viewModel()) {
private fun PosterWithDesc(model: CarouselViewModel = viewModel()) {
Carousel(model = model) {
Column {
Card(
modifier = Modifier
.weight(0.6F)
.fillMaxWidth(),
backgroundColor = Color.Transparent
) {
Image(
painter = painterResource(id = R.drawable.hot_activity_background),
contentDescription = null
)
Image(
painter = painterResource(id = it),
contentDescription = null
)
}
Poster(modifier = Modifier
.weight(0.6F)
.fillMaxWidth(),id = it)
DescCard(
modifier = Modifier
.weight(0.4F)

@ -394,6 +394,31 @@ fun Body( content:@Composable (nav:NavHostController, scaffoldState:ScaffoldStat
}
}
/**
* 活动海报
*
*/
@Composable
fun Poster(modifier: Modifier=Modifier,@DrawableRes id: Int){
Card(
modifier = modifier,
backgroundColor = Color.Transparent
) {
Box(contentAlignment = Alignment.Center) {
Image(
painter = painterResource(id = R.drawable.hot_activity_background),
contentDescription = null,
modifier=Modifier.fillMaxSize()
)
Image(
painter = painterResource(id = id),
contentDescription = null,
modifier=Modifier.fillMaxSize()
)
}
}
}
/**
* 介绍卡片
*

@ -17,6 +17,14 @@ abstract class FormName<T>(val formDesc:String){
abstract fun onChange(value:T)
}
/**
* 文本输入框控制
*
* @property textLength
* @constructor
*
* @param formDesc
*/
open class StringForm(formDesc: String, val textLength: Int) : FormName<String>(formDesc = formDesc),
FormLength {
override val nameLengthError="${formDesc}不能超过最大长度$textLength"
@ -31,6 +39,10 @@ open class StringForm(formDesc: String, val textLength: Int) : FormName<String>(
}
}
/**
* snackbar
*
*/
class ScaffoldModel:ViewModel(){
private val _message=MutableLiveData<String>()
val message:LiveData<String> = _message
@ -38,4 +50,19 @@ class ScaffoldModel:ViewModel(){
fun update(message:String?=null){
_message.value=message
}
}
}
abstract class ScrollList<T>:ViewModel(){
protected val _data=MutableLiveData<MutableList<T>>(mutableListOf())
val data:LiveData<MutableList<T>> = _data
abstract val initSize:Int
//加载列表
abstract fun load()
//加载更多数据
abstract fun loadMore(callback:(message:String) -> Unit)
}

Loading…
Cancel
Save