diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 0ceb916..436d7b4 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -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"]}")
//测试
diff --git a/app/src/androidTest/java/com/gyf/csams/TestPreview.kt b/app/src/androidTest/java/com/gyf/csams/TestPreview.kt
new file mode 100644
index 0000000..ca25fb6
--- /dev/null
+++ b/app/src/androidTest/java/com/gyf/csams/TestPreview.kt
@@ -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("填充父项允许的所有可用空间,通过旋转和前置子布局对调位置")
+ }
+ })
+ }
+ }
+ }
+
+}
diff --git a/app/src/main/java/com/gyf/csams/ui/Base.kt b/app/src/main/java/com/gyf/csams/ui/Base.kt
index 007e902..869cc18 100644
--- a/app/src/main/java/com/gyf/csams/ui/Base.kt
+++ b/app/src/main/java/com/gyf/csams/ui/Base.kt
@@ -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)
}
\ No newline at end of file
diff --git a/app/src/main/java/com/gyf/csams/ui/MainActivity.kt b/app/src/main/java/com/gyf/csams/ui/MainActivity.kt
index aed0362..72b8608 100644
--- a/app/src/main/java/com/gyf/csams/ui/MainActivity.kt
+++ b/app/src/main/java/com/gyf/csams/ui/MainActivity.kt
@@ -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)
+ })
+ }
}
}
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_account.xml b/app/src/main/res/drawable/ic_account.xml
new file mode 100644
index 0000000..c209003
--- /dev/null
+++ b/app/src/main/res/drawable/ic_account.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_account_fill.xml b/app/src/main/res/drawable/ic_account_fill.xml
new file mode 100644
index 0000000..8d3b735
--- /dev/null
+++ b/app/src/main/res/drawable/ic_account_fill.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_all.xml b/app/src/main/res/drawable/ic_all.xml
new file mode 100644
index 0000000..83b27b0
--- /dev/null
+++ b/app/src/main/res/drawable/ic_all.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_all_fill.xml b/app/src/main/res/drawable/ic_all_fill.xml
new file mode 100644
index 0000000..1c38c96
--- /dev/null
+++ b/app/src/main/res/drawable/ic_all_fill.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_comments.xml b/app/src/main/res/drawable/ic_comments.xml
new file mode 100644
index 0000000..d5ea5e2
--- /dev/null
+++ b/app/src/main/res/drawable/ic_comments.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_home.xml b/app/src/main/res/drawable/ic_home.xml
new file mode 100644
index 0000000..df3983e
--- /dev/null
+++ b/app/src/main/res/drawable/ic_home.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_home_fill.xml b/app/src/main/res/drawable/ic_home_fill.xml
new file mode 100644
index 0000000..6b19821
--- /dev/null
+++ b/app/src/main/res/drawable/ic_home_fill.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_notification.xml b/app/src/main/res/drawable/ic_notification.xml
new file mode 100644
index 0000000..15c4247
--- /dev/null
+++ b/app/src/main/res/drawable/ic_notification.xml
@@ -0,0 +1,9 @@
+
+
+