mirror of
https://github.com/AntennaPod/AntennaPod.git
synced 2024-12-27 01:03:15 +01:00
Added pie chart to statistics page
This commit is contained in:
parent
80de04a324
commit
6b03dce78b
@ -15,6 +15,7 @@ import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.core.glide.ApGlideSettings;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
import de.danoeh.antennapod.core.util.Converter;
|
||||
import de.danoeh.antennapod.view.PieChartView;
|
||||
|
||||
/**
|
||||
* Adapter for the statistics list
|
||||
@ -67,6 +68,12 @@ public class StatisticsListAdapter extends RecyclerView.Adapter<RecyclerView.Vie
|
||||
HeaderHolder holder = (HeaderHolder) h;
|
||||
long time = countAll ? statisticsData.totalTimeCountAll : statisticsData.totalTime;
|
||||
holder.totalTime.setText(Converter.shortLocalizedDuration(context, time));
|
||||
float[] dataValues = new float[statisticsData.feedTime.size()];
|
||||
for (int i = 0; i < statisticsData.feedTime.size(); i++) {
|
||||
DBReader.StatisticsItem item = statisticsData.feedTime.get(i);
|
||||
dataValues[i] = countAll ? item.timePlayedCountAll : item.timePlayed;
|
||||
}
|
||||
holder.pieChart.setData(dataValues);
|
||||
} else {
|
||||
StatisticsHolder holder = (StatisticsHolder) h;
|
||||
DBReader.StatisticsItem statsItem = statisticsData.feedTime.get(position - 1);
|
||||
@ -105,10 +112,12 @@ public class StatisticsListAdapter extends RecyclerView.Adapter<RecyclerView.Vie
|
||||
|
||||
static class HeaderHolder extends RecyclerView.ViewHolder {
|
||||
TextView totalTime;
|
||||
PieChartView pieChart;
|
||||
|
||||
HeaderHolder(View itemView) {
|
||||
super(itemView);
|
||||
totalTime = itemView.findViewById(R.id.total_time);
|
||||
pieChart = itemView.findViewById(R.id.pie_chart);
|
||||
}
|
||||
}
|
||||
|
||||
|
120
app/src/main/java/de/danoeh/antennapod/view/PieChartView.java
Normal file
120
app/src/main/java/de/danoeh/antennapod/view/PieChartView.java
Normal file
@ -0,0 +1,120 @@
|
||||
package de.danoeh.antennapod.view;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.widget.AppCompatImageView;
|
||||
import android.util.AttributeSet;
|
||||
import io.reactivex.annotations.Nullable;
|
||||
|
||||
public class PieChartView extends AppCompatImageView {
|
||||
private PieChartDrawable drawable;
|
||||
|
||||
public PieChartView(Context context) {
|
||||
super(context);
|
||||
setup();
|
||||
}
|
||||
|
||||
public PieChartView(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setup();
|
||||
}
|
||||
|
||||
public PieChartView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
setup();
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
private void setup() {
|
||||
drawable = new PieChartDrawable();
|
||||
setImageDrawable(drawable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set array od names, array of values and array of colors.
|
||||
*/
|
||||
public void setData(float[] dataValues) {
|
||||
drawable.dataValues = dataValues;
|
||||
drawable.valueSum = 0;
|
||||
for (float datum : dataValues) {
|
||||
drawable.valueSum += datum;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
int width = getMeasuredWidth();
|
||||
setMeasuredDimension(width, width / 2);
|
||||
}
|
||||
|
||||
private static class PieChartDrawable extends Drawable {
|
||||
private static final float MIN_DEGREES = 10f;
|
||||
private static final float PADDING_DEGREES = 3f;
|
||||
private static final float STROKE_SIZE = 15f;
|
||||
private static final int[] COLOR_VALUES = {0xFF3775E6,0xffe51c23,0xffff9800,0xff259b24,0xff9c27b0,
|
||||
0xff0099c6,0xffdd4477,0xff66aa00,0xffb82e2e,0xff316395,
|
||||
0xff994499,0xff22aa99,0xffaaaa11,0xff6633cc,0xff0073e6};
|
||||
private float[] dataValues;
|
||||
private float valueSum;
|
||||
private final Paint linePaint;
|
||||
|
||||
private PieChartDrawable() {
|
||||
linePaint = new Paint();
|
||||
linePaint.setStyle(Paint.Style.STROKE);
|
||||
linePaint.setStrokeJoin(Paint.Join.ROUND);
|
||||
linePaint.setStrokeCap(Paint.Cap.ROUND);
|
||||
linePaint.setStrokeWidth(STROKE_SIZE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(@NonNull Canvas canvas) {
|
||||
if (valueSum == 0) {
|
||||
return;
|
||||
}
|
||||
float radius = getBounds().height() - STROKE_SIZE;
|
||||
float center = getBounds().width() / 2.f;
|
||||
RectF arc_bounds = new RectF(center - radius, STROKE_SIZE, center + radius, STROKE_SIZE + radius * 2);
|
||||
|
||||
float startAngle = 180;
|
||||
for (int i = 0; i < dataValues.length; i++) {
|
||||
float datum = dataValues[i];
|
||||
float sweepAngle = 180 * datum / valueSum;
|
||||
if (sweepAngle < MIN_DEGREES) {
|
||||
break;
|
||||
}
|
||||
linePaint.setColor(COLOR_VALUES[i % COLOR_VALUES.length]);
|
||||
float padding = i == 0 ? PADDING_DEGREES / 2 : PADDING_DEGREES;
|
||||
canvas.drawArc(arc_bounds, startAngle + padding, sweepAngle - padding, false, linePaint);
|
||||
startAngle = startAngle + sweepAngle;
|
||||
}
|
||||
|
||||
linePaint.setColor(Color.GRAY);
|
||||
float sweepAngle = 360 - startAngle - PADDING_DEGREES / 2;
|
||||
if (sweepAngle > PADDING_DEGREES) {
|
||||
canvas.drawArc(arc_bounds, startAngle + PADDING_DEGREES, sweepAngle - PADDING_DEGREES, false, linePaint);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacity() {
|
||||
return PixelFormat.TRANSLUCENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(int alpha) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorFilter(ColorFilter cf) {
|
||||
}
|
||||
}
|
||||
}
|
@ -1,40 +1,42 @@
|
||||
<?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="wrap_content"
|
||||
android:orientation="vertical">
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="16dp">
|
||||
|
||||
<LinearLayout
|
||||
<de.danoeh.antennapod.view.PieChartView
|
||||
android:id="@+id/pie_chart"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
android:id="@+id/total_time_description"
|
||||
android:textSize="14sp"
|
||||
android:text="@string/total_time_listened_to_podcasts"
|
||||
android:gravity="center_horizontal"
|
||||
android:layout_above="@+id/total_time"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14sp"
|
||||
android:text="@string/total_time_listened_to_podcasts"
|
||||
android:gravity="center_horizontal"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/total_time"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:gravity="center_horizontal"
|
||||
android:textSize="28sp"
|
||||
tools:text="10.0 hours"/>
|
||||
|
||||
</LinearLayout>
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/total_time"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:gravity="center_horizontal"
|
||||
android:textSize="28sp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_alignBottom="@id/pie_chart"
|
||||
tools:text="10.0 hours"/>
|
||||
|
||||
<View
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?android:attr/dividerVertical"/>
|
||||
android:layout_marginTop="16dp"
|
||||
android:background="?android:attr/dividerVertical"
|
||||
android:layout_below="@+id/pie_chart"/>
|
||||
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
Loading…
Reference in New Issue
Block a user