From b653b90d4598ee2a65bceffa793bb75353b6d186 Mon Sep 17 00:00:00 2001 From: cloudroam <cloudroam> Date: 星期三, 26 二月 2025 17:21:53 +0800 Subject: [PATCH] add: 快递列表展示 --- app/src/main/java/com/example/firstapp/adapter/ExpressAdapter.kt | 87 ++++++++ app/src/main/java/com/example/firstapp/database/repository/CodeRepository.kt | 4 app/src/main/java/com/example/firstapp/model/ExpressGroup.kt | 12 + app/src/main/res/navigation/mobile_navigation.xml | 2 app/src/main/java/com/example/firstapp/adapter/ReminderAdapter.kt | 1 app/src/main/res/layout/item_express_package.xml | 46 ++++ app/src/main/java/com/example/firstapp/database/dao/CodeDao.kt | 7 app/src/main/res/layout/fragment_home.xml | 130 ++++++++++-- app/src/main/java/com/example/firstapp/ui/home/HomeViewModel.kt | 62 ++++- app/src/main/res/drawable/location.png | 0 app/src/main/java/com/example/firstapp/database/dao/ReminderDao.kt | 3 app/src/main/java/com/example/firstapp/ui/home/HomeFragment.kt | 82 +++++-- app/src/main/java/com/example/firstapp/MainActivity.kt | 62 +++--- app/src/main/java/com/example/firstapp/database/repository/ReminderRepository.kt | 5 app/src/main/res/layout/item_express_group.xml | 54 +++++ 15 files changed, 459 insertions(+), 98 deletions(-) diff --git a/app/src/main/java/com/example/firstapp/MainActivity.kt b/app/src/main/java/com/example/firstapp/MainActivity.kt index df33c98..6abffe0 100644 --- a/app/src/main/java/com/example/firstapp/MainActivity.kt +++ b/app/src/main/java/com/example/firstapp/MainActivity.kt @@ -66,10 +66,10 @@ // logout() // } // 在此位置初始化 homeViewModel - homeViewModel = ViewModelProvider(this).get(HomeViewModel::class.java) - - val navView: BottomNavigationView = binding.navView - +// homeViewModel = ViewModelProvider(this).get(HomeViewModel::class.java) +// +// val navView: BottomNavigationView = binding.navView + val navView = binding.navView val navController = findNavController(R.id.nav_host_fragment_activity_main) // Passing each menu ID as a set of Ids because each // menu should be considered as top level destinations. @@ -91,34 +91,34 @@ registerSmsReceiver() syncRecentSms() } - val recyclerView = findViewById<RecyclerView>(R.id.recyclerView) - recyclerView.layoutManager = LinearLayoutManager(this) +// val recyclerView = findViewById<RecyclerView>(R.id.recyclerView) +// recyclerView.layoutManager = LinearLayoutManager(this) +// +// // 初始化适配器 +// adapter = MyAdapter() +// recyclerView.adapter = adapter +// +// // 观察 LiveData 数据 +// homeViewModel.codeList.observe(this) { codeList -> +// // 如果 codeList 为 null,避免闪退 +// if (codeList != null) { +// adapter.submitList(codeList) +// // 滚动到顶部 +// recyclerView.scrollToPosition(0) +// } else { +// // 如果数据为空,可以显示空列表或其他处理 +// Toast.makeText(this, "No data available", Toast.LENGTH_SHORT).show() +// } +// } - // 初始化适配器 - adapter = MyAdapter() - recyclerView.adapter = adapter - - // 观察 LiveData 数据 - homeViewModel.codeList.observe(this) { codeList -> - // 如果 codeList 为 null,避免闪退 - if (codeList != null) { - adapter.submitList(codeList) - // 滚动到顶部 - recyclerView.scrollToPosition(0) - } else { - // 如果数据为空,可以显示空列表或其他处理 - Toast.makeText(this, "No data available", Toast.LENGTH_SHORT).show() - } - } - - // 注册广播接收器来监听数据更新 - val filter = IntentFilter("com.example.firstapp.DATA_UPDATED") - registerReceiver(object : BroadcastReceiver() { - override fun onReceive(context: Context, intent: Intent) { - // 数据已更新,刷新 LiveData - homeViewModel.loadData() - } - }, filter) +// // 注册广播接收器来监听数据更新 +// val filter = IntentFilter("com.example.firstapp.DATA_UPDATED") +// registerReceiver(object : BroadcastReceiver() { +// override fun onReceive(context: Context, intent: Intent) { +// // 数据已更新,刷新 LiveData +// homeViewModel.loadData() +// } +// }, filter) } diff --git a/app/src/main/java/com/example/firstapp/adapter/ExpressAdapter.kt b/app/src/main/java/com/example/firstapp/adapter/ExpressAdapter.kt new file mode 100644 index 0000000..2445433 --- /dev/null +++ b/app/src/main/java/com/example/firstapp/adapter/ExpressAdapter.kt @@ -0,0 +1,87 @@ +package com.example.firstapp.adapter + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import androidx.recyclerview.widget.ListAdapter +import com.example.firstapp.databinding.ItemExpressGroupBinding +import com.example.firstapp.databinding.ItemExpressPackageBinding +import androidx.recyclerview.widget.DiffUtil +import com.example.firstapp.model.ExpressGroup +import com.example.firstapp.model.ExpressPackage + +class ExpressAdapter : ListAdapter<ExpressGroup, ExpressAdapter.ViewHolder>(ExpressGroupDiffCallback()) { + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + val binding = ItemExpressGroupBinding.inflate( + LayoutInflater.from(parent.context), parent, false + ) + return ViewHolder(binding) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val group = getItem(position) + holder.bind(group) + } + + class ViewHolder(private val binding: ItemExpressGroupBinding) : RecyclerView.ViewHolder(binding.root) { + private val packagesAdapter = ExpressPackageAdapter() + + init { + binding.rvPackages.apply { + layoutManager = LinearLayoutManager(context) + adapter = packagesAdapter + } + } + + fun bind(group: ExpressGroup) { + binding.tvStationName.text = group.stationName + binding.tvPackageCount.text = "共${group.packages.size}个包裹" + packagesAdapter.submitList(group.packages) + } + } +} + +class ExpressPackageAdapter : ListAdapter<ExpressPackage, ExpressPackageAdapter.ViewHolder>(ExpressPackageDiffCallback()) { + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + val binding = ItemExpressPackageBinding.inflate( + LayoutInflater.from(parent.context), parent, false + ) + return ViewHolder(binding) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val pack = getItem(position) + holder.bind(pack) + } + + class ViewHolder(private val binding: ItemExpressPackageBinding) : RecyclerView.ViewHolder(binding.root) { + fun bind(pack: ExpressPackage) { + binding.tvCompany.text = pack.company + binding.tvTrackingNumber.text = pack.trackingNumber + binding.tvDate.text = pack.date + } + } +} + +private class ExpressGroupDiffCallback : DiffUtil.ItemCallback<ExpressGroup>() { + override fun areItemsTheSame(oldItem: ExpressGroup, newItem: ExpressGroup): Boolean { + return oldItem.stationName == newItem.stationName + } + + override fun areContentsTheSame(oldItem: ExpressGroup, newItem: ExpressGroup): Boolean { + return oldItem == newItem + } +} + +private class ExpressPackageDiffCallback : DiffUtil.ItemCallback<ExpressPackage>() { + override fun areItemsTheSame(oldItem: ExpressPackage, newItem: ExpressPackage): Boolean { + return oldItem.trackingNumber == newItem.trackingNumber + } + + override fun areContentsTheSame(oldItem: ExpressPackage, newItem: ExpressPackage): Boolean { + return oldItem == newItem + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/firstapp/adapter/ReminderAdapter.kt b/app/src/main/java/com/example/firstapp/adapter/ReminderAdapter.kt index e4a2ade..3a579bc 100644 --- a/app/src/main/java/com/example/firstapp/adapter/ReminderAdapter.kt +++ b/app/src/main/java/com/example/firstapp/adapter/ReminderAdapter.kt @@ -5,7 +5,6 @@ import androidx.recyclerview.widget.RecyclerView import com.example.firstapp.database.entity.Reminder import com.example.firstapp.databinding.ItemReminderBinding -import com.sun.mail.imap.protocol.FetchResponse.getItem class ReminderAdapter(private val onDelete: (Reminder) -> Unit) : ListAdapter<Reminder, ReminderAdapter.ReminderViewHolder>(ReminderDiffCallback()) { diff --git a/app/src/main/java/com/example/firstapp/database/dao/CodeDao.kt b/app/src/main/java/com/example/firstapp/database/dao/CodeDao.kt index 8df5a2b..64e658e 100644 --- a/app/src/main/java/com/example/firstapp/database/dao/CodeDao.kt +++ b/app/src/main/java/com/example/firstapp/database/dao/CodeDao.kt @@ -41,4 +41,11 @@ @Query("SELECT * FROM Code order by time desc") abstract fun getAllCodesDesc(): List<Code> + + @Query(""" + SELECT * FROM Code + WHERE type LIKE '%' || :keyword || '%' + ORDER BY time DESC + """) + fun getByKeyword(keyword: String): List<Code> } diff --git a/app/src/main/java/com/example/firstapp/database/dao/ReminderDao.kt b/app/src/main/java/com/example/firstapp/database/dao/ReminderDao.kt index 59d5af1..e0cd71f 100644 --- a/app/src/main/java/com/example/firstapp/database/dao/ReminderDao.kt +++ b/app/src/main/java/com/example/firstapp/database/dao/ReminderDao.kt @@ -15,4 +15,7 @@ @Delete fun delete(reminder: Reminder) + + @Query("SELECT * FROM reminders WHERE type = :type") + fun getByType(type: String): List<Reminder> } \ No newline at end of file diff --git a/app/src/main/java/com/example/firstapp/database/repository/CodeRepository.kt b/app/src/main/java/com/example/firstapp/database/repository/CodeRepository.kt index 2d9eceb..c5d1165 100644 --- a/app/src/main/java/com/example/firstapp/database/repository/CodeRepository.kt +++ b/app/src/main/java/com/example/firstapp/database/repository/CodeRepository.kt @@ -17,5 +17,9 @@ fun getAllDesc() = codeDao.getAllCodesDesc() + @WorkerThread + fun getByKeyword(keyword: String): List<Code> { + return codeDao.getByKeyword(keyword) + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/firstapp/database/repository/ReminderRepository.kt b/app/src/main/java/com/example/firstapp/database/repository/ReminderRepository.kt index 6017712..20f90f4 100644 --- a/app/src/main/java/com/example/firstapp/database/repository/ReminderRepository.kt +++ b/app/src/main/java/com/example/firstapp/database/repository/ReminderRepository.kt @@ -18,4 +18,9 @@ fun delete(reminder: Reminder) { reminderDao.delete(reminder) } + + @WorkerThread + fun getByType(type: String): List<Reminder> { + return reminderDao.getByType(type) + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/firstapp/model/ExpressGroup.kt b/app/src/main/java/com/example/firstapp/model/ExpressGroup.kt new file mode 100644 index 0000000..7122769 --- /dev/null +++ b/app/src/main/java/com/example/firstapp/model/ExpressGroup.kt @@ -0,0 +1,12 @@ +package com.example.firstapp.model + +data class ExpressGroup( + val stationName: String, + val packages: List<ExpressPackage> +) + +data class ExpressPackage( + val company: String, + val trackingNumber: String, + val date: String +) \ No newline at end of file diff --git a/app/src/main/java/com/example/firstapp/ui/home/HomeFragment.kt b/app/src/main/java/com/example/firstapp/ui/home/HomeFragment.kt index bf4b7ec..5cdc5e0 100644 --- a/app/src/main/java/com/example/firstapp/ui/home/HomeFragment.kt +++ b/app/src/main/java/com/example/firstapp/ui/home/HomeFragment.kt @@ -10,7 +10,7 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.example.firstapp.R -import com.example.firstapp.adapter.MyAdapter +import com.example.firstapp.adapter.ExpressAdapter import com.example.firstapp.core.Core import com.example.firstapp.databinding.FragmentHomeBinding @@ -23,45 +23,73 @@ private val binding get() = _binding!! private lateinit var homeViewModel: HomeViewModel - private lateinit var adapter: MyAdapter + private lateinit var expressAdapter: ExpressAdapter +// private lateinit var financeAdapter: FinanceAdapter +// private lateinit var memorialAdapter: MemorialAdapter - + //onCreateView这个方法创建后被调用,通常是初始化视图组件和观察者 override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { - homeViewModel = - ViewModelProvider(this).get(HomeViewModel::class.java) - _binding = FragmentHomeBinding.inflate(inflater, container, false) - val root: View = binding.root + return binding.root + } -// val textView: TextView = binding.textHome -// homeViewModel.text.observe(viewLifecycleOwner) { -// textView.text = it -// } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + //通过 ViewModelProvider 获取 HomeViewModel 的实例,以便在视图中使用。 + homeViewModel = ViewModelProvider(this).get(HomeViewModel::class.java) - // 初始化适配器 - adapter = MyAdapter() + //调用这个方法来设置 RecyclerView用于设置 RecyclerView 的布局和适配器。 + setupRecyclerViews() + //调用这个方法来观察 ViewModel 中的数据变化 + observeViewModelData() + } - // 获取数据 -// val codeList = Core.code.getAllDesc() - - // 使用 binding 来访问 RecyclerView - val recyclerView: RecyclerView = binding.recyclerView - recyclerView.layoutManager = LinearLayoutManager(requireContext()) // 使用 requireContext() 获取上下文 - recyclerView.adapter = adapter - - // 观察 LiveData,当数据发生变化时,更新 RecyclerView 的内容 - homeViewModel.codeList.observe(viewLifecycleOwner) { codeList -> - adapter.submitList(codeList) // 更新 RecyclerView 的数据 - // 滚动到顶部 - recyclerView.scrollToPosition(0) + private fun setupRecyclerViews() { + // 快递列表 + //layoutManager = LinearLayoutManager(context):设置 RecyclerView 的布局管理器为线性布局管理器,表示列表是垂直排列的。 + //创建一个 ExpressAdapter 的实例,用于提供 RecyclerView 的数据。 + //将适配器设置给 RecyclerView,以便显示数据。 + binding.expressRecycler.apply { + layoutManager = LinearLayoutManager(context) + expressAdapter = ExpressAdapter() + adapter = expressAdapter } - return root +// // 财务列表 +// binding.financeRecycler.apply { +// layoutManager = LinearLayoutManager(context) +// financeAdapter = FinanceAdapter() +// adapter = financeAdapter +// } +// +// // 纪念日列表 +// binding.memorialRecycler.apply { +// layoutManager = LinearLayoutManager(context) +// memorialAdapter = MemorialAdapter() +// adapter = memorialAdapter +// } + } + + //这个方法用于观察 homeViewModel 中的 expressItems 数据。 + private fun observeViewModelData() { + //当 expressItems 数据发生变化时,更新 RecyclerView 的数据。 + homeViewModel.expressItems.observe(viewLifecycleOwner) { items -> + //将新的数据列表提交给适配器,以更新 RecyclerView 的显示内容。 + expressAdapter.submitList(items) + } + +// homeViewModel.financeItems.observe(viewLifecycleOwner) { items -> +// financeAdapter.submitList(items) +// } +// +// homeViewModel.memorialItems.observe(viewLifecycleOwner) { items -> +// memorialAdapter.submitList(items) +// } } override fun onDestroyView() { diff --git a/app/src/main/java/com/example/firstapp/ui/home/HomeViewModel.kt b/app/src/main/java/com/example/firstapp/ui/home/HomeViewModel.kt index 630b6af..a8b15bf 100644 --- a/app/src/main/java/com/example/firstapp/ui/home/HomeViewModel.kt +++ b/app/src/main/java/com/example/firstapp/ui/home/HomeViewModel.kt @@ -3,34 +3,66 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope import com.example.firstapp.core.Core import com.example.firstapp.database.entity.Code +import com.example.firstapp.model.ExpressGroup +import com.example.firstapp.model.ExpressPackage +import kotlinx.coroutines.launch class HomeViewModel : ViewModel() { - private val _text = MutableLiveData<String>().apply { - value = "短信主页面" - } - val text: LiveData<String> = _text +// private val _text = MutableLiveData<String>().apply { +// value = "短信主页面" +// } +// val text: LiveData<String> = _text +// +// private val _codeList = MutableLiveData<List<Code>>() +// +// val codeList: LiveData<List<Code>> get() = _codeList - private val _codeList = MutableLiveData<List<Code>>() - - val codeList: LiveData<List<Code>> get() = _codeList + private val _expressItems = MutableLiveData<List<ExpressGroup>>() + val expressItems: LiveData<List<ExpressGroup>> = _expressItems init { // 初始化时加载数据 - loadData() + // loadData() + loadExpressData() } // 加载数据的方法 - fun loadData() { - // 获取数据,并更新 LiveData - _codeList.value = Core.code.getAllDesc() // 假设这是获取最新的 data 的方法 - } +// fun loadData() { +// // 获取数据,并更新 LiveData +// _codeList.value = Core.code.getAllDesc() // 假设这是获取最新的 data 的方法 +// } +// +// // 如果需要手动更新数据,可以调用这个方法 +// fun updateData() { +// _codeList.value = Core.code.getAllDesc() // 重新获取并更新数据 +// } - // 如果需要手动更新数据,可以调用这个方法 - fun updateData() { - _codeList.value = Core.code.getAllDesc() // 重新获取并更新数据 + fun loadExpressData() { + viewModelScope.launch { + // 1. 获取所有驿站类型的提醒设置 + val stations = Core.reminder.getByType("驿站") + + // 2. 按驿站分组获取包裹信息 + val groups = stations.map { station -> + val packages = Core.code.getByKeyword(station.nickname).map { code -> + ExpressPackage( + company = code.name, //快递公司 + trackingNumber = code.code, // 取件码 + date = code.overtime //时间 + ) + } + ExpressGroup( + stationName = station.nickname, + packages = packages + ) + } + + _expressItems.postValue(groups) + } } } \ No newline at end of file diff --git a/app/src/main/res/drawable/location.png b/app/src/main/res/drawable/location.png new file mode 100644 index 0000000..89a457e --- /dev/null +++ b/app/src/main/res/drawable/location.png Binary files differ diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index 0a6dc93..87907ab 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -1,30 +1,112 @@ <?xml version="1.0" encoding="utf-8"?> -<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" +<ScrollView 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" - tools:context=".ui.home.HomeFragment"> + android:layout_height="match_parent"> -<!-- <TextView--> -<!-- android:id="@+id/text_home"--> -<!-- android:layout_width="match_parent"--> -<!-- android:layout_height="wrap_content"--> -<!-- android:layout_marginStart="8dp"--> -<!-- android:layout_marginTop="8dp"--> -<!-- android:layout_marginEnd="8dp"--> -<!-- android:textAlignment="center"--> -<!-- android:textSize="20sp"--> -<!-- app:layout_constraintBottom_toBottomOf="parent"--> -<!-- app:layout_constraintEnd_toEndOf="parent"--> -<!-- app:layout_constraintStart_toStartOf="parent"--> -<!-- app:layout_constraintTop_toTopOf="parent" />--> - - <androidx.recyclerview.widget.RecyclerView - xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/recyclerView" +<!-- LinearLayout的作用是按照垂直或者水平方向排列其子视图--> +<!-- CardView组件是用于实现卡片式布局--> +<!-- RecyclerView 回收商视图 它使用适配器(Adapter)来管理数据的显示,--> +<!-- 开发者可以根据自己的需求实现适配器的方法,将数据与视图进行绑定。--> +<!-- 这使得 RecyclerView 能够轻松地处理各种类型的数据,并按照自定义的布局方式展示。--> +<!-- 支持局部刷新 通知数据集变化--> + <LinearLayout android:layout_width="match_parent" - android:layout_height="match_parent" - android:padding="8dp"/> + android:layout_height="wrap_content" + android:orientation="vertical" + android:padding="16dp"> -</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file + <!-- 我的快递板块 --> + <androidx.cardview.widget.CardView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginBottom="16dp" + app:cardCornerRadius="8dp" + app:cardElevation="2dp"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="我的快递" + android:textColor="#333333" + android:textSize="16sp" + android:textStyle="bold"/> + + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/express_recycler" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="8dp" /> + + + </LinearLayout> + </androidx.cardview.widget.CardView> + + <!-- 我的财务板块 --> + <androidx.cardview.widget.CardView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginBottom="16dp" + app:cardCornerRadius="8dp" + app:cardElevation="2dp"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:padding="16dp" + android:background="#E8F5E9"> + + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/finance_recycler" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="8dp"/> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="我的财务" + android:textColor="#333333" + android:textSize="16sp" + android:textStyle="bold"/> + </LinearLayout> + </androidx.cardview.widget.CardView> + + <!-- 纪念日板块 --> + <androidx.cardview.widget.CardView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginBottom="16dp" + app:cardCornerRadius="8dp" + app:cardElevation="2dp"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:padding="16dp" + android:background="#FFF3E0"> + + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/memorial_recycler" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="8dp"/> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="纪念日" + android:textColor="#333333" + android:textSize="16sp" + android:textStyle="bold"/> + </LinearLayout> + </androidx.cardview.widget.CardView> + + </LinearLayout> +</ScrollView> \ No newline at end of file diff --git a/app/src/main/res/layout/item_express_group.xml b/app/src/main/res/layout/item_express_group.xml new file mode 100644 index 0000000..4a13e84 --- /dev/null +++ b/app/src/main/res/layout/item_express_group.xml @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginHorizontal="12dp" + android:layout_marginVertical="6dp" + app:cardCornerRadius="8dp" + app:cardElevation="2dp"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:padding="16dp"> + + <!-- 驿站名称和包裹数量 --> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:layout_marginBottom="12dp"> + + <ImageView + android:id="@+id/iv_station_icon" + android:layout_width="20dp" + android:layout_height="20dp" + android:layout_gravity="center_vertical" + android:src="@drawable/location"/> + + <TextView + android:id="@+id/tv_station_name" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:layout_marginStart="8dp" + android:textSize="16sp" + android:textColor="#333333"/> + + <TextView + android:id="@+id/tv_package_count" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textSize="14sp" + android:textColor="#666666"/> + </LinearLayout> + + <!-- 包裹列表 --> + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/rv_packages" + android:layout_width="match_parent" + android:layout_height="wrap_content"/> + </LinearLayout> +</androidx.cardview.widget.CardView> \ No newline at end of file diff --git a/app/src/main/res/layout/item_express_package.xml b/app/src/main/res/layout/item_express_package.xml new file mode 100644 index 0000000..b5389c3 --- /dev/null +++ b/app/src/main/res/layout/item_express_package.xml @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:padding="12dp"> + + <ImageView + android:id="@+id/iv_company_logo" + android:layout_width="24dp" + android:layout_height="24dp" + android:layout_gravity="center_vertical" /> + + <LinearLayout + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginStart="12dp" + android:layout_weight="1" + android:orientation="vertical"> + + <TextView + android:id="@+id/tv_company" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textColor="#333333" + android:textSize="15sp" /> + + <TextView + android:id="@+id/tv_date" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:textColor="#999999" + android:textSize="12sp" /> + + </LinearLayout> + + <TextView + android:id="@+id/tv_tracking_number" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="4dp" + android:textColor="#666666" + android:textSize="14sp" /> + +</LinearLayout> \ No newline at end of file diff --git a/app/src/main/res/navigation/mobile_navigation.xml b/app/src/main/res/navigation/mobile_navigation.xml index bc776fe..293c825 100644 --- a/app/src/main/res/navigation/mobile_navigation.xml +++ b/app/src/main/res/navigation/mobile_navigation.xml @@ -5,6 +5,8 @@ android:id="@+id/mobile_navigation" app:startDestination="@+id/navigation_home"> + <!-- 对应的多个片段--> + <!-- tools:layout="@layout/fragment_home"表示设计视图中显示的应该是fragment_home.xml的内容,而不是当前布局的内容--> <fragment android:id="@+id/navigation_home" android:name="com.example.firstapp.ui.home.HomeFragment" -- Gitblit v1.9.3