莆田有交做外贸网站的没,做软件界面一般用什么软件,网页设计实训报告1000字,网页版微信文件存储路径一、背景及样式效果
因项目需要#xff0c;需要文本编辑时#xff0c;支持项目符号#xff08;无序列表#xff09;尝试了BulletSpan#xff0c;但不是很理想#xff0c;并且考虑到影响老版本回显等因素#xff0c;最终决定自定义一个BulletEditText。 先看效果需要文本编辑时支持项目符号无序列表尝试了BulletSpan但不是很理想并且考虑到影响老版本回显等因素最终决定自定义一个BulletEditText。 先看效果 视频效果 二、自定义View BulletEditText 自定义控件BulletEditText源码
package com.ml512.widgetimport android.content.Context
import android.util.AttributeSet
import androidx.core.widget.doOnTextChanged/*** Description: 简单支持项目号的文本编辑器* Author: Marlon* CreateDate: 2024/2/1 17:44* UpdateRemark: 更新说明* Version: 1.0*/
class BulletEditText : androidx.appcompat.widget.AppCompatEditText {/*** 是否开启项目符号*/private var isNeedBullet: Boolean false/*** 项目符号*/private var bulletPoint: String • /*** 项目符号占用字符数方便设置光标位置*/private var bulletOffsetIndex bulletPoint.length/*** 相关监听回调*/private var editListener: EditListener? nullconstructor(context: Context) : super(context)constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context,attrs,defStyleAttr)init {this.doOnTextChanged { text, start, before, count -//如果是关闭状态不做格式处理if (!isNeedBullet) {returndoOnTextChanged}if (count before) {//处理项目号逻辑var offset 0var tmp text.toString()//连续回车去掉项目符号if (start bulletOffsetIndex tmp.substring(start, start count) \n) {val preSub tmp.substring(start - bulletOffsetIndex, start)if (preSub bulletPoint) {changeBulletState(false)tmp tmp.replaceRange(start-bulletOffsetIndex, start count, )offset - bulletOffsetIndex 1setTextAndSelection(tmp, start count offset)returndoOnTextChanged}}//加入项目符号if (tmp.substring(start, start count) \n) {changeBulletState(true)tmp tmp.replaceRange(start, start count, \n$bulletPoint)offset bulletOffsetIndexsetTextAndSelection(tmp, start count offset)}}}}override fun onSelectionChanged(selStart: Int, selEnd: Int) {super.onSelectionChanged(selStart, selEnd)//复制选择时直接返回关闭项目符号if (selStart ! selEnd) {changeBulletState(false)return}//判断当前段落是否有项目号有开启没有关闭val tmp text.toString()val prefix tmp.substring(0, selectionStart)if (prefix.isEmpty()) {changeBulletState(false)return}if (prefix.startsWith(bulletPoint) !prefix.contains(\n)) {changeBulletState(true)return}val lastEnterIndex prefix.lastIndexOf(\n)if (lastEnterIndex ! -1 lastEnterIndex bulletOffsetIndex 1 prefix.length) {val mathStr prefix.substring(lastEnterIndex, lastEnterIndex bulletOffsetIndex 1)if (mathStr \n$bulletPoint) {changeBulletState(true)return}}changeBulletState(false)}/*** 更新bullet状态*/private fun changeBulletState(isOpen: Boolean) {isNeedBullet isOpeneditListener?.onBulletStateChange(isOpen)}/*** 设置是否开启项目号*/fun setBullet(isOpen: Boolean) {isNeedBullet isOpenval tmp text.toString()var index selectionStartvar prefix tmp.substring(0, index)val suffix tmp.substring(index)//加项目号if (isOpen) {//首个段落if (!prefix.contains(\n) prefix.startsWith(bulletPoint)) {return}index bulletOffsetIndexif (prefix.isEmpty() || (!prefix.contains(\n) !prefix.startsWith(bulletPoint))) {setTextAndSelection($bulletPoint$prefix$suffix, index)return}prefix prefix.replaceLast(\n, \n$bulletPoint)setTextAndSelection($prefix$suffix, index)return}//去掉项目号if (prefix.startsWith(bulletPoint) !prefix.contains(\n$bulletPoint)) {//首行逻辑index - bulletOffsetIndexprefix prefix.replaceLast(bulletPoint, )setTextAndSelection($prefix$suffix, index)return}if (prefix.contains(\n$bulletPoint)) {index - bulletOffsetIndexprefix prefix.replaceLast(\n$bulletPoint, \n)setTextAndSelection($prefix$suffix, index)}}/*** 设置文本及光标位置*/private fun setTextAndSelection(text: String, index: Int) {setText(text)setSelection(index)}/*** 替换最后一个字符*/private fun String.replaceLast(oldValue: String, newValue: String): String {val lastIndex lastIndexOf(oldValue)if (lastIndex -1) {return this}val prefix substring(0, lastIndex)val suffix substring(lastIndex oldValue.length)return $prefix$newValue$suffix}/*** 设置监听*/fun setEditListener(listener: EditListener) {editListener listener}/*** 监听回调*/interface EditListener {/*** 项目符号开关状态变化*/fun onBulletStateChange(isOpen: Boolean)}
}
三、调用 使用时一个项目符号的按钮开关设置调用setBullet(isOpen: Boolean) 设置是否开启项目符号同时实现一个setEditListener(listener: EditListener)根据光标位置判断当前段落是否含有项目符号并回显按钮状态。 com.ml512.widget.BulletEditTextandroid:idid/etInputandroid:layout_widthmatch_parentandroid:layout_height200dpandroid:layout_belowid/tvTitleandroid:layout_marginStart15dpandroid:layout_marginTop15dpandroid:layout_marginEnd15dpandroid:layout_marginBottom15dpandroid:autofillHintsnoandroid:backgrounddrawable/shape_edit_bgandroid:gravitytopandroid:hintstring/text_please_input_some_worldsandroid:inputTypetextMultiLineandroid:padding15dpandroid:textColorcolor/blackandroid:textColorHintcolor/color_FF_999999android:textSize16sp / //点击按钮设置添加/取消项目符号tvBullet.setOnClickListener {tvBullet.isSelected !tvBullet.isSelectedetInput.setBullet(tvBullet.isSelected)}//项目符号状态监听回显到按钮etInput.setEditListener(object :BulletEditText.EditListener{override fun onBulletStateChange(isOpen: Boolean) {tvBullet.isSelected isOpen}})
大功告成