界面逻辑封装

增加社团界面
master
pan 3 years ago
parent 014d4ae16c
commit 743486211b
  1. 4
      app/src/main/AndroidManifest.xml
  2. 99
      app/src/main/java/com/gyf/csams/account/ui/AccountActivity.kt
  3. 84
      app/src/main/java/com/gyf/csams/association/model/AssociationViewModel.kt
  4. 263
      app/src/main/java/com/gyf/csams/association/ui/AssociationActivity.kt
  5. 107
      app/src/main/java/com/gyf/csams/association/ui/RegAssociationActivity.kt
  6. 9
      app/src/main/java/com/gyf/csams/main/model/MainViewModel.kt
  7. 108
      app/src/main/java/com/gyf/csams/main/ui/MainActivity.kt
  8. 133
      app/src/main/java/com/gyf/csams/uikit/BaseView.kt
  9. 9
      app/src/main/res/drawable/ic_arrow_down.xml
  10. 9
      app/src/main/res/drawable/ic_arrow_left.xml
  11. 9
      app/src/main/res/drawable/ic_configuration.xml

@ -44,6 +44,10 @@
<activity android:name=".association.ui.RegAssociationActivity"
android:exported="true">
</activity>
<activity android:name=".association.ui.AssociationActivity"
android:exported="true">
</activity>
</application>
</manifest>

@ -27,11 +27,11 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.navigate
import androidx.navigation.compose.rememberNavController
import com.gyf.csams.BuildConfig
import com.gyf.csams.account.model.AccountViewModel
import com.gyf.csams.account.model.DialogMessage
import com.gyf.csams.uikit.AnimationText
import com.gyf.csams.uikit.Body
import com.gyf.csams.uikit.theme.CSAMSTheme
@ -46,62 +46,57 @@ class AccountActivity: ComponentActivity() {
setContent {
CSAMSTheme {
// A surface container using the 'background' color from the theme
Surface(color = MaterialTheme.colors.background) {
val navController = rememberNavController()
val scaffoldState = rememberScaffoldState()
Scaffold(scaffoldState=scaffoldState) {
NavHost(navController, startDestination = AccountRoute.login.name) {
composable(AccountRoute.login.name) {
Account(scaffoldState=scaffoldState,route = AccountRoute.login) { isValidForm: Boolean, accountViewModel: AccountViewModel ->
Spacer(modifier = Modifier.height(10.dp))
OutlinedButton(onClick = {accountViewModel.login()},
enabled = isValidForm,
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 10.dp)) {
Text(text = accountViewModel.loginDesc)
}
val finishLogin:Boolean? by accountViewModel.finishLogin.observeAsState()
if(finishLogin==true){
finish()
}
OutlinedButton(onClick = { navController.navigate(AccountRoute.register.name)},
modifier = Modifier.fillMaxWidth(),
colors = ButtonDefaults.outlinedButtonColors(
contentColor = MaterialTheme.colors.onBackground)) {
Text(text = accountViewModel.goRegister)
}
}
Body {
nav, scaffoldState ->
NavHost(navController = nav, startDestination = AccountRoute.login.name) {
composable(AccountRoute.login.name) {
Account(scaffoldState=scaffoldState,route = AccountRoute.login) { isValidForm: Boolean, accountViewModel: AccountViewModel ->
Spacer(modifier = Modifier.height(10.dp))
OutlinedButton(onClick = {accountViewModel.login()},
enabled = isValidForm,
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 10.dp)) {
Text(text = accountViewModel.loginDesc)
}
val finishLogin:Boolean? by accountViewModel.finishLogin.observeAsState()
if(finishLogin==true){
finish()
}
OutlinedButton(onClick = { nav.navigate(AccountRoute.register.name)},
modifier = Modifier.fillMaxWidth(),
colors = ButtonDefaults.outlinedButtonColors(
contentColor = MaterialTheme.colors.onBackground)) {
Text(text = accountViewModel.goRegister)
}
}
}
composable(AccountRoute.register.name) {
Account(scaffoldState=scaffoldState,route = AccountRoute.register) { isValidForm: Boolean, accountViewModel: AccountViewModel ->
Spacer(modifier = Modifier.height(10.dp))
OutlinedButton(onClick = { accountViewModel.register()},
enabled = isValidForm,
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 10.dp)) {
Text(text = accountViewModel.regBtnDesc)
}
composable(AccountRoute.register.name) {
Account(scaffoldState=scaffoldState,route = AccountRoute.register) { isValidForm: Boolean, accountViewModel: AccountViewModel ->
Spacer(modifier = Modifier.height(10.dp))
OutlinedButton(onClick = { accountViewModel.register()},
enabled = isValidForm,
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 10.dp)) {
Text(text = accountViewModel.regBtnDesc)
}
OutlinedButton(onClick = { navController.navigate(AccountRoute.login.name)},
modifier = Modifier.fillMaxWidth(),
colors = ButtonDefaults.outlinedButtonColors(
contentColor = MaterialTheme.colors.onBackground)) {
Text(text = accountViewModel.backLogin)
}
}
OutlinedButton(onClick = { nav.navigate(AccountRoute.login.name)},
modifier = Modifier.fillMaxWidth(),
colors = ButtonDefaults.outlinedButtonColors(
contentColor = MaterialTheme.colors.onBackground)) {
Text(text = accountViewModel.backLogin)
}
}
}
}
}
}

@ -0,0 +1,84 @@
package com.gyf.csams.association.model
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.gyf.csams.uikit.AssociationMenu
import com.gyf.csams.uikit.StringForm
import com.orhanobut.logger.Logger
import kotlinx.coroutines.launch
class AssociationViewModel:ViewModel() {
private val _currentMenu=MutableLiveData<AssociationMenu>()
val currentMenu:LiveData<AssociationMenu> = _currentMenu
fun clickMenu(menu:AssociationMenu){
_currentMenu.value=menu
}
}
data class MemberVo(val name:String)
/**
* 社团会员
*
*/
class MemberViewModel:ViewModel(){
val name=StringForm(formDesc = "姓名关键字",5)
val search="搜索"
private val _memberList=MutableLiveData<MutableList<MemberVo>>(mutableListOf())
val memberList=_memberList
init {
initMemberList()
}
/**
* 初始化成员
*
*/
private fun initMemberList(){
viewModelScope.launch {
_memberList.value?.apply {
repeat(10) {
add(MemberVo(name = "成员${it+1}"))
}
}
Logger.i("初始化社团成员size=${_memberList.value?.size}")
}
}
/**
* 加载更多成员
*
*/
fun loadMore(){
viewModelScope.launch {
_memberList.value?.let {
val t= mutableListOf<MemberVo>()
t.addAll(it)
t.apply {
repeat(10){
add(MemberVo(name = "成员${t.size+1}"))
}
}
_memberList.postValue(t)
Logger.i("加载更多社团成员,size=${t.size}")
}
}
}
/**
* TODO 社团成员搜索
*
* @param callback
*/
fun search(callback: (value: String) -> Unit){
Logger.i("搜索条件[成员姓名:${name.formValue.value}]")
callback("功能尚未实现,敬请期待")
}
}

@ -0,0 +1,263 @@
package com.gyf.csams.association.ui
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Image
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.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.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.association.model.AssociationViewModel
import com.gyf.csams.association.model.MemberViewModel
import com.gyf.csams.association.model.MemberVo
import com.gyf.csams.uikit.*
import com.gyf.csams.uikit.theme.CSAMSTheme
/**
* 社团界面
*
*/
class AssociationActivity: ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
CSAMSTheme {
Body {
nav, scaffoldState ->
val context= LocalContext.current as AssociationActivity
val model:AssociationViewModel= viewModel()
val startMenu=AssociationMenu.main
val menu:AssociationMenu by model.currentMenu.observeAsState(startMenu)
Column {
AssociationAppBar(menu = menu,nav = nav,back = { context.onBackPressed() }){
}
NavHost(navController = nav, startDestination = startMenu.name) {
composable(AssociationMenu.member.name){
model.clickMenu(AssociationMenu.member)
Member()
ShowSnackbar(scaffoldState = scaffoldState)
}
composable(AssociationMenu.main.name){
model.clickMenu(AssociationMenu.main)
Main()
ShowSnackbar(scaffoldState = scaffoldState)
}
composable(AssociationMenu.list.name){
model.clickMenu(AssociationMenu.list)
AssociationList()
ShowSnackbar(scaffoldState = scaffoldState)
}
}
}
}
}
}
}
}
/**
* 社团成员
*
*/
@Composable
private fun Member(){
MainFrame(background = { Background(image = BackgroundImage.association_main) }) {
val searchWeight=0.2F
Search(modifier = Modifier
.fillMaxWidth()
.weight(searchWeight))
MemberList(modifier = Modifier
.fillMaxWidth()
.weight(1 - searchWeight))
}
}
/**
* 检索成员
*
*/
@Composable
private fun Search(modifier:Modifier=Modifier, model: MemberViewModel= viewModel(), scaffoldModel: ScaffoldModel= viewModel()){
Column(modifier = modifier.fillMaxSize()) {
Spacer(modifier = Modifier.weight(0.5F))
Row(modifier = Modifier
.fillMaxWidth()
.weight(0.5F),verticalAlignment = Alignment.CenterVertically) {
val textFieldWeight=0.4F
val buttonWeight=0.2F
val spaceWeight=(1-textFieldWeight-buttonWeight)/3
Spacer(modifier = Modifier.weight((spaceWeight)))
BaseTextField(modifier = Modifier.weight(textFieldWeight),form = model.name,singeLine = true)
Spacer(modifier = Modifier.weight(spaceWeight))
OutlinedButton(onClick = { model.search { scaffoldModel.update(it) } },modifier = Modifier.weight(buttonWeight)) {
Text(text = model.search)
}
Spacer(modifier = Modifier.weight(spaceWeight))
}
}
}
/**
* 成员列表
*
*/
@Composable
private fun MemberList(modifier: Modifier=Modifier,viewModel: MemberViewModel=viewModel()){
val list:MutableList<MemberVo>? by viewModel.memberList.observeAsState()
val listState= rememberLazyListState()
LazyColumn(state = listState,modifier = modifier) {
list?.forEach {
item {
Column {
Spacer(modifier = Modifier.height(10.dp))
Row{
val weight = 1F / 3
Spacer(modifier = Modifier.weight(weight))
Card(
modifier = Modifier.weight(weight),
backgroundColor = MaterialTheme.colors.background
) {
Text(text = it.name)
}
Spacer(modifier = Modifier.weight(weight))
}
Spacer(modifier = Modifier.height(10.dp))
Divider(color = MaterialTheme.colors.background)
}
}
}
item {
Row(horizontalArrangement = Arrangement.Center,modifier = Modifier.fillMaxWidth()) {
IconButton(onClick = { viewModel.loadMore() }) {
Icon(painter = painterResource(id = R.drawable.ic_arrow_down), contentDescription = null)
}
}
}
}
}
/**
* 社团主页
*
*/
@Composable
private fun Main(){
MainFrame(background = {
Background(image = BackgroundImage.association_main,alpha = 0.7F)
}) {
val nameW=0.1F
val cardW=0.66F*0.4F
Name(modifier = Modifier
.fillMaxWidth()
.weight(nameW))
DescCard(
modifier = Modifier
.weight(cardW)
.fillMaxWidth()
)
Commander(
modifier = Modifier.weight(cardW)
)
Showcase(modifier = Modifier.weight(1F-nameW-cardW-cardW))
}
}
/**
* 社团名字
*
* @param modifier
*/
@Composable
private fun Name(modifier: Modifier){
Box(modifier = modifier) {
Image(
painter = painterResource(id = R.drawable.association_name_border),
contentDescription = null,
contentScale = ContentScale.FillBounds,
modifier=Modifier.fillMaxSize()
)
Column{
Spacer(modifier = Modifier.weight(1.7F / 3))
Row(modifier = Modifier
.fillMaxWidth()
.weight(1F / 3),
horizontalArrangement = Arrangement.Center) {
Text(text = "社团名字")
}
Spacer(modifier = Modifier.weight(0.3F / 3))
}
}
}
/**
* 团长名字
*
* @param modifier
*/
@Composable
private fun Commander(modifier: Modifier){
Box(modifier=modifier,contentAlignment = Alignment.Center){
Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.Center) {
Image(painter = painterResource(id = R.drawable.association_persion_name_border),
contentDescription = null
)
}
Text(text = "团长")
}
}
/**
* 风采展示区
*
* @param modifier
*/
@Composable
private fun Showcase(modifier: Modifier){
Box(modifier = modifier,contentAlignment = Alignment.Center) {
Image(painter = painterResource(id = R.drawable.showcase_border),
contentDescription = null,
modifier=Modifier.fillMaxSize())
Image(painter = painterResource(id = R.drawable.ic_launcher_foreground), contentDescription = null)
}
}
/**
* 活动列表
*
*/
@Composable
private fun AssociationList(){
MainFrame(background = { Background(image = BackgroundImage.association_main,alpha = 07F) }) {
Text(text = "活动列表")
}
}
@Preview
@Composable
fun NamePreview(){
Divider(color = MaterialTheme.colors.background)
}

@ -2,7 +2,6 @@ package com.gyf.csams.association.ui
import android.Manifest
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.BitmapFactory
@ -12,13 +11,15 @@ import android.provider.MediaStore
import androidx.activity.ComponentActivity
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.compose.setContent
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.material.IconButton
import androidx.compose.material.MaterialTheme
import androidx.compose.material.OutlinedButton
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
@ -28,7 +29,6 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.core.content.ContextCompat
import androidx.lifecycle.viewmodel.compose.viewModel
@ -48,72 +48,46 @@ class RegAssociationActivity: ComponentActivity(){
super.onCreate(savedInstanceState)
setContent {
CSAMSTheme {
Body()
Body {
scaffoldState ->
MainFrame(background = { Background(BackgroundImage.reg_association,alpha = 0.5F) }) {
Spacer(
modifier = Modifier
.weight(0.1F)
)
Title()
Name()
Desc(
modifier = Modifier
.weight(0.1F)
.fillMaxWidth()
)
Spacer(modifier = Modifier.weight(0.05F))
Logo(
modifier = Modifier
.weight(0.2F)
.fillMaxWidth()
)
Spacer(modifier = Modifier.weight(0.05F))
BottomButton(modifier = Modifier.fillMaxWidth())
Spacer(modifier = Modifier.weight(0.05F))
ShowSnackbar(scaffoldState = scaffoldState)
}
}
}
}
}
}
@Composable
fun Body(model:RegAssociationViewModel= viewModel()){
val scaffoldState = rememberScaffoldState()
Scaffold(scaffoldState = scaffoldState) {
Surface(color = MaterialTheme.colors.background) {
MainFrame(background = { Background(BackgroundImage.reg_association,alpha = 0.7F) }) {
Spacer(
modifier = Modifier
.weight(0.1F)
)
Title(model = model)
Name(model = model)
Desc(
model = model, modifier = Modifier
.weight(0.1F)
.fillMaxWidth()
)
Spacer(modifier = Modifier.weight(0.05F))
Logo(
model = model, modifier = Modifier
.weight(0.2F)
.fillMaxWidth()
)
Spacer(modifier = Modifier.weight(0.05F))
BottomButton(modifier = Modifier.fillMaxWidth())
Spacer(modifier = Modifier.weight(0.05F))
ShowSnackbar(scaffoldState = scaffoldState)
}
}
}
}
//@Composable
fun PermissionHandle(context: Context, launcher: ActivityResultLauncher<String>,onGranted:()->Unit){
// Check permission
when (PackageManager.PERMISSION_GRANTED) {
ContextCompat.checkSelfPermission(
context,
Manifest.permission.READ_EXTERNAL_STORAGE
) -> {
// Some works that require permission
onGranted()
}
else -> {
// Asking for permission
launcher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
}
}
}
/**
* 社团Logo
*
* @param modifier
*/
@Composable
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)
photoIntent.type = "image/*"
val uri:Uri? by model.picture.observeAsState()
@ -201,7 +175,7 @@ fun Logo(model:RegAssociationViewModel= viewModel(),modifier: Modifier) {
}
@Composable
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
Row(modifier = modifier,horizontalArrangement = Arrangement.Center) {
OutlinedButton(onClick = {
@ -224,7 +198,7 @@ fun BottomButton(modifier: Modifier=Modifier,scaffoldModel: ScaffoldModel= viewM
*
*/
@Composable
fun Title(model:RegAssociationViewModel= viewModel()){
private fun Title(model:RegAssociationViewModel= viewModel()){
Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.Center) {
Text(text = model.frameDesc,style = MaterialTheme.typography.h4)
}
@ -235,7 +209,7 @@ fun Title(model:RegAssociationViewModel= viewModel()){
* @param model
*/
@Composable
fun Name(model:RegAssociationViewModel= viewModel()){
private fun Name(model:RegAssociationViewModel= viewModel()){
BaseTextField(form = model.name,singeLine = true,modifier = Modifier.fillMaxWidth())
}
@ -244,15 +218,6 @@ fun Name(model:RegAssociationViewModel= viewModel()){
* @param model
*/
@Composable
fun Desc(model:RegAssociationViewModel= viewModel(),modifier:Modifier){
private fun Desc(model:RegAssociationViewModel= viewModel(),modifier:Modifier){
BaseTextField(form = model.desc,modifier = modifier)
}
@Preview
@Composable
fun NamePreview(){
val model=RegAssociationViewModel()
Body(model=model)
}

@ -183,13 +183,4 @@ class ListViewModel:ViewModel(){
*/
class CenterViewModel:ViewModel(){
val myAssociationDesc="我的社团"
/**
* TODO 打开我的社团
*
* @param callback
*/
fun openMyAssociation(callback: (value: String) -> Unit){
callback("功能尚未实现,敬请期待")
}
}

@ -24,11 +24,11 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.gyf.csams.R
import com.gyf.csams.association.ui.AssociationActivity
import com.gyf.csams.association.ui.RegAssociationActivity
import com.gyf.csams.main.model.*
import com.gyf.csams.uikit.*
@ -45,38 +45,27 @@ class MainActivity : ComponentActivity() {
setContent {
CSAMSTheme {
Body()
}
}
}
}
Body { nav, scaffoldState ->
NavHost(navController = nav, startDestination = MainMenu.Main.name) {
composable(MainMenu.Main.name) {
Main(navController = nav)
ShowSnackbar(scaffoldState = scaffoldState)
}
composable(MainMenu.List.name) {
AssociationList(navController = nav)
ShowSnackbar(scaffoldState = scaffoldState)
}
composable(MainMenu.Center.name) {
Center(navController = nav)
ShowSnackbar(scaffoldState = scaffoldState)
}
}
@Composable
fun Body() {
// A surface container using the 'background' color from the theme
Surface(color = MaterialTheme.colors.background) {
val navController = rememberNavController()
val scaffoldState = rememberScaffoldState()
Scaffold(scaffoldState = scaffoldState) {
NavHost(navController, startDestination = MainMenu.Main.name) {
composable(MainMenu.Main.name) {
Main(navController = navController)
ShowSnackbar(scaffoldState = scaffoldState)
}
composable(MainMenu.List.name) {
AssociationList(navController = navController)
ShowSnackbar(scaffoldState = scaffoldState)
}
composable(MainMenu.Center.name) {
Center(navController = navController)
ShowSnackbar(scaffoldState = scaffoldState)
}
}
}
}
}
@ -85,16 +74,17 @@ fun Body() {
*
*/
@Composable
fun Center(model:CenterViewModel= viewModel(), scaffoldModel: ScaffoldModel= viewModel(), navController: NavController){
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) {
Column(modifier = Modifier
.weight(0.33F)
.fillMaxWidth(),verticalArrangement = Arrangement.Bottom) {
Card(backgroundColor = MaterialTheme.colors.background) {
val context= LocalContext.current
Row(modifier = Modifier
.fillMaxWidth()
.clickable(onClick = {
model.openMyAssociation { scaffoldModel.update(it) }
context.startActivity(Intent(context, AssociationActivity::class.java))
}),verticalAlignment = Alignment.CenterVertically) {
Spacer(modifier = Modifier.weight(0.33F))
Row(modifier = Modifier.weight(0.33F),horizontalArrangement = Arrangement.Center) {
@ -121,7 +111,7 @@ fun Center(model:CenterViewModel= viewModel(), scaffoldModel: ScaffoldModel= vie
* 主界面
*/
@Composable
fun Main(navController: NavController) {
private fun Main(navController: NavHostController) {
MainFrame(background = { Background(image = BackgroundImage.main) }, mainMenu = MainMenu.Main, nav = navController) {
Column(modifier = Modifier.weight(0.33F)) {
Notification()
@ -143,7 +133,7 @@ fun Main(navController: NavController) {
* @param navController
*/
@Composable
fun AssociationList(navController: NavController) {
private fun AssociationList(navController: NavHostController) {
MainFrame(
background = { Background(image = BackgroundImage.list) },
mainMenu = MainMenu.List,
@ -160,7 +150,7 @@ fun AssociationList(navController: NavController) {
*
*/
@Composable
fun RegisterAssociation() {
private fun RegisterAssociation() {
val context= LocalContext.current
Row(
horizontalArrangement = Arrangement.End,
@ -185,7 +175,7 @@ fun RegisterAssociation() {
*
*/
@Composable
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 listState = rememberLazyListState()
@ -222,8 +212,9 @@ fun AssociationListBody(model: ListViewModel = viewModel(),scaffoldModel: Scaffo
}
@Composable
fun Association(associationDto: AssociationDto) {
Card {
private fun Association(associationDto: AssociationDto) {
val context= LocalContext.current
Card(modifier = Modifier.clickable(onClick = { context.startActivity(Intent(context,AssociationActivity::class.java)) })) {
Image(
painter = painterResource(id = R.drawable.association_list_border),
contentDescription = null
@ -242,7 +233,7 @@ fun Association(associationDto: AssociationDto) {
*
*/
@Composable
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)) {
Column {
@ -271,7 +262,7 @@ fun AssociationSearch(model: ListViewModel = viewModel(),scaffoldModel: Scaffold
*
*/
@Composable
fun Notification(mainViewModel: MainViewModel= viewModel(),scaffoldModel: ScaffoldModel= viewModel()) {
private fun Notification(mainViewModel: MainViewModel= viewModel(),scaffoldModel: ScaffoldModel= viewModel()) {
Row(
horizontalArrangement = Arrangement.End,
modifier = Modifier
@ -295,7 +286,7 @@ fun Notification(mainViewModel: MainViewModel= viewModel(),scaffoldModel: Scaffo
*
*/
@Composable
fun MyBorder(content: @Composable BoxScope.() -> Unit) {
private fun MyBorder(content: @Composable BoxScope.() -> Unit) {
Box(modifier = Modifier.padding(horizontal = 15.dp)) {
Box(
modifier = Modifier
@ -315,7 +306,7 @@ fun MyBorder(content: @Composable BoxScope.() -> Unit) {
*
*/
@Composable
fun MessageBoard(model: MarqueeViewModel = viewModel(),mainViewModel:MainViewModel= viewModel(),scaffoldModel: ScaffoldModel= viewModel()) {
private fun MessageBoard(model: MarqueeViewModel = viewModel(),mainViewModel:MainViewModel= viewModel(),scaffoldModel: ScaffoldModel= viewModel()) {
MyBorder {
Row(
verticalAlignment = Alignment.CenterVertically
@ -350,7 +341,7 @@ fun MessageBoard(model: MarqueeViewModel = viewModel(),mainViewModel:MainViewMod
*
*/
@Composable
fun ClubActivitiesTitle() {
private fun ClubActivitiesTitle() {
MyBorder {
Row(
modifier = Modifier
@ -369,12 +360,13 @@ fun ClubActivitiesTitle() {
}
}
/**
* 活动海报
*
*/
@Composable
fun ClubActivitiesImage(model: CarouselViewModel = viewModel()) {
private fun ClubActivitiesImage(model: CarouselViewModel = viewModel()) {
Carousel(model = model) {
Column {
Card(
@ -393,35 +385,11 @@ fun ClubActivitiesImage(model: CarouselViewModel = viewModel()) {
contentDescription = null
)
}
Card(
DescCard(
modifier = Modifier
.weight(0.4F)
.fillMaxWidth(),
backgroundColor = Color.Transparent
) {
Image(
painter = painterResource(id = R.drawable.hot_activity_desc_background),
contentDescription = null
)
Row(modifier = Modifier.fillMaxWidth()) {
Spacer(modifier = Modifier.weight(0.2F))
Column(
modifier = Modifier
.weight(0.5F)
) {
Spacer(modifier = Modifier.weight(0.1F))
Text(
text = "文字对任何界面都属于核心内容,而利用 Jetpack Compose 可以更轻松地显示或写入文字。Compose 可以充分利用其构建块的组合,这意味着您无需覆盖各种属性和方法,也无需扩展大型类,即可拥有特定的可组合项设计以及按您期望的方式运行的逻辑。"
.repeat(10), overflow = TextOverflow.Ellipsis,
modifier = Modifier.weight(0.8F)
)
Spacer(modifier = Modifier.weight(0.1F))
}
Spacer(modifier = Modifier.weight(0.2F))
}
}
.fillMaxWidth()
)
}
}
}

@ -5,6 +5,7 @@ import androidx.compose.animation.Crossfade
import androidx.compose.animation.animateColor
import androidx.compose.animation.core.*
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
@ -14,7 +15,9 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.State
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.graphics.DefaultAlpha
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
@ -25,7 +28,7 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController
import androidx.navigation.NavHostController
import androidx.navigation.compose.navigate
import androidx.navigation.compose.rememberNavController
import com.gyf.csams.APP
@ -96,14 +99,14 @@ fun MenuIconButton(_menu: MainMenu,menu: MainMenu,modifier: Modifier,onClick: ()
}
/**
* 底部菜单
* 主界面底部菜单
*
* @param menu
* @param nav
* @param modifier
*/
@Composable
fun MainBottomAppBar(menu:MainMenu, nav: NavController, modifier: Modifier=Modifier){
fun MainBottomAppBar(menu:MainMenu, nav: NavHostController, modifier: Modifier=Modifier){
BottomAppBar(backgroundColor = MaterialTheme.colors.background,modifier=modifier) {
//图标宽度平等分
@ -121,6 +124,49 @@ fun MainBottomAppBar(menu:MainMenu, nav: NavController, modifier: Modifier=Modif
}
/**
* 社团菜单
*
*/
enum class AssociationMenu(val menuName:String){
member("社团成员"),
main("社团主页"),
list("活动列表")
}
/**
* 社团顶部菜单
*
*/
@Composable
fun AssociationAppBar(menu: AssociationMenu,nav: NavHostController,back:()->Unit,dropMenu:()->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)
}
}
}
IconButton(onClick = dropMenu,modifier = Modifier.weight(0.1F)) {
Icon(painter = painterResource(id = R.drawable.ic_configuration), contentDescription = null)
}
}
}
}
/**
* 跑马灯
*
@ -186,7 +232,7 @@ fun MarqueeText(model: MarqueeViewModel = viewModel(), offset: State<Float>) {
* @param body 内容
*/
@Composable
fun MainFrame( background:@Composable ()->Unit,mainMenu: MainMenu,nav: NavController,body:@Composable ColumnScope.()->Unit){
fun MainFrame( background:@Composable ()->Unit,mainMenu: MainMenu,nav: NavHostController,body:@Composable ColumnScope.()->Unit){
Box(modifier = Modifier.fillMaxSize()) {
background()
Column {
@ -289,7 +335,9 @@ enum class BackgroundImage(@DrawableRes val id:Int){
//个人中心
center(R.drawable.mb_bg_fb_28),
//注册社团
reg_association(R.drawable.mb_bg_fb_07)
reg_association(R.drawable.mb_bg_fb_06),
//社团主界面
association_main(R.drawable.mb_bg_fb_25_180)
}
/**
@ -313,6 +361,75 @@ fun Background(image: BackgroundImage, alpha:Float= DefaultAlpha){
}
}
/**
*
*
* @param content
*/
@Composable
fun Body(content:@Composable (scaffoldState:ScaffoldState)->Unit){
Surface(color = MaterialTheme.colors.background) {
val scaffoldState = rememberScaffoldState()
Scaffold(scaffoldState = scaffoldState) {
content(scaffoldState=scaffoldState)
}
}
}
/**
* 带导航的主体
*
* @param content
*/
@Composable
fun Body( content:@Composable (nav:NavHostController, scaffoldState:ScaffoldState)->Unit){
Surface(color = MaterialTheme.colors.background) {
val navController = rememberNavController()
val scaffoldState = rememberScaffoldState()
Scaffold(scaffoldState = scaffoldState) {
content(nav=navController,scaffoldState=scaffoldState)
}
}
}
/**
* 介绍卡片
*
*/
@Composable
fun DescCard(modifier: Modifier){
Card(
modifier = modifier,
backgroundColor = Color.Transparent
) {
Image(
painter = painterResource(id = R.drawable.hot_activity_desc_background),
contentDescription = null
)
Row(modifier = Modifier.fillMaxWidth()) {
Spacer(modifier = Modifier.weight(0.2F))
Column(
modifier = Modifier
.weight(0.5F)
) {
Spacer(modifier = Modifier.weight(0.1F))
Text(
text = "文字对任何界面都属于核心内容,而利用 Jetpack Compose 可以更轻松地显示或写入文字。Compose 可以充分利用其构建块的组合,这意味着您无需覆盖各种属性和方法,也无需扩展大型类,即可拥有特定的可组合项设计以及按您期望的方式运行的逻辑。"
.repeat(10), overflow = TextOverflow.Ellipsis,
modifier = Modifier.weight(0.8F)
)
Spacer(modifier = Modifier.weight(0.1F))
}
Spacer(modifier = Modifier.weight(0.2F))
}
}
}
@Preview
@Composable
fun AnimationTextPreview(){
@ -322,13 +439,7 @@ fun AnimationTextPreview(){
//@Preview
@Composable
fun MyBottomAppBarPreview(){
val nav= rememberNavController()
CSAMSTheme {
Surface(color = MaterialTheme.colors.background) {
Column() {
}
MainBottomAppBar(menu = MainMenu.Main, nav = nav)
}
}
}

@ -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="M500.8,604.78L267.31,371.39l-45.23,45.27 278.74,278.61L779.31,416.66l-45.25,-45.25z"/>
</vector>

@ -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="M641.28,278.61l-45.23,-45.23 -278.63,278.76 278.61,278.49 45.25,-45.27 -233.37,-233.24z"/>
</vector>

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="211.71875dp"
android:height="200dp"
android:viewportWidth="1084"
android:viewportHeight="1024">
<path
android:fillColor="#FF000000"
android:pathData="M825.22,90.35c-18.07,-36.14 -60.24,-60.24 -102.4,-60.24s-84.33,24.09 -102.4,60.24H0v120.47h620.42c18.07,36.14 60.24,60.24 102.4,60.24s84.33,-24.09 102.4,-60.24H1084.24v-120.47h-259.01zM542.12,391.53c-42.16,0 -78.31,24.09 -102.4,54.21H0v120.47h433.69c18.07,36.14 60.24,66.26 108.42,66.26s84.33,-24.09 108.42,-66.26H1084.24v-120.47h-439.72c-24.09,-30.12 -60.24,-54.21 -102.4,-54.21zM783.06,752.94c-42.16,0 -72.28,18.07 -96.38,48.19H0v120.47h674.64c18.07,42.16 60.24,72.28 108.42,72.28s90.35,-30.12 108.42,-72.28H1084.24v-120.47h-204.8c-24.09,-30.12 -54.21,-48.19 -96.38,-48.19z"/>
</vector>
Loading…
Cancel
Save