<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Android仿支付寶賬單統(tǒng)計餅狀圖

          共 5318字,需瀏覽 11分鐘

           ·

          2021-11-18 02:23

          仿支付寶統(tǒng)計餅狀圖,如下圖:


          效果圖:



          源代碼:

          /** * 餅狀圖 */public class PieChartView extends View {
          private Paint paintChart, paintText, paintLine, paintMasking; private RectF mRectF = new RectF(); //餅狀圖的數(shù)據(jù)(如:name、value數(shù)值、顏色等) private List mPieDatas = new ArrayList<>(); //總數(shù),方便算百分比 private float mSumValue; //半徑 private int radius; //直徑 private int diameter; //中心坐標(biāo) private int centerX, centerY; //間隔的距離 private float space;
          private boolean showTip; private int tipSize; private boolean openAnimation; private ValueAnimator mAnimator;
          // 默認的動效周期 2s private int defaultDuration = 1000; //動畫的執(zhí)行的百分比mAnimatorValue private float mAnimatorValue = 1f;
          public PieChartView(Context context) { super(context); initAll(); }
          public PieChartView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); }
          public PieChartView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.PieChartView, defStyleAttr, 0); diameter = typedArray.getDimensionPixelSize(R.styleable.PieChartView_pie_size, 0); space = typedArray.getFloat(R.styleable.PieChartView_pie_space, 0f); openAnimation = typedArray.getBoolean(R.styleable.PieChartView_open_animation, false); showTip = typedArray.getBoolean(R.styleable.PieChartView_show_tip, false); tipSize = showTip?100:0;//如果顯示tip,則預(yù)留出tip控件的間距 typedArray.recycle(); initAll(); }
          private void initAll() { initPain(); if (openAnimation) { startAnimation(); } }
          private void initPain() { paintChart = new Paint(); paintChart.setAntiAlias(true); paintChart.setColor(Color.BLACK);
          paintMasking = new Paint(); paintMasking.setColor(Color.WHITE); paintMasking.setStyle(Paint.Style.FILL); paintMasking.setAntiAlias(true);
          paintLine = new Paint(); paintLine.setStyle(Paint.Style.STROKE); paintLine.setStrokeWidth(5); paintLine.setAntiAlias(true);
          paintText = new Paint(); paintText.setColor(Color.BLACK); paintText.setStyle(Paint.Style.FILL); paintText.setStrokeWidth(20); paintText.setTextSize(30); }
          /** * 設(shè)置數(shù)據(jù)源 * @param pieData 餅狀圖的數(shù)據(jù) */ public void setPieData(List pieData) { if (pieData.size() > 0) { mPieDatas = pieData; if (mPieDatas.size() > 0) { int sumValue = 0; for (PieData data : mPieDatas) { sumValue += data.getValue(); } mSumValue = sumValue; } } }
          @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); }
          @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); //設(shè)置尺寸,沒有設(shè)置pie_size或者設(shè)置的size + 預(yù)留給tip控件的距離>=最小邊時不使用xml里設(shè)置的直徑尺寸 if (diameter <= 0 || diameter+tipSize >= getWidth() || diameter+tipSize >= getHeight()) { diameter = (getWidth() > getHeight() ? getHeight() : getWidth()) - tipSize; } radius = diameter / 2; centerX = getWidth() / 2; centerY = getHeight() / 2; mRectF.set(centerX - radius, centerY - radius, centerX + radius, centerY + radius); }
          private float startAngle = -90; private float sweepAngle;
          @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (mPieDatas == null || mPieDatas.size() <= 0) { canvas.drawArc(mRectF, 0, 360, true, paintChart); canvas.drawCircle(centerX, centerY, radius / 2, paintMasking); return; } for (PieData data : mPieDatas) { paintChart.setColor(data.getColor()); paintLine.setColor(data.getColor()); sweepAngle = (data.getValue() / mSumValue) * 360f; canvas.drawArc(mRectF, startAngle, sweepAngle * mAnimatorValue - space, true, paintChart); if (showTip) { //是否畫標(biāo)簽說明的小部件 drawTip(canvas, data); } startAngle += sweepAngle; } canvas.drawCircle(centerX, centerY, radius / 2, paintMasking); }
          /** * 畫tip控件 */ private void drawTip(Canvas canvas, PieData data) { Path pathLine = new Path(); PathMeasure measure = new PathMeasure();
          float textPadding = 10; float textHigh = (paintText.getFontMetrics().bottom - paintText.getFontMetrics().top) / 2; float padding = 20; float dotSize = 10; float dotX = (float) (centerX + (radius + padding) * Math.cos(Math.toRadians((startAngle + sweepAngle / 2)))); float dotY = (float) (centerY + (radius + padding) * Math.sin(Math.toRadians((startAngle + sweepAngle / 2))));
          float lineX = (float) (centerX + (radius + padding * 2) * Math.cos(Math.toRadians((startAngle + sweepAngle / 2)))); float lineY = (float) (centerY + (radius + padding * 2) * Math.sin(Math.toRadians((startAngle + sweepAngle / 2)))); canvas.drawCircle(dotX, dotY, dotSize, paintChart);
          if (dotX > centerX) { //右側(cè) pathLine.moveTo(dotX, dotY); pathLine.lineTo(lineX, lineY); pathLine.lineTo(getRight(), lineY); measure.setPath(pathLine, false); Path dst = new Path(); measure.getSegment(0, measure.getLength() * mAnimatorValue, dst, true); canvas.drawPath(dst, paintLine);
          if (mAnimatorValue == 1) { paintText.setTextAlign(Paint.Align.RIGHT); canvas.drawText((data.getValue() / mSumValue) * 100 + "%", getWidth() - textPadding, lineY - textPadding, paintText); canvas.drawText(data.getName(), getWidth() - textPadding, lineY + textHigh + textPadding, paintText); } } else { //左側(cè) measure = new PathMeasure(); pathLine.moveTo(dotX, dotY); pathLine.lineTo(lineX, lineY); pathLine.lineTo(0, lineY); measure.setPath(pathLine, false); Path dst = new Path(); measure.getSegment(0, measure.getLength() * mAnimatorValue, dst, true); canvas.drawPath(dst, paintLine);
          if (mAnimatorValue == 1) { paintText.setTextAlign(Paint.Align.LEFT); canvas.drawText((data.getValue() / mSumValue) * 100 + "%", 0 + textPadding, lineY - textPadding, paintText); canvas.drawText(data.getName(), 0 + textPadding, lineY + textHigh + textPadding, paintText); } } }
          /** * 開啟動畫 */ private void startAnimation() { mAnimator = ValueAnimator.ofFloat(0, 1).setDuration(defaultDuration); mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { mAnimatorValue = (float) valueAnimator.getAnimatedValue(); invalidate(); } }); mAnimator.start();??}}


          attrs 屬性文件:

                                                      


          xml 布局文件:

                      android:id="@+id/pie_char"        android:layout_width="match_parent"        android:layout_height="200dp"        app:pie_size="190dp"        app:pie_space="2"        app:show_tip="true"        app:open_animation="true"        android:visibility="visible"/>


          自定義一個PieData,設(shè)置相關(guān)屬性, pieChartView.setPieData(datas);

          源碼地址:
          https://github.com/bigeyechou/CustomViewCollection

          到這里就結(jié)束啦。
          瀏覽 60
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  久艹在线蜜桃 | 亚洲欧美色图 | 国际操逼网 | 欧美成人性爱在线视频免费 | 国产黄片免费播放 |