Convert Figma logo to code with AI

sendtion logoXRichText

一个Android富文本类库,支持图文混排,支持编辑和预览,支持插入和删除图片。

1,761
263
1,761
17

Top Related Projects

Android平台下的富文本解析器,支持Html和Markdown

RichEditor for Android is a beautiful Rich Text WYSIWYG Editor for Android.

2,109

Knife is a rich text editor component for writing documents in Android.

TextView to display simple HTML

Quick Overview

XRichText is a powerful and flexible rich text editor library for iOS and macOS, built using Swift. It provides a comprehensive set of features for creating and manipulating rich text content, including support for various text styles, inline images, and custom views.

Pros

  • Extensive Feature Set: XRichText offers a wide range of features for rich text editing, including support for bold, italic, underline, strikethrough, font size, font family, text alignment, and more.
  • Customizable: The library allows for a high degree of customization, enabling developers to tailor the editor to their specific needs.
  • Cross-Platform: XRichText is available for both iOS and macOS, providing a consistent user experience across Apple's platforms.
  • Active Development: The project is actively maintained, with regular updates and bug fixes.

Cons

  • Learning Curve: The library has a relatively steep learning curve, especially for developers new to rich text editing.
  • Performance: Depending on the complexity of the content being edited, the library may experience some performance issues, particularly on older devices.
  • Limited Documentation: The project's documentation could be more comprehensive, making it challenging for new users to get started.
  • Dependency on UIKit/AppKit: XRichText is tightly coupled with Apple's UIKit and AppKit frameworks, which may limit its portability to other platforms.

Code Examples

// Creating a new XRichTextView
let richTextView = XRichTextView()
richTextView.frame = view.bounds
view.addSubview(richTextView)

// Inserting text with formatting
let attributedString = NSMutableAttributedString(string: "Hello, World!")
attributedString.addAttribute(.font, value: UIFont.systemFont(ofSize: 18), range: NSRange(location: 0, length: 13))
attributedString.addAttribute(.foregroundColor, value: UIColor.blue, range: NSRange(location: 0, length: 13))
richTextView.attributedText = attributedString

// Inserting an image
let image = UIImage(named: "myImage")
let imageAttachment = NSTextAttachment()
imageAttachment.image = image
let imageString = NSAttributedString(attachment: imageAttachment)
richTextView.textStorage.insert(imageString, at: richTextView.selectedRange.location)

Getting Started

To get started with XRichText, follow these steps:

  1. Add the XRichText library to your project using a dependency manager like CocoaPods or Carthage.
# CocoaPods
pod 'XRichText'
  1. Import the XRichText framework in your Swift file.
import XRichText
  1. Create an instance of XRichTextView and add it to your view hierarchy.
let richTextView = XRichTextView()
richTextView.frame = view.bounds
view.addSubview(richTextView)
  1. Customize the rich text editor by setting various properties and attributes on the XRichTextView instance.
richTextView.font = UIFont.systemFont(ofSize: 16)
richTextView.textColor = .black
richTextView.backgroundColor = .white
richTextView.isEditable = true
  1. Interact with the rich text content using the provided APIs, such as setting the attributed text, inserting images, or handling user interactions.
let attributedString = NSAttributedString(string: "This is some rich text.")
richTextView.attributedText = attributedString

For more advanced usage and customization, refer to the project's documentation and sample code.

Competitor Comparisons

Android平台下的富文本解析器,支持Html和Markdown

Pros of RichText

  • Supports a wide range of rich text formatting, including bold, italic, underline, strikethrough, and more.
  • Provides a simple and easy-to-use API for integrating rich text into Android applications.
  • Offers good performance and is optimized for large amounts of text.

Cons of RichText

  • Limited support for custom styling and layout options compared to XRichText.
  • May not be as feature-rich as some other rich text libraries, such as XRichText.
  • Requires some boilerplate code to set up and configure.

Code Comparison

RichText:

RichTextView richTextView = findViewById(R.id.rich_text_view);
richTextView.setRichText("<b>Hello, World!</b> This is some <i>rich text</i>.");

XRichText:

val richTextView = findViewById<XRichTextView>(R.id.rich_text_view)
richTextView.setRichText(
    XRichText.Builder()
        .append("Hello, World!")
        .bold()
        .append(" This is some ")
        .italic()
        .append("rich text")
        .build()
)

RichEditor for Android is a beautiful Rich Text WYSIWYG Editor for Android.

Pros of richeditor-android

  • Provides a rich text editor with a wide range of formatting options, including bold, italic, underline, font size, and font color.
  • Supports inserting images and links into the text.
  • Includes a built-in toolbar for easy access to formatting options.

Cons of richeditor-android

  • Requires more setup and configuration compared to XRichText.
  • May have a larger footprint in terms of file size and dependencies.
  • Lacks some of the advanced features and customization options available in XRichText.

Code Comparison

XRichText:

val richText = XRichText(context)
richText.setTextColor(Color.BLACK)
richText.setFontSize(16f)
richText.setHtml("<b>Hello, World!</b>")
richText.setOnTextChangeListener { text -> /* handle text changes */ }

richeditor-android:

val richEditor = RichEditor(context)
richEditor.setEditorHeight(200)
richEditor.setEditorFontSize(16)
richEditor.setEditorFontColor(Color.BLACK)
richEditor.setPlaceholder("Enter text...")
2,109

Knife is a rich text editor component for writing documents in Android.

Pros of Knife

  • Knife provides a more comprehensive set of features, including support for tables, images, and code blocks, which are not available in XRichText.
  • Knife has a more intuitive and user-friendly API, making it easier to integrate into your project.
  • Knife has better performance and is more efficient in handling large amounts of text.

Cons of Knife

  • Knife has a larger codebase and may be more complex to set up and configure compared to XRichText.
  • Knife may have a steeper learning curve for developers who are new to the library.
  • Knife may have fewer community resources and support compared to the more established XRichText.

Code Comparison

XRichText:

let richText = XRichText(frame: view.bounds)
richText.text = "This is a sample text with *bold*, _italic_, and [link](https://example.com)."
richText.font = UIFont.systemFont(ofSize: 16)
richText.textColor = .black
view.addSubview(richText)

Knife:

let knife = Knife(frame: view.bounds)
knife.attributedText = NSAttributedString(string: "This is a sample text with *bold*, _italic_, and [link](https://example.com).", attributes: [
    .font: UIFont.systemFont(ofSize: 16),
    .foregroundColor: UIColor.black
])
view.addSubview(knife)

TextView to display simple HTML

Pros of html-textview

  • Supports a wide range of HTML tags, including tables, lists, and images.
  • Provides a simple and lightweight implementation for displaying HTML content.
  • Includes built-in support for handling links and clickable elements.

Cons of html-textview

  • Limited customization options compared to XRichText.
  • May not offer the same level of performance and rendering quality as XRichText.
  • Lacks some advanced features like custom styling and event handling.

Code Comparison

XRichText:

val richText = XRichText(context)
richText.setTextWithTags("<b>Bold</b> <i>Italic</i> <u>Underline</u>")

html-textview:

val htmlTextView = HtmlTextView(context)
htmlTextView.text = "<b>Bold</b> <i>Italic</i> <u>Underline</u>"

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

XRichText

一个Android富文本类库,支持图文混排,支持编辑和预览,支持插入和删除图片。

实现的原理:

  • 使用ScrollView作为最外层布局包含LineaLayout,里面填充TextView和ImageView。
  • 删除的时候,根据光标的位置,删除TextView和ImageView,文本自动合并。
  • 生成的数据为list集合,可自定义处理数据格式。

注意事项

  • V1.4版本开放了图片点击事件接口和删除图片接口,具体使用方式可以参考后面的文档说明,也可以参考Demo实现。
  • V1.6版本升级RxJava到2.2.3版本,RxAndroid到2.1.0版本。设置字体大小时需要带着单位,如app:rt_editor_text_size="16sp"。
  • V1.9.3及后续版本,xrichtext库中已去掉Glide依赖,开放接口可以自定义图片加载器。具体使用方式可以参考后面的文档说明,也可以参考Demo实现。
  • Demo中图片选择器为知乎开源库Matisse,适配Android 7.0系统使用FileProvider获取图片路径。
  • 开发环境更新为 AS 3.4.2 + Gradle 4.4 + compileSDK 28 + support library 28.0.0,导入项目报版本错误时,请手动修改为自己的版本。
  • 请参考Demo的实现,进行了解本库。可以使用Gradle引入,也可以下载源码进行修改。
  • 如有问题,欢迎提出。欢迎加入QQ群交流:745215148。

截图预览

笔记列表 文字笔记详情 编辑笔记 图片笔记详情

使用方式

1. 作为module导入

把xrichtext作为一个module导入你的工程。

2. gradle依赖

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}

dependencies {
    implementation 'com.github.sendtion:XRichText:1.9.4'
}

如果出现support版本不一致问题,请排除XRichText中的support库,或者升级自己的support库为28.0.0版本。 使用方式:

implementation ('com.github.sendtion:XRichText:1.9.4') {
    exclude group: 'com.android.support'
}

具体使用

在xml布局中添加基于EditText编辑器(可编辑)

<com.sendtion.xrichtext.RichTextEditor
    android:id="@+id/et_new_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:rt_editor_text_line_space="6dp"
    app:rt_editor_image_height="500"
    app:rt_editor_image_bottom="10"
    app:rt_editor_text_init_hint="在这里输入内容"
    app:rt_editor_text_size="16sp"
    app:rt_editor_text_color="@color/grey_900"/>

在xml布局中添加基于TextView编辑器(不可编辑)

<com.sendtion.xrichtext.RichTextView
    android:id="@+id/tv_note_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:rt_view_text_line_space="6dp"
    app:rt_view_image_height="0"
    app:rt_view_image_bottom="10"
    app:rt_view_text_size="16sp"
    app:rt_view_text_color="@color/grey_900"/>

自定义属性

具体参考Demo

  • RichTextView
rt_view_image_height        图片高度,默认为0自适应,可以设置为固定数值,如500、800等
rt_view_image_bottom        上下两张图片的间隔,默认10
rt_view_text_size           文字大小,使用sp单位,如16sp
rt_view_text_color          文字颜色,使用color资源文件
rt_view_text_line_space     字体行距,跟TextView使用一样,比如6dp
  • RichTextEditor
rt_editor_image_height      图片高度,默认为500,可以设置为固定数值,如500、800等,0为自适应高度
rt_editor_image_bottom      上下两张图片的间隔,默认10
rt_editor_text_init_hint    默认提示文字,默认为“请输入内容”
rt_editor_text_size         文字大小,使用sp单位,如16sp
rt_editor_text_color        文字颜色,使用color资源文件
rt_editor_text_line_space   字体行距,跟TextView使用一样,比如6dp

生成数据

我把数据保存为了html格式,生成字符串存储到了数据库。

String noteContent = getEditData();

private String getEditData() {
    List<RichTextEditor.EditData> editList = et_new_content.buildEditData();
    StringBuffer content = new StringBuffer();
    for (RichTextEditor.EditData itemData : editList) {
        if (itemData.inputStr != null) {
            content.append(itemData.inputStr);
        } else if (itemData.imagePath != null) {
            content.append("<img src=\"").append(itemData.imagePath).append("\"/>");
        }
    }
    return content.toString();
}

显示数据

et_new_content.post(new Runnable() {
     @Override
     public void run() {
         showEditData(content);
     }
 });

protected void showEditData(String content) {
    et_new_content.clearAllLayout();
    List<String> textList = StringUtils.cutStringByImgTag(content);
    for (int i = 0; i < textList.size(); i++) {
        String text = textList.get(i);
        if (text.contains("<img")) {
            String imagePath = StringUtils.getImgSrc(text);
            int width = ScreenUtils.getScreenWidth(this);
            int height = ScreenUtils.getScreenHeight(this);
            et_new_content.measure(0,0);
            Bitmap bitmap = ImageUtils.getSmallBitmap(imagePath, width, height);
            if (bitmap != null){
                et_new_content.addImageViewAtIndex(et_new_content.getLastIndex(), bitmap, imagePath);
            } else {
            et_new_content.addEditTextAtIndex(et_new_content.getLastIndex(), text);
            }
            et_new_content.addEditTextAtIndex(et_new_content.getLastIndex(), text);
        }
    }
}

图片点击事件

tv_note_content.setOnRtImageClickListener(new RichTextView.OnRtImageClickListener() {
    @Override
    public void onRtImageClick(String imagePath) {
        ArrayList<String> imageList = StringUtils.getTextFromHtml(myContent, true);
        int currentPosition = imageList.indexOf(imagePath);
        showToast("点击图片:"+currentPosition+":"+imagePath);
        // TODO 点击图片预览
    }
});

图片加载器使用

请在Application中设置,经测试在首页初始化会出现问题。Demo仅供参考,具体实现根据您使用的图片加载器而变化。

XRichText.getInstance().setImageLoader(new IImageLoader() {
    @Override
    public void loadImage(String imagePath, ImageView imageView, int imageHeight) {
       //如果是网络图片
       if (imagePath.startsWith("http://") || imagePath.startsWith("https://")){
           Glide.with(getApplicationContext()).asBitmap().load(imagePath).dontAnimate()
                   .into(new SimpleTarget<Bitmap>() {
                       @Override
                       public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
                           if (imageHeight > 0) {//固定高度
                               RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
                                       FrameLayout.LayoutParams.MATCH_PARENT, imageHeight);//固定图片高度,记得设置裁剪剧中
                               lp.bottomMargin = 10;//图片的底边距
                               imageView.setLayoutParams(lp);
                               Glide.with(getApplicationContext()).asBitmap().load(imagePath).centerCrop()
                                       .placeholder(R.mipmap.img_load_fail).error(R.mipmap.img_load_fail).into(imageView);
                           } else {//自适应高度
                               Glide.with(getApplicationContext()).asBitmap().load(imagePath)
                                       .placeholder(R.mipmap.img_load_fail).error(R.mipmap.img_load_fail).into(new TransformationScale(imageView));
                           }
                       }
                   });
       } else { //如果是本地图片
           if (imageHeight > 0) {//固定高度
               RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
                       FrameLayout.LayoutParams.MATCH_PARENT, imageHeight);//固定图片高度,记得设置裁剪剧中
               lp.bottomMargin = 10;//图片的底边距
               imageView.setLayoutParams(lp);

               Glide.with(getApplicationContext()).asBitmap().load(imagePath).centerCrop()
                       .placeholder(R.mipmap.img_load_fail).error(R.mipmap.img_load_fail).into(imageView);
           } else {//自适应高度
               Glide.with(getApplicationContext()).asBitmap().load(imagePath)
                       .placeholder(R.mipmap.img_load_fail).error(R.mipmap.img_load_fail).into(new TransformationScale(imageView));
           }
       }
    }
});

TransformationScale类请参考Demo

具体的使用方式,请参考Demo代码。

更新历史

v1.9.4 2019.11.05

  • lib,解决网络图片不能自适应高度的问题;
  • demo,提供加载https图片实现方式;
  • demo,XRichText设置图片加载器放置在Application中。

v1.9.3 2019.10.19

  • 去除依赖的Glide,改为接口回调,可使用自定义图片加载器
  • 优化代码结构,提升稳定性

v1.9.1 2019.04.30

  • 图片点击事件接口返回点击的View
  • 修复图片显示时高度拉伸变形问题
  • Demo中实现了点击图片放大浏览功能
  • Support支持库升级为28.0.0

v1.9.0 2019.04.10

  • 编辑时支持关键词高亮
  • 修复插入图片时空指针异常
  • 代码异常处理

v1.8 2018.12.02

  • 修复编辑时设置文字颜色无效的问题
  • 编辑时添加和删除图片加入动画效果

v1.6 2018.11.16

  • RxJava升级到2.2.3版本,RxAndroid升级到2.1.0版本
  • 编辑图片时支持自适应高度,高度设置为0即自适应,比如app:rt_editor_image_height="0"
  • 修改字体大小设置方式,像正常使用带着单位,比如app:rt_editor_text_size="16sp"
  • 支持设置字体行间距,比如app:rt_editor_text_line_space="6dp"
  • 修复xrichtext库及Demo中的各种崩溃异常

v1.5 2018.07.10

  • 修复详情页连续加载多张图片导致后续图片都跟第一张图片相同高度的问题
  • 修复Demo插入图片后点击图片导致空指针异常的问题
  • 去掉Demo插入图片后会插入一张网络图片的测试代码

v1.4 2018.06.22

  • 添加自定义属性,可以设置图片高度,相邻图片间隔,文字大小和颜色
  • 修复没有实现图片删除接口导致的崩溃问题,开放图片删除接口
  • 添加点击图片查看大图的功能,开放图片点击接口
  • 加入崩溃日志信息展示,加入崩溃日志信息发送到邮件
  • 优化图片插入代码,删除多余的无用代码

v1.3 2018.05.05

  • 更新Glide依赖版本为4.7.1,Glide4使用方式:http://bumptech.github.io/glide/doc/getting-started.html
  • 开发环境更新到AS 3.1.2 + Gradle 4.4
  • 优化图片插入的逻辑
  • 在Demo中加入插入网络图片的示例代码
  • 在Demo中图片选择器更换为知乎matisse

v1.2 2018.04.05

  • 编辑笔记时,使用接口回调在外部处理图片的删除操作,可以自行实现删除本地图片还是网络图片
  • 实现网络图片的加载,插入图片时,可以传入本地图片SD卡路径,也可以传入网络图片地址
  • 在新建或编辑笔记时,连续多张图片之间插入输入框,方便在图片间输入文本内容
  • 修复在文件中间插入图片时,导致的后面文字丢失的问题
  • 修复连续插入多张图片时,会出现图片倒序插入的问题

v1.1 2017.03.27

  • 优化内存占用,解决内存溢出问题
  • 结合RxJava使用(参考Demo)
  • 支持连续插入多张图片不卡顿(参考Demo)
  • 解决插入图片导致的卡顿和崩溃

v1.0 2016.10.26

  • 初次提交
  • 实现插入图片
  • 实现图文混排
  • 实现编辑和保存

感谢

本库参考了以下项目,感谢各位大神的优秀作品!

其他

License

Copyright 2019 sendtion

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.