主界面UI

master
pan 3 years ago
parent 5f5f8bb45c
commit 890af8cfcd
  1. 2
      app/build.gradle.kts
  2. 156
      app/src/androidTest/java/com/gyf/csams/TestPreview.kt
  3. 65
      app/src/main/java/com/gyf/csams/ui/Base.kt
  4. 232
      app/src/main/java/com/gyf/csams/ui/MainActivity.kt
  5. 9
      app/src/main/res/drawable/ic_account.xml
  6. 9
      app/src/main/res/drawable/ic_account_fill.xml
  7. 9
      app/src/main/res/drawable/ic_all.xml
  8. 9
      app/src/main/res/drawable/ic_all_fill.xml
  9. 9
      app/src/main/res/drawable/ic_comments.xml
  10. 9
      app/src/main/res/drawable/ic_home.xml
  11. 9
      app/src/main/res/drawable/ic_home_fill.xml
  12. 9
      app/src/main/res/drawable/ic_notification.xml

@ -129,6 +129,8 @@ dependencies {
kapt("androidx.room:room-compiler:${rootProject.extra["room_version"]}")
// optional - Kotlin Extensions and Coroutines support for Room
implementation("androidx.room:room-ktx:${rootProject.extra["room_version"]}")
//
implementation("androidx.constraintlayout:constraintlayout-compose:1.0.0-alpha03")
// optional - Test helpers
testImplementation("androidx.room:room-testing:${rootProject.extra["room_version"]}")
//测试

@ -0,0 +1,156 @@
package com.gyf.csams
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.rotate
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
@Composable
fun BoxSetSize(degrees:Float=0F,content: @Composable BoxScope.() -> Unit){
Box(modifier = Modifier
.height(300.dp)
.fillMaxWidth()
.background(Color.Gray)
.rotate(degrees = degrees),contentAlignment = Alignment.Center){
Canvas(modifier = Modifier.size(200.dp)) {
rotate(45f){
drawRect(color = Color.Cyan)
}
}
content()
}
}
@Composable
fun BoxFillSize(degrees:Float=0F, content: @Composable BoxScope.() -> Unit){
Box(modifier = Modifier
.fillMaxSize()
.background(Color.LightGray)
.rotate(degrees = degrees),contentAlignment = Alignment.Center){
Canvas(modifier = Modifier.size(100.dp)) {
rotate(80f){
drawRect(color = Color.Cyan)
}
}
content()
}
}
@Preview
@Composable
fun TestPreview(){
Column(modifier = Modifier.fillMaxSize()){
BoxSetSize {
Text(buildAnnotatedString {
withStyle(style = SpanStyle(fontSize = 30.sp)){
append("前置子布局固定尺寸")
}
})
}
BoxFillSize {
Text(buildAnnotatedString {
withStyle(style = SpanStyle(fontSize = 30.sp)){
append("后置子布局使用")
}
withStyle(style = SpanStyle(color= Color.Red,fontSize = 30.sp)){
append("fillMaxSize修饰符")
}
withStyle(style = SpanStyle(fontSize = 30.sp)){
append("填充父项允许的所有可用空间")
}
})
}
}
}
@Preview
@Composable
fun TestPreview2(){
Column(modifier = Modifier.fillMaxSize()){
Text(buildAnnotatedString {
withStyle(style = SpanStyle(fontSize = 30.sp)){
append("如果使用示例1方法是")
}
withStyle(style = SpanStyle(color= Color.Red,fontSize = 30.sp)){
append("无法实现前置子布局填充父项所有可用空间,后置子布局固定尺寸")
}
withStyle(style = SpanStyle(fontSize = 30.sp)){
append("因为前置布局已经填充父项允许的所有可用空间,后置子布局没有剩余空间可用")
}
})
BoxFillSize {
Text(buildAnnotatedString {
withStyle(style = SpanStyle(fontSize = 30.sp)){
append("前置子布局填充父项允许的所有可用空间")
}
})
}
BoxSetSize {
Text(buildAnnotatedString {
withStyle(style = SpanStyle(fontSize = 30.sp)){
append("后置子布局固定尺寸")
}
})
}
}
}
@Preview
@Composable
fun TestPreview3(){
Column(modifier = Modifier
.fillMaxSize()) {
Text(buildAnnotatedString {
withStyle(style = SpanStyle(fontSize = 30.sp)){
append("折衷方案是通过父项旋转180°实现,子项分别旋转180°复位可")
}
withStyle(style = SpanStyle(color= Color.Red,fontSize = 30.sp)){
append("实现前置子布局填充父项所有可用空间,后置子布局固定尺寸")
}
withStyle(style = SpanStyle(fontSize = 30.sp)){
append(",除了旋转,应该有更好的实现方式?")
}
})
Column(modifier = Modifier.rotate(180F)){
BoxSetSize(degrees = 180F) {
Text(buildAnnotatedString {
withStyle(style = SpanStyle(fontSize = 30.sp)){
append("前置子布局固定尺寸,通过旋转和后置子布局对调位置")
}
})
}
BoxFillSize(degrees = 180F) {
Text(buildAnnotatedString {
withStyle(style = SpanStyle(fontSize = 30.sp)){
append("后置子布局使用")
}
withStyle(style = SpanStyle(color= Color.Red,fontSize = 30.sp)){
append("fillMaxSize修饰符")
}
withStyle(style = SpanStyle(fontSize = 30.sp)){
append("填充父项允许的所有可用空间,通过旋转和前置子布局对调位置")
}
})
}
}
}
}

@ -1,13 +1,22 @@
package com.gyf.csams.ui
import androidx.annotation.DrawableRes
import androidx.compose.animation.animateColor
import androidx.compose.animation.core.*
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.navigation.NavController
import androidx.navigation.compose.navigate
import androidx.navigation.compose.rememberNavController
import com.gyf.csams.R
/**
* 淡入淡出并且颜色变化文本
@ -33,9 +42,61 @@ fun AnimationText(text:String){
)
}
/**
* 主菜单
*
*/
enum class MainMenu(@DrawableRes val selectedIcon:Int,
@DrawableRes val unSelectedIcon:Int){
//主页
Main(R.drawable.ic_home_fill,R.drawable.ic_home),
//社团列表
List(R.drawable.ic_all_fill,R.drawable.ic_all),
//个人中心
Center(R.drawable.ic_account_fill,R.drawable.ic_account)
}
@Composable
fun MenuIconButton(_menu: MainMenu,menu: MainMenu,modifier: Modifier,onClick: () -> Unit){
Row(modifier = modifier
,horizontalArrangement = Arrangement.Center) {
IconButton(onClick = onClick) {
Icon(
painter = painterResource(id = if (_menu == menu) menu.selectedIcon else menu.unSelectedIcon),
contentDescription = null
)
}
}
}
@Composable
fun MyBottomAppBar(menu:MainMenu,nav: NavController,modifier: Modifier=Modifier){
BottomAppBar(backgroundColor = Color.Transparent,modifier=modifier) {
//图标宽度平等分
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)})
MenuIconButton(_menu = menu,menu = MainMenu.List,Modifier.weight(weight),
onClick = { nav.navigate(MainMenu.List.name)})
MenuIconButton(_menu = menu,menu = MainMenu.Center,Modifier.weight(weight),
onClick = { nav.navigate(MainMenu.Center.name)})
}
}
}
@Preview
@Composable
fun AnimationTextPreview(){
AnimationText(text = "6666")
}
@Preview
@Composable
fun MyBottomAppBarPreview(){
val nav= rememberNavController()
MyBottomAppBar(menu = MainMenu.Main,nav=nav)
}

@ -3,40 +3,244 @@ package com.gyf.csams.ui
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.constraintlayout.compose.ConstraintLayout
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.gyf.csams.R
import com.gyf.csams.ui.theme.CSAMSTheme
/**
* 主界面
*
*/
class MainActivity: ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
CSAMSTheme {
// A surface container using the 'background' color from the theme
Surface(color = MaterialTheme.colors.background) {
Row(horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.fillMaxSize()){
AnimationText(text = "主界面设计中。。。。")
Body()
}
}
}
}
@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){
Box(modifier = Modifier.fillMaxSize()) {
Column {
Notification()
MessageBoard()
Spacer(modifier = Modifier.height(10.dp))
ClubActivitiesTitle()
Spacer(modifier = Modifier.height(10.dp))
Column(Modifier.rotate(180F)) {
MyBottomAppBar(MainMenu.Main, navController,Modifier.rotate(180F))
ClubActivitiesImage()
}
}
}
}
composable(MainMenu.List.name){
Box(modifier = Modifier.fillMaxSize()) {
Column(Modifier.rotate(180F)){
MyBottomAppBar(MainMenu.List, navController,Modifier.rotate(180F))
Row(modifier = Modifier
.fillMaxSize()
.rotate(180F),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically) {
AnimationText(text = "社团列表")
}
}
}
}
composable(MainMenu.Center.name){
Box(modifier = Modifier.fillMaxSize()) {
Column(Modifier.rotate(180F)){
MyBottomAppBar(MainMenu.Center, navController,Modifier.rotate(180F))
Row(modifier = Modifier
.fillMaxSize()
.rotate(180F),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically) {
AnimationText(text = "个人中心")
}
}
}
}
}
}
}
}
@Preview(showBackground = true)
/**
* 通知
*
*/
@Composable
fun Notification(){
Row(horizontalArrangement = Arrangement.End,
modifier = Modifier
.fillMaxWidth()
.padding(10.dp)) {
Icon(painter = painterResource(id = R.drawable.ic_notification),
contentDescription = null,
modifier = Modifier.size(50.dp))
}
}
/**
* 圆角矩形边框
*
*/
@Composable
fun MyBorder(content: @Composable BoxScope.() -> Unit){
Box(modifier = Modifier.padding(horizontal = 15.dp)) {
Box(
modifier = Modifier
.border(width = 1.dp, color = Color.Black, shape = RoundedCornerShape(size = 20.dp)),
){
content()
}
}
}
/**
* 留言板
*
*/
@Composable
fun MessageBoard() {
MyBorder {
Row(modifier = Modifier.rotate(180F),
verticalAlignment = Alignment.CenterVertically) {
Icon(
painter = painterResource(id = R.drawable.ic_comments),
contentDescription = null,
modifier = Modifier
.size(50.dp)
.rotate(180F)
)
Row(
horizontalArrangement = Arrangement.Center,
modifier = Modifier
.fillMaxWidth()
.rotate(180F)
) {
Text(text = "跑马灯留言")
}
}
}
}
/**
* 活动标题
*
*/
@Composable
fun ClubActivitiesTitle(){
MyBorder {
Row(
modifier = Modifier
.fillMaxWidth()
.height(50.dp),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically
) {
Text(text = "超级课程表X滴滴出行-了不起的社团",
style = MaterialTheme.typography.h6,
overflow = TextOverflow.Ellipsis,
maxLines = 1)
}
}
}
/**
* 活动海报
*
*/
@Composable
fun ClubActivitiesImage(){
Column(modifier=Modifier.fillMaxSize()) {
Card(modifier = Modifier
.weight(0.4f)
.fillMaxWidth()) {
Image(painter = painterResource(id = R.drawable.hot_activity_desc_background),
contentDescription = null)
Box(modifier = Modifier
.padding(horizontal = 85.dp, vertical = 30.dp)
.rotate(180F)){
Text(text = "文字对任何界面都属于核心内容,而利用 Jetpack Compose 可以更轻松地显示或写入文字。Compose 可以充分利用其构建块的组合,这意味着您无需覆盖各种属性和方法,也无需扩展大型类,即可拥有特定的可组合项设计以及按您期望的方式运行的逻辑。"
.repeat(10),overflow = TextOverflow.Ellipsis)
}
}
Card(modifier = Modifier
.weight(0.6f)
.fillMaxWidth()) {
Image(painter = painterResource(id = R.drawable.hot_activity_background),
contentDescription = null)
Image(painter = painterResource(id = R.drawable.ic_launcher_foreground),
contentDescription = null)
}
}
}
//@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
CSAMSTheme {
// A surface container using the 'background' color from the theme
AnimationText(text = "sdfsdf")
Box(modifier = Modifier.fillMaxSize()) {
Column {
ClubActivitiesImage()
}
}
}
}
@Preview
@Composable
fun ConstraintLayoutContent() {
Box(modifier = Modifier.background(Color.Cyan)) {
ConstraintLayout {
// Create references for the composables to constrain
val (button, text,text2,box) = createRefs()
Box(Modifier.fillMaxSize())
Box(Modifier.size(50.dp).background(Color.Red).constrainAs(box){
bottom.linkTo(parent.bottom)
end.linkTo(parent.end)
})
}
}
}

@ -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="M644.8,581.57l160.64,187.46a64,64 0,0 1,-48.6 105.64L267.16,874.67a64,64 0,0 1,-48.6 -105.64l160.66,-187.43a253.81,253.81 0,0 0,61.21 26.94l-173.27,202.13h489.69l-173.27,-202.13a254.61,254.61 0,0 0,61.23 -26.97zM512,149.33c117.82,0 213.33,95.51 213.33,213.33S629.82,576 512,576s-213.33,-95.51 -213.33,-213.33S394.18,149.33 512,149.33zM512,213.33A149.33,149.33 0,1 0,512 512a149.33,149.33 0,0 0,0 -298.67z"/>
</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="M644.8,581.57l160.64,187.46A64,64 0,0 1,756.84 874.67H267.16a64,64 0,0 1,-48.6 -105.64l160.66,-187.43A254.81,254.81 0,0 0,512 618.67c48.64,0 94.08,-13.55 132.8,-37.1zM512,149.33c117.82,0 213.33,95.51 213.33,213.33s-95.51,213.33 -213.33,213.33 -213.33,-95.51 -213.33,-213.33S394.18,149.33 512,149.33z"/>
</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="M490.67,533.33v256a64,64 0,0 1,-64 64h-192a64,64 0,0 1,-64 -64v-192a64,64 0,0 1,64 -64h256zM789.33,533.33a64,64 0,0 1,64 64v192a64,64 0,0 1,-64 64h-192a64,64 0,0 1,-64 -64L533.33,533.33h256zM426.67,597.33h-192v192h192v-192zM789.33,597.33h-192v192h192v-192zM426.67,170.67a64,64 0,0 1,64 64v256L234.67,490.67a64,64 0,0 1,-64 -64v-192a64,64 0,0 1,64 -64h192zM693.33,170.67a160,160 0,1 1,0 320,160 160,0 0,1 0,-320zM426.67,234.67h-192v192h192v-192zM693.33,234.67a96,96 0,1 0,0 192,96 96,0 0,0 0,-192z"/>
</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="M490.67,533.33v256a64,64 0,0 1,-64 64h-192a64,64 0,0 1,-64 -64v-192a64,64 0,0 1,64 -64h256zM789.33,533.33a64,64 0,0 1,64 64v192a64,64 0,0 1,-64 64h-192a64,64 0,0 1,-64 -64L533.33,533.33h256zM426.67,170.67a64,64 0,0 1,64 64v256L234.67,490.67a64,64 0,0 1,-64 -64v-192a64,64 0,0 1,64 -64h192zM693.33,170.67a160,160 0,1 1,0 320,160 160,0 0,1 0,-320z"/>
</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="M810.67,213.33a64,64 0,0 1,64 64L874.67,704a64,64 0,0 1,-64 64L478.34,768l-146.65,96.11a21.33,21.33 0,0 1,-33.02 -17.86L298.67,768h-85.33a64,64 0,0 1,-64 -64L149.33,277.33a64,64 0,0 1,64 -64h597.33zM810.67,277.33L213.33,277.33L213.33,704h149.33v63.3L459.24,704h351.42L810.67,277.33zM539.31,490.67v64h-176.64v-64h176.64zM661.33,362.67v64L362.67,426.67v-64h298.67z"/>
</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="M556.59,159.36l288.49,183.91A64,64 0,0 1,874.67 397.25v392.75a64,64 0,0 1,-64 64H555.46l0.02,-196.99H490.67v196.99H234.67a64,64 0,0 1,-64 -64v-398.29a64,64 0,0 1,30.27 -54.4l287.53,-178.35a64,64 0,0 1,68.14 0.43zM810.67,790.02V397.23L522.2,213.33 234.67,391.68v398.34h192v-197.01h192.81v196.99H810.67z"/>
</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="M556.59,159.36l288.49,183.91A64,64 0,0 1,874.67 397.25v392.75a64,64 0,0 1,-64 64l-224,-0.02V597.33H448v256.64l-213.33,0.04a64,64 0,0 1,-64 -64V391.68a64,64 0,0 1,30.27 -54.4l287.53,-178.35a64,64 0,0 1,68.14 0.43z"/>
</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="M938.67,256c0,-46.93 -38.4,-85.33 -85.33,-85.33L170.67,170.67c-46.93,0 -85.33,38.4 -85.33,85.33v512c0,46.93 38.4,85.33 85.33,85.33h682.67c46.93,0 85.33,-38.4 85.33,-85.33L938.67,256zM853.33,256l-341.33,212.91L170.67,256h682.67zM853.33,768L170.67,768L170.67,341.33l341.33,213.33 341.33,-213.33v426.67z"/>
</vector>
Loading…
Cancel
Save