这是效果图
主要功能 :
1、单个分数绘制,
2、多个分数绘制时添加运算符号,
3、运算结果的填写
其中代码注释已经很清楚了,就不在赘述了,有什么不明白直接看代码
不废话直接上代码
自定义view,直接复制调用即可
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
/**
* 分数绘制
* @author 驰珺
* whechat : chijun9
* create at : 2024/5/23 23:27
*/
public class DrawFenShuView extends View {
//中间线段两边偏移距离
int linePadding = 10;
//线段高度
float lineHeight = 5;
float startPadding = 10;
//开始绘制位置
float startX = startPadding;
//中间分割线和数字之间的距离
int lineAndNumberDistance = 20;
//运算符号放大比例 倍数关系 0.3指比文字大0.3倍
double signAmplifyProportion = 0.3;
float endX;
float endY;
//结果分子
int resultFenZi;
//结果分母
int resultFenMu;
//默认字体大小
float size = 30;
Paint paint;
FenShu[] fenShuList = new FenShu[]{new FenShu(822,25000,true),new FenShu(52,75,false)};
public DrawFenShuView(Context context, FenShu[] fenShuList,int size) {
super(context);
this.fenShuList = fenShuList;
//dp转换px
this.size = dp2px(size);
paint = new Paint();
paint.setColor(Color.BLACK);
paint.setTextSize(this.size);
paint.setStrokeWidth(lineHeight);//线条宽度
}
public DrawFenShuView(Context context, FenShu fenShu,int size) {
super(context);
fenShuList = new FenShu[] {fenShu};
//dp转换px
this.size = dp2px(size);
paint = new Paint();
paint.setColor(Color.BLACK);
paint.setTextSize(this.size);
paint.setStrokeWidth(lineHeight);//线条宽度
}
public DrawFenShuView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
//dp转换px
this.size = dp2px(size);
paint = new Paint();
paint.setColor(Color.BLACK);
paint.setTextSize(this.size);
paint.setStrokeWidth(lineHeight);//线条宽度
}
@Override
protected void onDraw(@NonNull Canvas canvas) {
super.onDraw(canvas);
if (fenShuList.length < 1) return;
startX = startPadding;
for (int i = 0; i < fenShuList.length; i++) {
paint.setColor(fenShuList[i].color);
drawFenShu(String.valueOf(fenShuList[i].fenZi),String.valueOf(fenShuList[i].fenMu),canvas);
if (fenShuList.length > 1) {
if (i<fenShuList.length -1) {
if (fenShuList[i].isJiaFa) {
paint.setColor(Color.BLUE);
drawYunSuanFuHao(0,canvas);
} else {
paint.setColor(Color.RED);
drawYunSuanFuHao(1,canvas);
}
} else {
//最后一个数据画等号
drawYunSuanFuHao(2,canvas);
}
}
}
//画结果
if (resultFenZi > 0 || resultFenMu > 0) {
paint.setColor(Color.rgb(223,104,0));
String fenzi = "";
if (resultFenZi > 0) fenzi = String.valueOf(resultFenZi);
String fenmu = "";
if (resultFenMu > 0) fenmu = String.valueOf(resultFenMu);
drawFenShu(fenzi,fenmu,canvas);
}
// measure(getWidth(),getHeight());
}
private void drawFenShu(String fenzi,String fenmu, Canvas canvas){
startX = startX + linePadding;
//单行文本高度
//Y的起始坐标
float startY = size;
//分子宽度
float fenZiWidth = paint.measureText(fenzi);
//分母宽度
float fenMuWidth = paint.measureText(fenmu);
//获取最大文字宽度
float max = Math.max(fenZiWidth,fenMuWidth);
//求出居中位置需要的偏移量
float v = Math.abs(fenZiWidth - fenMuWidth) / 2;
float fenZiY = startY;
float lineY = (float) (size * 2 + lineAndNumberDistance * 2) /2 - lineHeight/2;
endY = size * 2 +lineAndNumberDistance;
//画出分子
float fenZiX = max == fenZiWidth ? startX: startX + v;
canvas.drawText(fenzi, fenZiX,fenZiY,paint);
//画出中间分割线
float lineStartX = startX-linePadding;
endX = startX+linePadding+max;
//超出范围减小字体大小重绘
if (endX > ScreenUtils.getAppScreenWidth()) {
size = size-(int)((double)size*0.1);
invalidate();//重绘
return;
} else {
}
canvas.drawLine(lineStartX,lineY,endX,lineY,paint);
//画出分母
float fenMuX = max == fenMuWidth ? startX : startX + v;
canvas.drawText(fenmu, fenMuX,endY,paint);
}
private void drawYunSuanFuHao(int type,Canvas canvas){
//画出运算符号
float yunSuanFuHaoY = endY / 2 + size/2;
startX = endX;
paint.setTextSize(size + (float) ((double)size*signAmplifyProportion));
String yunSuanFu = "";
if (type == 0) yunSuanFu = " + ";
if (type == 1) yunSuanFu = " — ";
if (type == 2) yunSuanFu = " = ";
canvas.drawText(yunSuanFu, startX,yunSuanFuHaoY,paint);
startX += paint.measureText(yunSuanFu);
endX = startX;
//超出范围减小字体大小重绘
if (startX > ScreenUtils.getAppScreenWidth()) {
size = size-(int)((double)size*0.1);
invalidate();//重绘
return;
}
paint.setTextSize(size);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(measureWidth(widthMeasureSpec),
measureHeight(heightMeasureSpec));
}
private int measureHeight(int measureSpec) {
float result = 0;
int mode = MeasureSpec.getMode(measureSpec);
int size = MeasureSpec.getSize(measureSpec);
if (mode == MeasureSpec.EXACTLY) {
result = size;
} else {
result=this.size*2+lineAndNumberDistance*2+5;
if (mode == MeasureSpec.AT_MOST) {
result = Math.min(result, size);
}
}
return (int)result;
}
private int measureWidth(int measureSpec) {
float result = 0;
int mode = MeasureSpec.getMode(measureSpec);
int size2 = MeasureSpec.getSize(measureSpec);
if (mode == MeasureSpec.EXACTLY) {
result = size2;
} else {
// result = size2;
//开始位置的偏移距离
result += startPadding;
paint.setTextSize(size);
//分数的宽度
for (FenShu fenShu : fenShuList) {
float fenZiWidth = paint.measureText(String.valueOf(fenShu.fenZi));
//分母宽度
float fenMuWidth = paint.measureText(String.valueOf(fenShu.fenMu));
result += Math.max(fenZiWidth,fenMuWidth);
result += linePadding * 2;
}
//加上结果
float fenZiWidth = paint.measureText(String.valueOf(resultFenZi));
float fenMuWidth = paint.measureText(String.valueOf(resultFenMu));
result += Math.max(fenZiWidth,fenMuWidth);
result += linePadding * 2;
//符号的宽度
if (fenShuList.length > 1) {
float v = size;
double vvv = size*signAmplifyProportion;
v += (float) vvv;
paint.setTextSize(v);
v = paint.measureText(" - ");
result += v * (fenShuList.length);
paint.setTextSize(size);
}
if (mode == MeasureSpec.AT_MOST) {
result = Math.min(result, size2);
}
}
return (int)result;
}
public int getResultFenZi() {
return resultFenZi;
}
public void setResultFenZi(int resultFenZi) {
this.resultFenZi = resultFenZi;
requestLayout();//重绘
}
public int getResultFenMu() {
return resultFenMu;
}
public void setResultFenMu(int resultFenMu) {
this.resultFenMu = resultFenMu;
requestLayout();//重绘
}
public int getLinePadding() {
return linePadding;
}
public void setLinePadding(int linePadding) {
this.linePadding = linePadding;
}
public float getLineHeight() {
return lineHeight;
}
public void setLineHeight(float lineHeight) {
this.lineHeight = lineHeight;
}
public float getStartX() {
return startPadding;
}
public void setStartX(float startX) {
this.startPadding = startX;
}
public FenShu[] getFenShuList() {
return fenShuList;
}
public void setFenShuList(FenShu[] fenShuList,int size) {
LogUtils.d("设置参数");
this.fenShuList = fenShuList;
this.size = dp2px(size);
paint.setTextSize(this.size);
// requestLayout();
}
public int getLineAndNumberDistance() {
return lineAndNumberDistance;
}
public void setLineAndNumberDistance(int lineAndNumberDistance) {
this.lineAndNumberDistance = lineAndNumberDistance;
}
public double getSignAmplifyProportion() {
return signAmplifyProportion;
}
public void setSignAmplifyProportion(double signAmplifyProportion) {
this.signAmplifyProportion = signAmplifyProportion;
}
private int dp2px(final float dpValue) {
final float scale = Resources.getSystem().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
}
里面用到的分数类
public class FenShu {
public FenShu(int fenMu,int fenZi,boolean isJiaFa){
this.fenMu = fenMu;
this.fenZi = fenZi;
this.isJiaFa = isJiaFa;
}
public FenShu(int fenMu,int fenZi){
this.fenMu = fenMu;
this.fenZi = fenZi;
this.isJiaFa = true;
}
public int fenMu;
public int fenZi;
public boolean isJiaFa;
public float size = 12;
public int color = 0;
}
调用
<com.example.ccj.b.c.draw.DrawFenShuView
android:id="@+id/activity_main_test_navigation_12"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/teal_200"
/>
//分子结果填写 用普通的
<Button
android:id="@+id/activity_test_fen_shu_fenzi"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
//分母结果填写
<Button
android:id="@+id/activity_test_fen_shu_fenmu"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
DrawFenShuView drawFenShuView = findViewById(R.id.activity_main_test_navigation_12);
Button fenzi = findViewById(R.id.activity_test_fen_shu_fenzi);
Button fenmu = findViewById(R.id.activity_test_fen_shu_fenmu);
//
fenzi.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
@Override
public void afterTextChanged(Editable s) {
//填写分子结果
if (!StringUtils.isEmpty(s)) drawFenShuView.setResultFenZi(Integer.parseInt(s.toString()));
}
});
fenmu.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
@Override
public void afterTextChanged(Editable s) {
//填写分母结果
if (!StringUtils.isEmpty(s)) drawFenShuView.setResultFenMu(Integer.parseInt(s.toString()));
}
});
//设置数据
drawFenShuView.setFenShuList(new FenShu[]{new FenShu(58,89,true),
new FenShu(58,89,false),
new FenShu(58,89,false),
new FenShu(58,89,true)},18);