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文件我就不全部发出来了,这里可以自主发挥。

相关推荐
Kotlin上海用户组31 分钟前
Koin vs. Hilt——最流行的 Android DI 框架全方位对比
android·架构·kotlin
zzq19961 小时前
Android framework 开发者模式下,如何修改动画过度模式
android
木叶丸1 小时前
Flutter 生命周期完全指南
android·flutter·ios
阿幸软件杂货间1 小时前
阿幸课堂随机点名
android·开发语言·javascript
没有了遇见1 小时前
Android 渐变色整理之功能实现<二>文字,背景,边框,进度条等
android
没有了遇见2 小时前
Android RecycleView 条目进入和滑出屏幕的渐变阴影效果
android
站在巨人肩膀上的码农3 小时前
去掉长按遥控器power键后提示关机、飞行模式的弹窗
android·安卓·rk·关机弹窗·power键·长按·飞行模式弹窗
呼啦啦--隔壁老王3 小时前
屏幕旋转流程
android
人生何处不修行3 小时前
实战:Android 15 (API 35) 适配 & 构建踩坑全记录
android
用户2018792831674 小时前
gralde的《依赖契约法典》
android