更新MPAndroidChart中的XAxis值
我正在开发一个预算应用程序,在本例中,我有一个统计类,其中使用MPAndroidChart收集和填充每组费用的值。其思想是,当我们在微调器中选择不同的月份时,图表中显示的值会相应地更新。当当前月份的费用类别数与所选新月份的类别数相同时,此功能正常工作。另一方面,如果当前月份的类别数与所选月份的类别数不同,我将获得ArrayIndexOutOfBoundsException 每次在微调器中选择不同的月份时,我已经在创建此类的新对象,因此我的问题是,如何更新MyXaxiValueFormatter中的mValues数组以避免出现此异常 Statistics.java更新MPAndroidChart中的XAxis值,android,indexoutofboundsexception,mpandroidchart,Android,Indexoutofboundsexception,Mpandroidchart,我正在开发一个预算应用程序,在本例中,我有一个统计类,其中使用MPAndroidChart收集和填充每组费用的值。其思想是,当我们在微调器中选择不同的月份时,图表中显示的值会相应地更新。当当前月份的费用类别数与所选新月份的类别数相同时,此功能正常工作。另一方面,如果当前月份的类别数与所选月份的类别数不同,我将获得ArrayIndexOutOfBoundsException 每次在微调器中选择不同的月份时,我已经在创建此类的新对象,因此我的问题是,如何更新MyXaxiValueFormatter中
package com.robin.xbudget;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.fragment.app.Fragment;
import com.github.mikephil.charting.charts.BarChart;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.data.BarData;
import com.github.mikephil.charting.data.BarDataSet;
import com.github.mikephil.charting.data.BarEntry;
import com.github.mikephil.charting.formatter.IndexAxisValueFormatter;
import com.github.mikephil.charting.utils.ColorTemplate;
import java.time.LocalDate;
import java.time.Period;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class Statistics extends Fragment {
private final String TAG = this.getClass().getSimpleName();
StatisticsListener callback;
private TextView mNumberIncomes;
private TextView mNumberExpenses;
private TextView mNumberDaysPassed;
private TextView mNumberDaysRemaining;
private LocalDate mLocalDateFirst;
private LocalDate mLocalDateLast;
private Spinner monthSpinner;
private BarChart mBarChart;
private BarDataSet mBarDataSet;
private BarData mData;
ArrayList<BarEntry> barEntries;
@RequiresApi(api = Build.VERSION_CODES.O)
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_statistics, container, false);
mNumberIncomes = (TextView) view.findViewById(R.id.number_incomes);
mNumberExpenses = (TextView) view.findViewById(R.id.number_expenses);
mNumberDaysPassed = (TextView) view.findViewById(R.id.days_passed_number);
mNumberDaysRemaining = (TextView) view.findViewById(R.id.days_remaining_number);
mLocalDateFirst = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth());
mLocalDateLast = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth());
mNumberIncomes.setText(String.valueOf(callback.getTotalIncomes()));
mNumberExpenses.setText(String.valueOf(callback.getTotalExpenses()));
mNumberDaysPassed.setText(String.valueOf(Period.between(mLocalDateFirst, LocalDate.now()).getDays()));
mNumberDaysRemaining.setText(String.valueOf(Period.between(LocalDate.now(), mLocalDateLast).getDays()));
monthSpinner = (Spinner) view.findViewById(R.id.spinner_month_stats);
monthSpinner.setAdapter(callback.getArrayAdapter());
monthSpinner.setSelection(callback.getSpinnerPosition());
monthSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
callback.setPeriodSelected((String) monthSpinner.getAdapter().getItem(position));
dataFiller();
mBarChart.invalidate();
Log.d(TAG, "onItemSelected called");
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
mBarChart = (BarChart) view.findViewById(R.id.bar_chart);
dataFiller();
return view;
}
public void dataFiller(){
mBarChart.setDrawBarShadow(false);
mBarChart.setDrawValueAboveBar(true);
mBarChart.setMaxVisibleValueCount(50);
mBarChart.setPinchZoom(false);
mBarChart.setDrawGridBackground(false);
barEntries = new ArrayList<>();
int x = 0;
for (String s : callback.getExpensesDataGroup()) {
float value = 0;
for (Transaction t : callback.getExpensesDataChild().get(s)) {
value += t.getQuantity();
}
barEntries.add(new BarEntry((float) ++x, value));
}
//This is the graphic
mBarDataSet = new BarDataSet(barEntries, "Expenses");
mBarDataSet.setColors(ColorTemplate.COLORFUL_COLORS);
mBarDataSet.notifyDataSetChanged();
mData = new BarData(mBarDataSet);
mData.setBarWidth(0.9f);
mBarChart.setData(mData);
String[] expenses = new String[callback.getExpensesDataGroup().size() + 1];
expenses[0] = "Dummy";
for (int i = 1; i <= callback.getExpensesDataGroup().size(); i++) {
expenses[i] = callback.getExpensesDataGroup().get(i - 1);
}
Log.d(TAG, "Prior to mValues before: " + expenses.length);
mBarChart.notifyDataSetChanged();
XAxis xAxis = mBarChart.getXAxis();
xAxis.setValueFormatter(new myXAxisValueFormatter(expenses));
xAxis.setPosition(XAxis.XAxisPosition.TOP);
xAxis.setGranularity(1f);
//xAxis.setCenterAxisLabels(true);
//xAxis.setAxisMinimum(1);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
try{
callback = (StatisticsListener)context;
}catch(ClassCastException cce){
throw new ClassCastException("Class must implement StatisticListener");
}
}
class myXAxisValueFormatter extends IndexAxisValueFormatter {
private String[] mValues;
public myXAxisValueFormatter(String[]values) {
this.mValues = values;
}
@Override
public String getFormattedValue(float value) {
return mValues[(int)value];
}
}
interface StatisticsListener{
double getTotalIncomes();
double getTotalExpenses();
Map<String, List<Transaction>> getExpensesDataChild();
List<String> getExpensesDataGroup();
ArrayAdapter getArrayAdapter();
void setPeriodSelected(String periodSelected);
int getSpinnerPosition();
}
}
您需要检查getFormattedValue中的值,因为它可以是<0或>=mValues.length
class myXAxisValueFormatter extends IndexAxisValueFormatter {
private String[] mValues;
public myXAxisValueFormatter(String[]values) {
this.mValues = values;
}
@Override
public String getFormattedValue(float value) {
int intValue = (int)value;
if (intValue < 0 || intValue >= mValues.length){
return "";
} else {
return mValues[intValue];
}
}
}
类myXAxisValueFormatter扩展了IndexAxisValueFormatter{
私有字符串[]mValues;
公共MyXaxiValueFormatter(字符串[]值){
this.mValues=值;
}
@凌驾
公共字符串getFormattedValue(浮点值){
int值=(int)值;
if(intValue<0 | | intValue>=mValues.length){
返回“”;
}否则{
返回mValues[intValue];
}
}
}
class myXAxisValueFormatter extends IndexAxisValueFormatter {
private String[] mValues;
public myXAxisValueFormatter(String[]values) {
this.mValues = values;
}
@Override
public String getFormattedValue(float value) {
int intValue = (int)value;
if (intValue < 0 || intValue >= mValues.length){
return "";
} else {
return mValues[intValue];
}
}
}