cloudroam
2025-02-26 b653b90d4598ee2a65bceffa793bb75353b6d186
add: 快递列表展示
已修改10个文件
已添加5个文件
557 ■■■■ 文件已修改
app/src/main/java/com/example/firstapp/MainActivity.kt 62 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/adapter/ExpressAdapter.kt 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/adapter/ReminderAdapter.kt 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/database/dao/CodeDao.kt 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/database/dao/ReminderDao.kt 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/database/repository/CodeRepository.kt 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/database/repository/ReminderRepository.kt 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/model/ExpressGroup.kt 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/ui/home/HomeFragment.kt 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/ui/home/HomeViewModel.kt 62 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/drawable/location.png 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/fragment_home.xml 130 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/item_express_group.xml 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/item_express_package.xml 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/navigation/mobile_navigation.xml 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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)
    }
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
    }
}
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()) {
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>
}
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>
}
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)
    }
}
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)
    }
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
)
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() {
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)
        }
    }
}
app/src/main/res/drawable/location.png
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>
        <!-- 我的快递板块 -->
        <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>
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>
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>
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"