jetpack compose 框架

Compose

Rows,Columns,Box

在这里插入图片描述

Row 和Column是用来设置子项的位置。在水平方向(horizontal)和竖直方向(vertical)设置有两个参数,分别是排列(Arrangement)和布局(Alignment)

  1. Arrangement

    • Center

    • End

    • Start

    • SpaceAround (每个元素之间的距离相等为d,但最顶部的距离与最近一个元素的距离为d/2)

    • SpaceBetween (尽可能的增大两个元素之间的距离)

    • SpaceEvenly (每个元素之间的距离相等)

  2. Alignment

    • Bottom(底部)
    • Top (顶端)
    • CenterVertically (居中对齐)
    • BottomStart
//Row(horizontalArrangement =... ,
		verticalAlignment=...){
			...
		}
//Column(verticalArrangement=... ,
			horizontalAlignment=...){
			...
		}

在这里插入图片描述

Modifiers

Modifier 是一种修饰符

  1. 大小
    • fillMaxSize(0.xf) 与父元素大小相等
    • fillMaxWidth(0.xf)
    • fillMaxHeight(0.xf)
    • width(x.dp) 直接定义大小
    • height(x.dp)
    • requiredWidth 强制设定大小,不考虑父元素的限制
  2. 背景颜色
    • background (Color. x)
  3. 边距
    • padding(x.dp)
    • offset(x.dp,x.dp)
    • Spacer(modifier=Modifier.height(x.dp))
    • border
  4. 特效
    • clickable 点击
    • scrollable 滚动
    • draggable 拖拉
// Eg1
Column(modifier= Modifier.background(Color.Green)  //设置背景(颜色)
		.padding(15.dp) //设置内边距
	)
	
//Eg2
Text("hello",modifier=Modifier.offset(50.dp,20.dp))
Spacer(modifier=Modifier.height(50.dp))
Text("world")

Image

  • painterResource(id=R.drawable.x) 引入图片
  • card(){} 卡片布局
  • Image(){} 图片布局
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val painter = painterResource(id = R.drawable.pic1)  
            val description="我喜欢哆啦A梦"
            val title="哆啦A梦"
            Box(modifier = Modifier
                .fillMaxSize(0.5f)
                .padding(16.dp)){
                ImageCard( //调用函数
                    painter = painter,
                    contentDescription = description,
                    title = title
                )
            }
        }
    }
}
@Composable
fun ImageCard(
    painter: Painter,
    contentDescription: String,
    title: String,
    modifier:Modifier=Modifier
    ) {
    Card(
        modifier = modifier.fillMaxWidth(),   
        shape = RoundedCornerShape(15.dp),  //形状
        elevation = 5.dp  
    ) {
        Box(modifier = Modifier.height(200.dp)) {
            Image(
                painter = painter,
                contentDescription = contentDescription,
                contentScale = ContentScale.Crop  
            )
            Box(modifier = Modifier  
                .fillMaxSize()
                .background(
                    Brush.verticalGradient(  // 黑色透明背景
                        colors = listOf(
                            Color.Transparent,
                            Color.Black
                        ),
                        startY=300f
                    )
                )
            )
            Box(
                modifier = Modifier
                    .fillMaxSize()
                    .padding(12.dp),
                contentAlignment = Alignment.BottomStart
            ) {
                Text(title, style = TextStyle(color = Color.White, fontSize = 16.sp))
            }
        }
    }
}

在这里插入图片描述

  • 图片拖拽
@Preview(name = "studyImage")
@Composable
fun StudyImageView() {
    val draggerOffset:MutableState<Float> = remember{ mutableStateOf(0f) }
    val imageBitmap: ImageBitmap = ImageBitmap.imageResource(R.drawable.pic4)
    Image(
        bitmap = imageBitmap,
        contentScale = ContentScale.FillBounds,
        contentDescription ="Star",
        modifier = Modifier.ImageModifier(draggerOffset)
    )
}

private fun Modifier.ImageModifier(draggerOffset: MutableState<Float>):Modifier =
    composed { Modifier
        .height(260.dp)
        .width(200.dp)
        .padding(horizontal = 30.dp, vertical = 30.dp)
        .clip(
            RectangleShape
        )
        .rotate(10f)
        .draggable(state = DraggableState(onDelta = {
            draggerOffset.value = +it
            Log.e("ondelta", "StudyImageView: " + draggerOffset.value)
        }), orientation = Orientation.Horizontal)
        .offset(x = draggerOffset.value.dp)
    }

Styling Text

Text

官方讲解

设置文字样式

Text(
	text="...", //文本内容
	color=Color.x, // 文字颜色
	fontSize=x.sp //字号
	fontStyle=FontStyle.Italic ,//斜体
	fontWeight=FontWeight.Bold ,//粗体   FontWeight.thin 细 , FontWeight(0~1000)值越大,字体越粗
	textAlign=TextAlign.Center ,//居中对齐
	letterSpacing = TextUnit.Unspecified ,// 字间距   自定义间距 =x.sp
	textDecoration = TextDecoration.None ,// 文本装饰  下划线 .underline   删除线.LineThrough
	lineHeight = x.sp  ,//行高
	overflow = TextOverflow.Clip  ,//文本溢出截断  .Ellipsis// 省略号表示
	maxline=x //最大显示行数
	softWrap = true //换行  =false 不换行
	            
    modifier = Modifier.border( //边框
                border = BorderStroke(
                    width = 3.dp,
                    color = Color(0xFF999999),
                ),
                shape = RoundedCornerShape(20f, 60f, 20f, 160f),
            ),
)

自带字体
在这里插入图片描述
溢出的文本
TextOverflow.Clip不指定宽高或最大行数时没有效果
TextOverflow.Ellipsis 配合 maxLines: Int 最大行数使用
在这里插入图片描述
软换行
在这里插入图片描述

包含多种样式

buildAnnotatedString{…}

  • 字符级别 spanStyle
 Text(
        buildAnnotatedString {
            withStyle(style = SpanStyle(color = Color.Blue)) {
                append("H")
            }
            append("ello ")
            
            withStyle(style = SpanStyle(fontWeight = FontWeight.Bold, color = Color.Red)) {
                append("W")
            }
            append("orld")
        }
     )

在这里插入图片描述

  • 段落级别 ParagraphStyle
@Composable
fun ParagraphStyle() {
    Text(
        buildAnnotatedString {
            withStyle(style = ParagraphStyle(lineHeight = 30.sp)) {
                withStyle(style = SpanStyle(color = Color.Blue)) {
                    append("Hello\n")
                }
                withStyle(
                    style = SpanStyle(
                        fontWeight = FontWeight.Bold,
                        color = Color.Red
                    )
                ) {
                    append("World\n")
                }
                append("Compose")
            }
        }
    )
}

在这里插入图片描述

用户互动

  • 选择文字 SelectionContainer{ }
@Composable
fun PartiallySelectableText() {
    SelectionContainer {
        Column {
            Text("This text is selectable")
            Text("This one too")
            Text("This one as well")
            DisableSelection {  // 不可以选择的部分
                Text("But not this one")
                Text("Neither this one")
            }
            Text("But again, you can select this one")
            Text("And this one too")
        }
    }
}

在这里插入图片描述

State

  • 随机变换颜色的盒子
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Text("hello")
            ColorBox(
                Modifier.fillMaxSize()
            )
        }
    }
}


@Composable
fun ColorBox(modifier: Modifier=Modifier
){
    val color= remember {
        mutableStateOf(Color.Yellow)
    }
    Box(modifier = Modifier
        .background(Color.Red)
        .clickable {
            color.value = Color(
                Random.nextFloat(),
                Random.nextFloat(),
                Random.nextFloat(),
                alpha = 1f
            )
        }
    )
}

  • 通过手势拖动盒子
@Preview
@Composable
fun TransformGestureDemo() {
    var boxSize = 100.dp
    var offset by remember { mutableStateOf(Offset.Zero) }
    var ratationAngle by remember { mutableStateOf(0f) }
    var scale by remember { mutableStateOf(1f) }
    Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
        Box(Modifier
            .size(boxSize)
            .rotate(ratationAngle) // 需要注意offset与rotate的调用先后顺序
            .scale(scale)
            .offset {
                IntOffset(offset.x.roundToInt(), offset.y.roundToInt())
            }
            .background(Color.Green)
            .pointerInput(Unit) {
                detectTransformGestures(
                    panZoomLock = true, // 平移或放大时是否可以旋转
                    onGesture = { centroid: Offset, pan: Offset, zoom: Float, rotation: Float ->
                        offset += pan
                        scale *= zoom
                        ratationAngle += rotation
                    }
                )
            }
        )
    }
}

Textfield, Button,Sankerbars

  • Textfield, Button
       setContent {
            val scaffoldState = rememberScaffoldState()
            var textFieldState by remember {
                mutableStateOf(" ")
            }
            val scope= rememberCoroutineScope()
            Scaffold(modifier = Modifier.fillMaxSize(),
                     scaffoldState = scaffoldState
            ) {
                Column(horizontalAlignment = Alignment.CenterHorizontally,
                        verticalArrangement = Arrangement.Center,
                        modifier = Modifier
                            .fillMaxSize()
                            .padding(horizontal = 30.dp)
                ) {
                    TextField(value = textFieldState,
                            onValueChange ={textFieldState=it},
                            label = {Text("Enter Your Name")} ,
                            singleLine =true,
                            modifier = Modifier.height(50.dp).fillMaxWidth(0.8f) )
                    Spacer(modifier = Modifier.height(16.dp))
                    Button( onClick={
                        scope.launch {
                            scaffoldState.snackbarHostState.showSnackbar("Hello $textFieldState")
                        }
                    }){
                        Text("pls greet me")
                    }
                }
            }
        }
//Botton
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Column(
                verticalArrangement = Arrangement.SpaceEvenly,
                horizontalAlignment = Alignment.CenterHorizontally,
                modifier = Modifier.fillMaxSize()
            ) {
                ButtonDemo()
            }
        }
    }
}
 
@Composable
fun ButtonDemo() {
 
    val context = LocalContext.current
 
    Button(onClick = {
        Toast.makeText(context, "Clicked on Button", Toast.LENGTH_SHORT).show()
    })
    {
        Text("Standard")
    }
 
    Button(
        onClick = {
            Toast.makeText(context, "Clicked on Button", Toast.LENGTH_SHORT).show()
        },
        enabled = false
    ) {
        Text("Disabled")
    }
 
    TextButton(onClick = {
        Toast.makeText(context, "Clicked on Text Button", Toast.LENGTH_SHORT).show()
    }) {
        Text("  Text  ")
    }
 
    OutlinedButton(onClick = {
        Toast.makeText(context, "Clicked on Out Lined Button", Toast.LENGTH_SHORT).show()
    }) {
        Text("Outlined")
    }
 
    IconButton(onClick = {
        Toast.makeText(context, "Clicked on Icon Button", Toast.LENGTH_SHORT).show()
    }) {
        Icon(
            Icons.Filled.Refresh,
            contentDescription = "Refresh Button",
            tint = Color.DarkGray,
            modifier = Modifier.size(80.dp)
        )
    }
}
 

在这里插入图片描述

 Button(onClick = {
        Toast.makeText(context, "Clicked on Button", Toast.LENGTH_SHORT).show()
    },
        contentPadding = PaddingValues(16.dp),
        border = BorderStroke(10.dp, Color.Black),
        colors = ButtonDefaults.textButtonColors(
            backgroundColor = Color.DarkGray,
            contentColor = Color.White
        )
    ) {
        Text("Add To Cart",
            style = MaterialTheme.typography.h3,
            modifier = Modifier.padding(5.dp)
        )
    }

在这里插入图片描述

    Button(onClick = {
        Toast.makeText(context, "Clicked on Button", Toast.LENGTH_SHORT).show()
    },
        shape = CircleShape,//shape = CutCornerShape(10.dp),
        contentPadding = PaddingValues(16.dp),
        border = BorderStroke(10.dp, Color.Black),
        colors = ButtonDefaults.textButtonColors(
            backgroundColor = Color.DarkGray,
            contentColor = Color.White
        )
    ) {
        Text("Add To Cart",
            style = MaterialTheme.typography.h3,
            modifier = Modifier.padding(5.dp)
        )
    }
  • List
            LazyColumn {
                itemsIndexed(
                    listOf("This","is","Jetpack","Compose")
                ){ index, string ->
                    Text(
                        text =string,
                        fontSize = 24.sp,
                        fontWeight = FontWeight.Bold,
                        textAlign = TextAlign.Center,
                        modifier = Modifier
                            .fillMaxWidth()
                            .padding(vertical = 24.dp)
                    )
                }
            }
        

在这里插入图片描述

sideEffect

  • 点击按钮,数字加1
        setContent {
            val scaffoldState= rememberScaffoldState()
            val scope= rememberCoroutineScope()
            Scaffold(scaffoldState=scaffoldState) {
                var counter by remember {
                    mutableStateOf(0)
                }
                if(counter %5==0 && counter>0){
                   LaunchedEffect(key1 = scaffoldState.snackbarHostState){
                        scaffoldState.snackbarHostState.showSnackbar("hello")
                    }
                }
                Button(onClick = {counter++}) {
                    Text("Click me: $counter")
                }
            }
        }

        setContent {
            val scaffoldState= rememberScaffoldState()
            val scope= rememberCoroutineScope()
            Scaffold(scaffoldState=scaffoldState) {
                var counter= produceState(initialValue =0 ){
                    delay(3000L)
                    value=4  //点击按钮后,直接跳转至4
                }
                if(counter.value %5==0 && counter.value>0){
                   LaunchedEffect(key1 = scaffoldState.snackbarHostState){
                        scaffoldState.snackbarHostState.showSnackbar("hello")
                    }
                }
                Button(onClick = {}) {
                    Text("Click me: ${counter.value}")
                }
            }
        }
  • 变大的盒子
        //点击按钮自动增大
        setContent {
            var sizeState by remember {
                mutableStateOf(200.dp)
            }
            val size by animateDpAsState(
                targetValue = sizeState,
                tween( //增大的较为平缓
                  durationMillis = 3000,
                  delayMillis = 300,
                  easing = LinearOutSlowInEasing
                )
                /*
                spring( //增大的过程中有震荡
                    Spring.DampingRatioHighBouncy
                )
                keyframes { //增大的速度不同
                    durationMillis=5000
                    sizeState at 0 with LinearEasing
                    sizeState * 1.5f at 1000 with FastOutLinearInEasing
                    sizeState * 2f at 5000
                }
                */
            )
            Box(modifier = Modifier
                .size(size)
                .background(Color.Red),
                contentAlignment = Alignment.Center
            ){
                Button(onClick = {
                    sizeState+=50.dp
                }) {
                    Text("Increase size")
                }
            }
        }
//从红渐变到绿再从绿变红
setContent {
            var sizeState by remember {
                mutableStateOf(200.dp)
            }
            val size by animateDpAsState(
                targetValue = sizeState,
                tween(
                    durationMillis = 1000
                )
            )
            val infiniteTransition= rememberInfiniteTransition()
            val color by infiniteTransition.animateColor(
                initialValue = Color.Red,
                targetValue = Color.Green,
                animationSpec = infiniteRepeatable(
                    tween(durationMillis = 2000),
                    repeatMode = RepeatMode.Reverse
                )
            )
            Box(modifier = Modifier
                .size(size)
                .background(color),
                contentAlignment = Alignment.Center
            ){
                Button(onClick = {
                    sizeState+=50.dp
                }) {
                    Text("Increase size")
                }
            }
        }
  • Progressbar
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Box(modifier = Modifier.fillMaxSize(),
                contentAlignment = Alignment.Center
            ){
                CircularProgressBar(percentage = 0.8f, number =100 )
            }
        }
    }
}

@Composable
fun CircularProgressBar(
    percentage: Float,
    number: Int,
    fontSize:TextUnit=28.sp,
    radius: Dp =50.dp,
    color:Color= Color.Green,
    strokeWidth:Dp=8.dp,
    animDuration: Int=1000,
    animDelay: Int=0
    ) {
    var animationPlayed by remember {
        mutableStateOf(false)
    }
    val curPercentage = animateFloatAsState(
        targetValue = if (animationPlayed) percentage else 0f,
        animationSpec = tween(
            durationMillis = animDuration,
            delayMillis = animDelay
        )
    )
    LaunchedEffect(key1 = true) {
        animationPlayed = true
    }
    Box(
        contentAlignment = Alignment.Center,
        modifier = Modifier.size(radius * 2f)
    ) {
            Canvas(modifier = Modifier.size(radius*2f))
            {
                drawArc(
                    color=color,
                    -90f,
                    360*curPercentage.value,
                    useCenter=false,
                    style=Stroke(strokeWidth.toPx(),cap= StrokeCap.Round)
                )
            }
        Text(
            text=(curPercentage.value*number).toInt().toString(),
            color = Color.Black,
            fontSize=fontSize,
            fontWeight = FontWeight.Bold
        )
    }
}

  • 折现图绘制
@Preview
@Composable
fun MyLineView(){
    Canvas(
        modifier = Modifier
            .padding(10.dp)
            .width(200.dp)
            .height(100.dp),
    ){
        drawIntoCanvas {canvas->
            val paint= Paint()
            paint.color=Color(208,208,208)
            paint.style= PaintingStyle.Stroke
            paint.strokeWidth=3f


            val paintFill=Paint()
            paintFill.color=Color.Gray
            paintFill.style= PaintingStyle.Stroke
            paintFill.strokeWidth=3f

            //1.绘制坐标轴
            canvas.translate(0f,size.height)
            canvas.scale(1f,-1f)
            //2.绘制x轴
            val pathY =Path()
            pathY.moveTo(0f,0f)
            pathY.relativeLineTo(0f,size.height)
            canvas.drawPath(pathY,paint)


            //2.绘制y轴
            val pathX =Path()
            pathX.moveTo(0f,0f)
            pathX.relativeLineTo(size.width,0f)
            canvas.drawPath(pathX,paint)


            val dataList:MutableList<Offset> =  mutableListOf(Offset(20f,60f),Offset(40f,30f),Offset(50f,34f),Offset(80f,54f),Offset(100f,34f),Offset(200f,134f),Offset(400f,154f),Offset(480f,134f))
            val linePath=Path()
            paint.color=Color.Blue
            val colors:MutableList<Color> = mutableListOf(Color.Red,Color.Blue,Color.Green)
            paint.shader= LinearGradientShader(Offset(0f,0f),Offset(size.width,0f),colors,null,TileMode.Clamp)
            paint.isAntiAlias=true

            //3.绘制折线填充
            for (index in 0 until dataList.size){
                linePath.lineTo(dataList[index].x,dataList[index].y)
            }
            linePath.lineTo(dataList[dataList.size-1].x,0f)
            linePath.close()
            //绘制填充
            paintFill.style= PaintingStyle.Fill
            paintFill.shader= LinearGradientShader(Offset(0f,size.height),Offset(0f,0f), arrayListOf(Color(59,157,254,161),Color(59,157,254,21)),null,TileMode.Clamp)
            canvas.drawPath(linePath,paintFill)

            //2绘制折线2
            val line =Path()
            for (index in 0 until dataList.size){
                line.lineTo(dataList[index].x,dataList[index].y)
            }
            paint.style= PaintingStyle.Stroke
            canvas.drawPath(line,paint)

            /*
            //3绘制圆圈
            paint.style= PaintingStyle.Fill
            for (index in 0 until dataList.size){
                canvas.drawCircle(Offset(dataList[index].x,dataList[index].y),6f,paint)
            }
            canvas.drawImage(image = bitmap, Offset(100f,100f),paint)

             */
        }
    }

}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zyw2002

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值