当前位置: 首页 > news >正文

大连凯杰建设有限公司网站推广普通话的重要意义

大连凯杰建设有限公司网站,推广普通话的重要意义,怎么做售房网站,动易网站建设有两种实现方案。 方案一:是自己写一个TextWatcher。 方案二:是重写TextView的getOffsetForPosition方法,返回一个计算好的offset。 我在工作时,使用的是方案一。在离职之后,我还是对这个问题耿耿于怀,所以…

有两种实现方案。
方案一:是自己写一个TextWatcher。
方案二:是重写TextView的getOffsetForPosition方法,返回一个计算好的offset。

我在工作时,使用的是方案一。在离职之后,我还是对这个问题耿耿于怀,所以才去看源码,最后想到了方案二。

但实际测试时,发现方案二存在一些问题,而且看了找了好久的源码,都不知道要重写哪个方法来解决,所以只能提供另一个半成品的方案二出来。

先看看两种方案的gif吧。
方案一
在这里插入图片描述
方案二
在这里插入图片描述
从方案一的gif图片可以看到,在输入文本之后,会在文本后面追加suffix text。如果在suffix text的范围内输入会删除,则会将这些操作传递到已输入的文本上。如果已输入的最后一个文本被删除,则会删除掉所有文本。

方案二则相对简单,输入后依然有suffix text,但suffix 的范围是不可以点击的。咋一看,这个方案好像很好,但我在实际测试时发现了一些问题,而且还不知道要怎么解决。

  • 长按EditText会出现全选的dialog,并且点击全选将选择suffix text。这个操作我认为是有问题的。既然suffix text没办法被selection,那全选就不应该将它包含进来
  • 双击suffix text,也会选择suffix text

我找了很久很久的源码,不断的debug,尝试定位到第一个问题和第二个问题调用的源码,并看看能否重写某些方法来改变其逻辑,但最终都无功而返。
在上面我也提到了,我是重写getOffsetForPosition方法实现了这个功能,所以我也尝试在这个方法上动手脚,但最终的效果不是很好。在模拟器上,如果是用了全选,会出现,先全选,再选回suffix text前面的文本。对于用户来说,两个动画同时出现,未免也太滑稽了吧。所以我最终没有采用这种方案。

无论使用哪种方案,在复制时都会将suffix text复制进来,想要解决这个问题也很简单,可以EditText并重写EditText的onTextContextMenuItem方法,并判断id是否为android.R.id.copy。如果是,就重写一下copy的逻辑。至于为什么我知道可以这样做,可以看一下这篇博客。

图也给了,也解释了图片里面发生了什么,下面贴一下代码,注释已经补在代码里面。
方案一

open class SuffixTextWatcher(private val editText: EditText, private val suffixText: String) : TextWatcher {private var lastText = ""override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {if (suffixText.isEmpty()) {return}editText.removeTextChangedListener(this)val preText = s.toString()val suffixText = suffixText// 如果输入的文本等于suffixText,就说明已经清空了输入的文本,那就直接设置为空字符串if (preText == suffixText) {lastText = ""editText.setText(lastText)} else {// 如果不是以suffixText结尾,则说明suffix已经遭到破坏,或者是还没有suffixTextif (preText.isNotEmpty() && preText.endsWith(suffixText).not()) {// 如果lastText等于空,就说明还没有suffixTextif (lastText.isEmpty()) {lastText = preText.plus(suffixText)editText.setText(lastText)editText.setSelection(preText.length)} else {// 如果执行到该else,就说明suffixText已经被破坏了val suffixTextStartIndex = lastText.length - suffixText.length// 如果两个文本的长度不相等if (lastText.length != preText.length) {// 获取上次已输入的字符串val lastInputText = lastText.substring(0, suffixTextStartIndex)// 如果lastText的长度小于preText的长度,就说明已经suffixText里面输入了字符// 这个if-else就是用于获取实际输入的字符val latestInputText = if (lastText.length < preText.length) {// 获取输入的字符,并拼接到上次已输入的字符串末尾val inputChar = preText.substring(start, start + 1)lastInputText.plus(inputChar)} else {// 如果不大于,那就是小于,因为已经在上面判断了两个不相等// 如果小于,就是将suffixText中的某个字符删除掉// 上次如果只输入了一个字符,本次就将输入的字符设置为空字符串if (lastInputText.length == 1) {""} else {// 否则就删掉最后一个字符lastInputText.substring(0, lastInputText.length - 1)}}// 如果上面获取到的最新输入文本不为空,就在后面追加suffixText// 否则就将lastText设置为空字符串lastText = if (latestInputText.isNotEmpty()) {latestInputText.plus(suffixText)} else ""editText.setText(lastText)if (lastText.isNotEmpty()) {editText.setSelection(latestInputText.length)}} else {// 这个else一般执行不到,但为了防止出现考虑不到的问题,还是简单处理一下if (start in suffixTextStartIndex until lastText.length) {editText.setText(lastText)editText.setSelection(suffixTextStartIndex)}}}} else {// 执行到该else,就说明suffixText没有遭到破坏// 如果用户没有乱来,一般就是执行到这里,但也有例外// 从gif图片可以看到,如果在su中间输入s,也是没有问题的,因为此时endWith为true,但这种情况下,selectionIndex是不正确的// 此时selectionIndex是在su中间,而不是在ss中间,所以下面的的代码就是处理这个问题// 处理的方式也很简单,获取suffixText的长度,并判断start是否在suffixText的范围内// 如果是,就将index设置到suffixText前面if(preText.isNotEmpty()) {val suffixTextStartIndex = preText.length - suffixText.lengthif (start >= suffixTextStartIndex) {editText.setSelection(suffixTextStartIndex)}}lastText = preText}}editText.addTextChangedListener(this)}override fun afterTextChanged(s: Editable?) {}}

方案二

class SuffixEditText @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :AppCompatEditText(context, attrs) {// textWatcher用来补齐后缀private val textWatcher = SuffixTextWatcher(this)var suffixText = ""set(value) {val oldSuffix = fieldfield = valuetextWatcher.suffixText = valueupdateSuffixText(oldSuffix, value)}init {addTextChangedListener(textWatcher)if (suffixText.isNotEmpty()){textWatcher.suffixText = suffixText}}private fun updateSuffixText(oldSuffix: String, newSuffix: String) {val text = text ?: ""if (oldSuffix.isEmpty() || text.isEmpty()) {return}val oldSuffixIndex = text.lastIndexOf(oldSuffix)if (oldSuffixIndex != -1) {setText(text.substring(0, oldSuffixIndex))}}// 这里就是修改selectionIndext的代码,如果用户的touch行为导致selectionIndex发生变化// EditText就会调用这里获取index,所以只需重写该方法即可override fun getOffsetForPosition(x: Float, y: Float): Int {var superResult = super.getOffsetForPosition(x, y)val text = text ?: ""val suffixText = suffixTextif (text.isEmpty() || suffixText.isEmpty()) {return superResult}val textLength = text.length - suffixText.length// 如果index在suffixText的范围内,就设置为inputText的最大indexif (superResult >= textLength) {superResult = textLength}return superResult}override fun onTextContextMenuItem(id: Int): Boolean {// 如果不希望用户复制的内容包含suffix text,就可以重写该方法,并按照我上面提到的代码去做return super.onTextContextMenuItem(id)}private class SuffixTextWatcher(val editText: EditText) : TextWatcher {var suffixText: String = ""override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {val text = s?.toString() ?: ""if (text.isEmpty()) {return}editText.removeTextChangedListener(this)// 如果没有suffix text,就在最后追加suffix textif (text.endsWith(suffixText).not()) {if (text.isNotEmpty()) {editText.setText("$text$suffixText")editText.setSelection(text.length)}} else {if (text == suffixText) {editText.setText("")}}editText.addTextChangedListener(this)}override fun afterTextChanged(s: Editable?) {}}
}
http://www.hkea.cn/news/462424/

相关文章:

  • 兼容手机的网站百度怎么推广自己的视频
  • 宝安中心医院入职体检跟我学seo
  • 企业网站后端模板石家庄疫情最新情况
  • 沈阳哪家网站做的好网络营销是指什么
  • 我的网站模板网站建设主要推广方式
  • 国外app素材网站seo运营是做什么的
  • 企业网站seo怎么做百度帐号个人中心
  • 郑州网站建设亅汉狮网络百度网盘seo优化
  • 模板型网站seo优化平台
  • 官方网站下载免费软件培训机构有哪些?哪个比较好
  • 网站导航怎么做的惠州seo计费管理
  • 建设公司网站模板全国唯一一个没有疫情的城市
  • 网站怎么做seo_南京百度提升优化
  • 旅游网站开发与设计论文怎么样建网站
  • 北京网站推广排名公司企业网站的搜索引擎推广与优化
  • 动态网站期末设计广告营销策略
  • 山东网站营销推广费用旺道seo推广
  • 邢台网站建设服务周到百度数据分析工具
  • 周口网站建设竞价恶意点击犯法吗
  • 网站建设没有预付款seo快速提升排名
  • 网站开发者的设计构想网络推广平台软件
  • 做立体字的网站重庆seo公司排名
  • 电子商务网站的建设包含哪些流程搜索引擎关键词怎么优化
  • 将自己做的网站发布到谷歌推广新手教程
  • 深圳保障性住房管理办法seo排名优化方法
  • 2022注册公司取名推荐网络营销的优化和推广方式
  • 做网站费是多少贵州二级站seo整站优化排名
  • 做网站潍坊培训课程安排
  • python做网站需要什么seo学习论坛
  • 用手机怎样制作网站网络seo是什么