You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio中如何将Firestore数据加载至MPChart(柱状图、饼图)

Loading Firestore Data into MPAndroidChart (BarChart & PieChart)

I see you already have a working setup with mock data for your LineChart and BarChart. Let's convert that to pull real data from Firestore, and we'll add the PieChart implementation too. Here's a step-by-step solution:

Step 1: Define Your Firestore Data Structure

First, make sure your Firestore collection is structured to hold weekly income data tied to the authenticated user. For example, create a collection named weeklyIncomes where each document has:

  • day: String (e.g. "Sunday", "Monday")
  • income: Number (integer value of the day's income)
  • userId: String (matches the current user's UID from Firebase Auth)

Step 2: Update the Fragment Code to Fetch Firestore Data

We'll replace your mock data method with Firestore's asynchronous data fetch, and add the PieChart logic. Here's the updated StatisticFragment code:

public class StatisticFragment extends Fragment {
    FirebaseAuth fAuth;
    FirebaseFirestore db;
    String userID;
    LineChart lineChart;
    LineData lineData;
    LineDataSet lineDataSet;
    ArrayList lineEntries;
    BarChart weeklyIncomeBarchart;
    PieChart weeklyIncomePieChart; // Added PieChart
    ArrayList<BarEntry> barEntryArrayList;
    ArrayList<String> labelsName;
    ArrayList<WeeklyIncomeChart> weeklyIncomeCharts = new ArrayList<>();
    ArrayList<PieEntry> pieEntryArrayList; // For PieChart

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_statistic, container, false);
        getActivity().setTitle("Statistic");
        fAuth = FirebaseAuth.getInstance();
        db = FirebaseFirestore.getInstance();
        userID = fAuth.getCurrentUser().getUid(); // Get current user ID

        // Initialize LineChart (keep your existing mock setup or replace with Firestore data later)
        lineChart = v.findViewById(R.id.lineChart);
        getEntries();
        lineDataSet = new LineDataSet(lineEntries, "");
        lineData = new LineData(lineDataSet);
        lineChart.setData(lineData);
        lineDataSet.setColors(ColorTemplate.JOYFUL_COLORS);
        lineDataSet.setValueTextColor(Color.BLACK);
        lineDataSet.setValueTextSize(18f);

        // Initialize BarChart and PieChart
        weeklyIncomeBarchart = v.findViewById(R.id.weeklyIncomeBarchart);
        weeklyIncomePieChart = v.findViewById(R.id.weeklyIncomePieChart); // Initialize PieChart
        barEntryArrayList = new ArrayList<>();
        labelsName = new ArrayList<>();
        pieEntryArrayList = new ArrayList<>();

        // Fetch data from Firestore and update charts
        fetchWeeklyIncomeFromFirestore();

        return v;
    }

    // Keep your existing LineChart mock data method for now
    private void getEntries() {
        lineEntries = new ArrayList<>();
        lineEntries.add(new Entry(2f, 0));
        lineEntries.add(new Entry(4f, 1));
        lineEntries.add(new Entry(6f, 1));
        lineEntries.add(new Entry(8f, 3));
        lineEntries.add(new Entry(7f, 4));
        lineEntries.add(new Entry(3f, 3));
    }

    // Replace mock fill method with Firestore fetch
    private void fetchWeeklyIncomeFromFirestore() {
        weeklyIncomeCharts.clear();
        barEntryArrayList.clear();
        labelsName.clear();
        pieEntryArrayList.clear();

        // Query Firestore for current user's weekly income data
        db.collection("weeklyIncomes")
                .whereEqualTo("userId", userID)
                .get()
                .addOnSuccessListener(queryDocumentSnapshots -> {
                    for (DocumentSnapshot document : queryDocumentSnapshots) {
                        // Map document to your WeeklyIncomeChart model
                        WeeklyIncomeChart incomeData = document.toObject(WeeklyIncomeChart.class);
                        weeklyIncomeCharts.add(incomeData);

                        // Prepare data for BarChart
                        String day = incomeData.getDays();
                        int income = incomeData.getIncome();
                        labelsName.add(day);
                        barEntryArrayList.add(new BarEntry(labelsName.size()-1, income));

                        // Prepare data for PieChart
                        pieEntryArrayList.add(new PieEntry(income, day));
                    }

                    // Update BarChart
                    updateBarChart();

                    // Update PieChart
                    updatePieChart();
                })
                .addOnFailureListener(e -> {
                    // Handle error (e.g., show toast)
                    Toast.makeText(getContext(), "Failed to load data: " + e.getMessage(), Toast.LENGTH_SHORT).show();
                });
    }

    private void updateBarChart() {
        BarDataSet barDataSet = new BarDataSet(barEntryArrayList, "Days");
        barDataSet.setColors(ColorTemplate.COLORFUL_COLORS);
        Description description = new Description();
        description.setText("Weekly Income");
        weeklyIncomeBarchart.setDescription(description);
        BarData barData = new BarData(barDataSet);
        weeklyIncomeBarchart.setData(barData);

        // Configure XAxis (keep your existing setup)
        XAxis xAxis = weeklyIncomeBarchart.getXAxis();
        xAxis.setValueFormatter(new IndexAxisValueFormatter(labelsName));
        xAxis.setPosition(XAxis.XAxisPosition.TOP);
        xAxis.setDrawGridLines(false);
        xAxis.setDrawAxisLine(false);
        xAxis.setGranularity(1f);
        xAxis.setLabelCount(labelsName.size());
        xAxis.setLabelRotationAngle(270);

        weeklyIncomeBarchart.animateY(2000);
        weeklyIncomeBarchart.invalidate(); // Refresh chart
    }

    private void updatePieChart() {
        PieDataSet pieDataSet = new PieDataSet(pieEntryArrayList, "Weekly Income Distribution");
        pieDataSet.setColors(ColorTemplate.MATERIAL_COLORS);
        pieDataSet.setValueTextColor(Color.BLACK);
        pieDataSet.setValueTextSize(14f);

        PieData pieData = new PieData(pieDataSet);
        weeklyIncomePieChart.setData(pieData);
        weeklyIncomePieChart.setDescription(new Description()); // Hide default description
        weeklyIncomePieChart.setCenterText("Weekly Income");
        weeklyIncomePieChart.animateY(1500);
        weeklyIncomePieChart.invalidate(); // Refresh chart
    }
}

Step 3: Update the Layout XML to Include PieChart

Add the PieChart widget below your BarChart in fragment_statistic.xml (we also added a ScrollView to handle overflow):

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
    android:background="@android:color/holo_green_light">

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="16dp">

            <com.github.mikephil.charting.charts.LineChart
                android:id="@+id/lineChart"
                android:layout_width="match_parent"
                android:layout_height="200dp" />

            <com.github.mikephil.charting.charts.BarChart
                android:id="@+id/weeklyIncomeBarchart"
                android:layout_width="match_parent"
                android:layout_height="250dp"
                android:layout_marginTop="20dp"
                android:layout_below="@+id/lineChart"/>

            <!-- Added PieChart -->
            <com.github.mikephil.charting.charts.PieChart
                android:id="@+id/weeklyIncomePieChart"
                android:layout_width="match_parent"
                android:layout_height="250dp"
                android:layout_marginTop="20dp"
                android:layout_below="@+id/weeklyIncomeBarchart"/>

        </RelativeLayout>
    </ScrollView>
</FrameLayout>

Key Points to Note

  • Asynchronous Data Fetch: Firestore operations are async, so we update the charts only inside the onSuccess() callback once data is retrieved.
  • Model Class Compatibility: Ensure your WeeklyIncomeChart class has a no-argument constructor and public getters for days and income so Firestore can map the document data to it.
  • Error Handling: We added a onFailure() listener to handle cases where data fetch fails (e.g., network issues).
  • Chart Refresh: Always call invalidate() after updating chart data to force the UI to refresh.

内容的提问来源于stack exchange,提问作者Muhammad Pauzi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 18:37:31