SelectTextHelper
打造一个全网最逼近微信聊天消息自由复制,双击查看文本内容框架。 支持图片和富文本选中,汇聚底层TextView
框架、原理并加以整理得出的一个实用的Helper
。
仅用几个类实现便实现如此强大的功能,用法也超级简单,侵入性极低。
项目持续维护中... 您的宝贵意见和建议是技术前进的方向
消息页效果 | 查看内容效果 |
---|---|
消息页全选 | 消息页自由复制放大镜 |
---|---|
消息页选中文本 | 查看内容 |
---|---|
- 支持自由选择文本
- 支持
富文本
选择 - 支持自定义文本有:游标颜色、游标大小、选中文本颜色
- 支持默认全选文字或选2个文字
- 支持滑动依然显示弹窗
- 支持放大镜功能
- 支持全选情况下自定义弹窗
- 支持操作弹窗:每行个数、图片、文字、监听回调、弹窗颜色、箭头图片
allprojects {
repositories {
...
maven { url "https://jitpack.io" }
}
}
dependencies {
implementation 'com.github.ITxiaoguang:SelectTextHelper:1.1.0'
}
通过 仿照的例子 并改进弹窗坐标位置、加对ImageSpan支持、大小加上EventBus
实现
把该项目里的selecttext Module
放入你的项目里面 或者 按照Gradle
添加的步骤导入依赖。
val mSelectableTextHelper = SelectTextHelper.Builder(textView) // 放你的textView到这里!!
.setCursorHandleColor(ContextCompat.getColor(mContext, R.color.colorAccent)) // 游标颜色
.setCursorHandleSizeInDp(22f) // 游标大小 单位dp
.setSelectedColor(ContextCompat.getColor(mContext, R.color.colorAccentTransparent)) // 选中文本的颜色
.setSelectAll(true) // 初次选中是否全选 default true
.setScrollShow(true) // 滚动时是否继续显示 default true
.setSelectedAllNoPop(true) // 已经全选无弹窗,设置了监听会回调 onSelectAllShowCustomPop 方法
.setMagnifierShow(true) // 放大镜 default true
.setSelectTextLength(2)// 首次选中文本的长度 default 2
.setPopDelay(100)// 弹窗延迟时间 default 100毫秒
.setPopAnimationStyle(R.style.Base_Animation_AppCompat_Dialog)// 弹窗动画 default 无动画
.addItem(0/*item的图标*/,"复制"/*item的描述*/, {Log.i("SelectTextHelper","复制")/*item的回调*/}// 操作弹窗的每个item
.setPopSpanCount(5) // 设置操作弹窗每行个数 default 5
.setPopStyle(
R.drawable.shape_color_4c4c4c_radius_8 /*操作弹窗背*/,
R.drawable.ic_arrow /*箭头图片*/
) // 设置操作弹窗背景色、箭头图片
.build()
mSelectableTextHelper!!.setSelectListener(object : OnSelectListener {
/**
* 点击回调
*/
override fun onClick(v: View?, originalContent: CharSequence?) {
// 拿原始文本方式
// clickTextView(msgBean.content!!) // 推荐
// clickTextView(originalContent!!) // 不推荐 富文本可能被修改值 导致gif动不了
}
/**
* 长按回调
*/
override fun onLongClick(v: View?) {
}
/**
* 选中文本回调
*/
override fun onTextSelected(content: CharSequence?) {
}
/**
* 弹窗关闭回调
*/
override fun onDismiss() {}
/**
* 点击TextView里的url回调
*
* 已被下面重写
* textView.setMovementMethod(new LinkMovementMethodInterceptor());
*/
override fun onClickUrl(url: String?) {
}
/**
* 全选显示自定义弹窗回调
*/
override fun onSelectAllShowCustomPop() {
}
/**
* 重置回调
*/
override fun onReset() {
// SelectTextEventBus.instance.dispatch(SelectTextEvent("dismissOperatePop"))
}
/**
* 解除自定义弹窗回调
*/
override fun onDismissCustomPop() {
// SelectTextEventBus.instance.dispatch(SelectTextEvent("dismissOperatePop"))
}
/**
* 是否正在滚动回调
*/
override fun onScrolling() {
// removeShowSelectView()
}
})
查看文本内容方法:
- 该方法比较简单,将
textView
参照步骤2放入SelectTextHelper
中,在dismiss
调用SelectTextHelper
的reset()
即可。
override fun dismiss() {
mSelectableTextHelper.reset()
super.dismiss()
}
高仿微信聊天消息列表自由复制方法:
-
recycleView
+adapter
+ 多布局的使用在这里不阐述,请看本项目demo。 -
为
adapter
里text类型ViewHolder
中的textView
参照步骤2放入SelectTextHelper
中,注册SelectTextEventBus
。 -
SelectTextEventBus
类特别说明、原理:SelectTextEventBus
在EventBus
基础上加功能。在register
时记录下类和方法,方便在Activity/Fragment Destroy
时unregister
所有SelectTextEventBus
的EventBus
。 -
text类型
ViewHolder
添加EventBus
监听
/**
* 自定义SelectTextEvent 隐藏 光标
*/
@Subscribe(threadMode = ThreadMode.MAIN)
fun handleSelector(event: SelectTextEvent) {
if (null == mSelectableTextHelper) {
return
}
val type = event.type
if (TextUtils.isEmpty(type)) {
return
}
when (type) {
"dismissAllPop" -> mSelectableTextHelper!!.reset()
"dismissAllPopDelayed" -> postReset(Companion.RESET_DELAY)
}
}
- 重写
adapter
里的onViewRecycled
方法,该方法在回收View
时调用
override fun onViewRecycled(holder: RecyclerView.ViewHolder) {
super.onViewRecycled(holder)
if (holder is ViewHolderText) {
// 注销
SelectTextEventBus.instance.unregister(holder)
}
}
- 对ImageSpan表情支持(支持动态表情!!)(#4 )
val emojiMap: MutableMap<String, Int> = HashMap()
emojiMap["\\[笑脸\\]"] = R.drawable.emoji_00
emojiMap["\\[瘪嘴\\]"] = R.drawable.emoji_01
emojiMap["\\[色\\]"] = R.drawable.emoji_02
emojiMap["\\[瞪大眼\\]"] = R.drawable.emoji_03
emojiMap["\\[酷\\]"] = R.drawable.emoji_04
emojiMap["\\[Android\\]"] = R.mipmap.ic_launcher_round
emojiMap["\\[好的\\]"] = R.drawable.emoji_gif
emojiMap["\\[羊驼\\]"] = R.drawable.emoji_gif2
- 富文本支持 富文本用法点这里
// todo 方法一:富文本 需要转行成富文本形式
RichText.initCacheDir(holder.textView.context.applicationContext) // 项目里初始化一次即可
RichText.from(msgBean.content)
.autoFix(false) // 是否自动修复宽高,默认true
.autoPlay(true) // gif自动播放
.singleLoad(false) // RecyclerView里设为false 若同时启动了多个RichText,会并发解析,类似于AsyncTask的executeOnExecutor
.done { // 在成功回调处理
// 演示消息列表选择文本
holder.selectText(msgBean)
}
.into(holder.textView)
// todo 方法二:普通文本
holder.textView.text = msgBean.content
// 演示消息列表选择文本
holder.selectText(msgBean)