富文本编辑器,如图:
Android 富文本编辑器实现思路:
默认状态下编辑器显示一个EditText,点击图片,选择插入本地图片或者拍照图片.
插入图片时,如果当前位置后面没有文字,则直接插入图片,如果后面有文字,那么就将后面的文字截取出来,先插入这张图片,再新增一个EditText显示截取的文字;
删除信息时需要判断几种情况:
1.前面是文字,直接删除文字
2.当这个EditText中的已经没有信息了,继续点删除时,如果前面是图片,那么先删除当前这个EditText然后删除图片
3.如果前面是文字,那么先删除当前这个EditText,然后将光标置于前面EditText的最后一个
大体思路如上,下面看具体代码:
首先这个RichTextEditor集成自LinearLayout,
添加默认的EditText:
<span style="font-family:SimHei;font-size:18px;"> LayoutParams firstEditParam = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); EditText firstEdit = createEditText("", dip2px(EDIT_FIRST_PADDING_TOP)); allLayout.addView(firstEdit, firstEditParam);</span>
<span style="font-family:SimHei;font-size:18px;"> /** * 插入一张图片 */ private void insertImage(Bitmap bitmap, String imagePath) { String lastEditStr = lastFocusEdit.getText().toString(); int cursorIndex = lastFocusEdit.getSelectionStart(); String editStr1 = lastEditStr.substring(0, cursorIndex).trim(); int lastEditIndex = allLayout.indexOfChild(lastFocusEdit); lastFocusEdit.setText(editStr1); String editStr2 = lastEditStr.substring(cursorIndex).trim(); addEditTextAtIndex(lastEditIndex + 1, editStr2); addImageViewAtIndex(lastEditIndex + 1, bitmap, imagePath); lastFocusEdit.requestFocus(); lastFocusEdit.setSelection(editStr1.length(), editStr1.length()); hideKeyBoard(); }</span>先得到当前EditText中的文字信息,接下来判断光标所处位置,如果不是在文字的最后,则将文字拆分开,添加一个新的EditText并插入图片
<span style="font-family:SimHei;font-size:18px;">/** * 在特定位置添加ImageView */ private void addImageViewAtIndex(final int index, Bitmap bmp, String imagePath) { final RelativeLayout imageLayout = createImageLayout(); DataImageView imageView = (DataImageView) imageLayout .findViewById(R.id.edit_imageView); imageView.setImageBitmap(bmp); imageView.setBitmap(bmp); imageView.setAbsolutePath(imagePath); // 调整imageView的高度 int imageHeight = getWidth() * bmp.getHeight() / bmp.getWidth(); RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams( LayoutParams.MATCH_PARENT, imageHeight); imageView.setLayoutParams(lp); // onActivityResult无法触发动画,此处post处理 allLayout.postDelayed(new Runnable() { @Override public void run() { allLayout.addView(imageLayout, index); } }, 200); }</span>
<span style="font-family:SimHei;font-size:18px;">/** * 生成图片View */ private RelativeLayout createImageLayout() { RelativeLayout layout = (RelativeLayout) inflater.inflate( R.layout.richtextedit_imageview, null); layout.setTag(viewTagIndex++); View closeView = layout.findViewById(R.id.image_close); closeView.setTag(layout.getTag()); closeView.setOnClickListener(btnListener); return layout; } </span>
在实际的项目中,不仅需要我们发送富文本信息,同样也需要我们显示并修改从服务器端传过来的富文本信息,下面看一下添加一张网络图片:
<span style="font-family:SimHei;font-size:18px;"> /** * 插入网络图片 * * @param url */ public void insertImageByURL(String url) { if (url == null) return; final RelativeLayout imageLayout = createImageLayout(); final DataImageView imageView = (DataImageView) imageLayout .findViewById(R.id.edit_imageView); imageView.setImageResource(R.drawable.logo); imageView.setScaleType(ImageView.ScaleType.CENTER); allLayout.addView(imageLayout); addEditTextAtIndex(-1, ""); ImageLoader.getInstance().displayImage(url, imageView, new SimpleImageLoadingListener() { @Override public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { String path = fileUtils.savaRichTextImage(imageUri, loadedImage); imageView.setImageBitmap(loadedImage); imageView.setBitmap(loadedImage); imageView.setAbsolutePath(path); int imageHeight = getWidth() * loadedImage.getHeight() / loadedImage.getWidth(); RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams( LayoutParams.MATCH_PARENT, imageHeight); imageView.setLayoutParams(lp); imageView.setScaleType(ImageView.ScaleType.FIT_XY); } }); }</span>
返回富文本中的信息:
<span style="font-family:SimHei;font-size:18px;">public HashMap<String, Object> getRichEditData() { HashMap<String, Object> data = new HashMap<>(); StringBuilder editTextSB = new StringBuilder(); List<String> imgUrls = new ArrayList<>(); char separator = 26; int num = allLayout.getChildCount(); for (int index = 0; index < num; index++) { View itemView = allLayout.getChildAt(index); if (itemView instanceof EditText) { EditText item = (EditText) itemView; editTextSB.append(item.getText().toString()); } else if (itemView instanceof RelativeLayout) { DataImageView item = (DataImageView) itemView .findViewById(R.id.edit_imageView); imgUrls.add(item.getAbsolutePath()); editTextSB.append(separator); } } data.put("text", editTextSB); data.put("imgUrls", imgUrls); return data; }</span>
更多的代码实现逻辑就在项目中查找吧.
源码下载