自定义view 进度条式文本

先看实现的效果吧

进度条式文本

实现原理:

在同一位置绘制两个Text,第一个作为底色,绘制第二个Text之前先切割画布,再进行第二个Text的绘制

代码

自定义View文件 WordView.java
public class WordView extends View {
    
    
    private String mText;//需要绘制的文字
    private int mTextFirstColor,mTextSecondColor;//文本的颜色
    private int mTextSize;//文本的大小
    private float account;
    private Rect mBound;
    private Paint mPaint;
    private Paint.FontMetrics fontMetrics;

    public WordView(Context context){
    
    
        this(context,null);
    }
    public WordView(Context context, AttributeSet attrs){
    
    
        this(context,attrs,0);
    }
    public WordView(Context context,AttributeSet attrs,int defStyleAttr){
    
    
        super(context,attrs,defStyleAttr);
        //获取自定义属性
        TypedArray a = context.getTheme().obtainStyledAttributes(attrs,R.styleable.WordView,defStyleAttr,0);
        mText = a.getString(R.styleable.WordView_mText);
        mTextFirstColor = a.getColor(R.styleable.WordView_mTextFirstColor,Color.GREEN);
        mTextSecondColor = a.getColor(R.styleable.WordView_mTextSecondColor,Color.WHITE);
        mTextSize = a.getDimensionPixelSize(R.styleable.WordView_mTextSize,100);
        account = a.getFloat(R.styleable.WordView_account,(float)0.5);
        a.recycle();
        mPaint = new Paint();
        mPaint.setTextSize(mTextSize);
        mBound = new Rect();
        mPaint.getTextBounds(mText,0,mText.length(),mBound);
        fontMetrics=mPaint.getFontMetrics();
    }

    @Override
    protected void onDraw(Canvas canvas){
    
    
        drawMyText(canvas);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    
    
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);   //获取宽的模式
        int heightMode = MeasureSpec.getMode(heightMeasureSpec); //获取高的模式
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);   //获取宽的尺寸
        int heightSize = MeasureSpec.getSize(heightMeasureSpec); //获取高的尺寸
        int width;
        int height ;
        if (widthMode == MeasureSpec.EXACTLY) {
    
    
            width = widthSize;
        } else {
    
    
            width = (int)(mBound.width()+(float)(fontMetrics.bottom*0.5));
        }
        if (heightMode == MeasureSpec.EXACTLY) {
    
    
            height = heightSize;
        } else {
    
    
            height = (int)(mBound.height()+(float)(fontMetrics.bottom*1.5));
        }
        setMeasuredDimension(width, height);
    }

    private void drawMyText(Canvas canvas){
    
    
        int width = canvas.getWidth();

        //字母顶部的坐标
        float TextTop = (float)(fontMetrics.ascent*0.87-fontMetrics.top+fontMetrics.descent*0.13);
        //字母高度
        float MyTextHigh=(float)((fontMetrics.descent-fontMetrics.ascent)*0.87);

        //红色的部分
        mPaint.setColor(mTextFirstColor);
        mPaint.setTextSize(mTextSize);
        canvas.drawText(mText,0,-fontMetrics.top,mPaint);

        //白色的部分
        mPaint.setColor(mTextSecondColor);
        canvas.save();
        canvas.clipRect(0,0,width,(float)(TextTop+MyTextHigh*(1.0-account)));
        canvas.drawText(mText,0,-fontMetrics.top,mPaint);
        canvas.restore();
    }

    public void setAccount(float account) {
    
    
        this.account = account;
        invalidate();
    }

}
attrs文件 wordview_attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="WordView">
        <attr name="mText" format="string"/>
        <attr name="mTextFirstColor" format="color"/>
        <attr name="mTextSecondColor" format="color"/>
        <attr name="mTextSize" format="dimension"/>
        <attr name="account" format="float"/>
    </declare-styleable>

</resources>

WordViewTestActivity.java
public class WordViewTestActivity extends AppCompatActivity {
    
    

    WordView word;
    SeekBar seekBar;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_word_view_test);
        seekBar = (SeekBar)findViewById(R.id.seekBar);
        word = (WordView)findViewById(R.id.word);
        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
    
    
            @Override
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
    
    
                word.setAccount((float)(i/100.0));
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
    
    

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
    
    

            }
        });
    }
}
activity_word_view_test.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#cec1c1"
    tools:context=".WordViewTestActivity">

    <com.example.administrator.listviewadptwebjsonimg.WordView
        android:id="@+id/word"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        app:mText="I Love You"
        app:mTextFirstColor="#d60a47"
        app:mTextSecondColor="#FFFFFF"
        app:mTextSize="50sp"
        app:account="0.5"
        />

    <SeekBar
        android:id="@+id/seekBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:progress="50"
        android:max="100"
        android:layout_below="@+id/word"/>

</RelativeLayout>

猜你喜欢

转载自blog.csdn.net/lmmmmmmmmmmmmmmm/article/details/104181121