Jetpack Compose中的布局组件、状态栏高度padding

前言

自定义组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/**
* 配置 WebView 的基本设置
*/
@SuppressLint("SetJavaScriptEnabled")
private fun WebView.setupWebView() {
settings.javaScriptEnabled = true // 必须启用JavaScript
settings.domStorageEnabled = true
settings.allowFileAccess = true
settings.allowContentAccess = true
settings.loadWithOverviewMode = true
settings.useWideViewPort = true
settings.defaultTextEncodingName = "UTF-8"

// 透明背景核心设置
setBackgroundColor(0x00000000) // 完全透明
setLayerType(WebView.LAYER_TYPE_SOFTWARE, null) // 禁用硬件加速,解决某些设备透明问题
// 禁用滚动条,由父容器控制
isVerticalScrollBarEnabled = false
isHorizontalScrollBarEnabled = false
}

@Composable
fun DynamicHeightRichTextWebView(
htmlContent: String,
baseUrl: String? = null,
maxHeight: Int = Int.MAX_VALUE,
modifier: Modifier = Modifier
) {
var webViewHeight by remember { mutableStateOf(0) }
var isLoaded by remember { mutableStateOf(false) }

class WebAppInterface(private val onHeightChanged: (Int) -> Unit) {
@JavascriptInterface
fun setHeight(height: Int) {
onHeightChanged(height)
}
}

AndroidView(
modifier = modifier,
factory = { context ->
WebView(context).apply {
setupWebView()
webViewClient = object : WebViewClient() {
override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url)
view?.evaluateJavascript(
"(function() { " +
"return document.body.scrollHeight;" +
"})();"
) { heightStr ->
// 直接在evaluateJavascript的回调中处理高度
try {
val height = heightStr.toIntOrNull() ?: 0
if (height > 0) {
val density = context.resources.displayMetrics.density
Log.i(TAG, "onPageFinished:density " + density)
Log.i(TAG, "onPageFinished:height " + height)
val pixelHeight = (height).toInt()
webViewHeight = pixelHeight.coerceAtMost(maxHeight)
isLoaded = true
}
} catch (e: Exception) {
// 处理可能的异常
}
}
}
}

loadDataWithBaseURL(baseUrl, htmlContent, "text/html", "UTF-8", null)
}
},
update = { webView ->
// 在这里处理高度更新,替代原来的lambda
Log.i(TAG, "DynamicHeightRichTextWebView: " + webView.layoutParams.height)
Log.i(TAG, "DynamicHeightRichTextWebView: webViewHeight" + webViewHeight)
if (isLoaded) {

// webView.layoutParams.height = webViewHeight
// Log.i(TAG, "DynamicHeightRichTextWebView: " + webViewHeight)
// 强制重新布局
webView.requestLayout()
}

// 当内容变化时重新加载
if (webView.url != htmlContent) {
webView.loadDataWithBaseURL(baseUrl, htmlContent, "text/html", "UTF-8", null)
}
}
)
}

附录

富文本带图片

1
<p class="MsoNormal" align="left" style="text-align:left;line-height:150%"><span style="font-size:12.0pt;line-height:150%;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri"></span><span lang="EN-US" style="font-size:12.0pt;line-height:150%;font-family:&quot;Times New Roman&quot;,&quot;serif&quot;"> </span><span lang="EN-US" style="font-size:12.0pt;line-height:150%">          <img width="166" height="45" src="https://schoolstatic.xhkjedu.com/static/node01/pingtai/question/2/1NJCJC/SEGJ76/1NJCKQ/20200813/8cd9bc5123394f6f980b2ad918d8bd10.jpg" v:shapes="图片_x0020_4">          <o:p></o:p></span></p><br>    <p class="MsoNormal" align="left" style="text-align:left;line-height:150%"><span style="font-size:12.0pt;line-height:150%;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri"></span><span lang="EN-US" style="font-size:12.0pt;line-height:150%;font-family:&quot;Times New Roman&quot;,&quot;serif&quot;"> </span><span style="font-size:12.0pt;line-height:150%;font-family:宋体;mso-ascii-font-family:&quot;Times New Roman&quot;;mso-hansi-font-family:&quot;Times New Roman&quot;">词的上片“望”字统领的内容是:</span><span lang="EN-US" style="font-size:12.0pt;line-height:150%;font-family:&quot;Times New Roman&quot;,&quot;serif&quot;">______________</span><span style="font-size:12.0pt;line-height:150%;font-family:宋体;mso-ascii-font-family:&quot;Times New Roman&quot;;mso-hansi-font-family:&quot;Times New Roman&quot;">。下片“惜”字在句中的意思是</span><span lang="EN-US" style="font-size:12.0pt;line-height:150%;font-family:&quot;Times New Roman&quot;,&quot;serif&quot;">______________</span><span style="font-size:12.0pt;line-height:150%;font-family:宋体;mso-ascii-font-family:&quot;Times New Roman&quot;;mso-hansi-font-family:&quot;Times New Roman&quot;">,它领起的内容是:</span><span lang="EN-US" style="font-size:12.0pt;line-height:150%;font-family:&quot;Times New Roman&quot;,&quot;serif&quot;">______________</span><span style="font-size:12.0pt;line-height:150%;font-family:宋体;mso-ascii-font-family:&quot;Times New Roman&quot;;mso-hansi-font-family:&quot;Times New Roman&quot;"></span><span lang="EN-US" style="font-size:12.0pt;line-height:150%;font-family:&quot;Times New Roman&quot;,&quot;serif&quot;">     <o:p></o:p></span></p><br>    <p class="MsoNormal" align="left" style="text-align:left;line-height:150%"><span style="font-size:12.0pt;line-height:150%;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri"></span><span lang="EN-US" style="font-size:12.0pt;line-height:150%;font-family:&quot;Times New Roman&quot;,&quot;serif&quot;"> </span><span style="font-size:12.0pt;line-height:150%;font-family:宋体;mso-ascii-font-family:&quot;Times New Roman&quot;;mso-hansi-font-family:&quot;Times New Roman&quot;">下列对课文的理解有误的一项是</span><span lang="EN-US" style="font-size:12.0pt;line-height:150%;font-family:&quot;Times New Roman&quot;,&quot;serif&quot;">(<span style="mso-spacerun:yes">&nbsp;&nbsp; </span>)     <o:p></o:p></span></p>    <p class="a"><span style="font-size:12.0pt;line-height:150%;font-family:宋体;mso-ascii-font-family:&quot;Times New Roman&quot;;mso-hansi-font-family:&quot;Times New Roman&quot;"></span><span lang="EN-US" style="font-size:12.0pt;line-height:150%;font-family:&quot;Times New Roman&quot;,&quot;serif&quot;">A. </span><span style="font-size:12.0pt;line-height:150%;font-family:宋体;mso-ascii-font-family:&quot;Times New Roman&quot;;mso-hansi-font-family:&quot;Times New Roman&quot;">这首词既洋溢着热爱祖国山河的豪情,又抒发了词人必将创造空前伟大的业绩的自信和抱负。</span><span lang="EN-US" style="font-size:12.0pt;line-height:150%;font-family:&quot;Times New Roman&quot;,&quot;serif&quot;">     <o:p></o:p></span></p>    <p class="a"><span lang="EN-US" style="font-size:12.0pt;line-height:150%;font-family:&quot;Times New Roman&quot;,&quot;serif&quot;">B. </span><span style="font-size:12.0pt;line-height:150%;font-family:宋体;mso-ascii-font-family:&quot;Times New Roman&quot;;mso-hansi-font-family:&quot;Times New Roman&quot;">这首词的上片描写北国雪景,展现祖国山河的壮丽。前十句写眼前的实景,后三句写的是虚景。</span><span lang="EN-US" style="font-size:12.0pt;line-height:150%;font-family:&quot;Times New Roman&quot;,&quot;serif&quot;">     <o:p></o:p></span></p>    <p class="a"><span lang="EN-US" style="font-size:12.0pt;line-height:150%;font-family:&quot;Times New Roman&quot;,&quot;serif&quot;">C. </span><span style="font-size:12.0pt;line-height:150%;font-family:宋体;mso-ascii-font-family:&quot;Times New Roman&quot;;mso-hansi-font-family:&quot;Times New Roman&quot;">下片中一个“惜”字,定下对历史上英雄人物的评论基调,饱含惋惜之情而又有批判,一概否定了他们。</span><span lang="EN-US" style="font-size:12.0pt;line-height:150%;font-family:&quot;Times New Roman&quot;,&quot;serif&quot;">     <o:p></o:p></span></p>    <p class="a"><span lang="EN-US" style="font-size:12.0pt;line-height:150%;font-family:&quot;Times New Roman&quot;,&quot;serif&quot;">D. </span><span style="font-size:12.0pt;line-height:150%;font-family:宋体;mso-ascii-font-family:&quot;Times New Roman&quot;;mso-hansi-font-family:&quot;Times New Roman&quot;">下片开头两句,“江山如此多娇”承上,总括上片的写景,对“北国风光”作总评;“引无数英雄竞折腰”启下,展开对历代英雄的评论,抒发词人的抱负。</span><span lang="EN-US" style="font-size:12.0pt;line-height:150%;font-family:&quot;Times New Roman&quot;,&quot;serif&quot;">     <o:p></o:p></span></p>

富文本 带公式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>公式编辑器MathJax</title>
</head>
<body>
<div>
行内公式 \(ax^2 + bx + c = 0\) <br>
下面是块级公式
$$ x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$
</div>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css" integrity="sha384-n8MVd4RsNIU0tAv4ct0nTaAbDJwPJzDEaqSD1odI+WdtXRGWt2kTvGFasHpSy3SV" crossorigin="anonymous">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js" integrity="sha384-XjKyOOlGwcjNTAIQHIpgOno0Hl1YQqzUOEleOLALmuqehneUG+vnGctmUb0ZY0l8" crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/contrib/auto-render.min.js" integrity="sha384-+VBxd3r6XgURycqtZ117nYw44OOcIax56Z4dCRWbxyPt0Koah1uHoK0o4+/RRE05" crossorigin="anonymous"></script>
<script>
document.addEventListener("DOMContentLoaded", function () {
window.renderMathInElement(document.body, {
delimiters: [
{left: '$$', right: '$$', display: true},
{left: '\\[', right: '\\]', display: true},
{left: '$', right: '$', display: false},
{left: '\\(', right: '\\)', display: false}
],
throwOnError: false
});
});
</script>
</body>
</html>