实现效果如下:
如上,将头像后面的东西看作一个整体,因为不能影响后面内容的换行,且前面控件的长度是可变的,所以采用自定义View的方法来实现:
/**
* CSDN深海呐 https://blog.csdn.net/qq_40945489/article/details/109399596
*/
public class TagTextView extends AppCompatTextView {
private Context mContext;
private TextView mTabText;
private StringBuffer mContentStringBuffer;
//必须重写所有的构造器,否则可能会出现无法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 dataList, List typeList) {
mContentStringBuffer = new StringBuffer();
for (String item : dataList) {//将内容添加到content,用drawable替代这些内容所占的位置
mContentStringBuffer.append(item);
}
mContentStringBuffer.append(content);
SpannableString spannableString = new SpannableString(mContentStringBuffer);
for (int i = 0; i < dataList.size(); i++) {
String item = dataList.get(i);
View view = LayoutInflater.from(mContext).inflate(R.layout.layout_texttab, null);//R.layout.tag是每个标签的布局
switch (typeList.get(i)){
case 1:
view = LayoutInflater.from(mContext).inflate(R.layout.layout_texttab1, null);
break;
case 2:
view = LayoutInflater.from(mContext).inflate(R.layout.layout_texttab2, null);
break;
}
mTabText = view.findViewById(R.id.tabText);
mTabText.setText(item);
Bitmap bitmap = convertViewToBitmap(view);
Drawable d = new BitmapDrawable(bitmap);
d.setBounds(0, 0, mTabText.getWidth(), mTabText.getHeight());
ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BOTTOM);//图片对齐底部
int startIndex;
int endIndex;
startIndex = getLastLength(dataList, i );
endIndex = startIndex + item.length();
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;
}
}
使用举例: (抱歉啊使用这边没有用Java写,不会Kotlin的应该也能看懂啥意思)
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initView();
}
private fun initView() {
setText("很长很长的一段话一段话一段话 真的很长很长很长......")
}
private fun setText(string: String) {
val title : TagTextView = findViewById(R.id.main_text)
val dataList = arrayListOf()
dataList.add("用户的名字")
dataList.add("48")
dataList.add(" 长老")
val dataListType = arrayListOf()
dataListType.add(0);
dataListType.add(1);
dataListType.add(2);
title.setContentAndTag(""+string+"", dataList,dataListType)
}
}
activity_main.xml:
la:
dataListType的 0,1,2 分别对应三种不同的布局赋值,XML文件我就不全部发出来了,这里可以自主发挥。