本記事では、Androidアプリで円グラフをアニメーション化する方法について説明します。DecoViewライブラリを使用することで、Google Fitのようなスタイリッシュな円形視覚効果を簡単に実現できます。
- 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
- レイアウトファイルの作成
次に、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>
- 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));
}
}
このコードにより、円グラフの背景色を灰色、前景色を青色として表示し、クリックや自動更新によって進行状況をアニメーションで表現します。