Androidでの円グラフアニメーションの実装

本記事では、Androidアプリで円グラフをアニメーション化する方法について説明します。DecoViewライブラリを使用することで、Google Fitのようなスタイリッシュな円形視覚効果を簡単に実現できます。

  1. DecoViewライブラリの導入

プロジェクトのbuild.gradle(Module: app)に以下を追加し、同期を行います。

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

もし依存関係のエラーが発生した場合、それは古いAndroid Supportライブラリと新しいAndroidXライブラリが混在していることが原因です。これを解決するには、gradle.propertiesに以下の設定を追加してください。

# AndroidXライブラリを有効化
android.useAndroidX=true
# サードパーティーライブラリ内のSupportライブラリを自動的にAndroidXに変換
android.enableJetifier=true
  1. レイアウトファイルの作成

次に、cardview_deco.xmlというレイアウトファイルを作成します。

<androidx.cardview.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/card_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        
        <com.hookedonplay.decoviewlib.DecoView
            android:id="@+id/chart"
            android:layout_width="280dp"
            android:layout_height="280dp"
            android:layout_gravity="center"/>

        <TextView
            android:id="@+id/center_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="タップ"
            android:textSize="24sp"
            android:layout_gravity="center"/>
    
    </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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"/>

</androidx.constraintlayout.widget.ConstraintLayout>
  1. Javaコードの実装

MainActivity.javaを以下のように記述します。

package com.example.sample;

import androidx.appcompat.app.AppCompatActivity;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
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 container;
    private TextView centerText;
    private DecoView chart;
    private int seriesIndex;
    private int progress = 0;

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

        container = findViewById(R.id.container);
        View cardView = getLayoutInflater().inflate(R.layout.cardview_deco, container, false);
        container.addView(cardView);

        centerText = cardView.findViewById(R.id.center_text);
        chart = cardView.findViewById(R.id.chart);

        configureChart();
        setupClickListener();
        startAutoUpdate();
    }

    private void configureChart() {
        chart.configureAngles(360, 0);

        SeriesItem background = new SeriesItem.Builder(Color.DKGRAY)
                .setRange(0, 100, 100)
                .setLineWidth(40f)
                .build();
        chart.addSeries(background);

        SeriesItem foreground = new SeriesItem.Builder(Color.BLUE)
                .setRange(0, 100, 0)
                .setLineWidth(40f)
                .build();
        seriesIndex = chart.addSeries(foreground);
    }

    private void setupClickListener() {
        centerText.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (progress < 100) {
                    progress += 5;
                    updateProgress(progress);
                }
            }
        });
    }

    private void startAutoUpdate() {
        final Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                if (progress < 100) {
                    progress++;
                    updateProgress(progress);
                    handler.postDelayed(this, 1000);
                }
            }
        }, 1000);
    }

    private void updateProgress(int value) {
        DecoEvent event = new DecoEvent.Builder(value)
                .setIndex(seriesIndex)
                .setDuration(500)
                .build();
        chart.addEvent(event);
        centerText.setText(String.valueOf(value));
    }
}

このコードにより、円グラフの背景色を灰色、前景色を青色として表示し、クリックや自動更新によって進行状況をアニメーションで表現します。

タグ: Android DecoView Animation

5月30日 16:15 投稿