自定义开源控件的绘制实例-——价格区间图

效果如图,废话不多说,直接上代码。

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.support.annotation.NonNull;
import android.text.Layout;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.style.AbsoluteSizeSpan;
import android.text.style.ForegroundColorSpan;
import android.text.style.StyleSpan;
import android.util.AttributeSet;
import android.view.View;

import com.zhugefang.agent.R;


/**
 * Created by Administrator on 2016/6/20.
 * 价格区间view
 */
public class PriceIntervalView extends View {


    private int lowX, lowY, heightX, heightY, curX, curY;
    private Paint paint, pathPaint;
    private TextPaint textPaint;
    private float angle;

    private int radius = 10, bigRadius = 18;

    private int offset = 50;

    private String unit = "m²";
    private int topPrice = 10, floorPrice = 0, presentPrice;

    public PriceIntervalView(Context context, AttributeSet attrs) {
        super(context, attrs);
        paint = new Paint();
        pathPaint = new Paint();
        textPaint = new TextPaint();

        textPaint.setTextSize(context.getResources().getDimensionPixelSize(R.dimen.micro_micro));
        textPaint.setStrokeWidth(3);
        paint.setAntiAlias(true);
        pathPaint.setAntiAlias(true);
        textPaint.setAntiAlias(true);
        textPaint.setColor(getResources().getColor(R.color.color_FF878787));
        paint.setColor(getResources().getColor(R.color.color_FFFA891B));
        pathPaint.setColor(Color.parseColor("#FFECD5"));
    }

    /**
     * 设置价格区间参数
     *
     * @param topPrice     最高价格
     * @param floorPrice   最低价格
     * @param presentPrice 当前价格
     */
    public void setIntervalParams(int topPrice, int floorPrice, int presentPrice) {
        this.setIntervalParams(topPrice, floorPrice, presentPrice, "m²");
    }

    public void setIntervalParams(int topPrice, int floorPrice, int presentPrice, String unit) {
        this.topPrice = topPrice;
        this.floorPrice = floorPrice;
        this.presentPrice = presentPrice;
        this.unit = unit;
        invalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        angle = (getHeight() - offset) / (float) getWidth();

        canvas.drawLine(0, getHeight(), getWidth(), offset, paint);

        lowX = getWidth() / 4;
        lowY = (int) (getHeight() - lowX * angle);

        heightX = getWidth() * 3 / 4;
        heightY = (int) (getHeight() - heightX * angle);


        Path path = new Path();
        path.moveTo(lowX, lowY);
        path.lineTo(lowX, offset);
        path.lineTo(heightX, offset);
        path.lineTo(heightX, heightY);
        canvas.drawPath(path, pathPaint);


        canvas.drawCircle(lowX, lowY, radius, paint);
        canvas.drawCircle(heightX, heightY, radius, paint);

        String floorStr = floorPrice + "元/" + unit + "\r\n最低参考价";
        String topStr = topPrice + "元/" + unit + "\r\n最高参考价";

        SpannableString spannableString = getSpannableString(floorStr, (floorPrice + "").length(), (floorPrice + "元/" + unit).length(),
                getResources().getColor(R.color.color_FF333333), (int) textPaint.getTextSize());
        StaticLayout layout = new StaticLayout(spannableString, textPaint, 300,
                Layout.Alignment.ALIGN_NORMAL, 1.0F, 0.0F, true);

        SpannableString spannableString1 = getSpannableString(topStr, (topPrice + "").length(), (topPrice + "元/" + unit).length(),
                getResources().getColor(R.color.color_FF333333), (int) textPaint.getTextSize());
        StaticLayout layout1 = new StaticLayout(spannableString1, textPaint, 300,
                Layout.Alignment.ALIGN_NORMAL, 1.0F, 0.0F, true);
        canvas.save();
        canvas.translate(lowX, lowY + 5);
        layout.draw(canvas);

        canvas.translate(heightX - lowX, heightY - lowY);
        layout1.draw(canvas);
        canvas.restore();

        calculationCurLocation(canvas);
    }

    @NonNull
    private SpannableString getSpannableString(String floorStr, int first, int second, int color, int size) {
        SpannableString spannableString = new SpannableString(floorStr);
        spannableString.setSpan(new StyleSpan(Typeface.BOLD), 0, first, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        spannableString.setSpan(new AbsoluteSizeSpan((int) (size * 1.3)), 0, first, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        spannableString.setSpan(new ForegroundColorSpan(color), 0, second, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        return spannableString;
    }

    private void calculationCurLocation(Canvas canvas) {
        if (presentPrice == 0) return;
        if (presentPrice < floorPrice) {
            curX = (int) (lowX - (heightX - lowX) * 0.1);
            curY = (int) (getHeight() - angle * curX);
        } else if (presentPrice <= topPrice) {
            int interval = topPrice - floorPrice;
            int curInterval = presentPrice - floorPrice;

            float proportion = curInterval / (float) interval;

            curX = (int) (lowX + (heightX - lowX) * proportion);
            curY = (int) (getHeight() - angle * curX);
        } else {
            curX = (int) (heightX + (heightX - lowX) * 0.1);
            curY = (int) (getHeight() - angle * curX);
        }

        paint.setColor(Color.parseColor("#99FA891B"));
        canvas.drawCircle(curX, curY, bigRadius, paint);
        paint.setColor(getResources().getColor(R.color.color_FFFA891B));
        canvas.drawCircle(curX, curY, radius, paint);

        String text = presentPrice + "元/" + unit + "\r\n当前单价";
        Rect bounds = new Rect();
        String text1 = presentPrice + "元/" + unit;
        textPaint.getTextBounds(text1, 0, text1.length(), bounds);

        SpannableString spannableString = getSpannableString(text, (presentPrice + "").length(), (presentPrice + "元/" + unit).length(),
                getResources().getColor(R.color.color_FFFA891B), (int) textPaint.getTextSize());
        StaticLayout layout = new StaticLayout(spannableString, textPaint, 300,
                Layout.Alignment.ALIGN_NORMAL, 1.0F, 0.0F, true);
        int layoutHeight = layout.getHeight();
        float measureText = textPaint.measureText(spannableString, 0, (presentPrice + "元/" + unit).length());


        BitmapFactory.Options options = new BitmapFactory.Options();
        options.outWidth = (int) (measureText + offset);
        options.outHeight = layoutHeight + offset;
        Bitmap tv_Bg = BitmapFactory.decodeResource(getResources(), R.drawable.interval_textview_bg, options).copy(Bitmap.Config.ARGB_8888, true);

        float bgX = curX - tv_Bg.getWidth() / 2;
        float bgY = curY - tv_Bg.getHeight() - bigRadius;

        canvas.drawBitmap(tv_Bg, bgX, bgY, paint);

        canvas.save();
        canvas.translate(curX - measureText / 2 - 10, curY - bigRadius - layoutHeight - 10);
        layout.draw(canvas);
        canvas.restore();

    }

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值