现在有这样一个需求
1 显示一些图片和文字的混合内容,要求
A. 显示时图片在文字中的位置不能变,即必须图文混排
B. 图片的显示必须是异步获取
2 在对该文字和图片可以进行编辑时,要求
A.编辑时显示 图文混排效果
B.图片可删除,可新增图片
C.图文混排中 编辑提交时如果某一张图片是 服务器 已经存在的,则不必上传,如是 新增加的图片 则需上传
D.向服务器提交时必须提交图片位置
解决方案:
0 数据部分方案
A 服务器->客户端图文数据
我们采用的是xml 数据协议,在其中 的 content节点返回:
<content>今天天气不错,来看太阳<img src = "http://adfdd/adfsd/abc.jpg">不错吧,来给你看看我的小白<img src = "http://adfdd/adfsd/abc.jpg"></content>
通过上述字符串可以获取到图片以及图片位置,思来想后只有这种格式最好
B 客户端->服务器 图文数据
直接上字符串
未处理字符串
今天天气不错,来看太阳<img src = "http://adfdd/adfsd/abc.jpg">不错吧,来给你看看我的小白<img src = "/mnt/sdcard/abc/aaaa.jpg">
看到和数据部分A的区别了么,是的,第二张图片为本地图片,通过上述格式,可以上传给服务器图片和 图片的位置,上面上传给服务器的字符串只是其中一个参数,上传时解析该字符串,定义一个数组,上传 本地图片内容,而网络图片部分肯定是服务器已经存在的,不需要上传,这就避免了重复上传(本文不负责 怎么将本地图片上传服务器的问题)
1 图文混排显示方案
A. 用 fromHtml 显示(自行google)
但是有问题存在,这种图文方式 会 造成延时显示,即 当前界面卡一下 才会显示,体验不太好,所以我采用B计划
B.解析 返回的数据(详见数据部分),将 图片和文字所代表的字符串分开,分成 如下形式,保存在List<String>中
今天天气不错,来看太阳
http://adfdd/adfsd/abc.jpg
不错吧,来给你看看我的小白
http://adfdd/adfsd/abc.jpg
我的方法如下
public static final String[] suffixes = {"jpg","gif","jpeg","png"};
/**
* 得到 图片和 普通字符串的分离list
* @param html
* @return
*/
public static List<String> getList(String html){
String b = html.replace("<", "<").replace(">", ">");
String [] temp1 = b.toLowerCase().split("<img");
List<String> result = new ArrayList<String>();
for(String str : temp1){
if(str.indexOf("src") != -1){
for(String su:ImageTool.suffixes){
if( str.indexOf(su)!=-1){
result.add(str.substring(str.indexOf("http"), str.indexOf(su)+su.length()));
result.add(str.substring(str.indexOf(">")+1));
}
}
}else{
result.add(str);
}
}
return result;
}
想必这样是难不倒大家的,然后遍历该List<String> ,在一个linearLayout动态的 add imageView或者 TextView,达到图文混排的目的,当然,imageView的图片是异步处理。
public void initLinearLayout(LinearLayout linearLayout,Diary diary){
List<String> strs = FlexTool.getInstance().getList(diary.getContent());
for(int i = 0;i<strs.size();i++){
String temp = strs.get(i);
if(temp.indexOf("http")!=-1){如果是图片
View view = app.getInflater().inflate(R.layout.image_part, null);
ImageView iv_image = (ImageView) view.findViewById(R.id.iv_image);
ImageView iv_progressdialog = (ImageView) view.findViewById(R.id.iv_progressdialog);
//image 该asyncTask是我写的一个 图片获取的异步类,这里就不贴代码了
DiaryLoadImageAsyncTask dliat = new DiaryLoadImageAsyncTask(this, iv_image, iv_progressdialog, getActivity());
dliat.execute(temp);
linearLayout.addView(view);
}else{//如果是文字
//text
TextView tv = new TextView(getActivity(), null);
tv.setText(temp);
linearLayout.addView(tv);
}
}
}
ok,这样已经可以获得一个 图文混排的显示界面并且异步显示图片,中午午休电脑连接手机失败,,效果图先不传了
2 图文混输解决方案
采用在一个EditText中进行图片,文字的编辑操作,首先 将 图文内容显示在EditText中
public void initEditText(String b,EditText et){
List<String> a = getList(b);
for(int i = 0;i<a.size();i++){
String temp = a.get(i);
if(temp.indexOf("http")!=-1){
//把图片 加到末尾
Bitmap bitmap = getBitmap(temp);
//当有图片的时候 换行,图片单独一行
et.append("\n");
et.append(getBitmapMime(bitmap, temp));
//当有图片的时候 换行
et.append("\n");
}else{
//加到末尾
SpannableString ss = new SpannableString(temp);
et.append(ss);
}
}
}
getBitMap方法
public Bitmap getBitmap(String source) {
Bitmap drawable = null;
URL url;
try {
url = new URL(source);
// drawable = Drawable.createFromStream(url.openStream(), ""); //获取网路图片
drawable = BitmapFactory.decodeStream(url.openStream());
} catch (Exception e) {
e.printStackTrace();
return null;
}
// drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable
// .getIntrinsicHeight());
return drawable;
}
getBitmapMime方法
private SpannableString getBitmapMime(Bitmap pic,String path) {
path = "<img src=\""+path+"\">";//加入该标签是上传到服务器 容易解析
SpannableString ss = new SpannableString(path);
ImageSpan span = new ImageSpan(this, pic);
ss.setSpan(span, 0, path.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return ss;
}
这样 已经 将 图文内容混合显示在editText中,可以打印下 editText 的内容,为
1234
<img src="http://123sdfsd.jpg">
456
ok,接下来我们在实现 插入图片功能,比如我们在45两个字符中间插入图片,需要做的操作有以下几个
1 选择或进行系统拍照
2 得到 拍照或者系统中选取的图片(暂时只能一次一张)
3 将图片插入光标所在的位置,并使图片占一行
4 移动光标的位置
上面的第一步就不写了,我们从2开始
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if(data != null){
Uri uri = data.getData();
Cursor cursor = this.getContentResolver().query(uri, null,
null, null, null);
cursor.moveToFirst();
String imgPath = cursor.getString(1); // 图片文件路径
cursor.close();
//得到拍照或者选择的图片bitmap,并进行简单压缩,,,该代码不写了
Bitmap pic = ImageTool.getInstance().getCompressedBitmapBySize(imgPath);
insertIntoEditText(getBitmapMime(pic,imgPath),et_content.getSelectionStart());该方法的第一个参数方法刚才写过了,第二个方法为当前光标位置
}
}
将图片插入到光标位置
private void insertIntoEditText(SpannableString ss,int index) {
Editable et = et_content.getText();// 先获取Edittext中的内容
//插入换行符,使图片单独占一行
SpannableString n1 = new SpannableString("\n");
et.insert(index, n1);//
et.insert(index+1, ss);// 设置ss要添加的位置
et.insert(index+ss.length()+1, n1);//
et_content.setText(et);// 把et添加到Edittext中
et_content.setSelection(index + ss.length()+2);// 设置Edittext中光标在最后面显示
}
ok,这样已经成功实现预期目标
我们打印一下editText 的内容
1234
<img src="http://123sdfsd.jpg">
4
<image src = "mnt/sdcard/abc.jpg">
56
ok,到这里,已经完全弄完了,删除图片神马的按照正常删除文字一样操作就行,删除完图片你就会发现,该editText 内容中已经没有该 图片的地址。。。。。排版很乱,并且没有截图,后补