DecoView的使用

DecoView是一款专为Android平台设计的动画圆形图表库,能让你轻松打造出类似Google Fit那样的炫酷圆环视图.它的自定义选项很丰富,无论是数据序列(SeriesItem)还是动画事件(DecoEvent),从颜色到线条粗细都能精细配置.而且直接写在XML布局里就行,代码调用也很简单,做些健身,智能家居之类的App时用来展示进度或实时数据,效果会非常直观生动.

1. 引入DecoView的库

在Android项目的build.gradle(Module :app)中添加,然后在Sync.

implementation 'com.github.bmarrdev:android-DecoView-charting:v1.2'

如果出现下面的错误:

Duplicate class android.support.v4.app.INotificationSideChannel found in modules core-1.7.0-runtime (androidx.core:core:1.7.0) and support-v4-23.3.0-runtime (com.android.support:support-v4:23.3.0)
Duplicate class android.support.v4.app.INotificationSideChannel$Stub found in modules core-1.7.0-runtime (androidx.core:core:1.7.0) and support-v4-23.3.0-runtime (com.android.support:support-v4:23.3.0)
Duplicate class android.support.v4.app.INotificationSideChannel$Stub$Proxy found in modules core-1.7.0-runtime (androidx.core:core:1.7.0) and support-v4-23.3.0-runtime (com.android.support:support-v4:23.3.0)
Duplicate class android.support.v4.os.IResultReceiver found in modules core-1.7.0-runtime (androidx.core:core:1.7.0) and support-v4-23.3.0-runtime (com.android.support:support-v4:23.3.0)
Duplicate class android.support.v4.os.IResultReceiver$Stub found in modules core-1.7.0-runtime (androidx.core:core:1.7.0) and support-v4-23.3.0-runtime (com.android.support:support-v4:23.3.0)
Duplicate class android.support.v4.os.IResultReceiver$Stub$Proxy found in modules core-1.7.0-runtime (androidx.core:core:1.7.0) and support-v4-23.3.0-runtime (com.android.support:support-v4:23.3.0)
Duplicate class android.support.v4.os.ResultReceiver found in modules core-1.7.0-runtime (androidx.core:core:1.7.0) and support-v4-23.3.0-runtime (com.android.support:support-v4:23.3.0)
Duplicate class android.support.v4.os.ResultReceiver$1 found in modules core-1.7.0-runtime (androidx.core:core:1.7.0) and support-v4-23.3.0-runtime (com.android.support:support-v4:23.3.0)
Duplicate class android.support.v4.os.ResultReceiver$MyResultReceiver found in modules core-1.7.0-runtime (androidx.core:core:1.7.0) and support-v4-23.3.0-runtime (com.android.support:support-v4:23.3.0)
Duplicate class android.support.v4.os.ResultReceiver$MyRunnable found in modules core-1.7.0-runtime (androidx.core:core:1.7.0) and support-v4-23.3.0-runtime (com.android.support:support-v4:23.3.0)

Go to the documentation to learn how to Fix dependency resolution errors.

这个问题的核心是项目的依赖项中同时混用了老旧的Android Support库和现代的AndroidX库,而你的项目本身很可能已经迁移到了AndroidX.Android官方已经停止维护Support库,并推荐所有项目迁移到AndroidX.因此,唯一的解决方案是彻底清理项目中的Support库依赖.解决这个问题的唯一方法是彻底清除项目中对Support库的依赖.在gradle.properties文件中添加:

# 启用AndroidX库
android.useAndroidX=true
# 启用Jetifier,将第三方库中的Support库自动转换为AndroidX
android.enableJetifier=true

2. 在项目中添加如下的布局文件cardview_deco.xml:

<androidx.cardview.widget.CardView
    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:id="@+id/time_item_cardview2"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="0dp"
    app:cardUseCompatPadding="false"
    app:cardBackgroundColor="@android:color/transparent"
    app:cardElevation="0dp"
    app:cardMaxElevation="0dp"
    android:clipChildren="false"
    android:clipToPadding="false">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:gravity="center"
        android:paddingTop="4dp"
        android:paddingBottom="8dp"
        android:clipChildren="false"
        android:clipToPadding="false">


<FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingHorizontal="12dp" android:clipChildren="false" android:clipToPadding="false"> <FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <com.hookedonplay.decoviewlib.DecoView android:id="@+id/pie_chart_time2" android:layout_width="280dp" android:layout_height="280dp" android:layout_gravity="center" tools:ignore="MissingClass" /> </FrameLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="200dp" android:layout_gravity="center" android:orientation="vertical" android:gravity="center_horizontal" android:padding="0dp" android:clipChildren="false" android:clipToPadding="false"> <Space android:layout_width="match_parent" android:layout_height="40dp" /> <TextView android:id="@+id/txt_day" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Click" android:fontFeatureSettings="tnum" android:textColor="@android:color/black" android:textSize="28sp" android:textStyle="bold"/>

<LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" android:gravity="center" android:layout_weight="1"> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:gravity="center"> </LinearLayout> </LinearLayout>

</LinearLayout> <Space android:layout_width="match_parent" android:layout_height="0dp" /> <Space android:layout_width="match_parent" android:layout_height="10dp" /> </LinearLayout> </FrameLayout> </FrameLayout> </androidx.cardview.widget.CardView>

activity_main.xml改成:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">

    <LinearLayout
        android:id="@+id/container_deco"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        tools:ignore="MissingConstraints">
    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

3. MainActivity.java文件:

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.hookedonplay.decoviewlib.DecoView;
import com.hookedonplay.decoviewlib.charts.SeriesItem;
import com.hookedonplay.decoviewlib.events.DecoEvent;

public class MainActivity extends AppCompatActivity {

    private LinearLayout cardViewContainer;
    private TextView txtDays;
    private DecoView decoView;
    private SeriesItem redSeries;
    private int redSeriesIndex;
    private int currentAngle = 0;
    private Handler timerHandler;
    private Runnable timerRunnable;
    private boolean clicked = true;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        cardViewContainer = findViewById(R.id.container_deco);
        LayoutInflater inflater = LayoutInflater.from(this);
        View view = inflater.inflate(R.layout.cardview_deco, cardViewContainer, false);
        cardViewContainer.addView(view);
        txtDays = view.findViewById(R.id.txt_day);
        initDecoView();

        txtDays.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int newProgress = currentAngle + 5;

                if (newProgress > 100) {
                    newProgress = 100;
                }

                DecoEvent event = new DecoEvent.Builder(newProgress)
                        .setIndex(redSeriesIndex)                   
                        .setDuration(500)                          
                        .build();
                decoView.addEvent(event);

                currentAngle = newProgress;
                clicked = !clicked;
                if (clicked) {
                    txtDays.setText("Clicked!");
                }
                else {
                    txtDays.setText("Clicked again!");
                }
            }
        });

    }

    private void initDecoView() {
        decoView = findViewById(R.id.pie_chart_time2);
        decoView.configureAngles(360, 0); 

        // 创建灰色背景
        SeriesItem backgroundSeries = new SeriesItem.Builder(Color.GRAY)
                .setRange(0, 100, 100)
                .setLineWidth(40f)
                .build();
        decoView.addSeries(backgroundSeries);

        SeriesItem redSeries = new SeriesItem.Builder(Color.RED)
                .setRange(0, 100, 0) 
                .setLineWidth(40f)
                .build();
        redSeriesIndex = decoView.addSeries(redSeries);

        startAngleIncrease();
    }

    private void startAngleIncrease() {
        timerHandler = new Handler(Looper.getMainLooper());
        timerRunnable = new Runnable() {
            @Override
            public void run() {
                currentAngle = (currentAngle + 1) % 360;

                DecoEvent event = new DecoEvent.Builder(currentAngle)
                        .setIndex(redSeriesIndex)
                        .setDuration(500)
                        .build();
                decoView.addEvent(event);

                timerHandler.postDelayed(this, 1000);
            }
        };
        timerHandler.post(timerRunnable);
    }
}

上面的代码实现了下面的功能:绘制底色为灰色的红色圆环,点击一下圆环中间的文本,红色圆环增加5°,每秒钟红色圆环增加1°.

bafc184d3b1d1e18bf4833e93c668d03

 

posted @ 2026-04-25 23:22  MSTK  阅读(7)  评论(0)    收藏  举报