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

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

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
    评论
### 回答1: Qt是一个开源的C++ GUI工具包,您可以使用它来编写多边形控件。在Qt中,可以使用QPainter类绘制多边形,可以使用QPolygon类存储多边形的点。 您可以在QWidget的paintEvent()函数中创建QPainter对象,并使用drawPolygon()函数绘制多边形。 以下是一个示例代码,显示了如何使用QPainter绘制多边形: ``` void MyWidget::paintEvent(QPaintEvent *) { QPainter painter(this); QPolygon polygon; polygon << QPoint(10, 10) << QPoint(100, 10) << QPoint(50, 50); painter.drawPolygon(polygon); } ``` 在上面的代码中,MyWidget是继承自QWidget的自定义窗口类。paintEvent()函数在窗口需要重绘时被调用,在此函数中,我们创建了一个QPainter对象并使用drawPolygon()函数绘制了一个三角形。 希望这对您有所帮助! ### 回答2: 使用Qt编写多边形控件需要按照以下步骤进行: 1. 创建一个新的Qt项目。可以选择Qt Widgets应用程序模板作为起点。 2. 在Qt代码中,导入必要的头文件,包括QPainter和QWidget。 3. 创建一个新的自定义QWidget类,并继承QWidget。 4. 在自定义的QWidget类中重写paintEvent函数。paintEvent函数将在每次需要绘制控件时被调用。 5. 在paintEvent函数中,创建一个QPainter对象,并使用该对象绘制多边形。你可以使用QPainter的drawPolygon函数来绘制多边形,可以传入一个QVector<QPoint>参数,这个参数包含多边形的顶点坐标。 6. 在主窗口中创建一个新的多边形控件,即使用自定义的QWidget类创建一个实例。 7. 设置多边形控件的大小和位置,并将其添加至主窗口的布局中,或使用setGeometry函数直接设置位置和大小。 8. 运行程序,你将看到多边形控件显示在主窗口中,并呈现出你在paintEvent函数中定义的多边形。 需要注意的是,在编写多边形控件时,你可以通过重写其他事件函数,并使用QObject::event或QWidget::event过滤和处理事件,比如鼠标点击和键盘按键等。这样可以为多边形控件添加交互功能。 总结,在Qt中编写多边形控件主要是通过自定义一个QWidget类,并在该类中重写paintEvent函数,利用QPainter对象绘制多边形。然后在主窗口中创建多边形控件对象,并设置其大小和位置,最后将其添加至布局中显示。 ### 回答3: 使用Qt编写多边形控件的过程如下: 1. 引入Qt库文件:首先需要在项目中引入Qt库文件,可以通过在项目文件中添加`#include <QtWidgets>`来引入Qt中的Widgets模块。 2. 创建自定义控件类:使用Qt提供的QPolygon类来表示多边形的形状,可以通过继承QWidget类来创建自定义的多边形控件类。在类中重写基类的paintEvent函数来实现绘制多边形的功能。 3. 绘制多边形:在paintEvent函数中通过调用QPainter类的相关函数来实现多边形的绘制。可以使用QPolygon类的addPoint函数来添加多边形的每个顶点坐标,然后使用QPainter类的drawPolygon函数来绘制多边形。 4. 设置多边形属性:可以在自定义的多边形控件类中添加成员变量来设置多边形的属性,例如线条颜色、线宽、填充颜色等。在paintEvent函数中根据成员变量的值来设置QPainter的相应属性,从而实现多边形的样式定制。 5. 使用多边形控件:在其他窗口或对话框中,可以通过在UI设计界面中拖拽多边形控件设置其属性来使用自定义的多边形控件。也可以通过在代码中创建多边形控件实例来动态添加到布局中。 使用Qt编写多边形控件可以实现自定义的多边形形状显示,并且可以通过属性设置来定制多边形的样式。同时,Qt提供了丰富的绘函数和类,使得绘制多边形和操作多边形控件变得非常方便和灵活。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值