Jetpack Compose segmented control组件

2023年10月30日

Jetpack Compos好像默认并没有segmented control的组件,自定义一个吧。

@Composable
fun SegmentedControl(
   items: List<String>,
   defaultSelectedItemIndex: Int = 0,
   useFixedWidth: Boolean = false,
   itemWidth: Dp = 120.dp,
   cornerRadius : Int = 10,
   @ColorRes color : Int = R.color.teal_200,
   onItemSelection: (selectedItemIndex: Int) -> Unit
) {
   val selectedIndex = remember { mutableStateOf(defaultSelectedItemIndex) }
   Row(
       modifier = Modifier
   ) {
       items.forEachIndexed { index, item ->
           OutlinedButton(
               modifier = when (index) {
                   0 -> {
                       if (useFixedWidth) {
                           Modifier
                               .width(itemWidth)
                               .offset(0.dp, 0.dp)
                               .zIndex(if (selectedIndex.value == index) 1f else 0f)
                       } else {
                           Modifier
                               .wrapContentSize()
                               .offset(0.dp, 0.dp)
                               .zIndex(if (selectedIndex.value == index) 1f else 0f)
                       }
                   } else -> {
                       if (useFixedWidth)
                           Modifier
                               .width(itemWidth)
                               .offset((-1 * index).dp, 0.dp)
                               .zIndex(if (selectedIndex.value == index) 1f else 0f)
                       else Modifier
                           .wrapContentSize()
                           .offset((-1 * index).dp, 0.dp)
                           .zIndex(if (selectedIndex.value == index) 1f else 0f)
                   }
               },
               onClick = {
                   selectedIndex.value = index
                   onItemSelection(selectedIndex.value)
               },
               shape = when (index) {
                   /**
                    * left outer button
                    */
                   0 -> RoundedCornerShape(
                       topStartPercent = cornerRadius,
                       topEndPercent = 0,
                       bottomStartPercent = cornerRadius,
                       bottomEndPercent = 0
                   )
                   /**
                    * right outer button
                    */
                   items.size - 1 -> RoundedCornerShape(
                       topStartPercent = 0,
                       topEndPercent = cornerRadius,
                       bottomStartPercent = 0,
                       bottomEndPercent = cornerRadius
                   )
                   /**
                    * middle button
                    */
                   else -> RoundedCornerShape(
                       topStartPercent = 0,
                       topEndPercent = 0,
                       bottomStartPercent = 0,
                       bottomEndPercent = 0
                   )
               },
               border = BorderStroke(
                   1.dp, if (selectedIndex.value == index) {
                       colorResource(id = color)
                   } else {
                       colorResource(id = color).copy(alpha = 0.75f)
                   }
               ),
               colors = if (selectedIndex.value == index) {
                   /**
                    * selected colors
                    */
                   ButtonDefaults.outlinedButtonColors(
                       backgroundColor = colorResource(
                           id = color
                       )
                   )
               } else {
                   /**
                    * not selected colors
                    */
                   ButtonDefaults.outlinedButtonColors(backgroundColor = Color.Transparent)
               },
           ) {
               Text(
                   text = item,
                   fontWeight = FontWeight.Normal,
                   color = if (selectedIndex.value == index) {
                       Color.White
                   } else {
                       colorResource(id = color).copy(alpha = 0.9f)
                   },
               )
           }
       }
   }
}

使用代码示例:

val genders = listOf("Male", "Female")
SegmentedControl(
   items = genders,
   defaultSelectedItemIndex = 0
) {
   Log.e("CustomToggle", "Selected item : ${genders[it]}")
}

 

© 1987 - 2023 张晓刚 版权所有

浙ICP备16002143号-1