In fact, I was disgusted with this demand at the beginning, because there was no such example in the market (at that time compared with hornet’s nest, Flying Pig, Meituan, they did not adopt this way)? The tag will be placed on a separate line, not concatenated to the end of the TextView. But similar requirements have been implemented before (seeAndroid adds a View to the TextView), I don’t worry too much, just start to do, anyway, it doesn’t take much time. The effect is as follows:Multi-line effect:Let’s talk about the idea first. The title of the scenic spot is a TextView, and the label spelled behind is also a TextView. These two TextViews are arranged in a frameLayout. The key point of the problem is the position of the tag behind, that is, by correctly setting the upper, left, right and bottom margin of the tag TextView, it can be splicing behind the text. See the code for concrete implementation:
import android.content.Context; import android.graphics.Color; import android.text.Layout; import android.util.AttributeSet; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.widget.FrameLayout; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; @author ly * date 2020/3/9 10:22 */ public class AppendViewAfterTextView extends FrameLayout implements ViewTreeObserver.OnGlobalLayoutListener { private BoldTextView tv; private TextView tvSpecial; private String text; private FrameLayout.LayoutParams paramsSpecial; private int space; public AppendViewAfterTextView(@NonNull Context context) { super(context); init(); } public AppendViewAfterTextView(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(); } public AppendViewAfterTextView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { space = PixelUtil.dp2px(5); tv = new BoldTextView(getContext()); tv.setTextSize(21); TV. SetLineSpacing (1.2 1.0 f, f); tv.setIncludeFontPadding(false); setTextColor(ContextCompat.getColor(getContext(), R.color.black_text1)); tvSpecial = new TextView(getContext()); tvSpecial.setBackgroundResource(R.drawable.scenic_level_shape); tvSpecial.setTextSize(12); tvSpecial.setSingleLine(); tvSpecial.setTextColor(Color.WHITE); paramsSpecial = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); tvSpecial.setLayoutParams(paramsSpecial); addView(tv, new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); addView(tvSpecial); } @override public void onGlobalLayout() {textView.getLayout ()! SetMoreViewPosition (); / / remember to remove, or you will have been callback TV. GetViewTreeObserver () removeOnGlobalLayoutListener (this); } private void setMoreViewPosition() { Layout layout = tv.getLayout(); if (layout == null) return; int lineCount = layout.getLineCount(); float lineWidth = layout.getLineWidth(lineCount - 1); Int lineEnd = layout.getLineEnd(linecount-1); int lineEnd = layout.getLineEnd(linecount-1); if (lineWidth + tvSpecial.getMeasuredWidth() + space - (getWidth() - getPaddingRight() - getPaddingLeft()) > 0) If (text.length() > 2) {// Add two characters to the tvSpecial line, Text = text.subsequence (0, text.length() -2) + "\n" + text.subsequence (text.length() -2, text.length()); setText(text); return; // int lineH = layout.getLineBottom(Linecount-1) -layout.getLineTop (Linecount-1); int lineH = layout.getHeight() / layout.getLineCount(); int lastLineRight = (int) layout.getSecondaryHorizontal(lineEnd); paramsSpecial.leftMargin = lastLineRight + space; // Align the middle of tvSpecial with the middle of the last line of TV paramsSpecial.topmargin = layout.getheight () -tv. getPaddingBottom() -lineh / 2 - tvSpecial.getHeight() / 2; tvSpecial.setLayoutParams(paramsSpecial); } public void setText(final String text) { this.text = text; tv.setText(this.text); tv.getViewTreeObserver().addOnGlobalLayoutListener(this); } public void setSpecialViewText(String text) { tvSpecial.setText(text); } public void setTextColor(int color) { tv.setTextColor(color); }}Copy the code
The key of the above code is to get the leftMargin by getting the x-coordinate of the last character of the text TextView and to get the topMargin by the height difference. GetSecondaryHorizontal: getSecondaryHorizontal: getSecondaryHorizontal: getSecondaryHorizontal: getSecondaryHorizontal: getSecondaryHorizontal: getSecondaryHorizontal: getSecondaryHorizontal: getSecondaryHorizontal: getSecondaryHorizontal Exposed externally by setText and setSpecialViewText, you can set the text for each. Through this way can also expand the long text view more and fold up to now see this demand, in fact, also quite good, not so disgusting, is a small wheel.
// Give it a thumbs up before you leave