類似豆瓣、微信文章:多段文字穿插多張圖片,圖片需居中、適配寬度、支持點擊預覽大圖。
| 方案 | 核心思路 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|---|
| 1. 單 TextView + Spannable/ImageSpan | 數據解析 → 計算行高/字符數 → ImageSpan 插入文本 → TextView.setText(spannable) |
單控件,滾動流暢,內存佔用低,選中複製文本自然 | 複雜排版(多列、浮動)難實現;圖片加載需異步+占位圖;長文本渲染耗時 | 純閱讀類文章,圖文比例固定,性能敏感 |
| 2. WebView 載入 HTML | 拼接 HTML 字符串 → webView.loadDataWithBaseURL() |
排版能力最強(CSS 佈局、響應式、GIF/視頻)、開發效率高 | 啟動慢、內存大、JS 交互坑多、原生交互(點擊圖片彈窗)需 Bridge、滾動不如原生絲滑 | 富文本極複雜、需支持 HTML 標準、混合開發 |
| 3. ListView/RecyclerView 多 ItemType | 數據拆分為「文本段」「圖片段」列表 → getItemViewType 區分 → 多布局復用 |
最靈活:每段獨立佈局、圖片可異步加載、支持任意 View、滾動性能好(ViewHolder) | 需維護數據結構拆分邏輯;段落間間距需精細調整;選中複製跨 Item 困難 | 動態佈局需求強、圖文比例不固定、需插入廣告/卡片、長列表 |
| 4. 動態 LinearLayout/ConstraintLayout 添加 View | 解析數據 → 循環 inflate 或 new View → container.addView() |
邏輯直觀,無適配器樣板代碼 | 大量 View 時渲染慢、內存抖動、無視圖復用、ScrollView 嵌套易卡頓 | 內容極少(<10 段)、一次性展示、無滾動或極短滾動 |
// 數據模型封裝
sealed class ContentBlock {
data class Text(val text: String) : ContentBlock()
data class Image(val url: String, val width: Int, val height: Int) : ContentBlock()
}
// Adapter
class ArticleAdapter(private val blocks: List) :
RecyclerView.Adapter() {
companion object {
const val TYPE_TEXT = 0
const val TYPE_IMAGE = 1
}
override fun getItemViewType(position: Int) = when (blocks[position]) {
is ContentBlock.Text -> TYPE_TEXT
is ContentBlock.Image -> TYPE_IMAGE
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = when (viewType) {
TYPE_TEXT -> TextViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_text, parent, false))
TYPE_IMAGE -> ImageViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_image, parent, false))
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (val block = blocks[position]) {
is ContentBlock.Text -> (holder as TextViewHolder).bind(block.text)
is ContentBlock.Image -> (holder as ImageViewHolder).bind(block.url, block.width, block.height)
}
}
// ... ViewHolder 實現省略
}
override(width, height) 限制解碼尺寸,防 OOM。RecyclerView.setHasFixedSize(true) + 預估 Item 高度,減少佈局抖動。PhotoView / DialogFragment 全屏查看,支持雙指縮放。現代 Android 開發中,RecyclerView 多 ItemType 是圖文混排的「標準答案」,兼顧性能、擴展性與維護性。