All Projects → yuruiyin → Richeditor

yuruiyin / Richeditor

Licence: mit
基于原生EditText+span实现的Android富文本编辑器

Programming Languages

java
68154 projects - #9 most used programming language
kotlin
9241 projects

Projects that are alternatives of or similar to Richeditor

Springboot Rabbitmq
RabbitMQ为异步消息处理提出了一个很好的解决方案,它是一个非常好用的消息中间件,主要用于中间件的解耦,同时,Spring Boot为RabbitMQ提供了支持, Spring Boot为Rabbit准备了spring-boot-starter-amqp,spring-rabbit 支持 AMQP(即Advanced Message Queuing Protocol,高级消息队列协议,是应用层协议的一个开放标准),并且为RabbitTemplate和RabbitMQ提供了自动配置选项
Stars: ✭ 159 (-16.75%)
Mutual labels:  gradle
Gradlewiki
关于Gradle编译你需要知道的一切
Stars: ✭ 174 (-8.9%)
Mutual labels:  gradle
Gradle Testsets Plugin
A plugin for the Gradle build system that allows specifying test sets (like integration or acceptance tests).
Stars: ✭ 182 (-4.71%)
Mutual labels:  gradle
Sample Projects
Sample project files for JavaCPP, JavaCPP Presets, and JavaCV
Stars: ✭ 160 (-16.23%)
Mutual labels:  gradle
Materialsearchbar
Material Design Search Bar for Android
Stars: ✭ 2,008 (+951.31%)
Mutual labels:  gradle
Click Debounce
Using ASM to handle Android's click debounce, specially a quick double click.
Stars: ✭ 175 (-8.38%)
Mutual labels:  gradle
Worldedit
🗺️ Minecraft map editor and mod
Stars: ✭ 2,288 (+1097.91%)
Mutual labels:  gradle
Mvvmtemplate
An Android Template with MVVM and Clean Architecture
Stars: ✭ 182 (-4.71%)
Mutual labels:  gradle
Jitpack.io
Documentation and issues of https://jitpack.io
Stars: ✭ 2,156 (+1028.8%)
Mutual labels:  gradle
Maven Git Versioning Extension
This extension will virtually set project versions, based on current git branch or tag.
Stars: ✭ 178 (-6.81%)
Mutual labels:  gradle
Crown
Based on SpringBoot2, Crown builds a rapidly developed web application scaffolding.
Stars: ✭ 161 (-15.71%)
Mutual labels:  gradle
Simplenet
An easy-to-use, event-driven, asynchronous network application framework compiled with Java 11.
Stars: ✭ 164 (-14.14%)
Mutual labels:  gradle
Gradle 3 User Guide
Gradle 3 User Guide 中文翻译《Gradle 3 用户指南》
Stars: ✭ 177 (-7.33%)
Mutual labels:  gradle
Jda Utilities
A series of tools and utilities for JDA to assist in bot creation
Stars: ✭ 158 (-17.28%)
Mutual labels:  gradle
Stubbornjava
Unconventional Java code for building web servers / services without a framework. Think dropwizard but as a seed project instead of a framework. If this project had a theme it would be break the rules but be mindful of your decisions.
Stars: ✭ 184 (-3.66%)
Mutual labels:  gradle
Android Clean Architecture
Showcasing a Clean Architecture approach from our Android applications framework!
Stars: ✭ 160 (-16.23%)
Mutual labels:  gradle
Netbeans Gradle Project
This project is a NetBeans plugin able to open Gradle based Java projects. The implementation is based on Geertjan Wielenga's plugin.
Stars: ✭ 175 (-8.38%)
Mutual labels:  gradle
Kotlin Multiplatform Template
Kotlin Multiplatform Template
Stars: ✭ 185 (-3.14%)
Mutual labels:  gradle
Qmbform
Create simple Android forms
Stars: ✭ 184 (-3.66%)
Mutual labels:  gradle
Gradle Launch4j
A gradle-plugin to create windows executables with launch4j
Stars: ✭ 177 (-7.33%)
Mutual labels:  gradle

RichEditor

基于原生EditText+span实现的Android富文本编辑器

组件描述

该组件是基于原生EditText+span的方式实现的,旨在提供一个功能齐全且使用方便的Android富文本编辑器。主要支持了加粗斜体等行内样式、标题引用等段内样式以及插入图片视频甚至自定义View等。

功能演示

Demo

功能列表

  • [x] 支持加粗、斜体、删除线、下划线行内样式
  • [x] 支持插入标题、引用段内样式
  • [x] 支持插入段落图片、视频
  • [x] 支持插入段落自定义布局
  • [x] 支持视频、gif和长图标记
  • [x] 支持图片圆角
  • [x] 支持图片视频及自定义View的点击事件
  • [x] undo redo
  • [ ] 支持行内ImageSpan,如类似微博@xxx,#话题名#
  • [ ] 支持清除样式
  • [ ] 编辑器内部复制粘贴ImageSpan(任意以ImageSpan方式插入的的类型,如图片、视频、自定义view等)

如何使用

gradle

Step 1. Add the JitPack repository in your root build.gradle at the end of repositories:

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

Step 2. Add the dependency in your app build.gradle:

dependencies {
	implementation 'com.github.yuruiyin:RichEditor:latest-version'
}

参数定义

自定义属性名字 参数含义
editor_show_video_mark 是否显示视频标识图标
editor_video_mark_resource_id 视频图标资源id
editor_show_gif_mark 是否显示gif标识图标
editor_show_long_image_mark 是否显示长图标识
editor_image_radius 图片和视频圆角大小
editor_headline_text_size 标题字体大小

代码演示

说明:各个样式按钮的layout由调用方自行完成

1) 首先在xml中引用RichEditText:

<com.yuruiyin.richeditor.RichEditText
    android:id="@+id/richEditText"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="20dp"
    android:background="#ffffff"
    android:gravity="top|left"
    android:hint="请输入..."
    android:inputType="textMultiLine"
    android:lineSpacingExtra="5dp"
    android:maxLength="20000"
    android:minHeight="350dp"
    android:paddingBottom="70dp"
    android:paddingLeft="15dp"
    android:paddingRight="15dp"
    android:paddingTop="23dp"
    android:textColor="#171717"
    android:textColorHint="#aaaaaa"
    android:textCursorDrawable="@null"
    android:textSize="16dp"
    app:editor_video_mark_resource_id="@mipmap/editor_video_mark_icon"
    app:editor_image_radius="3dp"
    app:editor_show_gif_mark="true"
    app:editor_show_video_mark="true"
    app:editor_show_long_image_mark="true"
    />

2) 针对加粗、斜体、标题等需要修改图标样式的按钮(不包括插入图片按钮),处理如下:

    // 加粗, 仅包含图标(见demo)
    val styleBtnVm = StyleBtnVm.Builder()
            .setType(RichTypeEnum.BOLD)
            .setIvIcon(ivBold)
            .setIconNormalResId(R.mipmap.icon_bold_normal)
            .setIconLightResId(R.mipmap.icon_bold_light)
            .setClickedView(ivBold)
            .build()

    richEditText.initStyleButton(styleBtnVm)

    // 标题,包含图标和文字(图标高亮的同时文字也要高亮)
    val styleBtnVm = StyleBtnVm.Builder()
            .setType(RichTypeEnum.BLOCK_HEADLINE)  // 指定为段落标题类型
            .setIvIcon(ivHeadline)       // 图标ImageView,用于修改高亮状态
            .setIconNormalResId(R.mipmap.icon_headline_normal)  // 正常图标资源id
            .setIconLightResId(R.mipmap.icon_headline_light)    // 高亮图标资源id
            .setClickedView(vgHeadline)  // 指定被点击的view
            .setTvTitle(tvHeadline)      // 按钮标题文字
            .setTitleNormalColor(ContextCompat.getColor(this@MainActivity, R.color.headline_normal_text_color)) // 正常标题文字颜色
            .setTitleLightColor(ContextCompat.getColor(this@MainActivity, R.color.headline_light_text_color))   // 高亮标题文字颜色
            .build()

    richEditText.initStyleButton(styleBtnVm)

3)插入图片或视频

    /**
     * 处理插入图片
     */
    private fun handleAddImage() {
        val intent = Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
        startActivityForResult(intent, GET_PHOTO_REQUEST_CODE)
    }

    private fun doAddBlockImageSpan(
            realImagePath: String, blockImageSpanObtainObject: IBlockImageSpanObtainObject, isFromDraft: Boolean = false
    ) {
        val blockImageSpanVm = BlockImageSpanVm(blockImageSpanObtainObject) // 不指定宽高,使用图片原始大小(但组件内对最大宽和最大高还是有约束的)
    //        val blockImageSpanVm = BlockImageSpanVm(blockImageSpanObtainObject, imageWidth, imageMaxHeight) // 指定宽高
        blockImageSpanVm.isFromDraft = isFromDraft
        richEditText.insertBlockImage(realImagePath, blockImageSpanVm) { blockImageSpan ->
            val spanObtainObject = blockImageSpan.blockImageSpanVm.spanObject
            when (spanObtainObject) {
                is ImageVm -> {
                    Toast.makeText(this, "短按了图片-当前图片路径:${spanObtainObject.path}", Toast.LENGTH_SHORT).show()
                }
                is VideoVm -> {
                    Toast.makeText(this, "短按了视频-当前视频路径:${spanObtainObject.path}", Toast.LENGTH_SHORT).show()
                }
            }
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == GET_PHOTO_REQUEST_CODE && resultCode == RESULT_OK && data != null) {
            // 相册图片返回
            val selectedImageUri = data.data ?: return
            val realImagePath = FileUtil.getFileRealPath(this, selectedImageUri) ?: return
            val fileType = FileUtil.getFileType(realImagePath) ?: return
            when (fileType) {
                FileTypeEnum.STATIC_IMAGE, FileTypeEnum.GIF -> {
                    val imageVm = ImageVm(realImagePath, "2")
                    doAddBlockImageSpan(realImagePath, imageVm)
                }
                FileTypeEnum.VIDEO -> {
                    // 插入视频封面
                    val videoVm = VideoVm(realImagePath, "3")
                    doAddBlockImageSpan(realImagePath, videoVm)
                }
            }
        }
    }

4) 插入自定义布局

    /**
     * 插入游戏
     */
    private fun handleAddGame() {
        val gameVm = GameVm(1, "一起来捉妖")
        doAddGame(gameVm)
    }

    private fun doAddGame(gameVm: GameVm, isFromDraft: Boolean = false) {
        val gameItemView = layoutInflater.inflate(R.layout.editor_game_item, null)
        val ivGameIcon = gameItemView.findViewById<ImageView>(R.id.ivGameIcon)
        val tvGameName = gameItemView.findViewById<TextView>(R.id.tvGameName)
        ivGameIcon.setImageResource(R.mipmap.icon_game_zhuoyao)
        tvGameName.text = gameVm.name

        ivGameIcon.layoutParams.width = gameIconSize
        ivGameIcon.layoutParams.height = gameIconSize

        val gameItemWidth = getEditTextWidthWithoutPadding()
        ViewUtil.layoutView(gameItemView, gameItemWidth, gameItemHeight)

        val blockImageSpanVm = BlockImageSpanVm(gameVm, gameItemWidth, imageMaxHeight)
        blockImageSpanVm.isFromDraft = isFromDraft
        richEditText.insertBlockImage(ViewUtil.getBitmap(gameItemView), blockImageSpanVm) { blockImageSpan ->
            val retGameVm = blockImageSpan.blockImageSpanVm.spanObject as GameVm
            // 点击游戏item
            Toast.makeText(this, "短按了游戏:${retGameVm.name}", Toast.LENGTH_SHORT).show()
        }
    }    

说明:插入自定义布局最终也是通过bitmap以ImageSpan的形式插入到编辑器中的。

5)获取数据

    // 返回的编辑器实体是一个list,list中每个元素代表一个段落block,具体block参数可以参考RichEditorBlock, 
    // 但是若需要保存草稿功能,则需要对该list进行转换成自己的实体,否则List<RichEditorBlock>序列化后反序列化会丢失数据,可以参考demo
    val content: List<RichEditorBlock> = richEditText.content

具体使用请参考demo

相关引用

  1. 设置EditText的光标高度: LineHeightEditText
  2. 设置图片圆角: RoundedImageView
  3. undo redo: AndroidEdit

最后

您的star是我把组件做到完美的动力~

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].