请尊重个人劳动成果,转载注明出处,谢谢!
http://blog.csdn.net/xiaxiazaizai01
前段时间我的好基友遇到这样一个需求,根据用户的余额使用情况来动态的显示在矩形图上,让用户能更加直观的知道自己的余额使用情况。
问我好不好实现,咱能说不好实现吗,,毕竟是学习了一段时间的自定义view,于是下面就开启了装逼之旅。老规矩,效果图走起
public class CustomBalanceView extends View{
private int rectWidth = 200;
private int rectHeight = 245;
private int textSize = sp2px(14);
//矩形画笔
private Paint rectPaint;
private Paint linePaint;
private Paint textPaint;
private Paint trianglePaint;
private Path path;
private int triangleStrokeWidth = dp2px(2);
private int triangleLength = dp2px(10);
//余额正常的范围,其中数值上y2大于y1,坐标系中y2坐标小于y1
private float y1;
private float y2;
//传进来的比较数值
private float data;
private String flag;//传进来的标志位
float textWidth;//文字的宽
float textHeight;//文字的高
String text;//文字内容
private int mLeft = 200;
//颜色数组
private int[] colors = new int[]{Color.parseColor("#F75850"),Color.parseColor("#F7D62D"),
Color.parseColor("#19E6BB")};
public CustomBalanceView(Context context) {
this(context,null);
}
public CustomBalanceView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public CustomBalanceView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//设置画笔
setPaint();
path = new Path();
}
private void setPaint() {
rectPaint = new Paint();
rectPaint.setAntiAlias(true);
rectPaint.setDither(true);
rectPaint.setStyle(Paint.Style.FILL);
trianglePaint = new Paint();
trianglePaint.setAntiAlias(true);
trianglePaint.setDither(true);
trianglePaint.setStyle(Paint.Style.FILL);
trianglePaint.setStrokeWidth(triangleStrokeWidth);
linePaint = new Paint();
linePaint.setAntiAlias(true);
linePaint.setDither(true);
linePaint.setStyle(Paint.Style.FILL);
linePaint.setStrokeWidth(triangleStrokeWidth);
linePaint.setColor(Color.parseColor("#275D9D"));
textPaint = new Paint();
textPaint.setAntiAlias(true);
textPaint.setDither(true);
textPaint.setStyle(Paint.Style.FILL);
textPaint.setColor(Color.parseColor("#F76E6B"));
textPaint.setTextSize(textSize);
}
@Override
protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int mWidthSize = MeasureSpec.getSize(widthMeasureSpec);
int mHeightSize = MeasureSpec.getSize(heightMeasureSpec);
int widthSize;
int heightSize;
int mRectWidth = Math.abs(rectWidth);
if(widthMode != MeasureSpec.EXACTLY){
widthSize = getPaddingLeft() + mRectWidth + getPaddingRight();
widthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize,MeasureSpec.EXACTLY);
}
if(heightMode != MeasureSpec.EXACTLY){
heightSize = getPaddingTop() + dp2px(rectHeight) + dp2px(15) + getPaddingBottom();
heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize,MeasureSpec.EXACTLY);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected synchronized void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
canvas.translate(getPaddingLeft(),getPaddingTop());
Rect rect = new Rect(200,0,300,dp2px(rectHeight));
rect.centerY();
LinearGradient linearGradient = new LinearGradient(200,dp2px(rectHeight),300,0,colors,null, Shader.TileMode.MIRROR);
rectPaint.setShader(linearGradient);
canvas.drawRect(rect,rectPaint);
//绘制三角形
trianglePaint.setColor(Color.parseColor("#FF0000"));
int m = String.valueOf(Math.round(y2)).length();
int n = triangleLength*triangleLength - (triangleLength/2)*(triangleLength/2);
float firstX = (float) (mLeft - Math.sqrt(n));
float firstY;
if(flag.equals("1")){//余额不足
firstY = (1-data / 100)*dp2px(rectHeight);
//画文字
text = "余额不足";
}else if(flag.equals("2")){//余额正常
firstY = (1-data / 100)*dp2px(rectHeight);
//画文字
text = "余额正常";
}else{//余额充足
firstY = (1-data / 100)*dp2px(rectHeight);
//画文字
text = "余额充足";
}
path.moveTo(firstX,firstY-triangleLength/2);
path.lineTo(firstX,firstY+triangleLength/2);
path.lineTo(mLeft,firstY);
path.close();
//画三角形
canvas.drawPath(path,trianglePaint);
//画线
linePaint.setColor(Color.parseColor("#FFFFFF"));
canvas.drawLine(200,firstY,300,firstY,linePaint);
//画文字
textWidth = textPaint.measureText(text);
textHeight = (textPaint.descent() + textPaint.ascent()) / 2;
canvas.drawText(text,200-textWidth-triangleLength,firstY-textHeight/2+7,textPaint);
canvas.restore();
}
public void setCurrentData(float data){
this.data = data;
}
public void setFlag(String flag){
this.flag = flag;
}
/**
* dp 2 px
*
* @param dpVal
*/
protected int dp2px(int dpVal)
{
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
dpVal, getResources().getDisplayMetrics());
}
/**
* sp 2 px
*
* @param spVal
* @return
*/
protected int sp2px(int spVal)
{
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
spVal, getResources().getDisplayMetrics());
}
}
<RelativeLayout 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:background="#F2F2F2"
tools:context="com.example.custombalance.MainActivity">
<RelativeLayout
android:id="@+id/rl"
android:layout_width="match_parent"
android:layout_height="260dp"
android:layout_marginTop="30dp"
android:background="#FFFFFF">
<com.example.custombalance.CustomBalanceView
android:id="@+id/customBalanceView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:paddingTop="15dp"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
/>
RelativeLayout>
RelativeLayout>
public class MainActivity extends AppCompatActivity{
private CustomBalanceView balanceView;
private Button btn1,btn2,btn3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
balanceView = (CustomBalanceView) findViewById(R.id.customBalanceView);
balanceView.setCurrentData(50);
balanceView.setFlag("2");
}
}
@Override
protected synchronized void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
canvas.translate(getPaddingLeft(),getPaddingTop());
Rect rect = new Rect(200,0,300,dp2px(rectHeight));
rect.centerY();
LinearGradient linearGradient = new LinearGradient(200,dp2px(rectHeight),300,0,colors,null, Shader.TileMode.MIRROR);
rectPaint.setShader(linearGradient);
canvas.drawRect(rect,rectPaint);
//绘制三角形
trianglePaint.setColor(Color.parseColor("#FF0000"));
int m = String.valueOf(Math.round(y2)).length();
int n = triangleLength*triangleLength - (triangleLength/2)*(triangleLength/2);
float firstX = (float) (mLeft - Math.sqrt(n));
float firstY;
if(data >= y2){
float cha = 1-(data-y2) / (Math.pow(10,m) - y2)<0 ? 0 : (float) (1 - (data - y2) / (Math.pow(10, m) - y2));
firstY = cha*mRight;
path.moveTo(firstX,firstY-triangleLength/2);
path.lineTo(firstX,firstY+triangleLength/2);
path.lineTo(mLeft,firstY);
path.close();
//画文字
text = "余额充足";
}else if(data>y1 && data1-(data-y1) / (y2 - y1))*mRight + 300;
path.moveTo(firstX,firstY-triangleLength/2);
path.lineTo(firstX,firstY+triangleLength/2);
path.lineTo(mLeft,firstY);
path.close();
//画文字
text = "余额正常";
}else{
firstY =((y1-data) / y1)*mRight + 600;
path.moveTo(firstX,firstY-triangleLength/2);
path.lineTo(firstX,firstY+triangleLength/2);
path.lineTo(mLeft,firstY);
path.close();
//画文字
text = "余额不足";
}
//画三角形
canvas.drawPath(path,trianglePaint);
//画线
linePaint.setColor(Color.parseColor("#FFFFFF"));
canvas.drawLine(200,firstY,300,firstY,linePaint);
//画文字
textWidth = textPaint.measureText(text);
textHeight = (textPaint.descent() + textPaint.ascent()) / 2;
canvas.drawText(text,200-textWidth-triangleLength,firstY-textHeight/2+7,textPaint);
/*canvas.drawLine(0,300,300,300,linePaint);
canvas.drawLine(0,600,300,600,linePaint);*/
canvas.restore();
}