记录一下写小说阅读器过程中遇到的一些问题及解决方案。
首先第一个问题就是小说的分页。
如何分页
这里可以通过 ViewPager 来进行分页,但是 Compose 中并没有 ViewPager,经过我的寻找,找到了一个 Compose 中的 ViewPager,是 google 出的一个库。
https://google.github.io/accompanist/pager/
接下来就是第二个问题,如何确定一页的大小。也就是确定一页能够显示的字数。
确定一页能够显示的字数
这个也比较困难,因为 Compose 中的 Text 并没有暴露出太多的 api,所以也是比较困难的,最终在 https://my.oschina.net/gotax/blog/136860 这篇文章的启发下找到了解决办法。
@ExperimentalPagerApi
@Preview
@Composable
fun PageTest() {
Box(
modifier = Modifier
.fillMaxSize()
) {
val pageState = rememberPagerState(pageCount = 100, infiniteLoop = true)
HorizontalPager(
state = pageState,
modifier = Modifier.fillMaxHeight(),
verticalAlignment = Alignment.Top,
horizontalAlignment = Alignment.Start
) { state ->
Box(
modifier = Modifier
.fillMaxSize()
.graphicsLayer {
// Calculate the absolute offset for the current page from the
// scroll position. We use the absolute value which allows us to mirror
// any effects for both directions
val pageOffset = calculateCurrentOffsetForPage(state).absoluteValue
// We animate the scaleX + scaleY, between 85% and 100%
lerp(
start = 0.85f,
stop = 1f,
fraction = 1f - pageOffset.coerceIn(0f, 1f)
).also { scale ->
scaleX = scale
scaleY = scale
}
// We animate the alpha, between 50% and 100%
alpha = lerp(
start = 0.5f,
stop = 1f,
fraction = 1f - pageOffset.coerceIn(0f, 1f)
)
}
) {
Column {
val sb = StringBuilder()
repeat(state * 10) {
sb.append("阿a达")
}
var totalNumState by remember {
mutableStateOf(0)
}
Text(
text = "Page: $state current page = ${pageState.currentPage}",
)
Text(text = "$totalNumState")
Text(
onTextLayout = {
try {
val lineNum =
it.getLineForVerticalPosition(it.size.height.toFloat())
if (lineNum != 0) {
val totalNum = it.getLineEnd(lineNum, false)
Log.d(
"PageTest",
"line Number = $lineNum, line end totalNum = $totalNum str = ${sb.toString().length}"
)
totalNumState = totalNum
}
} catch (e: Exception) {
e.printStackTrace()
}
},
text = sb.toString()
)
}
}
}
}
}