Android TextView单行带着图标,末尾省略号,图标可点击。

前言

        最近开发需求,就是名称后面加一个查看按钮。显示条件是文字只允许一行,超出部分显示省略号,并且右边紧挨着一个图标。点击条件是只有图标可以点击。先看效果图。


一、效果图

效果1:

效果2:


二、踩坑

        因为想着条件是图标要单独点击,第一想到的就是使用ImageView实现。


踩坑1:

        一开始,采用的方案是TextView+ImageView的方式,如下:

<LinearLayout 
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/tv_resume_details_list_header"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:maxLines="1"
        android:ellipsize="end"
        tools:text="xxxxxxxxxxx" />

        <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="xxx"
        />

</LinearLayout>

 效果:文字超出一行时却是出现省略号,但就会把图标挤出屏幕外。

 结果: 看不见图标了。 失败!


踩坑2:

             我使用 weight 权重方式,这样就能保证文字超出一行时,能让图标留在屏幕内。

<LinearLayout 
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/tv_resume_details_list_header"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:maxLines="1"

                android:layout_weight="1"

        android:ellipsize="end"
        tools:text="xxxxxxxxxxx" />

        <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="xxx"
        />

</LinearLayout>

效果:文字超出一行显示省略号,图标也存在。  ✅  文字不足一行,图标不跟随文字。❌

结果:失败! 图标位置固定在最后面了。


踩坑3:

       同事建议使用约束布局-ConstraintLayout-实现 。一顿代码撸起来。。。。。

结果:图标要么依然挤出屏幕,要么固定在右边。


此时 陷入沉思。。。。


三、解决方案

        我突然想到,使用TextView会经常使用到android:drawableLeft="@drawable/ic_launcher"这些类似的属性。

        试了一下,果然好使!效果杠杠的!✅

        但是,结合需求的实际情况:1、动态显示图标;2、图标可点击。 

1、动态显示图标

而面对这些情况下,第一步就是需要动态在代码中设置文本周围的图标。

setCompoundDrawables(left, top, right, bottom);setCompoundDrawablesWithIntrinsicBounds(left, top, right, bottom);


  setCompoundDrawables 画的drawable的宽高是按drawable.setBound()设置的宽高,使用之前必须使用Drawable.setBounds设置Drawable的长宽。

Drawable drawable= getResources().getDrawable(R.drawable.xxx);  

drawable.setBounds(0, 0, 20, 20);  

txtView.setCompoundDrawables(drawable,null,null,null);  

  setCompoundDrawablesWithIntrinsicBounds画的drawable的宽高是按drawable固定的宽高。

public void setCompoundDrawablesWithIntrinsicBounds (Drawable left,  
Drawable top, Drawable right, Drawable bottom) 

  一般,建议使用setCompoundDrawablesWithIntrinsicBounds,这样你即无需设置Drawables的bounds了。

2、图标可点击。

 textview.getCompoundDrawables() 获取是一个drawable 数组。即上面设置的图标数组,而索引0,1,2,3,对应着左,上,右,下 这4个位置的图标,如果没有就为null。

判断点击的是图标:

获取点击的X坐标值,比(TextView最右边界减去drwable边界宽度)大就可以判断点击在Drawable上。

比如,textview 宽度 =100;drawble宽度 = 20;    点击在80 -100 之间即可。

 mCompanyName.setOnTouchListener((v, event) -> {
              
                Drawable rightDrawable=mCompanyName.getCompoundDrawables()[2];
               
                if(rightDrawable!=null&&event.getRawX()>=(mCompanyName.getRight()-rightDrawable.getBounds().width())){
                    ToastUtils.showShort("ok");
                }
                return false;
            });

四、解决案例代码

         

      <TextView
                android:id="@+id/tv_resume_details_experience_company_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:ellipsize="end"
                android:maxLines="1"
                android:textColor="#05081A"
                android:textSize="16dp"
                android:textStyle="bold"
                tools:text="北京新知百略科技有限公司北京新知百北京新知百略科技有限公司北京新知百" />
if (!companyNo.isEmpty()){
   mCompanyName.setCompoundDrawablesWithIntrinsicBounds(null, null, mContext.getResources().getDrawable(R.drawable.xxx), null);
   mCompanyName.setOnTouchListener((v, event) -> {
          Drawable rightDrawable= holder.mCompanyName.getCompoundDrawables()[2];
          if(rightDrawable!=null&&event.getRawX()>=( holder.mCompanyName.getRight()-rightDrawable.getBounds().width())){                             
            //点击成功
           }
           return false;
    });
}else{
     holder.mCompanyName.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
 }

五、补充 SpannableString 

/**
 * 初始化举报区域显示
 */
private void initReportZone() {
    String tip = "[icon] 提醒:以担保或任何理由索取财物,抵押证照,均涉嫌违法,请提高警惕!   点击举报 [arrow]";
    SpannableString spannable = new SpannableString(tip);
    //waring 图标
    Drawable warningDrawable = CommonUtils.getContext().getResources().getDrawable(R.drawable.icon_position_warning);
    warningDrawable.setBounds(0, 0, warningDrawable.getIntrinsicWidth(), warningDrawable.getIntrinsicHeight());
    CenterAlignImageSpan warningSpan = new CenterAlignImageSpan(warningDrawable, ImageSpan.ALIGN_BASELINE);
    int warningStartIndex = tip.indexOf("[icon]");
    spannable.setSpan(warningSpan, warningStartIndex, warningStartIndex + "[icon]".length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

    //粗体
    int boldStartIndex = tip.indexOf("提醒:");
    int boldEndIndex = boldStartIndex + "提醒:".length();
    spannable.setSpan(new ForegroundColorSpan(CommonUtils.getContext().getResources().getColor(R.color.color_282b2d)), boldStartIndex, boldEndIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    spannable.setSpan(new AbsoluteSizeSpan(12, true), boldStartIndex, boldEndIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    spannable.setSpan(new StyleSpan(Typeface.BOLD), boldStartIndex, boldEndIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

    //点击区域
    spannable.setSpan(new ClickableSpan() {
        @Override
        public void updateDrawState(TextPaint ds) {
            super.updateDrawState(ds);
            ds.setColor(0XFF626970);
            ds.setUnderlineText(false);
        }

        @Override
        public void onClick(@NonNull View widget) {
            reportPosition();
        }
    }, tip.indexOf("点击举报"), tip.indexOf("点击举报") + "点击举报".length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

    //最末端的箭头icon
    Drawable drawableArrowRight = ContextCompat.getDrawable(CommonUtils.getContext(), (R.drawable.position_detail_arrow_right));
    drawableArrowRight.setBounds(0, 0, drawableArrowRight.getIntrinsicWidth(), drawableArrowRight.getIntrinsicHeight());
    CenterAlignImageSpan arrowRightSpan = new CenterAlignImageSpan(drawableArrowRight, ImageSpan.ALIGN_BASELINE);
    spannable.setSpan(arrowRightSpan, tip.indexOf("[arrow]"), tip.indexOf("[arrow]") + "[arrow]".length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
    tv_report.setText(spannable);
    tv_report.setMovementMethod(LinkMovementMethod.getInstance());
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

艾阳Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值