Mus. 2023-07-21 20:49 采纳率: 0%
浏览 6

SpannableString在键盘变化时会失效

给编辑框加SpannableString之后图片是正常显示的,但再点一下编辑框,键盘弹上来之后SpannableString就失效了变成正常的文本了,这是什么情况啊

  • 写回答

2条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-07-21 22:10
    关注
    • 你可以看下这个问题的回答https://ask.csdn.net/questions/7638881
    • 你也可以参考下这篇文章:SpannableString文本和图片一起显示
    • 你还可以看下android参考手册中的 android SpannableStringBuilder 这是一个文本类,其内容和标记都可以被改变。
    • 除此之外, 这篇博客: Android SpannableString的使用中的 SpannableString基本用法 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:

    • SpannableString用于为TextView组件的文本内容设置样式,相当于文本内容的CSS。常用于TextView与EditText。使用方式如下:

      //待显示文本
      String str = "零一二三四五六七八九十";
      //创建SpannableString对象
      SpannableString spannableStr = new SpannableString(str);
      //创建样式对象
      ForegroundColorSpan fcs = new ForegroundColorSpan(Color.RED);
      //绑定样式
      spannableStr.setSpan(fcs, 1, 5, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
      //显示
      mEditText1.setText(spannableStr);

      Android为了SpannableString设计了多种样式,常见的有文本颜色、字体样式(粗体,斜体)、删除线、下划线、链接效果等等。下面有对其详细介绍。
      这里主要说一下setSpan方法,setSpan(Object what, int start, int end, int flags)方法需要传递四个对象,what表示样式,start表示格式字符串起始下标,end表示格式字符串终了下标,flags用于控制字符长度变化时改变字符的显示样式。flags常用属性包括以下四种:

      • Spanned.SPAN_INCLUSIVE_EXCLUSIVE
        从start位置插入字符时应用样式,从end位置插入字符时不应用样式。
      • Spanned.SPAN_INCLUSIVE_INCLUSIVE
        从start位置以及end位置插入字符时都会应用样式。
      • Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
        从start位置以及end位置插入字符都不会应用样式。
      • Spanned.SPAN_EXCLUSIVE_INCLUSIVE
        从start位置插入字符时不会应用样式,从end位置插入字符时会应用样式。

      flags不太容易理解,建议写个demo使用EditText亲自体验一下:

      mEditText1 = (EditText) findViewById(R.id.editText1);
      mEditText2 = (EditText) findViewById(R.id.editText2);
      mEditText3 = (EditText) findViewById(R.id.editText3);
      mEditText4 = (EditText) findViewById(R.id.editText4);
      
      String str = "零一二三四五六七八九十";
      
      SpannableString ss1 = new SpannableString(str);
      SpannableString ss2 = new SpannableString(str);
      SpannableString ss3 = new SpannableString(str);
      SpannableString ss4 = new SpannableString(str);
      
      ForegroundColorSpan fcs = new ForegroundColorSpan(Color.RED);
      
      ss1.setSpan(fcs, 1, 5, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
      ss2.setSpan(fcs, 1, 5, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
      ss3.setSpan(fcs, 1, 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
      ss4.setSpan(fcs, 1, 5, Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
      
      mEditText1.setText(ss1);
      mEditText2.setText(ss2);
      mEditText3.setText(ss3);
      mEditText4.setText(ss4);
    • 以下回答由chatgpt基于相关博客总结生成:

      根据问题描述,当再次点击编辑框,键盘弹出后,SpannableString就会失效,文本会变成正常文本。这可能是因为键盘弹出后,编辑框重新绘制,而重新绘制会导致之前设置的SpannableString失效。可以尝试在编辑框重新绘制时重新应用SpannableString来解决这个问题。

      具体解决方法如下:

      1. 创建一个自定义的EditText,命名为CustomEditText。
      public class CustomEditText extends EditText {
      
          public CustomEditText(Context context) {
              super(context);
              init();
          }
      
          public CustomEditText(Context context, AttributeSet attrs) {
              super(context, attrs);
              init();
          }
      
          public CustomEditText(Context context, AttributeSet attrs, int defStyleAttr) {
              super(context, attrs, defStyleAttr);
              init();
          }
      
          private void init() {
              // 添加EditText的文本改变监听器
              addTextChangedListener(new TextWatcher() {
                  @Override
                  public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                      // 在文本改变之前,暂停SpannableString的设置
                      clearSpans();
                  }
      
                  @Override
                  public void onTextChanged(CharSequence s, int start, int before, int count) {
                      // 文本改变时,重新应用SpannableString
                      applySpannableString();
                  }
      
                  @Override
                  public void afterTextChanged(Editable s) {
                      // 文本改变之后,重新恢复SpannableString的设置
                      applySpans();
                  }
              });
          }
      
          // 重新应用SpannableString
          private void applySpannableString() {
              // 获取之前设置过的SpannableString
              SpannableString spannableString = getSpannableString();
      
              if (spannableString != null) {
                  int start = getSelectionStart();
                  int end = getSelectionEnd();
                  spannableString.setSpan(new ForegroundColorSpan(Color.RED), start, end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
                  setText(spannableString);
                  setSelection(start, end);
              }
          }
      
          // 清除之前设置过的所有Span
          private void clearSpans() {
              SpannableString spannableString = getSpannableString();
      
              if (spannableString != null) {
                  ForegroundColorSpan[] spans = spannableString.getSpans(0, spannableString.length(), ForegroundColorSpan.class);
                  for (ForegroundColorSpan span : spans) {
                      spannableString.removeSpan(span);
                  }
              }
          }
      
          // 将之前设置过的所有Span重新应用到EditText上
          private void applySpans() {
              SpannableString spannableString = getSpannableString();
      
              if (spannableString != null) {
                  ForegroundColorSpan[] spans = spannableString.getSpans(0, spannableString.length(), ForegroundColorSpan.class);
                  for (ForegroundColorSpan span : spans) {
                      spannableString.setSpan(span, 0, spannableString.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
                  }
              }
          }
      
          // 获取之前设置过的SpannableString
          private SpannableString getSpannableString() {
              CharSequence text = getText();
      
              if (text instanceof SpannableString) {
                  return (SpannableString) text;
              }
      
              return null;
          }
      }
      
      1. 在布局文件中使用自定义的EditText,替换原有的EditText。
      <com.example.CustomEditText
          android:id="@+id/editText"
          android:layout_width="match_parent"
          android:layout_height="wrap_content" />
      

      通过重写EditText的相关方法,我们可以在每次文本改变时重新应用之前设置过的SpannableString,从而解决键盘弹出后失效的问题。注意,在应用SpannableString时需要保留之前的光标位置,以保证用户的编辑体验。

      希望这个解决方案对你有帮助。如果还有其他问题,请随时提问。

    评论

报告相同问题?

问题事件

  • 创建了问题 7月21日

悬赏问题

  • ¥15 如何使用python 实现对串口/dev/ttyUSB0进行上锁,使得该串口只能在一个python脚本中使用,其他脚本不能操作这个串口
  • ¥15 晶体塑性有限元——Damask求解
  • ¥15 写出这个有没有人能写一下今天中午就要
  • ¥30 设计一个图形用户界面来控制你机械臂的运动
  • ¥30 3d打印机无法识别到SD卡,如何解决?(相关搜索:格式化)
  • ¥15 RPG游戏架构设计和开发方法
  • ¥15 前端返回pdf时不显示内容
  • ¥50 如何在不能联网影子模式下的电脑解决usb锁
  • ¥20 服务器redhat5.8网络问题
  • ¥15 如何利用c++ MFC绘制复杂网络多层图