From 897ffe5e29ab022d75ad948ecf894e0a3ed3b2f5 Mon Sep 17 00:00:00 2001 From: cloudroam <cloudroam> Date: 星期二, 04 三月 2025 18:01:41 +0800 Subject: [PATCH] fix: 1 --- app/src/main/java/com/example/firstapp/ui/dashboard/DashboardFragment.kt | 293 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 283 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/example/firstapp/ui/dashboard/DashboardFragment.kt b/app/src/main/java/com/example/firstapp/ui/dashboard/DashboardFragment.kt index 0be390f..f32868e 100644 --- a/app/src/main/java/com/example/firstapp/ui/dashboard/DashboardFragment.kt +++ b/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,22 @@ 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 com.github.mikephil.charting.formatter.ValueFormatter +import java.util.* +import java.text.SimpleDateFormat +import android.util.Log class DashboardFragment : Fragment() { @@ -17,24 +33,281 @@ // 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 + + // 增大图表高度 + minimumHeight = (resources.displayMetrics.density * 300).toInt() + + // X轴设置 + xAxis.apply { + position = XAxis.XAxisPosition.BOTTOM + setDrawGridLines(false) + granularity = 1f + labelRotationAngle = -45f + textSize = 10f + } + + // Y轴设置 + axisLeft.apply { + setDrawGridLines(true) + axisMinimum = 0f + granularity = 1f + valueFormatter = object : ValueFormatter() { + override fun getFormattedValue(value: Float): String { + return value.toInt().toString() + } + } + } + axisRight.isEnabled = false + + // 设置图表交互 + setTouchEnabled(true) + isDragEnabled = true + setScaleEnabled(true) + } + + updateBarChartData() + } + private fun updateBarChartData() { + viewModel.getDailyStats().observe(viewLifecycleOwner) { stats -> + // 添加调试日志 + Log.d("DashboardFragment", "Stats size: ${stats.size}") + stats.forEach { stat -> + Log.d("DashboardFragment", "Week: ${stat.date}, Count: ${stat.count}, Start: ${stat.week_start}") + } + + if (stats.isEmpty()) { + Log.d("DashboardFragment", "No data found") + return@observe + } + + val entries = stats.mapIndexed { index, stat -> + BarEntry(index.toFloat(), stat.count.toFloat()) + } + + val dataSet = BarDataSet(entries, "包裹数量") + dataSet.color = resources.getColor(R.color.purple_500) + dataSet.valueTextSize = 12f + + val barData = BarData(dataSet) + barChart.data = barData + + // 设置X轴标签 + barChart.xAxis.apply { + valueFormatter = object : ValueFormatter() { + override fun getFormattedValue(value: Float): String { + val position = value.toInt() + if (position >= 0 && position < stats.size) { + val weekNum = stats[position].date.toIntOrNull() ?: 0 + // 获取月份信息 + val monthDay = stats[position].week_start?.let { + SimpleDateFormat("MM-dd", Locale.getDefault()).format( + SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).parse(it) + ) + } ?: "" + return "${monthDay}\n第${weekNum}周" + } + return "" + } + } + labelCount = stats.size + } + + barChart.notifyDataSetChanged() + barChart.invalidate() + } + } + private fun setupPieChart() { + pieChart.apply { + description.isEnabled = false + setUsePercentValues(false) // 改为显示实际数量 + setDrawEntryLabels(false) + + // 增大饼图尺寸 + setExtraOffsets(20f, 10f, 80f, 10f) + minimumHeight = (resources.displayMetrics.density * 400).toInt() // 设置最小高度 + + // 配置图例 + legend.apply { + isEnabled = true + verticalAlignment = Legend.LegendVerticalAlignment.CENTER + horizontalAlignment = Legend.LegendHorizontalAlignment.RIGHT + orientation = Legend.LegendOrientation.VERTICAL + setDrawInside(false) + xEntrySpace = 7f + yEntrySpace = 0f + yOffset = 0f + textSize = 12f // 增大图例文字大小 + } + } + + updatePieChartData() + } + private fun updatePieChartData() { + viewModel.getCourierStats(currentDate.timeInMillis).observe(viewLifecycleOwner) { stats -> + val entries = stats.map { stat -> + PieEntry(stat.count.toFloat(), "${stat.courierName}(${stat.count})") + } + + val dataSet = PieDataSet(entries, "快递公司分布") + dataSet.colors = listOf( + resources.getColor(R.color.purple_500), + resources.getColor(R.color.teal_200), + resources.getColor(R.color.purple_200), + resources.getColor(R.color.teal_700) + ) + dataSet.valueTextSize = 14f // 增大数值文字大小 + + val pieData = PieData(dataSet) + pieData.setValueFormatter(object : ValueFormatter() { + override fun getFormattedValue(value: Float): String { + return value.toInt().toString() + } + }) + + pieChart.data = pieData + 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 -- Gitblit v1.9.3