package com.example.firstapp.ui.dashboard
|
|
import com.example.firstapp.R
|
import android.os.Bundle
|
import android.view.LayoutInflater
|
import android.view.View
|
import android.view.ViewGroup
|
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() {
|
|
private var _binding: FragmentDashboardBinding? = null
|
|
// This property is only valid between onCreateView and
|
// 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 {
|
_binding = FragmentDashboardBinding.inflate(inflater, container, false)
|
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.category)
|
}
|
|
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)
|
DateType.WEEK -> TODO()
|
DateType.MONTH -> TODO()
|
DateType.YEAR -> TODO()
|
}
|
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
|
}
|
}
|