Android 富文本编辑器 图文混排

富文本编辑器,如图:

Android 富文本编辑器 图文混排_第1张图片 Android 富文本编辑器 图文混排_第2张图片 Android 富文本编辑器 图文混排_第3张图片

Android 富文本编辑器实现思路:

      默认状态下编辑器显示一个EditText,点击图片,选择插入本地图片或者拍照图片.

插入图片时,如果当前位置后面没有文字,则直接插入图片,如果后面有文字,那么就将后面的文字截取出来,先插入这张图片,再新增一个EditText显示截取的文字;

删除信息时需要判断几种情况:

1.前面是文字,直接删除文字

2.当这个EditText中的已经没有信息了,继续点删除时,如果前面是图片,那么先删除当前这个EditText然后删除图片

3.如果前面是文字,那么先删除当前这个EditText,然后将光标置于前面EditText的最后一个

大体思路如上,下面看具体代码:

首先这个RichTextEditor集成自LinearLayout,

添加默认的EditText:

                LayoutParams firstEditParam = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
		EditText firstEdit = createEditText("", dip2px(EDIT_FIRST_PADDING_TOP));
		allLayout.addView(firstEdit, firstEditParam);

添加一张本地图片:

        /**
	 * 插入一张图片
	 */
	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();
	}
先得到当前EditText中的文字信息,接下来判断光标所处位置,如果不是在文字的最后,则将文字拆分开,添加一个新的EditText并插入图片

/**
	 * 在特定位置添加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);
	}


/**
	 * 生成图片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;
	}

先生成自定义的图片布局,然后找到里面的DataImageView,这个类继承ImageView,额外提供设置图片的绝对地址的方法等,然后将图片和图片地址设置到这个DataImageView中,最后添加到这个LinearLayout中,这里通过延迟UI操作添加.

在实际的项目中,不仅需要我们发送富文本信息,同样也需要我们显示并修改从服务器端传过来的富文本信息,下面看一下添加一张网络图片:

        /**
	 * 插入网络图片
	 * 
	 * @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);
					}
				});
	}

这个方法用于显示网络返回的富文本信息,一般返回的富文本信息中的图片信息多以URL连接形式返回,这里使用ImageLoader类加载图片,并将加载出来的图片加载到缓存中,同时也将图片的地址添加到DataImageView中.

返回富文本中的信息:

public HashMap getRichEditData() {
		HashMap data = new HashMap<>();
		StringBuilder editTextSB = new StringBuilder();
		List 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;
	}

遍历LinearLayout中的元素,若为EditText则获取文字信息,若为ImageView,则获取图片地址.

 更多的代码实现逻辑就在项目中查找吧.

源码下载



你可能感兴趣的:(Android,自定义控件,Jiaxu的专栏)