Android 富文本編輯器 圖文混排

富文本編輯器,如圖:

  

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>

先生成自定義的圖片佈局,然後找到裏面的DataImageView,這個類繼承ImageView,額外提供設置圖片的絕對地址的方法等,然後將圖片和圖片地址設置到這個DataImageView中,最後添加到這個LinearLayout中,這裏通過延遲UI操作添加.

在實際的項目中,不僅需要我們發送富文本信息,同樣也需要我們顯示並修改從服務器端傳過來的富文本信息,下面看一下添加一張網絡圖片:

<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>

這個方法用於顯示網絡返回的富文本信息,一般返回的富文本信息中的圖片信息多以URL連接形式返回,這裏使用ImageLoader類加載圖片,並將加載出來的圖片加載到緩存中,同時也將圖片的地址添加到DataImageView中.

返回富文本中的信息:

<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>

遍歷LinearLayout中的元素,若爲EditText則獲取文字信息,若爲ImageView,則獲取圖片地址.

 更多的代碼實現邏輯就在項目中查找吧.

源碼下載



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章