Android中自定义Textview解决文字和数字换行不整齐

效果图:

上面的是原生Textview,第一行末尾数字整体换行了,

下面是自定义Textview,第一行末尾数字分别在第一行和第二行展示

布局中  MyTextview记得换成自己包名下的

    <TextView
        android:layout_margin="25dp"
        android:id="@+id/test_tv"
        android:lineSpacingExtra="8dp"
        android:textSize="15sp"
        android:textColor="#444444"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="文字文字文字文字文字文字文字文字文字1234567890字文字文字文字文字1234567890"
        />

    <com.littlejie.app.panterdialog.MyTextView
        android:layout_margin="25dp"
        android:id="@+id/test_mytv"
        android:lineSpacingExtra="8dp"
        android:textSize="15sp"
        android:textColor="#444444"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="文字文字文字文字文字文字文字文字文字1234567890字文字文字文字文字1234567890"
        />

自定义Textview:  MyTextView类

public class MyTextView extends View {
    //内容填充画笔
    private Paint contentPaint;
    //标准的字体颜色
    private String contentNormalColor = "#737373";
    //有焦点的字体颜色
    private String contentFocuedColor = "#333333";
    //控件宽度
    private int viewWidth = 0;
    //控件高度
    private int viewHeight = 0;
    //标准的字的样式
    public static final int TEXT_TYPE_NORMAL = 1;
    //控件获取焦点的时候进行的处理
    public static final int TEXT_TYPE_FOCUED = 2;
    //默认是标准的样式
    private int currentTextType = TEXT_TYPE_NORMAL;
    //默认当前的颜色
    private String textColor = "#444444";
    //字体大小
    private int textSize = 60;
    //内容
    private String mText = "测试的文字信息";
    //最小view高度
    private float minHeight = 0;
    //最小view宽度
    private float minWidth = 0;
    //行间距
    private float lineSpace;
    //最大行数
    private int maxLines = 0;
    //文字测量工具
    private Paint.FontMetricsInt textFm;
    ///真实的行数
    private int realLines;
    //当前显示的行数
    private int line;
    //在末尾是否显示省略号
    private boolean showEllipsise;
 
    //文字显示区的宽度
    private int textWidth;
    //单行文字的高度
    private int signleLineHeight;
    private int mPaddingLeft,mPaddingRight,mPaddingTop,mPaddingBottom;
    /**
     * 省略号
     **/
    private String ellipsis = "...";
    public MyTextView(Context context) {
        this(context,null);
    }
 
    public MyTextView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }
 
    public MyTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initAttr(context,attrs);
        init();
    }
    private boolean isFristload;
 
    /**
     * 初始化
     */
    private void init() {
        contentPaint = new Paint();
        contentPaint.setTextSize(textSize);
        contentPaint.setAntiAlias(true);
        contentPaint.setStrokeWidth(2);
        contentPaint.setColor(Color.parseColor(textColor));
        contentPaint.setTextAlign(Paint.Align.LEFT);
        textFm = contentPaint.getFontMetricsInt();
        signleLineHeight=Math.abs(textFm.top-textFm.bottom);
    }
 
    /**
     * 初始化属性
     * @param context
     * @param attrs
     */
    private void initAttr(Context context,AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyTextView);
        mPaddingLeft = typedArray.getDimensionPixelSize(R.styleable.MyTextView_paddingLeft, 0);
        mPaddingRight = typedArray.getDimensionPixelSize(R.styleable.MyTextView_paddingRight, 0);
        mPaddingTop = typedArray.getDimensionPixelSize(R.styleable.MyTextView_paddingTop, 0);
        mPaddingBottom = typedArray.getDimensionPixelSize(R.styleable.MyTextView_paddingBottom, 0);
 
        mText = typedArray.getString(R.styleable.MyTextView_text);
        textColor = typedArray.getString(R.styleable.MyTextView_textColor);
        if(textColor==null){
            textColor="#444444";
        }
     //   textSize = typedArray.getDimensionPixelSize(R.styleable.MyTextView_textSize, 60);

        textSize = typedArray.getDimensionPixelSize(R.styleable.MyTextView_textSize, DensityUtil.sp2px(context,15));
        lineSpace = typedArray.getInteger(R.styleable.MyTextView_lineSpacing, 20);
        typedArray.recycle();
    }
 
    public void setText(String ss){
        this.mText=ss;
        invalidate();
    }
 
 
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec,heightMeasureSpec);
        viewWidth=getMeasuredWidth();
        textWidth=viewWidth-mPaddingLeft-mPaddingRight;
        viewHeight= (int) getViewHeight();
        setMeasuredDimension(viewWidth, viewHeight);
    }
 
    private float getViewHeight() {
        char[] textChars=mText.toCharArray();
        float ww=0.0f;
       int count=0;
        StringBuilder sb=new StringBuilder();
        for(int i=0;i<textChars.length;i++){
            float v = contentPaint.measureText(textChars[i] + "");
            if(ww+v<=textWidth){
                sb.append(textChars[i]);
                ww+=v;
            }
            else{
                count++;
                sb=new StringBuilder();
                ww=0.0f;
                ww+=v;
                sb.append(textChars[i]);
            }
        }
        if(sb.toString().length()!=0){
            count++;
        }
        return count*signleLineHeight+lineSpace*(count-1)+mPaddingBottom+mPaddingTop;
    }
 
    @Override
    protected void onDraw(Canvas canvas) {
        drawText(canvas);
    }
 
    /**
     * 循环遍历画文字
     * @param canvas
     */
    private void drawText(Canvas canvas) {
 
        char[] textChars=mText.toCharArray();
        float ww=0.0f;
        float startL=0.0f;
        float startT=0.0f;
        startL+=mPaddingLeft;
        startT+=mPaddingTop+signleLineHeight/2+ (textFm.bottom-textFm.top)/2 - textFm.bottom;
        StringBuilder sb=new StringBuilder();
 
        for(int i=0;i<textChars.length;i++){
            float v = contentPaint.measureText(textChars[i] + "");
            if(ww+v<=textWidth){
                sb.append(textChars[i]);
                ww+=v;
            }
            else{
                canvas.drawText(sb.toString(),startL,startT,contentPaint);
                startT+=signleLineHeight+lineSpace;
                sb=new StringBuilder();
                ww=0.0f;
                ww+=v;
                sb.append(textChars[i]);
            }
        }
 
        if(sb.toString().length()>0){
            canvas.drawText(sb.toString(),startL,startT,contentPaint);
        }
 
    }
    
}

在 res-values下attr.xml中添加属性

   <!--解决文字和数字换行不整齐-->
    <declare-styleable name="MyTextView">
        <attr name="paddingLeft" format="dimension" />
        <attr name="paddingTop" format="dimension" />
        <attr name="paddingRight" format="dimension" />
        <attr name="paddingBottom" format="dimension" />
        <attr name="textSize" format="dimension" />
        <attr name="textColor" format="string" />
        <attr name="text" format="string"/>
        <attr name="lineSpacing" format="integer" />
        <attr name="maxLine" format="integer"/>
        <attr name="ellipsis" format="boolean" />
    </declare-styleable>

Activity中

  MyTextView testMyTv = findViewById(R.id.test_mytv);

        String str = "文字文字文字文字文字文字文字文字文字1234567890字文字文字文字文字1234567890";

        testMyTv.setText(str);

 

 

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值