cloudroam
2025-03-04 e3783b167f132005c7afcc4c10f9ab167806331d
app/src/main/java/com/example/firstapp/ui/dashboard/DashboardFragment.kt
@@ -1,5 +1,6 @@
package com.example.firstapp.ui.dashboard
import com.example.firstapp.R
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@@ -7,7 +8,20 @@
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.fragment.app.viewModels
import com.example.firstapp.databinding.FragmentDashboardBinding
import com.google.android.material.tabs.TabLayout
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.firstapp.adapter.PackageAdapter
import com.example.firstapp.core.Core
import com.github.mikephil.charting.charts.BarChart
import com.github.mikephil.charting.charts.PieChart
import com.github.mikephil.charting.components.Legend
import com.github.mikephil.charting.components.XAxis
import com.github.mikephil.charting.data.*
import com.github.mikephil.charting.formatter.IndexAxisValueFormatter
import java.util.*
import java.text.SimpleDateFormat
class DashboardFragment : Fragment() {
@@ -17,24 +31,209 @@
    // onDestroyView.
    private val binding get() = _binding!!
    private val packageAdapter = PackageAdapter()
    private var currentDate = Calendar.getInstance()
    private var currentDateType = DateType.DAY
    private lateinit var barChart: BarChart
    private lateinit var pieChart: PieChart
    enum class DateType {
        DAY, WEEK, MONTH, YEAR
    }
    private val viewModel: DashboardViewModel by viewModels()
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        val dashboardViewModel =
            ViewModelProvider(this).get(DashboardViewModel::class.java)
        _binding = FragmentDashboardBinding.inflate(inflater, container, false)
        val root: View = binding.root
        val textView: TextView = binding.textDashboard
        dashboardViewModel.text.observe(viewLifecycleOwner) {
            textView.text = it
        }
        return root
        return binding.root
    }
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        setupRecyclerView()
        setupTabLayout()
        setupDatePicker()
        updateDateDisplay()
        setupWeekView(view)
        loadPackages()
    }
    private fun setupRecyclerView() {
        binding.recyclerPackages.apply {
            layoutManager = LinearLayoutManager(context)
            adapter = packageAdapter
        }
    }
    private fun setupTabLayout() {
        binding.tabDateRange.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
            override fun onTabSelected(tab: TabLayout.Tab?) {
                currentDateType = when(tab?.position) {
                    0 -> DateType.DAY
                    1 -> DateType.WEEK
                    2 -> DateType.MONTH
                    3 -> DateType.YEAR
                    else -> DateType.DAY
                }
                // 切换视图
                binding.viewFlipperStats.displayedChild = when(currentDateType) {
                    DateType.DAY -> 0
                    DateType.WEEK -> 1
                    else -> 0
                }
                updateDateDisplay()
                //加载按天统计包裹数量和列表
                loadPackages()
                observePackages()
            }
            override fun onTabUnselected(tab: TabLayout.Tab?) {}
            override fun onTabReselected(tab: TabLayout.Tab?) {}
        })
    }
    private fun setupDatePicker() {
        binding.btnPreviousDate.setOnClickListener {
            adjustDate(-1)
        }
        binding.btnNextDate.setOnClickListener {
            adjustDate(1)
        }
    }
    private fun adjustDate(amount: Int) {
        when (currentDateType) {
            DateType.DAY -> currentDate.add(Calendar.DAY_OF_MONTH, amount)
            DateType.WEEK -> currentDate.add(Calendar.WEEK_OF_YEAR, amount)
            DateType.MONTH -> currentDate.add(Calendar.MONTH, amount)
            DateType.YEAR -> currentDate.add(Calendar.YEAR, amount)
        }
        updateDateDisplay()
        loadPackages()
    }
    private fun updateDateDisplay() {
        val dateFormat = when (currentDateType) {
            DateType.DAY -> "yyyy年MM月dd日"
            DateType.WEEK -> "yyyy年第ww周"
            DateType.MONTH -> "yyyy年MM月"
            DateType.YEAR -> "yyyy年"
        }
        binding.textCurrentDate.text = SimpleDateFormat(dateFormat, Locale.getDefault())
            .format(currentDate.time)
    }
    private fun setupWeekView(view: View) {
        val weekStatsView = binding.layoutWeekStats.root
        barChart = weekStatsView.findViewById(R.id.chart_daily_packages)
        pieChart = weekStatsView.findViewById(R.id.chart_courier_distribution)
        setupBarChart()
        setupPieChart()
    }
    private fun setupBarChart() {
        // 配置柱状图
        barChart.apply {
            description.isEnabled = false
            setDrawGridBackground(false)
            legend.isEnabled = false
            // X轴设置
            xAxis.apply {
                position = XAxis.XAxisPosition.BOTTOM
                setDrawGridLines(false)
                valueFormatter = IndexAxisValueFormatter(getDayLabels())
            }
            // Y轴设置
            axisLeft.apply {
                setDrawGridLines(true)
                axisMinimum = 0f
            }
            axisRight.isEnabled = false
        }
        updateBarChartData()
    }
    private fun updateBarChartData() {
        viewModel.getDailyStats(currentDate.timeInMillis).observe(viewLifecycleOwner) { stats ->
            val entries = stats.mapIndexed { index, stat ->
                BarEntry(index.toFloat(), stat.count.toFloat())
            }
            val dataSet = BarDataSet(entries, "包裹数量")
            dataSet.color = resources.getColor(R.color.purple_500)
            barChart.data = BarData(dataSet)
            barChart.invalidate()
        }
    }
    private fun setupPieChart() {
        // 配置饼图
        pieChart.apply {
            description.isEnabled = false
            setUsePercentValues(true)
            setDrawEntryLabels(false)
            legend.isEnabled = true
            legend.verticalAlignment = Legend.LegendVerticalAlignment.CENTER
            legend.horizontalAlignment = Legend.LegendHorizontalAlignment.RIGHT
            legend.orientation = Legend.LegendOrientation.VERTICAL
        }
        updatePieChartData()
    }
    private fun updatePieChartData() {
        viewModel.getCourierStats(currentDate.timeInMillis).observe(viewLifecycleOwner) { stats ->
            val entries = stats.map { stat ->
                PieEntry(stat.count.toFloat(), stat.courierName)
            }
            val dataSet = PieDataSet(entries, "快递公司分布")
            dataSet.colors = listOf(
                resources.getColor(R.color.purple_500),
                resources.getColor(R.color.teal_200)
            )
            pieChart.data = PieData(dataSet)
            pieChart.invalidate()
        }
    }
    private fun getDayLabels(): Array<String> {
        return arrayOf("周一", "周二", "周三", "周四", "周五", "周六", "周日")
    }
    private fun loadPackages() {
        // 这里应该从数据库或网络加载数据
        // 根据当前选择的日期类型传入对应参数
//        val packages = when (currentDateType) {
//            DateType.DAY -> Core.code.getPackagesByDay(currentDate.timeInMillis)
//            DateType.WEEK -> Core.code.getPackagesByWeek(currentDate.timeInMillis)
//            DateType.MONTH -> Core.code.getPackagesByMonth(currentDate.timeInMillis)
//            DateType.YEAR -> Core.code.getPackagesByYear(currentDate.timeInMillis)
//        }
        val packages =Core.code.getPackagesByDay(currentDate.timeInMillis)
        packageAdapter.updatePackages(packages)
        binding.textPackageCount.text = "${packageAdapter.itemCount}个"
    }
    private fun observePackages() {
        viewModel.getPackages(
            currentDate.timeInMillis,
            currentDateType.name
        ).observe(viewLifecycleOwner) { packages ->
            when (currentDateType) {
                DateType.WEEK -> {
                    // 更新图表数据
                    updateBarChartData()
                    updatePieChartData()
                }
                else -> {
                packageAdapter.updatePackages(packages)
            }
            }
            binding.textPackageCount.text = "${packages.size}个"
        }
    }
    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null