自定義MPAndroidChart水平柱狀樣式(圓角)

#使用MPAndroidChart實現(xiàn)水平柱狀圖(圓角)

## 在使用MPAndroidChart組件前,我們必須閱讀官方API,看官方給出的Simple使用實例。如果你想實現(xiàn)的圖表與官方給出的實例有出入需要修改Chart設(shè)定,那需要仔細(xì)閱讀使用教程。由于圖表的構(gòu)成是多模塊的,每個模塊涉及屬性較多,建議花點時間閱讀教程。

## 在我項目中運(yùn)用MPAndroidChart的地方比較多,大多數(shù)官方使用實例是可以滿足使用要求的,那在本篇文章里我只對實現(xiàn)水平柱狀圖作介紹,其他的不作概述。

##### 首先了解一下需求,如下圖所示需要實現(xiàn)圓角柱狀圖。

需求圖

##### 根據(jù)官方提供的HorizontalBarChart實現(xiàn)效果如下:

官方 HorizontalBarChart? 實現(xiàn)圖

##### 這里我簡單貼一下Activity中實現(xiàn)代碼:

```

import android.app.Activity;

import android.graphics.RectF;

import android.os.Bundle;

import android.util.Log;

import android.view.View;

import androidx.annotation.Nullable;

import com.github.mikephil.charting.charts.HorizontalBarChart;

import com.github.mikephil.charting.components.AxisBase;

import com.github.mikephil.charting.components.Legend;

import com.github.mikephil.charting.components.LimitLine;

import com.github.mikephil.charting.components.XAxis;

import com.github.mikephil.charting.components.YAxis;

import com.github.mikephil.charting.data.BarData;

import com.github.mikephil.charting.data.BarDataSet;

import com.github.mikephil.charting.data.BarEntry;

import com.github.mikephil.charting.data.Entry;

import com.github.mikephil.charting.formatter.IAxisValueFormatter;

import com.github.mikephil.charting.highlight.Highlight;

import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;

import com.github.mikephil.charting.listener.OnChartValueSelectedListener;

import com.github.mikephil.charting.utils.MPPointF;

import java.util.ArrayList;

import java.util.Random;

public class OrderCountActivity extends Activity implements OnChartValueSelectedListener {

? ? // 自定義Chatrt圖標(biāo)

? ? private HorizontalBarChart chart;

? ? // 測試數(shù)據(jù)

? ? private String labelName[] = {"","南京", "常州", "揚(yáng)州", "無錫", "南通", "淮安", "蘇州", "連云港", "鹽城", "泰州", "宿遷", "鎮(zhèn)江", "徐州"};


? ? @Override

? ? protected void onCreate(@Nullable Bundle savedInstanceState) {

? ? ? ? super.onCreate(savedInstanceState);

? ? ? ? setContentView(R.layout.activity_order_count);


? ? ? ? initViews();

? ? }

? ? public void initViews() {

? ? ? ? chart = findViewById(R.id.custom_chart);

? ? ? ? chart.setOnChartValueSelectedListener(this);

? ? ? ? chart.setDrawBarShadow(true);

? ? ? ? chart.setDrawValueAboveBar(true);

? ? ? ? chart.setExtraOffsets(0, 10, 0, 10); // 設(shè)置餅圖的偏移量,類似于內(nèi)邊距 ,設(shè)置視圖窗口大小

? ? ? ? chart.setDoubleTapToZoomEnabled(false); // 雙擊不可放大

? ? ? ? chart.getDescription().setEnabled(false); // 不顯示描述

? ? ? ? chart.setMaxVisibleValueCount(60); // 最大值

? ? ? ? chart.setPinchZoom(false); // x,y軸方向縮放

? ? ? ? chart.setDrawGridBackground(false);? //網(wǎng)格背景

? ? ? ? chart.animateY(2500); // Y軸 初始化時動畫效果

? ? ? ? // 設(shè)置x軸

? ? ? ? final XAxis xl = chart.getXAxis();

? ? ? ? xl.setPosition(XAxis.XAxisPosition.BOTTOM); // 設(shè)置x軸顯示在下方,默認(rèn)在上方

? ? ? ? xl.setDrawAxisLine(true); //設(shè)置為true,則繪制該行旁邊的軸線(axis-line)

? ? ? ? xl.setDrawGridLines(true);// 將此設(shè)置為true,繪制該軸的網(wǎng)格線

? ? ? ? xl.setAxisMinimum(0.0f); // 設(shè)置最小值? 不要隨便改

? ? ? ? xl.setLabelCount(labelName.length);

? ? ? ? xl.setTextSize(14.0f); // 設(shè)置文字大小

? ? ? ? // 設(shè)置x軸顯示的值的格式

? ? ? ? xl.setValueFormatter(new IAxisValueFormatter() {

? ? ? ? ? ? @Override

? ? ? ? ? ? public String getFormattedValue(float value, AxisBase axis) {

? ? ? ? ? ? ? ? if (value - xl.getAxisMinimum()< labelName.length) {

? ? ? ? ? ? ? ? ? ? return labelName[(int) (value - xl.getAxisMinimum())];

? ? ? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? ? ? return "";

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? });

? ? ? ? xl.setXOffset(0.0f); // 設(shè)置標(biāo)簽對x軸的偏移量,垂直方向

? ? ? ? // 設(shè)置y軸,y軸有兩條,分別為左和右

? ? ? ? YAxis yr = chart.getAxisRight();

? ? ? ? chart.getAxisLeft().setEnabled(false); // 隱藏右邊 的坐標(biāo)軸

? ? ? ? yr.setDrawAxisLine(false);

? ? ? ? yr.setDrawGridLines(false);

? ? ? ? yr.setTextSize(14.0f);

? ? ? ? // y軸添加限制線

? ? ? ? LimitLine limitLine = new LimitLine(2.0f, "平均值:2.0");

? ? ? ? limitLine.setLabelPosition(LimitLine.LimitLabelPosition.RIGHT_TOP);

? ? ? ? limitLine.setTextSize(12f);

? ? ? ? limitLine.setLineColor(getResources().getColor(R.color.colo_FFA224)); // 線的顏色

? ? ? ? limitLine.setTextColor(getResources().getColor(R.color.colo_FFA224)); // 文字的顏色

? ? ? ? yr.addLimitLine(limitLine);

? ? ? ? yr.setDrawZeroLine(true);

? ? ? ? yr.setYOffset(0.0f);

? ? ? ? Legend legend = chart.getLegend();

? ? ? ? legend.setEnabled(false);// 隱藏圖例

? ? ? ? setData(); // 填充數(shù)據(jù)

? ? }

? ? private void setData() {

? ? ? ? float barWidth = 0.5f;

? ? ? ? ArrayList<BarEntry> values_zs = new ArrayList<>();? // 總數(shù)

? ? ? ? ArrayList<BarEntry> values_ywc = new ArrayList<>(); // 已完成

? ? ? ? Random random = new Random();

? ? ? ? for (int i = 0; i < labelName.length; i++) {

? ? ? ? ? ? if(i==0){

? ? ? ? ? ? ? ? values_zs.add(new BarEntry(-1 , 0 ));

? ? ? ? ? ? ? ? values_ywc.add(new BarEntry(-1, 0));

? ? ? ? ? ? ? ? continue;

? ? ? ? ? ? }

? ? ? ? ? ? int val = random.nextInt(20);

? ? ? ? ? ? float val2 = (float) Math.random()*10;

? ? ? ? ? ? values_zs.add(new BarEntry(i , 2*val2));

? ? ? ? ? ? values_ywc.add(new BarEntry(i, val2));

? ? ? ? }

? ? ? ? if (chart.getData() != null &&

? ? ? ? ? ? ? ? chart.getData().getDataSetCount() > 0) {

? ? ? ? ? ? BarDataSet dataSetZs = (BarDataSet) chart.getData().getDataSetByIndex(0); // 總數(shù)

? ? ? ? ? ? BarDataSet dataSetYwc = (BarDataSet) chart.getData().getDataSetByIndex(1); // 已完成數(shù)

? ? ? ? ? ? dataSetZs.setValues(values_zs);

? ? ? ? ? ? dataSetYwc.setValues(values_ywc);

? ? ? ? ? ? chart.getData().notifyDataChanged();

? ? ? ? ? ? chart.notifyDataSetChanged();

? ? ? ? } else {

? ? ? ? ? ? ArrayList<IBarDataSet> dataSets = new ArrayList<>();

? ? ? ? ? ? BarDataSet dataSetZs = new BarDataSet(values_zs, "總數(shù)");

? ? ? ? ? ? dataSetZs.setDrawIcons(false);

? ? ? ? ? ? dataSetZs.setDrawValues(false); // 不顯示值

? ? ? ? ? ? dataSetZs.setColor(getResources().getColor(R.color.colo_EFE8E1)); // 淺灰色

? ? ? ? ? ? dataSets.add(dataSetZs);

? ? ? ? ? ? BarDataSet dataSetYwc = new BarDataSet(values_ywc, "已完成");

? ? ? ? ? ? dataSetYwc.setDrawIcons(false);

? ? ? ? ? ? dataSetYwc.setColor(getResources().getColor(R.color.colo_B79C81)); // 淺褐色

? ? ? ? ? ? dataSets.add(dataSetYwc);

? ? ? ? ? ? BarData data = new BarData(dataSets);

? ? ? ? ? ? data.setValueTextSize(10f);

? ? ? ? ? ? data.setBarWidth(barWidth);

? ? ? ? ? ? chart.setData(data);

? ? ? ? }

? ? ? ? findViewById(R.id.tv_ywcs).setVisibility(View.VISIBLE);

? ? ? ? findViewById(R.id.tv_zs).setVisibility(View.VISIBLE);

? ? }

? ? private final RectF mOnValueSelectedRectF = new RectF();

? ? @Override

? ? public void onValueSelected(Entry e, Highlight h) {

? ? ? ? if (e == null)

? ? ? ? ? ? return;

? ? ? ? RectF bounds = mOnValueSelectedRectF;

? ? ? ? chart.getBarBounds((BarEntry) e, bounds);

? ? ? ? MPPointF position = chart.getPosition(e, chart.getData().getDataSetByIndex(h.getDataSetIndex())

? ? ? ? ? ? ? ? .getAxisDependency());

? ? ? ? Log.i("bounds", bounds.toString());

? ? ? ? Log.i("position", position.toString());

? ? ? ? MPPointF.recycleInstance(position);

? ? }

? ? @Override

? ? public void onNothingSelected() {

? ? }

}

```

#####布局文件 activity_order_count.xml:

```

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout 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="@color/colo_F0F0F0"

? ? android:orientation="vertical">

? ? ? ? <!--? 已完成任務(wù)數(shù)對比-->

? ? ? ? <TextView

? ? ? ? ? ? android:id="@+id/title_bottom"

? ? ? ? ? ? android:layout_width="wrap_content"

? ? ? ? ? ? android:layout_height="wrap_content"

? ? ? ? ? ? android:layout_below="@+id/ll_middle"

? ? ? ? ? ? android:layout_margin="15dp"

? ? ? ? ? ? android:layout_weight="1"

? ? ? ? ? ? android:text="已完成任務(wù)數(shù)對比"

? ? ? ? ? ? android:textColor="@color/black"

? ? ? ? ? ? android:textSize="16sp"

? ? ? ? ? ? android:textStyle="bold" />

? ? ? ? <RelativeLayout

? ? ? ? ? ? android:layout_width="match_parent"

? ? ? ? ? ? android:layout_height="match_parent"

? ? ? ? ? ? android:layout_below="@+id/title_bottom">

? ? ? ? ? ? <TextView

? ? ? ? ? ? ? ? android:id="@+id/tv_ywcs"

? ? ? ? ? ? ? ? android:layout_width="wrap_content"

? ? ? ? ? ? ? ? android:layout_height="wrap_content"

? ? ? ? ? ? ? ? android:gravity="center_vertical"

? ? ? ? ? ? ? ? android:layout_alignParentTop="true"

? ? ? ? ? ? ? ? android:layout_alignParentRight="true"

? ? ? ? ? ? ? ? android:text="已完成"

? ? ? ? ? ? ? ? android:drawableLeft="@drawable/ic_brown_point"/>

? ? ? ? ? ? <TextView

? ? ? ? ? ? ? ? android:id="@+id/tv_zs"

? ? ? ? ? ? ? ? android:layout_width="wrap_content"

? ? ? ? ? ? ? ? android:layout_height="wrap_content"

? ? ? ? ? ? ? ? android:gravity="center_vertical"

? ? ? ? ? ? ? ? android:layout_alignParentTop="true"

? ? ? ? ? ? ? ? android:layout_toLeftOf="@+id/tv_ywcs"

? ? ? ? ? ? ? ? android:text="總數(shù)"

? ? ? ? ? ? ? ? android:layout_marginRight="10dp"

? ? ? ? ? ? ? ? android:drawableLeft="@drawable/ic_brown_low_point"/>

? ? ? ? ? ? <!-- 這是官方的HorizontalBarChart,后面使用自定義chart請?zhí)鎿Q成CustomHorizontalBarChart?-->

? ? ? ? ? ? <com.github.mikephil.charting.charts.HorizontalBarChart

? ? ? ? ? ? ? ? android:id="@+id/custom_chart"

? ? ? ? ? ? ? ? android:layout_width="match_parent"

? ? ? ? ? ? ? ? android:layout_height="match_parent"

? ? ? ? ? ? ? ? android:background="@android:color/white"

? ? ? ? ? ? ? ? android:layout_below="@+id/tv_ywcs"/>

? ? ? ? </RelativeLayout>

</LinearLayout>

```

#####距離實現(xiàn)圓角柱狀圖只差一步,自定義水平圓角柱狀圖,下面直接給出代碼吧

```

/**

*? 重寫HorizontalBarChart,更改其柱狀圖樣式

*/

public class CustomHorizontalBarChart extends HorizontalBarChart {

public CustomHorizontalBarChart(Context context) {

super(context);

? ? }

public CustomHorizontalBarChart(Context context, AttributeSet attrs) {

super(context, attrs);

? ? }

public CustomHorizontalBarChart(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

? ? }

@Override

? ? protected void init() {

super.init();

? ? ? ? this.mRenderer =new CustomHorizontalBarChartRenderer(this, this.mAnimator, this.mViewPortHandler);

? ? }

}

```

######最重要的步驟來了,重寫器渲染器,覆蓋HorizontalBarChartRenderer.java中繪制柱狀圖的方法。其中drawDataSet是繪制柱狀圖的方法,drawHighlighted是繪制點擊過后高亮柱狀圖。

```

import com.github.mikephil.charting.highlight.Highlight;

import com.github.mikephil.charting.highlight.Range;

import com.github.mikephil.charting.renderer.HorizontalBarChartRenderer;

import android.graphics.Canvas;

import android.graphics.Path;

import android.graphics.RectF;

import android.util.Log;

import com.github.mikephil.charting.animation.ChartAnimator;

import com.github.mikephil.charting.buffer.BarBuffer;

import com.github.mikephil.charting.data.BarData;

import com.github.mikephil.charting.data.BarEntry;

import com.github.mikephil.charting.interfaces.dataprovider.BarDataProvider;

import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;

import com.github.mikephil.charting.utils.Transformer;

import com.github.mikephil.charting.utils.Utils;

import com.github.mikephil.charting.utils.ViewPortHandler;

/**

* 繼承HorizontalBarChartRenderer寫一個新的渲染器,調(diào)整為水平顏色

*/

public class CustomHorizontalBarChartRenderer extends HorizontalBarChartRenderer {

public CustomHorizontalBarChartRenderer(BarDataProvider chart, ChartAnimator animator, ViewPortHandler viewPortHandler) {

super(chart, animator, viewPortHandler);

? ? }

private RectFmBarShadowRectBuffer =new RectF();

? ? @Override

? ? protected void drawDataSet(Canvas c, IBarDataSet dataSet, int index) {

Transformer trans =mChart.getTransformer(dataSet.getAxisDependency());

? ? ? ? mBarBorderPaint.setColor(dataSet.getBarBorderColor());

? ? ? ? mBarBorderPaint.setStrokeWidth(Utils.convertDpToPixel(dataSet.getBarBorderWidth()));

? ? ? ? final boolean drawBorder = dataSet.getBarBorderWidth() >0.f;

? ? ? ? float phaseX =mAnimator.getPhaseX();

? ? ? ? float phaseY =mAnimator.getPhaseY();

? ? ? ? // draw the bar shadow before the values

? ? ? ? if (mChart.isDrawBarShadowEnabled()) {

mShadowPaint.setColor(dataSet.getBarShadowColor());

? ? ? ? ? ? BarData barData =mChart.getBarData();

? ? ? ? ? ? final float barWidth = barData.getBarWidth();

? ? ? ? ? ? final float barWidthHalf = barWidth /2.0f;

? ? ? ? ? ? float x;

? ? ? ? ? ? for (int i =0, count = Math.min((int) (Math.ceil((float) (dataSet.getEntryCount()) * phaseX)), dataSet.getEntryCount());

? ? ? ? ? ? ? ? i < count;

? ? ? ? ? ? ? ? i++) {

BarEntry e = dataSet.getEntryForIndex(i);

? ? ? ? ? ? ? ? x = e.getX();

? ? ? ? ? ? ? ? mBarShadowRectBuffer.top = x - barWidthHalf;

? ? ? ? ? ? ? ? mBarShadowRectBuffer.bottom = x + barWidthHalf;

? ? ? ? ? ? ? ? trans.rectValueToPixel(mBarShadowRectBuffer);

? ? ? ? ? ? ? ? if (!mViewPortHandler.isInBoundsTop(mBarShadowRectBuffer.bottom))

continue;

? ? ? ? ? ? ? ? if (!mViewPortHandler.isInBoundsBottom(mBarShadowRectBuffer.top))

break;

? ? ? ? ? ? ? ? mBarShadowRectBuffer.left =mViewPortHandler.contentLeft();

? ? ? ? ? ? ? ? mBarShadowRectBuffer.right =mViewPortHandler.contentRight();

? ? ? ? ? ? ? ? float radius = (mBarShadowRectBuffer.bottom -mBarShadowRectBuffer.top) /2;

? ? ? ? ? ? ? ? // 畫半圓+矩形

? ? ? ? ? ? ? ? RectF rectFTo =new RectF(mBarShadowRectBuffer.right -2 * radius, mBarShadowRectBuffer.top,

? ? ? ? ? ? ? ? ? ? ? ? mBarShadowRectBuffer.right, mBarShadowRectBuffer.bottom);

? ? ? ? ? ? ? ? Path path =new Path();

? ? ? ? ? ? ? ? path.arcTo(rectFTo, -90, 180, true);

? ? ? ? ? ? ? ? if (mBarShadowRectBuffer.right -mBarShadowRectBuffer.left < radius) {

path.lineTo(rectFTo.centerX(), rectFTo.bottom);

? ? ? ? ? ? ? ? ? ? Path srcPath =new Path();

? ? ? ? ? ? ? ? ? ? srcPath.addRect(mBarShadowRectBuffer.left, mBarShadowRectBuffer.top, mBarShadowRectBuffer.right, mBarShadowRectBuffer.bottom, Path.Direction.CW);

? ? ? ? ? ? ? ? ? ? path.op(srcPath, Path.Op.INTERSECT); // 相交部分

? ? ? ? ? ? ? ? }else {

path.moveTo(rectFTo.centerX(), rectFTo.bottom);

? ? ? ? ? ? ? ? ? ? path.lineTo(mBarShadowRectBuffer.left, mBarShadowRectBuffer.bottom);

? ? ? ? ? ? ? ? ? ? path.lineTo(mBarShadowRectBuffer.left, mBarShadowRectBuffer.top);

? ? ? ? ? ? ? ? ? ? path.lineTo(rectFTo.centerX(), mBarShadowRectBuffer.top);

? ? ? ? ? ? ? ? }

c.drawPath(path, mShadowPaint);

? ? ? ? ? ? }

}

// initialize the buffer

? ? ? ? BarBuffer buffer =mBarBuffers[index];

? ? ? ? buffer.setPhases(phaseX, phaseY);

? ? ? ? buffer.setDataSet(index);

? ? ? ? buffer.setInverted(mChart.isInverted(dataSet.getAxisDependency()));

? ? ? ? buffer.setBarWidth(mChart.getBarData().getBarWidth());

? ? ? ? buffer.feed(dataSet);

? ? ? ? trans.pointValuesToPixel(buffer.buffer);

? ? ? ? final boolean isSingleColor = dataSet.getColors().size() ==1;

? ? ? ? if (isSingleColor) {

mRenderPaint.setColor(dataSet.getColor());

? ? ? ? }

for (int j =0; j < buffer.size(); j +=4) {

if (!mViewPortHandler.isInBoundsTop(buffer.buffer[j +3]))

break;

? ? ? ? ? ? if (!mViewPortHandler.isInBoundsBottom(buffer.buffer[j +1]))

continue;

? ? ? ? ? ? if (!isSingleColor) {

// Set the color for the currently drawn value. If the index

// is out of bounds, reuse colors.

? ? ? ? ? ? ? ? mRenderPaint.setColor(dataSet.getColor(j /4));

? ? ? ? ? ? }

// 畫半圓+矩形

? ? ? ? ? ? float barWidthHalf = (buffer.buffer[j +3] - buffer.buffer[j +1]) /2;

? ? ? ? ? ? RectF rectFTo =new RectF(buffer.buffer[j +2] -2 * barWidthHalf, buffer.buffer[j +1],

? ? ? ? ? ? ? ? ? ? buffer.buffer[j +2], buffer.buffer[j +3]);

? ? ? ? ? ? Path path =new Path();

? ? ? ? ? ? path.arcTo(rectFTo, -90, 180, true);

? ? ? ? ? ? if (buffer.buffer[j +2] - buffer.buffer[j] < barWidthHalf) {

path.lineTo(rectFTo.centerX(), rectFTo.bottom); // 封閉半圓

? ? ? ? ? ? ? ? Path srcPath =new Path();

? ? ? ? ? ? ? ? srcPath.addRect(buffer.buffer[j], buffer.buffer[j +1], buffer.buffer[j +2], buffer.buffer[j +3], Path.Direction.CW);

? ? ? ? ? ? ? ? path.op(srcPath, Path.Op.INTERSECT); // 相交部分

? ? ? ? ? ? }else {

path.moveTo(rectFTo.centerX(), rectFTo.bottom);

? ? ? ? ? ? ? ? path.lineTo(buffer.buffer[j], buffer.buffer[j +3]);

? ? ? ? ? ? ? ? path.lineTo(buffer.buffer[j], buffer.buffer[j +1]);

? ? ? ? ? ? ? ? path.lineTo(rectFTo.centerX(), buffer.buffer[j +1]);

? ? ? ? ? ? }

c.drawPath(path, mRenderPaint);

? ? ? ? ? ? if (drawBorder) {

c.drawPath(path, mBarBorderPaint);

? ? ? ? ? ? }

}

}

@Override

? ? public void drawHighlighted(Canvas c, Highlight[] indices) {

BarData barData =mChart.getBarData();

? ? ? ? final float barWidth = barData.getBarWidth();

? ? ? ? final float barWidthHalf = barWidth /2.0f;

? ? ? ? for (Highlight high : indices) {

IBarDataSet set = barData.getDataSetByIndex(high.getDataSetIndex());

? ? ? ? ? ? if (set ==null || !set.isHighlightEnabled())

continue;

? ? ? ? ? ? BarEntry e = set.getEntryForXValue(high.getX(), high.getY());

? ? ? ? ? ? if (!isInBoundsX(e, set))

continue;

? ? ? ? ? ? Transformer trans =mChart.getTransformer(set.getAxisDependency());

? ? ? ? ? ? mHighlightPaint.setColor(set.getHighLightColor());

? ? ? ? ? ? mHighlightPaint.setAlpha(set.getHighLightAlpha());

? ? ? ? ? ? boolean isStack = (high.getStackIndex() >=0 && e.isStacked()) ?true :false;

? ? ? ? ? ? final float y1;

? ? ? ? ? ? final float y2;

? ? ? ? ? ? if (isStack) {

if (mChart.isHighlightFullBarEnabled()) {

y1 = e.getPositiveSum();

? ? ? ? ? ? ? ? ? ? y2 = -e.getNegativeSum();

? ? ? ? ? ? ? ? }else {

Range range = e.getRanges()[high.getStackIndex()];

? ? ? ? ? ? ? ? ? ? y1 = range.from;

? ? ? ? ? ? ? ? ? ? y2 = range.to;

? ? ? ? ? ? ? ? }

}else {

y1 = e.getY();

? ? ? ? ? ? ? ? y2 =0.f;

? ? ? ? ? ? }

// 畫半圓

? ? ? ? ? ? float leftTo = y1 -2 * barWidth;

? ? ? ? ? ? float rightTo = y1;

? ? ? ? ? ? float topTo = e.getX() - barWidthHalf;

? ? ? ? ? ? float bottomTo = e.getX() + barWidthHalf;

? ? ? ? ? ? RectF rectFTo =new RectF(leftTo, topTo, rightTo, bottomTo);

? ? ? ? ? ? trans.rectToPixelPhase(rectFTo, mAnimator.getPhaseY());

? ? ? ? ? ? Path path =new Path();

? ? ? ? ? ? path.arcTo(rectFTo, -90, 180, true);

? ? ? ? ? ? RectF rectF =new RectF(y2, topTo, rightTo, bottomTo);

? ? ? ? ? ? trans.rectToPixelPhase(rectF, mAnimator.getPhaseY());

? ? ? ? ? ? if (y1 - barWidth <0) {

path.lineTo(rectFTo.centerX(), rectFTo.bottom);

? ? ? ? ? ? ? ? Path srcPath =new Path();

? ? ? ? ? ? ? ? srcPath.addRect(rectF.left,rectF.top, rectF.right, rectF.bottom, Path.Direction.CW);

? ? ? ? ? ? ? ? path.op(srcPath, Path.Op.INTERSECT); // 相交部分

? ? ? ? ? ? }else {

path.moveTo(rectFTo.centerX(), rectFTo.bottom);

? ? ? ? ? ? ? ? path.lineTo(rectF.left, rectFTo.bottom);

? ? ? ? ? ? ? ? path.lineTo(rectF.left, rectFTo.top);

? ? ? ? ? ? ? ? path.lineTo(rectFTo.centerX(), rectFTo.top);

? ? ? ? ? ? }

c.drawPath(path, mHighlightPaint);

? ? ? ? }

}

}

```

#####最后來看看最終實現(xiàn)效果:


實現(xiàn)圖

~~~~~~ 結(jié)束,第一次寫簡書,對簡書的格式不熟悉,可能會在代碼開頭和結(jié)尾有“```” ,復(fù)制代碼時請刪除```”。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容