MPAndroidChart chart case for Android

a brief introduction

1.1 Charts are used to intuitively analyze the distribution of data, and to compare the size and trend of data.

1.2 There are also many types of charts, the common ones are line, column, pie, and others include area, scatter, stock price, radar, dashboard, funnel, etc.

1.3 Android also has a very good chart library, such as MPAndroidChart, hellocharts-android, AnyChart-Android, etc. Among them, MPAndroidChart is currently the most used. All charts.

Two MPAndroidChart chart case, histogram

2.1 Effect

2.2 Add MPAndroidChart dependency library

repositories {
    maven { url 'https://jitpack.io' }
}

dependencies {
    implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
}

 2.4 xml add bar chart component BarChart

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.github.mikephil.charting.charts.BarChart
        android:id="@+id/chart1"
        android:layout_width="match_parent"
        android:layout_height="300dp" />
    
</FrameLayout>

2.5 Setting chart configuration and data

public class BarActivity extends AppCompatActivity {
    private BarChart chart;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bar_chart);

        //获取柱状图控件
        chart = findViewById(R.id.chart1);

        //初始化柱状图控件
        initBarChart();
    }

    /**
     * 初始化柱状图控件
     */
    private void initBarChart(){
        // 是否显示描述
        chart.getDescription().setEnabled(false);

        // 如果图表中显示的条目超过60个,则不会显示任何值
        chart.setMaxVisibleValueCount(60);

        // 只能分别在x轴和y轴上进行缩放
        chart.setPinchZoom(false);

        // 阴影
        chart.setDrawBarShadow(false);
        // 是否绘制背景线
        chart.setDrawGridBackground(false);

        // x坐标绘制
        XAxis xAxis = chart.getXAxis();
        // x坐标位置
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        // x坐标线
        xAxis.setDrawGridLines(false);

        //Y轴左边第1条线
        chart.getAxisLeft().setDrawGridLines(false);


        // 添加一个漂亮平滑的动画
        chart.animateY(1500);

        // 是否绘制图例
        chart.getLegend().setEnabled(false);

        //设置数据
        setData();
    }

    /**
     * 设置数据
     */
    private void setData(){
        //柱状数量 相当于二位数组的 二级数据
        ArrayList<BarEntry> values = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            float multi = (10 + 1);
            float val = (float) (Math.random() * multi) + multi / 3;
            values.add(new BarEntry(i, val));
        }

        // 柱状分类,相当于二位数组的 一级数据
        BarDataSet set1 = new BarDataSet(values, "Data Set");
        set1.setColors(ColorTemplate.VORDIPLOM_COLORS);
        set1.setDrawValues(false);

        // 图表数据集合
        ArrayList<IBarDataSet> dataSets = new ArrayList<>();
        dataSets.add(set1);

        // 填充图表数据
        BarData data = new BarData(dataSets);
        chart.setData(data);
        chart.setFitBars(true);

        // 刷新图表UI
        chart.invalidate();
    }

Three Pie Charts

3.1 Effect

 3.2 Add pie-shaped component PieChart in xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <com.github.mikephil.charting.charts.PieChart
        android:id="@+id/chart1"
        android:layout_width="match_parent"
        android:layout_height="300dp" />
</LinearLayout>

3.3 Configuration parameters and data in Activity

public class PieCharActivity extends Activity {
    private PieChart chart;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_pie_chart);

        //饼状图控件
        chart = findViewById(R.id.chart1);

        //初始化饼状组件
        initChart();
    }

    private void initChart(){
        //是否用于百分比数据
        chart.setUsePercentValues(true);
        chart.getDescription().setEnabled(false);
        chart.setExtraOffsets(5, 10, 5, 5);

        chart.setDragDecelerationFrictionCoef(0.95f);

        //设置中间文本的字体
        //chart.setCenterTextTypeface(tfLight);
        //chart.setCenterText(generateCenterSpannableText());

        //是否绘制中心圆形区域和颜色
        chart.setDrawHoleEnabled(true);
        chart.setHoleColor(Color.WHITE);

        //是否绘制中心边透明区域
        chart.setTransparentCircleColor(Color.WHITE);
        chart.setTransparentCircleAlpha(110);

        //绘制中中心圆,和圆边的边框大小
        chart.setHoleRadius(58f);
        chart.setTransparentCircleRadius(61f);

        //是否绘制中心区域文字
        chart.setDrawCenterText(true);

        //默认旋转角度
        chart.setRotationAngle(0);
        //通过触摸启用图表的旋转
        chart.setRotationEnabled(true);
        //触摸进行高亮的突出设置
        chart.setHighlightPerTapEnabled(true);

        //设置单位
        // chart.setUnit(" €");
        // chart.setDrawUnitsInChart(true);

        //添加选择侦听器
        chart.setOnChartValueSelectedListener(new OnChartValueSelectedListener() {
            @Override
            public void onValueSelected(Entry e, Highlight h) {
                //选中的扇页
            }

            @Override
            public void onNothingSelected() {
               //未选中的扇页
            }
        });

        //动画
        chart.animateY(1400, Easing.EaseInOutQuad);
        // chart.spin(2000, 0, 360);

        //图例
        Legend l = chart.getLegend();
        l.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
        l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT);
        l.setOrientation(Legend.LegendOrientation.VERTICAL);
        l.setDrawInside(false);
        l.setXEntrySpace(7f);
        l.setYEntrySpace(0f);
        l.setYOffset(0f);

        //标签样式
        chart.setEntryLabelColor(Color.WHITE);
        //chart.setEntryLabelTypeface(tfRegular);
        chart.setEntryLabelTextSize(12f);

        //设置数据
        setData();
    }


    //设置数据
    private void setData() {
        //二维数据的二级数据
        ArrayList<PieEntry> entries = new ArrayList<>();
        //new PieEntry(数值,描述,图标icon)第一个
        entries.add(new PieEntry(40.0f, "数据1", null));
        entries.add(new PieEntry(20.0f, "数据2", null));
        entries.add(new PieEntry(30.0f, "数据3", null));
        entries.add(new PieEntry(10.0f, "数据4", null));

        //二维数据的一级数据
        PieDataSet dataSet = new PieDataSet(entries, "Election Results");
        //数据配置,是否绘制图标
        dataSet.setDrawIcons(false);
        //扇页之间的空白间距
        dataSet.setSliceSpace(3f);
        //图标偏移
        dataSet.setIconsOffset(new MPPointF(0, 40));
        dataSet.setSelectionShift(5f);

        //添加颜色集合,
        ArrayList<Integer> colors = new ArrayList<>();
        //colors.add(ColorTemplate.LIBERTY_COLORS[0]);
        colors.add(Color.parseColor("#3790A2"));
        colors.add(Color.parseColor("#37F0A2"));
        colors.add(Color.parseColor("#49DBEE"));
        colors.add(Color.parseColor("#43C088"));
        dataSet.setColors(colors);
        //dataSet.setSelectionShift(0f);

        //设置图表数据
        PieData data = new PieData(dataSet);
        data.setValueFormatter(new PercentFormatter());
        data.setValueTextSize(11f);
        data.setValueTextColor(Color.WHITE);
        //data.setValueTypeface(tfLight);
        chart.setData(data);

        //撤消所有高光
        chart.highlightValues(null);

        //刷新图表UI
        chart.invalidate();
    }
}

Four-line chart

4.1 Effect

 4.2 xml add polyline component

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <com.github.mikephil.charting.charts.PieChart
        android:id="@+id/chart1"
        android:layout_width="match_parent"
        android:layout_marginTop="20dp"
        android:layout_height="300dp" />
</LinearLayout>

4.3 Activity configuration discount parameters and data

public class LineChartActivity extends Activity {
    private LineChart chart;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_line_chart);

        //折线图表组件
        chart = findViewById(R.id.chart1);

        //初始化图表
        initChart();
    }

    //初始化图表
    private void initChart(){
        //点击监听
        //chart.setOnChartValueSelectedListener(this);
        //绘制网格线
        chart.setDrawGridBackground(false);

        //描述文本
        chart.getDescription().setEnabled(false);

        //是否可以触摸
        chart.setTouchEnabled(true);

        //启用缩放和拖动
        chart.setDragEnabled(true);
        chart.setScaleEnabled(true);

        // 如果禁用,可以分别在x轴和y轴上进行缩放
        chart.setPinchZoom(true);

        //设置背景色
        // chart.setBackgroundColor(Color.GRAY);

        //创建自定义MarkerView(扩展MarkerView)并指定布局
        //MyMarkerView mv = new MyMarkerView(this, R.layout.custom_marker_view);
        //mv.setChartView(chart); // For bounds control
        //chart.setMarker(mv); // Set the marker to the chart

        //配置x坐标数据
        XAxis xl = chart.getXAxis();
        xl.setAvoidFirstLastClipping(true);
        xl.setAxisMinimum(0f);

        //配置y坐标左边数据
        YAxis leftAxis = chart.getAxisLeft();
        leftAxis.setInverted(true);
        leftAxis.setAxisMinimum(0f); // this replaces setStartAtZero(true)

        //关闭y坐标右边数据
        YAxis rightAxis = chart.getAxisRight();
        rightAxis.setEnabled(false);

        //抑制最大比例因子
        // chart.setScaleMinima(3f, 3f);

        //将视图居中到图表中的特定位置
        // chart.centerViewPort(10, 50);

        //图例
        Legend l = chart.getLegend();
        //修改图例
        l.setForm(Legend.LegendForm.LINE);

        setData();
    }


    private void setData() {
        //二维数组 一级数据
        ArrayList<Entry> entries = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            float xVal = (i+1);
            float yVal = (float) (Math.random() * 100);
            entries.add(new Entry(xVal, yVal));
        }

        //通过x坐标值排序
        Collections.sort(entries, new EntryXComparator());

        //二维数组 二级数据
        LineDataSet set1 = new LineDataSet(entries, "DataSet 1");

        //折现的宽度合折点的半径大小
        set1.setLineWidth(1.5f);
        set1.setCircleRadius(4f);

        //使用数据集创建数据对象
        LineData data = new LineData(set1);
        chart.setData(data);

        //刷新绘图
        chart.invalidate();
    }

}

Five advanced pie charts and line charts, configure double line and gradient area

5.1 Rendering

 5.2 Add pie and polyline components to xml layout

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <View
            android:id="@+id/view_statues"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:background="@color/white" />

        <RelativeLayout
            android:id="@+id/v_title_layout"
            android:layout_width="match_parent"
            android:layout_height="44dp"
            android:background="@color/white">


            <ImageView
                android:id="@+id/v_back"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_marginLeft="10dp"
                android:paddingLeft="10dp"
                android:paddingRight="10dp"
                android:src="@mipmap/ic_back" />

            <LinearLayout
                android:id="@+id/v_date"
                android:layout_width="wrap_content"
                android:layout_height="34dp"
                android:layout_alignParentRight="true"
                android:layout_centerVertical="true"
                android:layout_marginRight="20dp"
                android:background="@drawable/shape_bg_welcom_gradient"
                android:gravity="center"
                android:paddingLeft="7dp"
                android:paddingRight="7dp">

                <TextView
                    android:id="@+id/tv_date"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="2022.05"
                    android:textColor="@color/white"
                    android:textSize="16sp" />

                <ImageView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:src="@mipmap/down_white" />
            </LinearLayout>
        </RelativeLayout>

        <androidx.core.widget.NestedScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerVertical="true"
                    android:layout_marginLeft="20dp"
                    android:layout_marginTop="7dp"
                    android:gravity="center_vertical"
                    android:text="統計"
                    android:textColor="@color/color_text_title"
                    android:textSize="20sp" />

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerVertical="true"
                    android:layout_marginLeft="20dp"
                    android:layout_marginTop="18dp"
                    android:gravity="center_vertical"
                    android:text="記錄"
                    android:textColor="@color/color_text_title"
                    android:textSize="20sp" />

                <FrameLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="18dp"
                    android:paddingLeft="20dp"
                    android:paddingRight="20dp">

                    <com.github.mikephil.charting.charts.PieChart
                        android:id="@+id/v_pie_chart"
                        android:layout_width="match_parent"
                        android:layout_height="228dp" />
                </FrameLayout>

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="10dp"
                    android:paddingLeft="20dp"
                    android:paddingRight="20dp">

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_centerVertical="true"
                        android:drawableLeft="@drawable/shape_circle_tingji1"
                        android:drawablePadding="10dp"
                        android:gravity="center_vertical"
                        android:text="掃碼"
                        android:textColor="@color/color_text_title"
                        android:textSize="16sp" />

                    <View
                        android:layout_width="0dp"
                        android:layout_height="1dp"
                        android:layout_weight="1" />

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_centerVertical="true"
                        android:drawableLeft="@drawable/shape_circle_tingji2"
                        android:drawablePadding="10dp"
                        android:gravity="center_vertical"
                        android:text="歷史價格"
                        android:textColor="@color/color_text_title"
                        android:textSize="16sp" />

                    <View
                        android:layout_width="0dp"
                        android:layout_height="1dp"
                        android:layout_weight="1" />

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_centerVertical="true"
                        android:drawableLeft="@drawable/shape_circle_tingji3"
                        android:drawablePadding="10dp"
                        android:gravity="center_vertical"
                        android:text="個性二維碼"
                        android:textColor="@color/color_text_title"
                        android:textSize="16sp" />
                </LinearLayout>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerVertical="true"
                    android:layout_marginLeft="20dp"
                    android:layout_marginTop="20dp"
                    android:gravity="center_vertical"
                    android:text="訂單"
                    android:textColor="@color/color_text_title"
                    android:textSize="20sp" />

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="10dp"
                    android:paddingLeft="20dp"
                    android:paddingRight="20dp">

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_centerVertical="true"
                        android:drawableLeft="@drawable/shape_circle_order1"
                        android:drawablePadding="8dp"
                        android:gravity="center_vertical"
                        android:text="未購買"
                        android:textColor="@color/color_text_title"
                        android:textSize="16sp" />

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_centerVertical="true"
                        android:layout_marginLeft="20dp"
                        android:drawableLeft="@drawable/shape_circle_order2"
                        android:drawablePadding="8dp"
                        android:gravity="center_vertical"
                        android:text="已購買"
                        android:textColor="@color/color_text_title"
                        android:textSize="16sp" />
                </LinearLayout>

                <FrameLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="20dp"
                    android:paddingLeft="20dp"
                    android:paddingRight="10dp"
                    android:layout_marginBottom="20dp">

                    <com.github.mikephil.charting.charts.LineChart
                       android:id="@+id/v_line_chart"
                        android:layout_width="match_parent"
                        android:layout_height="228dp" />
                </FrameLayout>
            </LinearLayout>
        </androidx.core.widget.NestedScrollView>
    </LinearLayout>

</layout>

5.4 Activity configuration data

public abstract class BaseActivity<Binding extends ViewDataBinding> extends AppCompatActivity {
    private ActivityBaseBinding activityBaseBinding;
    public Binding mDataBinding;
    public Activity mContext;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mContext = this;
        activityBaseBinding=DataBindingUtil.setContentView(this, R.layout.activity_base);
        initLayoutView();
    }

    private void initLayoutView() {
        activityBaseBinding.vBack.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                finish();
            }
        });
        StatuesBarUtils.setAppBar(this, true, R.color.white);
        mDataBinding = DataBindingUtil.inflate(getLayoutInflater(), getLayoutId(),
                activityBaseBinding.vContainer, true);
        initData();
    }

    public void hideTitleLayout() {
        StatuesBarUtils.setNoAppBar(this, true);
        activityBaseBinding.vTitleLayout.setVisibility(View.GONE);
    }
    public void hideTitleLayout(View viewStatues) {
        StatuesBarUtils.setNoAppBar(this, true);
        activityBaseBinding.vTitleLayout.setVisibility(View.GONE);
        LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) viewStatues.getLayoutParams();
        layoutParams.height = StatuesBarUtils.getStatusHeight(mContext);
        viewStatues.setLayoutParams(layoutParams);
    }
    public void setTitleText(String text) {
        activityBaseBinding.vHeadTitle.setText(text);
    }

    protected abstract int getLayoutId();

    public abstract void initData();
}
public class StatisticsActivity extends BaseActivity<ActivityStatisticsBinding> {
    private LineChart chart;//折线图
    private PieChart pieChart;//饼状图

    @Override
    protected int getLayoutId() {
        return R.layout.activity_statistics;
    }

    @Override
    public void initData() {
        hideTitleLayout(mDataBinding.viewStatues);
        mDataBinding.vBack.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                finish();
            }
        });
        mDataBinding.vDate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                initDatePicker();
            }
        });


        //饼状图组件
        pieChart = mDataBinding.vPieChart;
        initChartPie();

       //折线图组件
        chart = mDataBinding.vLineChart;
        initLineChar();
    }

    //初始化饼状图
    private void initChartPie() {
        //百分比数据
        pieChart.setUsePercentValues(true);
        //关闭描述
        pieChart.getDescription().setEnabled(false);
        //设置四周间距
        pieChart.setExtraOffsets(5, 10, 5, 5);
        //拖动旋转摩擦系数
        pieChart.setDragDecelerationFrictionCoef(0.95f);

        //中间文本
        pieChart.setCenterText("");

        //半透明区域
        pieChart.setTransparentCircleColor(Color.WHITE);
        pieChart.setTransparentCircleAlpha(110);

        //中间白色圆环半径
        pieChart.setHoleRadius(58f);
        pieChart.setDrawHoleEnabled(false);
        pieChart.setTransparentCircleRadius(61f);
        pieChart.setDrawCenterText(true);
        
        //旋转角度
        pieChart.setRotationAngle(90);
        //是否可以触摸旋转
        pieChart.setRotationEnabled(true);
        pieChart.setHighlightPerTapEnabled(true);
        
        //单位
        //chart.setUnit(" €");
        //chart.setDrawUnitsInChart(true);

        //选中监听
        //chart.setOnChartValueSelectedListener(this);
        pieChart.setEntryLabelColor(Color.BLACK);

        //动画
        pieChart.animateY(700, Easing.EaseInOutQuad);
        //chart.spin(2000, 0, 360);

        //图例
        Legend l = pieChart.getLegend();
        l.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
        l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT);
        l.setOrientation(Legend.LegendOrientation.VERTICAL);
        l.setDrawInside(false);
        l.setEnabled(false);

        //设置饼状图数据
        setPieData();
    }

    //设置饼状图数据
    private void setPieData() {
        //二维数组 二级数据
        ArrayList<PieEntry> entries = new ArrayList<>();
        entries.add(new PieEntry(51.0f, "掃碼", null));
        entries.add(new PieEntry(23.0f, "歷史價格", null));
        entries.add(new PieEntry(39.0f, "個性二維碼", null));
        

        //二维数组 一级数据
        PieDataSet dataSet = new PieDataSet(entries, "Election Results");
        //扇页之间间距
        //dataSet.setSliceSpace(3f);
        //dataSet.setSelectionShift(5f);

        //添加颜色
        ArrayList<Integer> colors = new ArrayList<>();
        colors.add(Color.parseColor("#37F0A2"));
        colors.add(Color.parseColor("#49DBEE"));
        colors.add(Color.parseColor("#43C088"));
        dataSet.setColors(colors);

        //设置百分比线的位置,分别是拐角,长线和短线
        dataSet.setValueLinePart1OffsetPercentage(80.f);
        dataSet.setValueLinePart1Length(0.3f);
        dataSet.setValueLinePart2Length(0.7f);
        
        //设置百分比线是在圆盘上还是圆盘外
        //dataSet.setXValuePosition(PieDataSet.ValuePosition.OUTSIDE_SLICE);
        dataSet.setYValuePosition(PieDataSet.ValuePosition.OUTSIDE_SLICE);

        //设置饼状数据
        PieData data = new PieData(dataSet);
        data.setValueFormatter(new PercentFormatter());
        //data.setValueFormatter(new AssetsFormatter());
        data.setValueTextSize(11f);
        data.setValueTextColor(Color.BLACK);
        pieChart.setData(data);

        //取消高亮
        pieChart.highlightValues(null);
        
        //刷新UI
        pieChart.invalidate();
    }


    //初始化折线配置
    private void initLineChar() {
        //选中监听
        //chart.setOnChartValueSelectedListener(this);

        //是否开启描述
        chart.getDescription().setEnabled(false);
        chart.setDescription(null);

        //是否支持手势点击
        chart.setTouchEnabled(true);
        //拖动摩擦系数,即拖动流畅度
        chart.setDragDecelerationFrictionCoef(0.9f);

        //是否可以缩放和拖拽
        chart.setDragEnabled(false);
        chart.setScaleEnabled(false);
        chart.setDrawGridBackground(false);
        chart.setHighlightPerDragEnabled(true);

        //如果禁用,可以分别在x轴和y轴上进行缩放
        chart.setPinchZoom(true);

        //背景颜色
        chart.setBackgroundColor(Color.TRANSPARENT);

        //动画
        chart.animateX(700);
        //无数据文案
        chart.setNoDataText("暫無數據");
        //四周间距
        //chart.setViewPortOffsets(10, 0, 0,10);

        //x轴配置
        XAxis xAxis = chart.getXAxis();
        //xAxis.setTypeface(tfLight);
        xAxis.setTextSize(11f);
        xAxis.setTextColor(Color.parseColor("#999999"));
        xAxis.setDrawGridLines(false);
        xAxis.setDrawAxisLine(false);
        //x轴刻度位置
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setAxisLineColor(Color.parseColor("#ECECEC"));
        xAxis.setGridColor(Color.parseColor("#ECECEC"));

        //Y轴左边线配置
        YAxis leftAxis = chart.getAxisLeft();
        //leftAxis.setTypeface(tfLight);
        leftAxis.setTextColor(Color.parseColor("#999999"));
        leftAxis.setAxisMaximum(200f);
        leftAxis.setAxisMinimum(0f);
        leftAxis.setDrawGridLines(true);
        leftAxis.setGranularityEnabled(false);
        leftAxis.setAxisLineColor(Color.TRANSPARENT);
        leftAxis.setGridColor(Color.parseColor("#ECECEC"));

        //禁用y轴右边线
        YAxis rightAxis = chart.getAxisRight();
        rightAxis.setEnabled(false);

        //图例
        Legend legend = chart.getLegend();
        legend.setEnabled(false);
        
        //设置折线数据
        setLineData();
    }


    //设置折线数据
    private List<Entry> allEntryList = new ArrayList<>();

    private void setLineData() {
        //二维数组 二级数据1
        ArrayList<Entry> values1 = new ArrayList<>();
        values1.add(new Entry(0, 12f));
        values1.add(new Entry(1, 29f));
        values1.add(new Entry(2, 19f));
        values1.add(new Entry(3, 25f));
        values1.add(new Entry(4, 18f));

        //二维数组 二级数据2
        ArrayList<Entry> values2 = new ArrayList<>();
        values2.add(new Entry(0, 16f));
        values2.add(new Entry(1, 33f));
        values2.add(new Entry(2, 11f));
        values2.add(new Entry(3, 20f));
        values2.add(new Entry(4, 26f));

        List<LineDataSet> lineDataSetList = new ArrayList<>();
        //第一条折线的数据
        if (values1.size() > 0) {
            LineDataSet set1 = new LineDataSet(values1, null);
            //创建数据集并为其指定类型
            set1.setAxisDependency(YAxis.AxisDependency.LEFT);
            //折线颜色
            set1.setColor(Color.parseColor("#35E5FF"));
            //折线宽
            set1.setLineWidth(2f);
            //折点是否填充,即实心还是空心
            set1.setFillAlpha(80);
            //高亮颜色
            set1.setHighLightColor(Color.TRANSPARENT);
            //绘制圆形孔
            set1.setDrawCircleHole(false);
            //折点颜色
            set1.setCircleColor(Color.parseColor("#FFBD02"));
            //折点半径
            set1.setCircleRadius(3f);
            //格式化折点数据
            //set1.setFillFormatter(new MyFillFormatter(0f));
            //是否绘制水平方向的高亮线
            set1.setDrawHorizontalHighlightIndicator(false);
            //该条折线是否可见
            //set1.setVisible(false);
            //绘制平面填充区域
            set1.setDrawFilled(true);
            if (Utils.getSDKInt() >= 18) {
                //仅在api级别18及以上版本上支持drawinables,渐变色drawable
                Drawable drawable = ContextCompat.getDrawable(this, R.drawable.line_fade_1);
                set1.setFillDrawable(drawable);
            } else {
                //纯色
                set1.setFillColor(Color.parseColor("#35E5FF"));
            }

            //添加所有折线的集合
            lineDataSetList.add(set1);
        }


        //第二条折线的数据
        if (values2.size() > 0) {
            LineDataSet set2 = new LineDataSet(values2, null);
            set2.setAxisDependency(YAxis.AxisDependency.RIGHT);
            set2.setColor(Color.parseColor("#FFBD02"));
            set2.setCircleColor(Color.parseColor("#35E5FF"));
            set2.setLineWidth(2f);
            set2.setCircleRadius(3f);
            set2.setFillAlpha(80);
            set2.setDrawFilled(true);
            set2.setDrawCircleHole(false);
            set2.setHighLightColor(Color.TRANSPARENT);
            if (Utils.getSDKInt() >= 18) {
                 //仅在api级别18及以上版本上支持drawinables,渐变色drawable
                Drawable drawable = ContextCompat.getDrawable(this, R.drawable.line_fade_2);
                set2.setFillDrawable(drawable);
            } else {
                set2.setFillColor(Color.parseColor("#FFBD02"));
            }

            lineDataSetList.add(set2);
        }

        //设置总数据
        if (lineDataSetList.size() > 0) {
            LineDataSet[] lineDataSets = lineDataSetList.toArray(new LineDataSet[lineDataSetList.size()]);    
            LineData data = new LineData(lineDataSets);
            data.setValueTextColor(Color.TRANSPARENT);
            data.setValueTextSize(9f);

            //这是折线数据
            chart.setData(data);

            //设置x轴值
            chart.getXAxis().setLabelCount(values1.size(), true);
            chart.getXAxis().setValueFormatter(new ValueFormatter() {
                @Override
                public String getFormattedValue(float value) {
                    String[] monthArray = new String[]{"一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"};
                    int index = (int) value;
                    return monthArray[index];
                }
            });

            //设置Y最大值
            allEntryList.clear();
            allEntryList.addAll(values1);
            allEntryList.addAll(values2);
            List<Float> floatYList = new ArrayList<>();
            for (Entry entry : allEntryList) {
                floatYList.add(entry.getY());
            }
            if (allEntryList.size() > 0) {
                //设置Y轴最大设置范围和格式化数据
                chart.getAxisLeft().setAxisMaximum(Collections.max(floatYList) + 10);
                chart.getAxisLeft().setValueFormatter(new ValueFormatter() {
                    @Override
                    public String getFormattedValue(float v) {
                        return String.valueOf(v);
                    }
                });
            }
        } else {
            chart.setData(null);
        }
        //刷新图表
        chart.invalidate();
    }
}

Advanced six-line chart, add average limit line

6.1 Rendering

6.2 Go directly to the configuration

package com.xixia.chart;

import android.content.Context;
import android.graphics.Color;

import com.github.mikephil.charting.charts.LineChart;
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.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.formatter.IndexAxisValueFormatter;
import com.github.mikephil.charting.utils.ColorTemplate;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;

/**
 * @ClassName LineChartViewUtils
 * @Description TODO 内容
 * @Author biekangdong
 * @CreateDate 2023/5/25 21:28
 * @Version 1.0
 * @UpdateDate 2023/5/25 21:28
 * @UpdateRemark 更新说明
 */
public class LineChartViewUtils {
    private Context context;
    public LineChartViewUtils(Context context) {
        this.context=context;
    }

    //配置折线数据
    private void initChart(LineChart chart) {
        //关闭描述
        chart.getDescription().setEnabled(false);
        //关闭高亮
        chart.setHighlightPerDragEnabled(false);

        //关闭图例
        Legend l = chart.getLegend();
        l.setEnabled(false);

        //x轴数据
        XAxis xAxis = chart.getXAxis();
        xAxis.setPosition(XAxis.XAxisPosition.BOTH_SIDED);
        xAxis.setTextSize(10f);
        xAxis.setTextColor(Color.parseColor("#999999"));
        xAxis.setDrawAxisLine(true);
        xAxis.setAxisLineColor(Color.parseColor("#DADADA"));
        xAxis.setAxisLineWidth(0.5f);
        xAxis.setDrawGridLines(true);
        xAxis.setGridColor(Color.parseColor("#DADADA"));
        xAxis.setGridLineWidth(0.5f);
        chart.getXAxis().setValueFormatter(indexAxisValueFormatter);

        //Y轴数据
        YAxis leftAxis = chart.getAxisLeft();
        leftAxis.setEnabled(true);
        leftAxis.setPosition(YAxis.YAxisLabelPosition.INSIDE_CHART);
        leftAxis.setTextColor(Color.TRANSPARENT);
        leftAxis.setDrawGridLines(false);
        leftAxis.setDrawAxisLine(false);
        //最小Y轴
        //leftAxis.setAxisMinimum(0f);
        //最大Y轴
        //leftAxis.setAxisMaximum(170f);
        //Y轴偏移
        //leftAxis.setYOffset(-9f);

        //关闭右边Y轴数值显示
        YAxis rightAxis = chart.getAxisRight();
        rightAxis.setEnabled(true);
        rightAxis.setPosition(YAxis.YAxisLabelPosition.INSIDE_CHART);
        rightAxis.setTextColor(Color.TRANSPARENT);
        rightAxis.setDrawGridLines(false);
        rightAxis.setDrawAxisLine(false);
    }

    int position = 0;
    //时间格式化
    SimpleDateFormat mFormatHour = new SimpleDateFormat("HH:mm", Locale.ENGLISH);
    SimpleDateFormat mFormatMonth = new SimpleDateFormat("MM/dd", Locale.ENGLISH);
    SimpleDateFormat mFormatYear = new SimpleDateFormat("MM", Locale.ENGLISH);
    IndexAxisValueFormatter indexAxisValueFormatter = new IndexAxisValueFormatter() {
        @Override
        public String getFormattedValue(float value) {
            String valueString = "";
            long millis = System.currentTimeMillis();
            switch (position) {
                case 0:
                case 1:
                    valueString = mFormatHour.format(new Date(millis));
                    break;
                case 2:
                    valueString = getWeekOfDate(millis);
                    break;
                case 3:
                    valueString = mFormatMonth.format(new Date(millis));
                    break;
                case 4:
                    valueString = mFormatYear.format(new Date(millis));
                    break;
            }
            return valueString;
        }
    };

    //根据时间戳获取星期
    public static String getWeekOfDate(long timestamp) {
        String[] weekDays = {"周日", "周一", "周二", "周三", "周四", "周五", "周六"};
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date(timestamp));
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0)
            w = 0;
        return weekDays[w];
    }

    //设置数据
    public void setCharDataList(LineChart chart, ArrayList<Entry> entryList, List<Float> valueList, float allValue, String unit) {
        //平均值
        float average = allValue / 10;
        LimitLine limitLine = new LimitLine(average, average + unit + " 平均");
        limitLine.enableDashedLine(10f, 10f, 0f);
        if (Collections.max(valueList) - average > 0.3) {
            limitLine.setLabelPosition(LimitLine.LimitLabelPosition.LEFT_TOP);
        } else {
            limitLine.setLabelPosition(LimitLine.LimitLabelPosition.LEFT_BOTTOM);
        }
        limitLine.setTextSize(10f);
        limitLine.setLineColor(Color.parseColor("#6b9cdf"));
        limitLine.setLineWidth(0.5f);
        limitLine.setTextSize(10);
        limitLine.setTextColor(Color.parseColor("#6b9cdf"));
        limitLine.setYOffset(10);

        //Y轴左右平均值数据
        YAxis leftAxis = chart.getAxisLeft();
        YAxis rightAxis = chart.getAxisRight();
        leftAxis.removeAllLimitLines();
        rightAxis.removeAllLimitLines();
        leftAxis.setDrawLimitLinesBehindData(true);
        rightAxis.setDrawLimitLinesBehindData(true);
        //Y轴左右添加平均线
        leftAxis.addLimitLine(limitLine);
        rightAxis.addLimitLine(limitLine);

        //填充数据
        LineDataSet set1 = new LineDataSet(entryList, "DataSet 1");
        set1.setAxisDependency(YAxis.AxisDependency.LEFT);
        set1.setColor(ColorTemplate.getHoloBlue());
        set1.setValueTextColor(ColorTemplate.getHoloBlue());
        set1.setLineWidth(1f);
        set1.setDrawCircles(false);
        set1.setDrawValues(false);
        set1.setFillAlpha(65);
        set1.setFillColor(Color.parseColor("#6b9cdf"));
        set1.setHighLightColor(Color.parseColor("#6b9cdf"));
        set1.setDrawCircleHole(false);

        //使用数据集创建数据对象
        LineData data = new LineData(set1);
        data.setValueTextColor(Color.WHITE);
        data.setValueTextSize(9f);

        //这是折线数据
        chart.setData(data);
        //动画
        //chart.animateX(1000);
        //chart.animateY(1000);
        //更新图表UI
        chart.invalidate();
    }


    //点击事件
    private void onViewClick(){
        setData(0);
    }
    //设置温度,湿度,华氏度图表数据
    public void setData(int tabSelectPosition) {
        //温度℃
        ArrayList<Entry> valuesTemperature = new ArrayList<>();//温度图表数据
        float allValueTemperature = 0;//温度平均值
        List<Float> temperatureList = new ArrayList<>();//温度集合
        //温度F
        ArrayList<Entry> valuesTemperatureFF = new ArrayList<>();//温度图表数据
        float allValueTemperatureFF = 0;//温度平均值
        List<Float> temperatureListFF = new ArrayList<>();//温度集合
        //湿度
        ArrayList<Entry> valuesHumidity = new ArrayList<>();//湿度图表数据
        float allValueHumidity = 0;//湿度平均值
        List<Float> humidityList = new ArrayList<>();//湿度集合

        //温度合集
        List<String> list = new ArrayList<>();
        list.add("50");
        list.add("20");
        list.add("40");
        list.add("60");
        list.add("40");
        list.add("30");
        for (int i = 0; i < list.size(); i++) {
            String temperature = list.get(i);
            String humidity = String.valueOf(Math.random());
            //温度℃
            temperatureList.add(Float.valueOf(temperature));
            allValueTemperature += Float.parseFloat(temperature);
            valuesTemperature.add(new Entry(i, Float.parseFloat(temperature)));
            //温度℉
            temperatureListFF.add(Float.valueOf(temperature) * 1.8f + 32);
            allValueTemperatureFF += Float.parseFloat(temperature) * 1.8f + 32;
            valuesTemperatureFF.add(new Entry(i, Float.parseFloat(temperature) * 1.8f + 32));
            //湿度
            humidityList.add(Float.valueOf(humidity));
            allValueHumidity += Float.parseFloat(humidity);
            valuesHumidity.add(new Entry(i, Float.parseFloat(humidity)));
        }

        int positon = 0;
        switch (positon) {
            case 0:
                setCharDataList(new LineChart(context), valuesTemperatureFF, temperatureListFF, allValueTemperatureFF, "℉");
                break;
            case 1:
                setCharDataList(new LineChart(context), valuesTemperature, temperatureList, allValueTemperature, "℃");
                break;
            case 2:
                setCharDataList(new LineChart(context), valuesHumidity, humidityList, allValueHumidity, "%");
                break;
        }
    }
}

Seven-ring progress chart with and without rounded corners

7.1 Effect drawing with rounded corners

 7.2 Customize the ring class, with rounded corners, the style of the first picture above

public class CircleProgressView extends View {

    private Paint mBackPaint, mProgPaint;   // 绘制画笔
    private RectF mRectF;       // 绘制区域
    private int[] mColorArray;  // 圆环渐变色
    private int mProgress;      // 圆环进度(0-100)

    public CircleProgressView(Context context) {
        this(context, null);
    }

    public CircleProgressView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CircleProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircularProgressView);

        // 初始化背景圆环画笔
        mBackPaint = new Paint();
        mBackPaint.setStyle(Paint.Style.STROKE);    // 只描边,不填充
        mBackPaint.setStrokeCap(Paint.Cap.ROUND);   // 设置圆角
        mBackPaint.setAntiAlias(true);              // 设置抗锯齿
        mBackPaint.setDither(true);                 // 设置抖动
        mBackPaint.setStrokeWidth(typedArray.getDimension(R.styleable.CircularProgressView_backWidth, 5));
        mBackPaint.setColor(typedArray.getColor(R.styleable.CircularProgressView_backColor, Color.LTGRAY));


        // 初始化进度圆环画笔
        mProgPaint = new Paint();
        mProgPaint.setStyle(Paint.Style.STROKE);    // 只描边,不填充
        mProgPaint.setStrokeCap(Paint.Cap.ROUND);   // 设置圆角
        mProgPaint.setAntiAlias(true);              // 设置抗锯齿
        mProgPaint.setDither(true);                 // 设置抖动
        mProgPaint.setStrokeWidth(typedArray.getDimension(R.styleable.CircularProgressView_progWidth, 10));
        mProgPaint.setColor(typedArray.getColor(R.styleable.CircularProgressView_progColor, Color.BLUE));

        // 初始化进度圆环渐变色
        int startColor = typedArray.getColor(R.styleable.CircularProgressView_progStartColor, -1);
        int firstColor = typedArray.getColor(R.styleable.CircularProgressView_progFirstColor, -1);
        if (startColor != -1 && firstColor != -1) mColorArray = new int[]{startColor, firstColor};
        else mColorArray = null;

        // 初始化进度
        mProgress = typedArray.getInteger(R.styleable.CircularProgressView_progress, 0);
        typedArray.recycle();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int viewWide = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
        int viewHigh = getMeasuredHeight() - getPaddingTop() - getPaddingBottom();
        int mRectLength = (int) ((viewWide > viewHigh ? viewHigh : viewWide) - (mBackPaint.getStrokeWidth() > mProgPaint.getStrokeWidth() ? mBackPaint.getStrokeWidth() : mProgPaint.getStrokeWidth()));
        int mRectL = getPaddingLeft() + (viewWide - mRectLength) / 2;
        int mRectT = getPaddingTop() + (viewHigh - mRectLength) / 2;
        mRectF = new RectF(mRectL, mRectT, mRectL + mRectLength, mRectT + mRectLength);

        // 设置进度圆环渐变色
        if (mColorArray != null && mColorArray.length > 1)
            mProgPaint.setShader(new LinearGradient(0, 0, 0, getMeasuredWidth(), mColorArray, null, Shader.TileMode.MIRROR));
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawArc(mRectF, 0, 360, false, mBackPaint);
        canvas.drawArc(mRectF, 275, 360 * mProgress / 100, false, mProgPaint);
    }

    // ---------------------------------------------------------------------------------------------

    /**
     * 获取当前进度
     *
     * @return 当前进度(0-100)
     */
    public int getProgress() {
        return mProgress;
    }

    /**
     * 设置当前进度
     *
     * @param progress 当前进度(0-100)
     */
    public void setProgress(int progress) {
        this.mProgress = progress;
        invalidate();
    }

    /**
     * 设置当前进度,并展示进度动画。如果动画时间小于等于0,则不展示动画
     *
     * @param progress 当前进度(0-100)
     * @param animTime 动画时间(毫秒)
     */
    public void setProgress(int progress, long animTime) {
        if (animTime <= 0) setProgress(progress);
        else {
            ValueAnimator animator = ValueAnimator.ofInt(mProgress, progress);
            animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    mProgress = (int) animation.getAnimatedValue();
                    invalidate();
                }
            });
            animator.setInterpolator(new OvershootInterpolator());
            animator.setDuration(animTime);
            animator.start();
        }
    }

    /**
     * 设置背景圆环宽度
     *
     * @param width 背景圆环宽度
     */
    public void setBackWidth(int width) {
        mBackPaint.setStrokeWidth(width);
        invalidate();
    }

    /**
     * 设置背景圆环颜色
     *
     * @param color 背景圆环颜色
     */
    public void setBackColor(@ColorRes int color) {
        mBackPaint.setColor(ContextCompat.getColor(getContext(), color));
        invalidate();
    }

    /**
     * 设置进度圆环宽度
     *
     * @param width 进度圆环宽度
     */
    public void setProgWidth(int width) {
        mProgPaint.setStrokeWidth(width);
        invalidate();
    }

    /**
     * 设置进度圆环颜色
     *
     * @param color 景圆环颜色
     */
    public void setProgColor(@ColorRes int color) {
        mProgPaint.setColor(ContextCompat.getColor(getContext(), color));
        mProgPaint.setShader(null);
        invalidate();
    }

    /**
     * 设置进度圆环颜色(支持渐变色)
     *
     * @param startColor 进度圆环开始颜色
     * @param firstColor 进度圆环结束颜色
     */
    public void setProgColor(@ColorRes int startColor, @ColorRes int firstColor) {
        mColorArray = new int[]{ContextCompat.getColor(getContext(), startColor), ContextCompat.getColor(getContext(), firstColor)};
        mProgPaint.setShader(new LinearGradient(0, 0, 0, getMeasuredWidth(), mColorArray, null, Shader.TileMode.MIRROR));
        invalidate();
    }

    /**
     * 设置进度圆环颜色(支持渐变色)
     *
     * @param colorArray 渐变色集合
     */
    public void setProgColor(@ColorRes int[] colorArray) {
        if (colorArray == null || colorArray.length < 2) return;
        mColorArray = new int[colorArray.length];
        for (int index = 0; index < colorArray.length; index++)
            mColorArray[index] = ContextCompat.getColor(getContext(), colorArray[index]);
        mProgPaint.setShader(new LinearGradient(0, 0, 0, getMeasuredWidth(), mColorArray, null, Shader.TileMode.MIRROR));
        invalidate();
    }
}

 use:

xml add control

 <RelativeLayout
        android:layout_width="177dp"
        android:layout_height="177dp"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="25dp"
        android:gravity="center_horizontal">

        <FrameLayout
            android:layout_width="177dp"
            android:layout_height="177dp">
            <View
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_margin="4dp"
                android:background="@drawable/shape_bg_f2efff"/>
            <com.example.finance.CircleProgressView
                android:id="@+id/cp_progress"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:backColor="@color/trans"
                app:backWidth="8dp"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:progColor="@color/color_blue"
                app:progWidth="8dp"
                app:progress="0" />
        </FrameLayout>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:gravity="center"
            android:orientation="vertical">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="24dp"
                android:text="BMI"
                android:textColor="#ff262729"
                android:textSize="20sp" />

            <TextView
                android:id="@+id/tv_progress"
                android:layout_width="wrap_content"
                android:layout_height="24dp"
                android:text="0"
                android:textStyle="bold"
                android:textColor="#ff7783ff"
                android:textSize="20sp" />

            <TextView
                android:id="@+id/tv_progress_value"
                android:layout_width="wrap_content"
                android:layout_height="16dp"
                android:text="你的体型很标准哦"
                android:textColor="#ff262729"
                android:layout_marginTop="13dp"
                android:textSize="12sp" />
        </LinearLayout>

    </RelativeLayout>

Java sets the progress of the ring:

CircleProgressView cpProgress = (CircleProgressView) findViewById(R.id.cp_progress);
cpProgress.setProgress((int) (30/60f*100));

7.3 Effect picture without rounded corners

 7.4 xml add components

 <androidx.cardview.widget.CardView
	android:id="@+id/cl_budget"
	android:layout_width="match_parent"
	android:layout_height="wrap_content"
	android:layout_marginLeft="15dp"
	android:layout_marginTop="20dp"
	android:layout_marginRight="15dp"
	app:cardBackgroundColor="@color/white"
	app:cardCornerRadius="@dimen/dp_5"
	app:cardElevation="3dp">

	<androidx.constraintlayout.widget.ConstraintLayout
		android:layout_width="110dp"
		android:layout_height="110dp"
		android:layout_gravity="center_vertical"
		android:layout_marginLeft="20dp"
		android:layout_marginTop="25dp"
		android:layout_marginBottom="25dp">

		<com.dinghe.financeapp.utils.CircleProgressView
		   android:id="@+id/cp_progress"
			android:layout_width="0dp"
			android:layout_height="0dp"
			app:backColor="@color/color_d8d8d8"
			app:backWidth="8dp"
			app:layout_constraintBottom_toBottomOf="parent"
			app:layout_constraintLeft_toLeftOf="parent"
			app:layout_constraintRight_toRightOf="parent"
			app:layout_constraintTop_toTopOf="parent"
			app:progColor="@color/color_blue"
			app:progWidth="8dp"
			app:progress="0" />

		<TextView
			android:id="@+id/tv_progress"
			style="@style/Font_black"
			android:layout_centerInParent="true"
			android:text="0"
			android:textColor="@color/color_3d"
			android:textSize="24sp"
			android:textStyle="bold"
			app:layout_constraintBottom_toBottomOf="parent"
			app:layout_constraintLeft_toLeftOf="parent"
			app:layout_constraintRight_toRightOf="parent"
			app:layout_constraintTop_toTopOf="parent" />

		<TextView
			style="@style/Font_black"
			android:layout_marginLeft="4dp"
			android:layout_marginBottom="3dp"
			android:text="%"
			android:textColor="@color/color_3d"
			android:textSize="14sp"
			app:layout_constraintBottom_toBottomOf="@id/tv_progress"
			app:layout_constraintLeft_toRightOf="@id/tv_progress" />
	</androidx.constraintlayout.widget.ConstraintLayout>

	<LinearLayout
		android:layout_width="match_parent"
		android:layout_height="wrap_content"
		android:layout_gravity="center_vertical"
		android:layout_marginLeft="140dp"
		android:layout_marginRight="15dp"
		android:orientation="vertical">

		<RelativeLayout
			android:layout_width="match_parent"
			android:layout_height="wrap_content"
			android:gravity="center_vertical">

			<TextView
				style="@style/Font_black"
				android:layout_centerVertical="true"
				android:text="@string/me_budget"
				android:textSize="17sp"
				android:textStyle="bold" />

			<ImageView
				android:layout_width="wrap_content"
				android:layout_height="wrap_content"
				android:layout_alignParentRight="true"
				android:layout_centerVertical="true"
				android:src="@mipmap/ic_next2" />
		</RelativeLayout>

		<TextView
			android:id="@+id/tv_budget_amount"
			style="@style/Font_black"
			android:layout_marginTop="10dp"
			android:text="@string/me_budget_amount"
			android:textSize="14sp" />

		<TextView
			android:id="@+id/tv_budget_outlay"
			style="@style/Font_black"
			android:layout_marginTop="5dp"
			android:text="@string/me_budget_outlay"
			android:textSize="14sp" />

		<TextView
			android:id="@+id/tv_budget_balance"
			style="@style/Font_black"
			android:layout_marginTop="5dp"
			android:text="@string/me_budget_balance"
			android:textSize="14sp" />
	</LinearLayout>
</androidx.cardview.widget.CardView>

java set progress

CircleProgressView cpProgress = (CircleProgressView) findViewById(R.id.cp_progress);
cpProgress.setProgress((int) (30/80f*100));

Eight gauge diagram

8.1 Rendering

 8.2 Custom Dashboard View

public class DashboardView3 extends BaseDashboardView {

    //外环画笔
    private Paint mPaintOuterArc;
    //内环画笔
    private Paint mPaintInnerArc;
    //进度点画笔
    private Paint mPaintProgressPoint;
    //指示器画笔
    private Paint mPaintIndicator;
    //外环区域
    private RectF mRectOuterArc;
    //内环区域
    private RectF mRectInnerArc;
    //圆环画笔颜色
    private int mOuterArcColor;
    private int mProgressOuterArcColor;
    //内环画笔颜色
    private int mInnerArcColor;
    private int mProgressInnerArcColor;
    //内外环之间的间距
    private float mArcSpacing;
    //进度条的圆点属性
    private float[] mProgressPointPosition;
    private float mProgressPointRadius;
    //指标器的Path
    private Path mIndicatorPath;
    //指示器的起始位置
    private float mIndicatorStart;

    //默认圆环之间间距
    private static final float DEFAULT_ARC_SPACING = 10;
    //外环的默认属性
    private static final float DEFAULT_OUTER_ARC_WIDTH = 1.5f;
    private static final int DEFAULT_OUTER_ARC_COLOR = Color.argb(80, 255, 255, 255);
    //外环进度的默认属性
    private static final int DEFAULT_PROGRESS_OUTER_ARC_COLOR = Color.argb(200, 255, 255, 255);
    //进度点的默认属性
    private static final float DEFAULT_PROGRESS_POINT_RADIUS = 3;
    private static final int DEFAULT_PROGRESS_POINT_COLOR = Color.WHITE;
    //内环默认属性
    private static final float DEFAULT_INNER_ARC_WIDTH = 1.5f;
    private static final int DEFAULT_INNER_ARC_COLOR = Color.argb(50, 255, 255, 255);
    //内环进度的默认属性
    private static final int DEFAULT_PROGRESS_INNER_ARC_COLOR = Color.argb(170, 255, 255, 255);
    //指示器默认属性
    private static final int DEFAULT_INDICATOR_COLOR = Color.argb(200, 255, 255, 255);


    public DashboardView3(Context context) {
        this(context, null);
    }

    public DashboardView3(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public DashboardView3(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    /**
     * 初始化界面
     */
    @Override
    protected void initView() {
        //默认数据
        mArcSpacing = dp2px(DEFAULT_ARC_SPACING);
        mOuterArcColor = DEFAULT_OUTER_ARC_COLOR;
        mProgressOuterArcColor = DEFAULT_PROGRESS_OUTER_ARC_COLOR;
        mProgressPointRadius = dp2px(DEFAULT_PROGRESS_POINT_RADIUS);
        mInnerArcColor = DEFAULT_INNER_ARC_COLOR;
        mProgressInnerArcColor = DEFAULT_PROGRESS_INNER_ARC_COLOR;

        //初始化画笔
        //外环画笔
        mPaintOuterArc = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaintOuterArc.setStrokeWidth(dp2px(DEFAULT_OUTER_ARC_WIDTH));
        mPaintOuterArc.setStyle(Paint.Style.STROKE);

        //内环画笔
        mPaintInnerArc = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaintInnerArc.setStrokeWidth(dp2px(DEFAULT_INNER_ARC_WIDTH));
        mPaintInnerArc.setStyle(Paint.Style.STROKE);
        mPaintInnerArc.setStrokeCap(Paint.Cap.ROUND);
        PathEffect mPathEffect = new DashPathEffect(new float[] { 10, 10 }, 0);
        mPaintInnerArc.setPathEffect(mPathEffect);

        //进度点画笔
        mPaintProgressPoint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaintProgressPoint.setStyle(Paint.Style.FILL);
        mPaintProgressPoint.setColor(DEFAULT_PROGRESS_POINT_COLOR);

        //指示器画笔
        mPaintIndicator = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaintIndicator.setStrokeCap(Paint.Cap.SQUARE);
        mPaintIndicator.setColor(DEFAULT_INDICATOR_COLOR);
        mPaintIndicator.setStrokeWidth(dp2px(1));

        //进度点的图片
        mProgressPointPosition = new float[2];
    }

    /**
     * 初始化圆环区域
     */
    @Override
    protected void initArcRect(float left, float top, float right, float bottom) {
        //外环区域
        mRectOuterArc = new RectF(left, top, right, bottom);

        initInnerRect();
    }

    /**
     * 初始化内部的区域
     */
    private void initInnerRect() {
        //内环位置
        mRectInnerArc = new RectF(mRectOuterArc.left + mArcSpacing,mRectOuterArc.top + mArcSpacing,
                mRectOuterArc.right - mArcSpacing , mRectOuterArc.bottom - mArcSpacing);

        //指标器的路径
        mIndicatorStart = mRectInnerArc.top + mArcSpacing / 2;
        mIndicatorPath = new Path();
        mIndicatorPath.moveTo(mRadius, mIndicatorStart);
        mIndicatorPath.rLineTo(-dp2px(2), dp2px(5));
        mIndicatorPath.rLineTo(dp2px(4), 0);
        mIndicatorPath.close();
    }

    /**
     * 绘制圆环
     */
    @Override
    protected void drawArc(Canvas canvas, float arcStartAngle, float arcSweepAngle) {
        //绘制圆环
        mPaintOuterArc.setColor(mOuterArcColor);
        canvas.drawArc(mRectOuterArc, arcStartAngle, arcSweepAngle, false, mPaintOuterArc);

        //绘制内环
        mPaintInnerArc.setColor(mInnerArcColor);
        canvas.drawArc(mRectInnerArc, arcStartAngle, arcSweepAngle, false, mPaintInnerArc);
    }

    /**
     * 绘制进度圆环
     */
    @Override
    protected void drawProgressArc(Canvas canvas, float arcStartAngle, float progressSweepAngle) {
        //绘制进度点
        if(progressSweepAngle == 0) {
            return;
        }
        Path path = new Path();
        //添加进度圆环的区域
        path.addArc(mRectOuterArc, arcStartAngle, progressSweepAngle);
        //计算切线值和为重
        PathMeasure pathMeasure = new PathMeasure(path, false);
        pathMeasure.getPosTan(pathMeasure.getLength(), mProgressPointPosition, null);
        //绘制圆环
        mPaintOuterArc.setColor(mProgressOuterArcColor);
        canvas.drawPath(path, mPaintOuterArc);
        //绘制进度点
        if(mProgressPointPosition[0] != 0 && mProgressPointPosition[1] != 0) {
            canvas.drawCircle(mProgressPointPosition[0], mProgressPointPosition[1], mProgressPointRadius, mPaintProgressPoint);
        }

        //绘制内环
        mPaintInnerArc.setColor(mProgressInnerArcColor);
        canvas.drawArc(mRectInnerArc, arcStartAngle, progressSweepAngle, false, mPaintInnerArc);

        //绘制指针
        canvas.save();
        canvas.rotate(arcStartAngle + progressSweepAngle - 270, mRadius, mRadius);
        mPaintIndicator.setStyle(Paint.Style.FILL);
        canvas.drawPath(mIndicatorPath, mPaintIndicator);
        mPaintIndicator.setStyle(Paint.Style.STROKE);
        canvas.drawCircle(mRadius, mIndicatorStart + dp2px(6) + 1, dp2px(2), mPaintIndicator);
        canvas.restore();
    }

    /**
     * 绘制文字
     */
    @Override
    protected void drawText(Canvas canvas, int value, String valueLevel, String currentTime) {
        //绘制数值
        float marginTop = mRadius + mTextSpacing;
        canvas.drawText(String.valueOf(value), mRadius, marginTop, mPaintValue);

        //绘制数值文字信息
        if(!TextUtils.isEmpty(valueLevel)){
            float margin = mRadius - mTextSpacing - getPaintHeight(mPaintValue, "9");
            canvas.drawText(valueLevel, mRadius, margin, mPaintValueLevel);
        }

        //绘制日期
        if(!TextUtils.isEmpty(currentTime)) {
            marginTop = marginTop + getPaintHeight(mPaintDate, currentTime) + mTextSpacing;
            canvas.drawText(currentTime, mRadius, marginTop, mPaintDate);
        }
    }

    /**
     * 设置圆环的距离
     */
    public void setArcSpacing(float dpSize){
        mArcSpacing = dp2px(dpSize);

        initInnerRect();

        postInvalidate();
    }

    /**
     * 设置外环颜色
     */
    public void setOuterArcPaint(float dpSize, @ColorInt int color){
        mPaintOuterArc.setStrokeWidth(dp2px(dpSize));
        mOuterArcColor = color;

        postInvalidate();
    }

    /**
     * 设置进度条的颜色
     */
    public void setProgressOuterArcColor(@ColorInt int color){
        mProgressOuterArcColor = color;

        postInvalidate();
    }

    /**
     * 设置内环的属性
     */
    public void setInnerArcPaint(float dpSize, @ColorInt int color){
        mPaintInnerArc.setStrokeWidth(dp2px(dpSize));
        mInnerArcColor = color;

        postInvalidate();
    }

    /**
     * 设置内环的属性
     */
    public void setProgressInnerArcPaint(@ColorInt int color){
        mProgressInnerArcColor = color;

        postInvalidate();
    }

    /**
     * 设置内环实线和虚线状态
     */
    public void setInnerArcPathEffect(float[] intervals){
        PathEffect mPathEffect = new DashPathEffect(intervals, 0);
        mPaintInnerArc.setPathEffect(mPathEffect);

        postInvalidate();
    }

    /**
     * 设置进度圆点的属性
     */
    public void setProgressPointPaint(float dpRadiusSize,@ColorInt int color){
        mProgressPointRadius = dp2px(dpRadiusSize);
        mPaintProgressPoint.setColor(color);

        postInvalidate();
    }

    /**
     * 设置指示器属性
     */
    public void setIndicatorPaint(@ColorInt int color){
        mPaintIndicator.setColor(color);

        postInvalidate();
    }
}

8.3 Use:

<LinearLayout
	android:layout_width="match_parent"
	android:layout_height="wrap_content"
	android:background="@drawable/bg"
	android:gravity="center_horizontal">

	<com.github.iron.chart.dashboard.DashboardView3
		android:id="@+id/dv"
		android:layout_width="250dp"
		android:layout_height="180dp"
		android:layout_marginTop="30dp"
		android:layout_marginBottom="40dp" />
</LinearLayout>
DashboardView3 dashboardView= findViewById(R.id.dv);
dashboardView.setDateStrPattern("评估时间:2023-05-25");
dashboardView.setValueLevelPattern("信用优秀");
int max = dashboardView.getMax();
int min = dashboardView.getMin();
dashboardView.setValue(new Random().nextInt(max - min) + min, anim, reset);

Guess you like

Origin blog.csdn.net/qq_29848853/article/details/130868720