安卓如何实现图文混排

安卓如何实现图文混排

一、安卓实现图文混排的几种方式

  • EditText with Spannable
  • RecyclerView
  • WebView

1. EditText with Spannable

EditText自身便是为编辑文本而设计的,通过ImageSpan即可实现图文混排的效果。

2. RecyclerView

通过组合EditText及ImageView可以实现图文混排的效果。

与EditText比较,RecyclerView方式只能实现文本和图片依次排列的效果,无法实现图文环绕效果。考虑到手机上阅读,其实并不需要图文环绕的效果。

3. WebView

网页版本的图文混排编辑器已经相当成熟,结合WebView强大的功能,或许是实现图文混排最好的方案。

F. 最终方案

神马笔记最终采用RecyclerView方案。

  • 优点:
    1. RecyclerView方案是3个方案中实现起来最简单的。
    2. 神马笔记之后会添加动态GIF,视频,音频,以及特定的数据内容,RecyclerView方式非常容易扩展。
  • 缺点
    1. 全选操作无法选择所有文本。
    2. RecyclerView滚动上似乎存在一些问题。

二、图片保存的几种方案

  • 图片保留在原来的位置
  • 图片复制到应用的文件夹下,例如WhatsNote/Photos
  • 图片复制到笔记的文件夹下,例如WhatsNote/xxxx/Photos

1. 保留在原来位置

只记录图片文件路径。

优点:节省存储空间

缺点:无法保证图片文件的有效性

2. 复制到应用的文件夹

复制一份图片到应用文件夹内,所有笔记的图片保存在同一个文件夹内。

优点:保证图片不会被第三方应用修改,图片总是有效的

缺点:复制了一份图片,占用了手机存储空间

3. 复制到笔记的文件夹

与方式2比较,只是图片复制的位置发生了改变,由应用管理的文件夹,变成笔记管理的文件夹。

F. 最终方案

神马笔记最终采用“复制到笔记的文件夹”方案。

技术实现上,比较不出笔记文件夹应用文件夹能带来哪些优点。

从资源管理的角度,应该选择应用文件夹的方式,便于管理图片资源。

从笔记管理的角度,与笔记相关的所有资源,应该保存在笔记文件夹内。

三、数据结构设计

交互采用了RecyclerView方案。

图片管理采用了复制到笔记文件夹方案。

接下来,完成最后一步,设计数据结构,实现图文混排有2件事情要做。

  1. 管理图片资源
  2. 将图片添加到笔记中

1. 管理图片资源

1. ImageEntry

1
2
3
4
5
6
7
8
9
public class ImageEntry extends BaseEntry {

@SerializedName("no")
int number; // 图片资源编号

@SerializedName("doc")
String documentId; // 所属的文章ID

}

其中BaseEntry提供了UUID唯一标识图片资源。

2. ImageTable

1
2
3
4
5
6
public class ImageTable extends BaseTable<ImageEntry> {

@SerializedName("no")
int number; // 累计的图片资源编号,每添加一张图片,累加1

}

目前采用JSON数据格式管理数据资源,未来考虑迁移到SQLite实现。

2. 笔记中插入图片

1. PictureEntry

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class PictureEntry extends ParagraphEntry {

public static final String TYPE = "picture";

@SerializedName("uri")
String uri; // 源图片Uri

@SerializedName("width")
int width; // 图片宽度

@SerializedName("height")
int height; // 图片高度

@SerializedName("signature")
String signature; // 图片签名,用于缓存图片

}

因为可以为图片添加描述,所以PictureEntry继承自ParagraphEntry,并且增加了图片相关的4个字段。

2. PictureEntity

1
2
3
public class PictureEntity extends ParagraphEntity<PictureEntry> {
Uri uri; // 图片Uri,笔记文件夹Uri或者外部Uri
}

PictureEntity为交互的数据结构。

3. PictureViewHolder

1
2
3
4
5
6
7
8
9
public class PictureViewHolder extends ComposeViewHolder<PictureEntity> {

public static final int LAYOUT_RES_ID = R.layout.layout_compose_picture_list_item;

View pictureLayout; // 提供边框及交互
TargetSizeImageView pictureView; // 显示图片

EditText editText; // 图片描述
}

PictureViewHolderPictureEntityRecyclerView中的ViewHolder。

四、Final

神马笔记最新版本:【神马笔记Version1.1.0_beta.apk