H4k*_*4kt 4 android kotlin android-jetpack-compose
我有一个代表消息的可组合组件。每条消息都可以是传入或传出,具体取决于我想要反转消息组件中的所有项目。
我发现的唯一方法是强制 RTL 布局,但这也会导致文本被反转。

还有其他办法解决这个问题吗?
MessageView.kt
@Composable
fun MessageView(
message: Message
) = Row(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight(),
verticalAlignment = Alignment.Bottom
) {
val (isIncoming) = message
val direction = if (isIncoming) {
LayoutDirection.Ltr
} else {
LayoutDirection.Rtl
}
CompositionLocalProvider(
LocalLayoutDirection provides direction
) {
MessageViewContent(message)
}
}
@Composable
private fun MessageViewContent(
message: Message
) = Row(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight(),
verticalAlignment = Alignment.Bottom
) {
val (isIncoming, text, at) = message
val background: Color
val textColor: Color
val timeColor: Color
val alignment: Alignment.Horizontal
val textAlignment: TextAlign
if (isIncoming) {
background = Color(0xFFEFEFEF)
textColor = Color(0xFF000000)
timeColor = Color(0xFF929292)
alignment = Alignment.End
textAlignment = TextAlign.Start
} else {
background = Color(0xFFE0727F)
textColor = Color(0xFFFEFEFE)
timeColor = Color(0xB3FEFEFE)
alignment = Alignment.Start
textAlignment = TextAlign.End
}
Image(
modifier = Modifier
.size(40.dp)
.clip(CircleShape),
painter = painterResource(R.drawable.ic_launcher_background),
contentDescription = null
)
Spacer(modifier = Modifier.width(12.dp))
Column(
modifier = Modifier
.weight(1F, fill = false)
.wrapContentWidth()
.background(
color = background,
shape = RoundedCornerShape(8.dp)
)
.padding(4.dp),
horizontalAlignment = alignment
) {
Text(
modifier = Modifier.padding(6.dp),
style = TextStyle(
fontSize = 16.sp,
color = textColor
),
text = text
)
Text(
style = TextStyle(
fontSize = 10.sp,
color = timeColor,
textAlign = textAlignment
),
text = "${at.hour}:${at.minute}",
)
}
Spacer(modifier = Modifier.width(60.dp))
}
Run Code Online (Sandbox Code Playgroud)
因此,我想出了一种解决方案,可以创建一个自定义水平排列,它使用现有End排列中的代码。
HorizontalArrangementExts.kt
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.LayoutDirection
val Arrangement.Reverse: Arrangement.Horizontal
get() = ReverseArrangement
object ReverseArrangement : Arrangement.Horizontal {
override fun Density.arrange(
totalSize: Int,
sizes: IntArray,
layoutDirection: LayoutDirection,
outPositions: IntArray
) = if (layoutDirection == LayoutDirection.Ltr) {
placeRightOrBottom(totalSize, sizes, outPositions, reverseInput = true)
} else {
placeLeftOrTop(sizes, outPositions, reverseInput = false)
}
// Had to copy function from sources because it is marked internal
private fun placeRightOrBottom(
totalSize: Int,
size: IntArray,
outPosition: IntArray,
reverseInput: Boolean
) {
val consumedSize = size.fold(0) { a, b -> a + b }
var current = totalSize - consumedSize
size.forEachIndexed(reverseInput) { index, it ->
outPosition[index] = current
current += it
}
}
// Had to copy function from sources because it is marked internal
private fun placeLeftOrTop(size: IntArray, outPosition: IntArray, reverseInput: Boolean) {
var current = 0
size.forEachIndexed(reverseInput) { index, it ->
outPosition[index] = current
current += it
}
}
// Had to copy function from sources because it is marked private
private inline fun IntArray.forEachIndexed(reversed: Boolean, action: (Int, Int) -> Unit) {
if (!reversed) {
forEachIndexed(action)
} else {
for (i in (size - 1) downTo 0) {
action(i, get(i))
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
727 次 |
| 最近记录: |