Android 在TextView前面添加多个任意View且不影响换行

实现效果如下:


如上,将头像后面的东西看作一个整体,因为不能影响后面内容的换行,且前面控件的长度是可变的,所以采用自定义View的方法来实现:

java 复制代码
/**
 *  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<String> dataList, List<Integer> 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<String> list, int maxLength) {
      int length = 0;
      for (int i = 0; i < maxLength; i++) {
         length += list.get(i).length();
      }
      return length;
   }
}

使用举例: (😂抱歉啊使用这边没有用Java写,不会Kotlin的应该也能看懂啥意思)

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<String>()
        dataList.add("用户的名字")
        dataList.add("48")
        dataList.add("  长老")
        val dataListType = arrayListOf<Int>()
        dataListType.add(0);
        dataListType.add(1);
        dataListType.add(2);
        title.setContentAndTag(""+string+"", dataList,dataListType)

    }
}

activity_main.xml:

html 复制代码
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

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

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/head" />

        <com.example.demo.TagTextView
            android:id="@+id/main_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="当前是用户发的一段话很长很长的一段话,非常长非常长!!!!!!"
            android:textColor="@color/TextColor"
            android:textSize="12sp" />

    </LinearLayout>

</LinearLayout>

la:

html 复制代码
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tabText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:drawablePadding="6dp"
        android:drawableRight="@mipmap/sex"
        android:gravity="center"
        android:paddingRight="8dp"
        android:text="CSDN深海呐"
        android:textColor="@color/HeadText"
        android:textSize="12sp" />

</LinearLayout>

dataListType的 0,1,2 分别对应三种不同的布局赋值,XML文件我就不全部发出来了,这里可以自主发挥。

相关推荐
找藉口是失败者的习惯26 分钟前
从传统到未来:Android XML布局 与 Jetpack Compose的全面对比
android·xml
Jinkey2 小时前
FlutterBasic - GetBuilder、Obx、GetX<Controller>、GetxController 有啥区别
android·flutter·ios
大白要努力!3 小时前
Android opencv使用Core.hconcat 进行图像拼接
android·opencv
天空中的野鸟4 小时前
Android音频采集
android·音视频
小白也想学C5 小时前
Android 功耗分析(底层篇)
android·功耗
曙曙学编程5 小时前
初级数据结构——树
android·java·数据结构
闲暇部落8 小时前
‌Kotlin中的?.和!!主要区别
android·开发语言·kotlin
诸神黄昏EX10 小时前
Android 分区相关介绍
android
大白要努力!11 小时前
android 使用SQLiteOpenHelper 如何优化数据库的性能
android·数据库·oracle
Estar.Lee11 小时前
时间操作[取当前北京时间]免费API接口教程
android·网络·后端·网络协议·tcp/ip