Android-使用StaticLayout实现icon跟随TextView末尾效果

Android-使用StaticLayout实现icon跟随TextView末尾效果

👉关于作者

已经工作三年的95后程序员,坐标上海。平时在公司写Android原生App,业余时间会抽空学习Java后端,目标是成为全栈工程师,志同道合的可以私我聊聊haha。加入CSDN快4年了,看了很多优秀作者的博客收获很多。后面的时间里,我也会整理一些工作中使用到的知识分享出来。我的座右铭:人生在勤,不索何获。大家一起努力加油吧

👉正文部分

1、StaticLayout基本使用

通过drawText方法绘制出的文字超过一行后不会自动换行,StaticLayout可以对文字进行换行;TextView也用了StaticLayout

1、使用
@Override
protected void onDraw(Canvas canvas) {
  TextPaint tp = new TextPaint();
  //Paint设置字体大小的单位时像素,要将dp转为px设置
  tp.setTextSize(UiUtils.dip2px(mContext,20));
  tp.setColor(Color.parseColor("#111111"));
  tp.setFakeBoldText(true);
  tp.setAntiAlias(true);
  tp.setStyle(Paint.Style.FILL);
  String text = "在Android开发中,Canvas.drawText不会换行,即使一个很长的字符串也只会显示一行,超出部分会隐藏在屏幕之外.StaticLayout是android中处理文字的一个工具类,StaticLayout 处理了文字换行的问题";
  //执行该方法后绘制出的文本不会进行换行
  //        canvas.drawText(text,0,UiUtils.dip2px(mContext,200),tp);
  StaticLayout staticLayout = new StaticLayout(text, tp, canvas.getWidth(), Layout.Alignment.ALIGN_NORMAL, 1f, 0f, false);
  staticLayout.draw(canvas);
}
2、构造器
public StaticLayout(CharSequence source, TextPaint paint, int outerwidth,Alignment align,float spacingmult, float spacingadd,boolean includepad){
}
  • source:文本
  • paint:画笔
  • outerWidth:一行的宽度
  • align:文本对齐方式
  • spacingmult:行间距
  • spacingadd:在行间距的基础上增加的值
  • includepad:略,设置false

2、使用StaticLayout实现icon跟随TextView末尾效果

在RelativeLayout中有一个TextView和ImageView,TextView会动态改变其内容,ImageView要始终跟着TextView的末尾处

1、效果图

在这里插入图片描述

2、XML代码
<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="20dp">

    <TextView
        android:id="@+id/tv"
        style="@style/style_title_light_black_size_14"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/follow_textview_demo"/>

    <ImageView
        android:id="@+id/iv"
        android:layout_width="16dp"
        android:layout_height="16dp"
        android:src="@drawable/question_gray_icon"/>

</RelativeLayout>
3、实现思路
1、如何获取TextView每一行文本的最右边位置

当TextView换行了,我们得知道TextView最底部的那一行的文本写到什么位置,这样ImageView可以跟着这个位置去显示。答案是用StaticLayout去获取,代码如下

//先要按照TextView的Style生成一个Paint
TextPaint tp = new TextPaint();
tp.setStyle(Paint.Style.FILL);
tp.setTextSize(UiUtils.dip2px(FollowTextViewDemoActivity.this,14));
tp.setColor(Color.parseColor("#111111"));
tp.setAntiAlias(true);

StaticLayout sl = new StaticLayout(tv.getText(), tp, tv.getWidth(), Layout.Alignment.ALIGN_NORMAL, 1f, 0f, false);
int lineBottom = sl.getLineBottom(sl.getLineCount() - 1);
float lineRight = sl.getLineRight(sl.getLineCount() - 1);
2、ImageView跟在TextView末尾会跑出屏幕外

ImageView跟在TextView末尾有两种情况:ImageView跟在TextView后面可以显示出来;ImageView跟在TextView后面不会显示出来。第一种,也就是TextView的文本没有占满屏幕宽度,ImageView可以在文本的末尾显示出来;第二种,TextView的文本几乎占满屏幕宽度,ImageView在文本后面显示,就跑出屏幕外了。第二种情况我们就要对TextView进行重新setText,将目前的文本以最后一个字符为分割线,中间加入换行符,这样原本会占满屏幕的TextView会重新换一行,此时ImageView再跟在后面就不会跑出屏幕了

StaticLayout sl;
TextPaint tp = new TextPaint();
tp.setStyle(Paint.Style.FILL);
tp.setTextSize(UiUtils.dip2px(FollowTextViewDemoActivity.this,14));
tp.setColor(Color.parseColor("#111111"));
tp.setAntiAlias(true);

tv.post(new Runnable() {
  @Override
  public void run() {
    sl = new StaticLayout(tv.getText(), tp, tv.getWidth(), Layout.Alignment.ALIGN_NORMAL, 1f, 0f, false);
    float lineRight = sl.getLineRight(sl.getLineCount() - 1);
    //如果TextView最后一行文本的最右边+ImageView的marginLeft+ImageView的大小超出了屏幕宽度
    if ((int)lineRight + UiUtils.dip2px(FollowTextViewDemoActivity.this,6)+ UiUtils.dip2px(FollowTextViewDemoActivity.this,16) > tv.getWidth()){
      //将现有文本的最后一个字符前加入换行符,以使TextView最后一行再换一行出来,就解决上面ImageView超出屏幕宽度的问题
      String text = tv.getText().toString();
      String substring1 = text.substring(0, text.length() - 1);
      String substring2 = text.substring(text.length() - 1);
      text = String.format("%s\n%s",substring1,substring2);
      tv.setText(text);
      tv.post(new Runnable() {
        @Override
        public void run() {
          //ImageView位置:底部和TextView底部同一位置,左边=TextView的最后一行文本的右边+ImageView的marginLeft
          sl = new StaticLayout(tv.getText(), tp, tv.getWidth(), Layout.Alignment.ALIGN_NORMAL, 1f, 0f, false);
          float lineRight = sl.getLineRight(sl.getLineCount() - 1);
          RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) iv.getLayoutParams();
          lp.topMargin = tv.getHeight() - lp.height;
          lp.leftMargin = (int)lineRight + UiUtils.dip2px(FollowTextViewDemoActivity.this,6);
          Log.e("FollowTextViewDemo","topMargin:"+lp.topMargin+",leftMargin:"+lp.leftMargin);
          iv.setLayoutParams(lp);
        }
      });
    }else {
      //ImageView位置:底部和TextView底部同一位置,左边=TextView的最后一行文本的右边+ImageView的marginLeft
      RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) iv.getLayoutParams();
      lp.topMargin = tv.getHeight() - lp.height;
      lp.leftMargin = (int)lineRight + UiUtils.dip2px(FollowTextViewDemoActivity.this,6);
      Log.e("FollowTextViewDemo","topMargin:"+lp.topMargin+",leftMargin:"+lp.leftMargin);
      iv.setLayoutParams(lp);
    }
  }
});
参考文章

StaticLayout的使用详解

android TextView文字换行内容末尾跟图标或其他View的实现

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
使用 Spannable 实现 TextView 的颜色渐变效果,你可以使用 ForegroundColorSpan 类来设置不同部分的字体颜色,并根据需要调整它们的位置和颜色值。 以下是一个示例代码,演示如何使用 Spannable 实现颜色渐变效果: ```java TextView textView = findViewById(R.id.textView); String text = "Hello World!"; Spannable spannable = new SpannableString(text); // 定义渐变色数组 int[] colors = {Color.RED, Color.GREEN, Color.BLUE}; // 定义颜色变化位置数组 float[] positions = {0f, 0.5f, 1f}; for (int i = 0; i < text.length(); i++) { // 计算当前字符的颜色 int color = interpolateColor(colors, positions, (float) i / (text.length() - 1)); // 创建 ForegroundColorSpan,并设置字体颜色 ForegroundColorSpan span = new ForegroundColorSpan(color); // 设置 span 的起始位置和结束位置 spannable.setSpan(span, i, i + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } // 将 spannable 设置给 TextView textView.setText(spannable); ``` 在这个示例中,我们首先创建了一个 SpannableString 对象,并将其初始化为需要处理的文本。然后,我们使用一个循环遍历文本中的每个字符,计算出当前字符的颜色值,然后创建一个 ForegroundColorSpan 对象,并将其应用到对应的字符上。最后,我们将处理后的 SpannableString 设置给 TextView。 在 interpolateColor 方法中,我们使用了一个插值算法来计算颜色的渐变值。你可以根据需要自定义这个方法,实现不同的颜色渐变效果。 这样,TextView 的文本就会呈现出颜色渐变的效果。你可以根据实际需求和喜好,调整渐变色数组、颜色变化位置数组以及插值算法来实现不同的颜色渐变效果

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值