Android 知识点 4.28

好记性不如破键盘

设计给了张差不多是这样的一张图。

屏幕快照 2017-04-28 下午8.56.05

编辑栏可以自由的添加文字或者是图片。

这玩意安卓原生控件肯定是不好搞。

(写到这我有种怪异的感觉,因为我现在的界面是这样的:

屏幕快照 2017-04-28 下午9.00.58

这不就和那个设计给的图的的效果几乎一样吗?)

通过 HTML 标签来解决,上面的编辑框就类似于是一个低配版的 MarkDown 编辑器显示框,而我们要传给服务器的就是那些带标签的字符串。

这玩意有个好听的叫富文本。

秉着不重复造轮子的态度,我 Github 了一下。(其实根本造不动)

就是它 RichEditor ,好家伙,快 3k 的星了。

直接下载,运行了下。除了图片死活出不来,别的都还好,(不是很清楚为什么出不来,因为我在自己项目里面跑起来了,而且我也改了 Demo 中的 url 了,还是不行,就没管了)。

其实这个源码很少,而且不复杂。由于我只要图文,所以来看看图片是怎么实现的。

使用方法很简单,只要

1
mRichEdit.insertImage(mHttpUrlPathArray.get(i),"商品详情");

前一个参数是图片的 url(注意是 url ,不是什么本地缓存之类的绝对路径),后一个是图片的 alt 。

点进去看看是怎么实现的:

1
2
3
4
public void insertImage(String url, String alt) {
exec("javascript:RE.prepareInsert();");
exec("javascript:RE.insertImage('" + url + "', '" + alt + "');");
}

说实话这个 RE 我还真不知道是什么东西,甚至我 Google 不到,原谅我菜。

但是我是这么想的,其实这并不是 js 库里面的什么对象,而只是,该类名 RichEditor 的缩写,MDZZ。

该类中有特别多的这种写法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public void redo() {
exec("javascript:RE.redo();");
}

public void setBold() {
exec("javascript:RE.setBold();");
}

public void setItalic() {
exec("javascript:RE.setItalic();");
}

public void setSubscript() {
exec("javascript:RE.setSubscript();");
}

public void setSuperscript() {
exec("javascript:RE.setSuperscript();");
}

public void setStrikeThrough() {
exec("javascript:RE.setStrikeThrough();");
}

因为图片都是属于插入的形式,所以会多了一个 prepareInsert() 步骤。

然后拼接下字符串,再进行下判断:

1
2
3
4
5
6
7
8
9
10
11
protected void exec(final String trigger) {
if (isReady) {
load(trigger);
} else {
postDelayed(new Runnable() {
@Override public void run() {
exec(trigger);
}
}, 100);
}
}

这个 isReady 是 WebViewClient 类中的生命周期中获取到的:

1
2
3
4
5
6
@Override public void onPageFinished(WebView view, String url) {
isReady = url.equalsIgnoreCase(SETUP_HTML);
if (mLoadListener != null) {
mLoadListener.onAfterInitialLoad(isReady);
}
}

如果没有准备好就延时 0.1 秒再执行,准备好了就真正的执行了:

1
2
3
4
5
6
7
private void load(String trigger) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
evaluateJavascript(trigger, null);
} else {
loadUrl(trigger);
}
}

为了兼容不同版本 Android 系统的 WebView 做了判断,然后就是底层代码调用了。

补充说明:Build.VERSION_CODES.KITKAT 就是 19,也就是安卓 4.4 ,它之前的版本用的是 WebKit内核,之后的版本用的是 Chromium 内核

两个内核的一些区别:

屏幕快照 2017-04-28 下午9.57.42

好了,主要知道使用是 insertImage() 方法就好了。然后就会遇到一个坑。

图片的大小,用安卓原生方法是控制不了的因为,那个东西是存在于类似网页中的。

所以在这里我纠结了挺久的,在想是不是要通过拼接 width 之类的 Img 属性上去。但是这样要修改 RE 中 setImg 的方法,觉得可能搞不定。于是我就想着看看别的一些类库都是怎么实现的。

于是看了几个也是挺受欢迎的库,像是这个这个

这两个库都是自动处理图片大小的。第一个在图片的右上角还有删除按钮,以及删除图片的动画,感觉特别人性化。

但是,两者都是通过绝对路径来确认图片以及用原生控件来展示的。(好像也行啊,无语)

所以··· 解决方法用 CSS 直接一点。

这个问题在 Issues 中也是有人反映过,而且知情人士也给出了简单好用的解决方案具体步骤:

屏幕快照 2017-04-28 下午10.06.01

然后就好了,亲测,好用。

好吧,我承认。结尾很潦草。

明天就是五一小长假了。这一不小心十点了啊。我要出去买点吃的,就先这样。