一、
6、Card及ConstraintLayout线性布局
//定义单独的机器人单独一行的卡片
@Composable
fun RobotCard(robot: Robot,navController:NavController){Card(modifier = Modifier.fillMaxWidth().wrapContentHeight().padding(5.dp),colors = CardDefaults.elevatedCardColors(contentColor = Color.Green, containerColor = Color.Blue),elevation = CardDefaults.elevatedCardElevation(defaultElevation = 3.dp)){ConstraintLayout(modifier= Modifier.fillMaxWidth()) {val (imageRef,nameRef,descRef) = remember{createRefs()}val vguideLine = createGuidelineFromStart(0.3f)val hguideLine = createGuidelineFromTop(0.4f)Image(modifier= Modifier.constrainAs(imageRef) {top.linkTo(parent.top)bottom.linkTo(parent.bottom)start.linkTo(parent.start)end.linkTo(vguideLine)}.clickable {
// val robotStr = Gson().toJson(robot)
// navController.na},painter = painterResource(id = robot.icon), contentDescription = robot.name )Text(modifier = Modifier.constrainAs(nameRef){top.linkTo(parent.top)bottom.linkTo(hguideLine)start.linkTo(vguideLine)end.linkTo(parent.end)},text = robot.name,fontSize = 18.sp)Text(modifier = Modifier.constrainAs(descRef){top.linkTo(hguideLine)bottom.linkTo(parent.bottom)start.linkTo(vguideLine)end.linkTo(parent.end)},text = robot.description,fontSize = 20.sp)}}
}
5、导航数组 新版
package com.example.uiapp.ui.screen
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material3.BottomAppBar
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.example.uiapp.ui.Component.MenuViews
import kotlinx.coroutines.launch@Composable
fun NavigationGraphScreen(navController: NavHostController) {NavHost(navController = navController, startDestination = "home") {composable(route = "home") {HomeScreen()}composable(route = "config") {ConfigScreen()}composable(route = "help") {HelpScreen()}}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainScreen2() {val navController:NavHostController= rememberNavController()val stateHolder= rememberState()Scaffold (
// topBar ={
// TopAppBar(
// navigationIcon = {
// IconButton(onClick = {
// stateHolder.scope.launch {
// stateHolder.drawerState.open()
// }
// }) {
// Icon(stateHolder.currentScreen.value.icon, contentDescription = "${stateHolder.currentScreen.value.route}")
// }
// },
// title ={
// Text(stateHolder.currentScreen.value.title)
// },
// actions = {
// IconButton(onClick = {
// stateHolder.expanded.value=!stateHolder.expanded.value;
// }) {
// Icon(Icons.Default.MoreVert, contentDescription ="more" )
// MenuViews(stateHolder.expanded,stateHolder.currentScreen)
//
// }
// }
// )}
// ,bottomBar = {BottomAppBar {screens.forEach{NavigationBarItem(selected = navController.currentDestination?.route==it.route,onClick = {navController.navigate(it.route)},icon = {Icon(it.icon, contentDescription = "null")})}}}){Box(modifier = Modifier.padding(it)){NavigationGraphScreen(navController)}}
}
不过这个只有底部导航栏
4、导航控件 旧版
代码于Day02test03
@Preview
@Composable
fun MainScreen(){
// val currentScreen:MutableState<Screen> = remember { mutableStateOf(Screen.Homepage) }
// //细节,在这里currentScreen后面写上这个类型代表也可以是其他页面
// val expanded = remember { mutableStateOf(false) }
// val drawerState= rememberDrawerState(initialValue = DrawerValue.Closed)
// val scope= rememberCoroutineScope()val stateHolder= rememberState()Scaffold(topBar={TopViews(stateHolder)},bottomBar={BottomViews(stateHolder.currentScreen)},floatingActionButton = {FloatingViews(stateHolder)},snackbarHost = {}) {Box(modifier = Modifier.padding(it)){//currentScreen.value.loadScreen.invoke()DrawViews(stateHolder.drawerState,currentScreen=stateHolder.currentScreen)}}
}
@Composable
@OptIn(ExperimentalMaterial3Api::class)
fun TopViews(stateHolder: StateHolder){TopAppBar(navigationIcon = {IconButton(onClick = {stateHolder.scope.launch {stateHolder.drawerState.open()}}) {Icon(stateHolder.currentScreen.value.icon, contentDescription = "${stateHolder.currentScreen.value.route}")}},title ={Text(stateHolder.currentScreen.value.title)},actions = {IconButton(onClick = {stateHolder.expanded.value=!stateHolder.expanded.value;}) {Icon(Icons.Default.MoreVert, contentDescription ="more" )MenuViews(stateHolder.expanded,stateHolder.currentScreen)}})
}
@Composable
fun BottomViews(currentScreen:MutableState<Screen>){BottomAppBar {screens.forEach{NavigationBarItem(selected = currentScreen.value==it,label = {Text(it.title, fontSize = 20.sp)},onClick = {currentScreen.value=it}, icon = {Icon(it.icon, contentDescription = "${it.route}")})}}}
@Composable
fun FloatingViews(stateHolder: StateHolder){FloatingActionButton(modifier = Modifier.clip(CircleShape),containerColor = Color.White,onClick = {stateHolder.currentScreen.value= Screen.Homepage}) {//tintIcon(Icons.Default.Home, contentDescription = "home")}
}
@Composable
fun DrawViews(drawerState: DrawerState, currentScreen: MutableState<Screen>){ModalNavigationDrawer(drawerState = drawerState,drawerContent = {Column (modifier = Modifier.width(300.dp).fillMaxHeight().background(Color.Black)){DrawerHead()DrawerBottom(drawerState,currentScreen)}}) {currentScreen.value.loadScreen()}
}
@Preview
@Composable
fun DrawerHead(){ConstraintLayout(modifier = Modifier.width(300.dp).height(200.dp).background(Color.Green)){val (imageRef,titleRef,contentRef)= remember { createRefs()}createVerticalChain(titleRef,contentRef, chainStyle = ChainStyle.Spread)val hGuideLine = createGuidelineFromStart(0.2f)val vGuideLine = createGuidelineFromTop(0.5f)Image(painter = painterResource(id=android.R.mipmap.sym_def_app_icon),contentDescription = "image", modifier = Modifier.constrainAs(imageRef){top.linkTo(parent.top)bottom.linkTo(parent.bottom)start.linkTo(parent.start)end.linkTo(hGuideLine)})Text("客人", fontSize = 20.sp, modifier = Modifier.constrainAs(titleRef){top.linkTo(parent.top)bottom.linkTo(vGuideLine)start.linkTo(hGuideLine)end.linkTo(parent.end)})Text(text = "这个人很懒",fontSize = 18.sp,modifier = Modifier.constrainAs(contentRef) {top.linkTo(vGuideLine)bottom.linkTo(parent.bottom)start.linkTo(hGuideLine)end.linkTo(parent.end)})}}@Composable
fun DrawerBottom(drawerState: DrawerState,currentScreen:MutableState<Screen>){val scope= rememberCoroutineScope()Column(modifier = Modifier.width((300.dp))) {screens.forEach{NavigationDrawerItem(colors = NavigationDrawerItemDefaults.colors(selectedIconColor = Color.Red,unselectedIconColor = Color.White,selectedTextColor = Color.Red,unselectedTextColor = Color.White,selectedBadgeColor = Color.DarkGray,unselectedBadgeColor = Color.Black),icon={Icon(it.icon, contentDescription = it.route)},label = {Text(it.title, fontSize = 24.sp)},selected = it==currentScreen.value,onClick = {currentScreen.value=itscope.launch{drawerState.close()}})}}}
3、序列化数据初始化
data class Student(val id:String,val name:String,val gender:String,val email:String): Parcelable {constructor(parcel: Parcel) : this(parcel.readString()!!,parcel.readString()!!,parcel.readString()!!,parcel.readString()!!) {}override fun writeToParcel(p0: Parcel, p1: Int) {p0.writeString(id)p0.writeString(name)p0.writeString(gender)p0.writeString(email)}override fun describeContents(): Int =0companion object CREATOR : Parcelable.Creator<Student> {override fun createFromParcel(parcel: Parcel): Student {return Student(parcel)}override fun newArray(size: Int): Array<Student?> {return arrayOfNulls(size)}}
}
利用Parcelable,也可以参考Android笔记【18】关于数据传输的三份代码,里面记录了不同方法的使用,但对于这份只是放了代码,后续会有更多深读。
它写好参数继承接口之后写好构造器writeToParcel后,会自动报错生成实现后面的抽象函数和伴随对象。
2、Column、Row、Image最基本的修饰
Column(modifier = Modifier.fillMaxSize(), // 使 Column 填满整个可用空间verticalArrangement = Arrangement.spacedBy(8.dp), // 子组件之间的垂直间距horizontalAlignment = Alignment.CenterHorizontally // 子组件的水平对齐方式) {Text("Item 1")Text("Item 2")Text("Item 3")}
Row(
modifier = Modifier
.fillMaxWidth()
.padding(60.dp), // 给 Row 添加内边距
verticalAlignment = Alignment.CenterVertically, // 垂直居中对齐
horizontalArrangement = Arrangement.SpaceBetween // 子组件之间的水平间距
) {Text(text = "Item 1")Button(onClick = { /* 处理点击事件 */ }) {Text("Button 1")}Text(text = "Item 2")Button(onClick = { /* 处理点击事件 */ }) {Text("Button 2")}
}
区别:
-
Arrangement.SpaceBetween:
- 子元素的第一个和最后一个元素与容器的边缘对齐。
- 子元素之间的空间被均匀分配,但容器的两端没有额外的空间。
- 例如,如果有三个元素,空间只分配在它们之间。
-
Arrangement.SpaceEvenly:
- 所有子元素之间的空间是均匀的,包括容器的边缘。
- 第一个和最后一个元素与容器边缘之间的空间与元素之间的空间相等。
- 例如,如果有三个元素,容器的两端也会有与子元素之间相同的间距。
Row(modifier = Modifier.padding(all = 8.dp)) {Image(painter = painterResource(R.drawable.profile_picture),contentDescription = null,modifier = Modifier.size(40.dp).clip(CircleShape).border(1.5.dp, MaterialTheme.colorScheme.primary, CircleShape))Spacer(modifier = Modifier.width(8.dp))
}
// We toggle the isExpanded variable when we click on this Column
Column(modifier = Modifier.clickable { isExpanded = !isExpanded }) {Text(text = msg.author,color = MaterialTheme.colorScheme.secondary,style = MaterialTheme.typography.titleSmall)Spacer(modifier = Modifier.height(4.dp))Surface(shape = MaterialTheme.shapes.medium,shadowElevation = 1.dp,) {Text(text = msg.body,modifier = Modifier.padding(all = 4.dp),// If the message is expanded, we display all its content// otherwise we only display the first linemaxLines = if (isExpanded) Int.MAX_VALUE else 1,style = MaterialTheme.typography.bodyMedium)}
}
用那个:
var isExpanded by remember { mutableStateOf(false) }
Android笔记【1】这里面讲了
val state by remember { mutableStateOf(默认值) }
这种方式使用了 Kotlin 的委托属性(delegated properties)。这里的 state 是一个 Int 类型的可读写属性,直接代表 mutableStateOf 的值。你可以直接使用 state 进行读写,而无需使用 .value。
1、debug页面切换Log
open class BaseActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)makeLog("${this.localClassName}-->onCreate")}override fun onStart() {super.onStart()makeLog("${this.localClassName}-->onStart")}override fun onResume() {super.onResume()makeLog("${this.localClassName}-->onResume")}override fun onPause() {super.onPause()makeLog("${this.localClassName}-->onPause")}override fun onStop() {super.onStop()makeLog("${this.localClassName}-->onStop")}override fun onDestroy() {super.onDestroy()makeLog("${this.localClassName}-->onDestroy")}private fun makeLog(log:String){Log.d("TAG",log)}
}
注意:那这样其他页面就不是继承componentActivity了,而是继承BaseActivity哈~
DownLoad 音乐播放器
music里面放骰子
Day01在Practice里面 (05_06withcontext自写音乐播放器)(app彩票生成器)( lifecycledemo跳转)(serializable 数据传递)
Day02(uiapp页面跳转草稿 ,day04test02重写,xinlitest草稿)
Day03 RobotCard
Day04(test02 parceble数据传输、页面跳转)(test03执行后退)(Looper test04) (test05test06货币转换)
Day05 聊天机器人
Day07contentProvider room mirgrate(书上有三种迁移,我的代码没完全)work1(坏了)
Day06GoogleUI
Day08两种weChat版本
Day09chat+room test03可以做到 贝儿的综合体世界
day10
DL 1 FakeWe-Chat Master 可以运行啦 打算做一个持久化 没做成功
project123 做一个线上购物软件,但获取不到fireBase里面的数据。。。
DL FakeWe-Chat Master 可以运行 改了搜索框