前言
可能很多朋友在做设计稿的时候经常会遇到这种问题:
好好的textView前面加了个标签...
这要是单行还好,直接一个drawable了事
但是多行...我可以自定义一个ShapeDrawable,实现drawableLeft,但是有个问题,如果是这样的话,drawable是会随字体居中的,那显示效果就很怪异了!
思路
通过html
最简单的方法肯定是通过html,不用计算什么start,end,而且现成就有的样式都可以 拿来用。
html样式代码如下:
<font color="white" style="background:red;border-radius: 6px;font-size: 18px">I love android font>
然而...并不支持,貌似是textView不支持这个border-radius属性...而我贫乏的html知识也只能记得这个属性了。好吧,这条路gg。
通过span
这个是最靠谱的解决方法了吧,其实span可以帮我们解决几乎所有关于textview的问题,可是貌似很多人(包括我)都不了解她。
具体可以了解下
https://blog.csdn.net/qq_16430735/article/details/50427978
代码实现:
自定义TextView
自定义了TextView 在其内部进行处理,免得每次都是一套function方法复制来复制去:
package com.example.ly.testdrawable;import android.content.Context;import android.graphics.Bitmap;import android.graphics.drawable.BitmapDrawable;import android.graphics.drawable.Drawable;import android.text.Spannable;import android.text.SpannableString;import android.text.style.ImageSpan;import android.util.AttributeSet;import android.util.Log;import android.view.Gravity;import android.view.LayoutInflater;import android.view.View;import android.widget.TextView;import java.util.List;public class TagTextView extends android.support.v7.widget.AppCompatTextView { private StringBuffer content_buffer; private TextView tv_tag; private View view;//标签布局的最外层布局 private Context mContext;//必须重写所有的构造器,否则可能会出现无法inflate布局的错误! public TagTextView(Context context) { super(context); mContext = context; } public TagTextView(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; } public TagTextView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mContext = context; } public void setContentAndTag(String content, List tags) { content_buffer = new StringBuffer(); for (String item : tags) {//将每个tag的内容添加到content后边,之后将用drawable替代这些tag所占的位置 content_buffer.append(item); } content_buffer.append(content); SpannableString spannableString = new SpannableString(content_buffer); for (int i = 0; i < tags.size(); i++) { String item = tags.get(i); View view = LayoutInflater.from(mContext).inflate(R.layout.tag, null);//R.layout.tag是每个标签的布局 tv_tag = view.findViewById(R.id.tv_tag); tv_tag.setText(item); Bitmap bitmap = convertViewToBitmap(view); Drawable d = new BitmapDrawable(bitmap); d.setBounds(0, 0, tv_tag.getWidth(), tv_tag.getHeight());//缺少这句的话,不会报错,但是图片不回显示 ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BOTTOM);//图片将对齐底部边线 int startIndex; int endIndex; startIndex = getLastLength(tags, i ); endIndex = startIndex + item.length(); Log.e("tag", "the start is" + startIndex + "the end is" + endIndex); spannableString.setSpan(span, startIndex, endIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } setText(spannableString); setGravity(Gravity.CENTER_VERTICAL); } private static Bitmap convertViewToBitmap(View view) { view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)); view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight()); view.buildDrawingCache(); Bitmap bitmap = view.getDrawingCache(); return bitmap; } private int getLastLength(List list, int maxLength) { int length = 0; for (int i = 0; i < maxLength; i++) { length += list.get(i).length(); } return length; }}
自定义一个标准的tag布局:
面向xml编程,后期需要修改drawable样式等可以通过这个xml做文章。
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/tv_tag" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginBottom="2dp" android:layout_marginRight="5dp" android:background="@drawable/bg_blue_20" android:gravity="center_vertical" android:paddingBottom="2dp" android:paddingLeft="3dp" android:paddingRight="3dp" android:text="标签" android:textColor="@android:color/white" android:textSize="12sp"/>LinearLayout>
具体使用(xml)
<?xml version="1.0" encoding="utf-8"?><android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.ly.testdrawable.MainActivity"> <com.example.ly.testdrawable.TagTextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent"/>android.support.constraint.ConstraintLayout>
具体使用(java)
package com.example.ly.testdrawable;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.drawable.Drawable;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.text.Html;import android.text.SpannableStringBuilder;import android.text.Spanned;import android.widget.TextView;import java.util.ArrayList;import java.util.List;public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TagTextView textView = findViewById(R.id.text); List<String> tags = new ArrayList<>(); tags.add("置顶"); tags.add("置顶1"); tags.add("置顶2"); textView.setContentAndTag("凌宇是个大帅逼", tags); }}
效果如下
到这里就结束啦.
往期精彩回顾:Android仿FaceBook登录动画效果
Android 仿京东、拼多多商品分类页
Android仿魅族应用商店下载进度控件
Android仿QQ个性标签功能
Android仿小红书启动页平行动画