| | |
| | | registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions -> |
| | | when { |
| | | permissions.getOrDefault( |
| | | Manifest.permission.RECEIVE_SMS, |
| | | false |
| | | Manifest.permission.RECEIVE_SMS, false |
| | | ) && permissions.getOrDefault(Manifest.permission.READ_SMS, false) -> { |
| | | // 两个权限都获得授权 |
| | | registerSmsReceiver() |
| | |
| | | |
| | | // 重置提醒计划并检查是否有错过的提醒 |
| | | resetReminders() |
| | | |
| | | |
| | | // 检查权限 |
| | | if (ContextCompat.checkSelfPermission( |
| | | this, Manifest.permission.RECEIVE_SMS |
| | |
| | | while (cursor.moveToNext()) { |
| | | val messageBody = cursor.getString(cursor.getColumnIndexOrThrow("body")) |
| | | val datetime = cursor.getLong(cursor.getColumnIndexOrThrow("date")) |
| | | |
| | | |
| | | // 转换为 Date 对象 |
| | | val date = Date(datetime) |
| | | val sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()) |
| | |
| | | // 使用协程处理API调用和数据库操作 |
| | | CoroutineScope(Dispatchers.IO).launch { |
| | | try { |
| | | val response = RetrofitModelClient.modelService.processSms(mapOf("content" to messageBody)) |
| | | |
| | | val response = |
| | | RetrofitModelClient.modelService.processSms(mapOf("content" to messageBody)) |
| | | |
| | | synchronized(syncLock) { |
| | | if (response.status == "success") { |
| | | when (response.data.category) { |
| | | "快递" -> { |
| | | val pickupCode = response.data.details.pickupCode ?: "" |
| | | if (pickupCode.isNotEmpty()) { |
| | | val existingCode = Core.code.queryByTypeAndCodeAndDate( |
| | | response.data.category, |
| | | pickupCode, |
| | | dateString |
| | | ) |
| | | val existingCode = |
| | | Core.code.queryByTypeAndCodeAndDate( |
| | | response.data.category, |
| | | pickupCode, |
| | | dateString |
| | | ) |
| | | |
| | | if (existingCode == null) { |
| | | val code = Code( |
| | |
| | | msgId = msgId, |
| | | createTime = dateString, |
| | | oneLevel = response.data.details.post ?: "", |
| | | secondLevel = response.data.details.company ?: "", |
| | | secondLevel = response.data.details.company |
| | | ?: "", |
| | | code = pickupCode, |
| | | pickup = 0, |
| | | pickupTime = "", |
| | | overTime = "", |
| | | address = response.data.details.address ?: "", |
| | | address = response.data.details.address |
| | | ?: "", |
| | | remarks = response.data.details.time ?: "", |
| | | ) |
| | | // if(code.oneLevel.isNotEmpty() && code.secondLevel.isNotEmpty() && code.code.isNotEmpty()) { |
| | | if(code.oneLevel.isNotEmpty() && code.code.isNotEmpty()) { |
| | | if (code.oneLevel.isNotEmpty() && code.code.isNotEmpty()) { |
| | | Core.code.insert(code) |
| | | android.util.Log.d("MainActivity", "历史快递短信已保存: $pickupCode") |
| | | android.util.Log.d( |
| | | "MainActivity", |
| | | "历史快递短信已保存: $pickupCode" |
| | | ) |
| | | } |
| | | } else { |
| | | android.util.Log.d("MainActivity", "发现重复快递短信,跳过保存: $pickupCode") |
| | | android.util.Log.d( |
| | | "MainActivity", |
| | | "发现重复快递短信,跳过保存: $pickupCode" |
| | | ) |
| | | } |
| | | } |
| | | } |
| | | |
| | | "还款" -> { |
| | | val amount = response.data.details.amount ?: "" |
| | | if (amount.isNotEmpty()) { |
| | | val existingCode = Core.code.queryByTypeAndCodeAndDate( |
| | | response.data.category, |
| | | amount, |
| | | dateString |
| | | ) |
| | | val existingCode = |
| | | Core.code.queryByTypeAndCodeAndDate( |
| | | response.data.category, amount, dateString |
| | | ) |
| | | |
| | | if (existingCode == null) { |
| | | val code = Code( |
| | |
| | | msgId = msgId, |
| | | createTime = dateString, |
| | | oneLevel = response.data.details.type ?: "", |
| | | secondLevel = response.data.details.bank ?: "", |
| | | secondLevel = response.data.details.bank |
| | | ?: "", |
| | | code = amount, |
| | | pickup = 0, |
| | | pickupTime = "", |
| | | overTime = response.data.details.date ?: "", |
| | | address = response.data.details.address ?: "", |
| | | address = response.data.details.address |
| | | ?: "", |
| | | remarks = "最小还款金额${response.data.details.min_amount}还款卡号${response.data.details.number}" |
| | | ) |
| | | if(code.oneLevel.isNotEmpty() && code.secondLevel.isNotEmpty() && code.code.isNotEmpty()) { |
| | | if (code.oneLevel.isNotEmpty() && code.secondLevel.isNotEmpty() && code.code.isNotEmpty()) { |
| | | Core.code.insert(code) |
| | | android.util.Log.d("MainActivity", "历史还款短信已保存: $amount") |
| | | android.util.Log.d( |
| | | "MainActivity", |
| | | "历史还款短信已保存: $amount" |
| | | ) |
| | | } |
| | | } else { |
| | | android.util.Log.d("MainActivity", "发现重复还款短信,跳过保存: $amount") |
| | | android.util.Log.d( |
| | | "MainActivity", |
| | | "发现重复还款短信,跳过保存: $amount" |
| | | ) |
| | | } |
| | | } |
| | | } |
| | | |
| | | "收入" -> { |
| | | val amount = response.data.details.amount ?: "" |
| | | if (amount.isNotEmpty()) { |
| | | val existingCode = Core.code.queryByTypeAndCodeAndDate( |
| | | response.data.category, |
| | | amount, |
| | | dateString |
| | | ) |
| | | val existingCode = |
| | | Core.code.queryByTypeAndCodeAndDate( |
| | | response.data.category, amount, dateString |
| | | ) |
| | | |
| | | if (existingCode == null) { |
| | | val code = Code( |
| | |
| | | msgId = msgId, |
| | | createTime = dateString, |
| | | oneLevel = response.data.details.bank ?: "", |
| | | secondLevel = response.data.details.bank ?: "", |
| | | secondLevel = response.data.details.bank |
| | | ?: "", |
| | | code = amount, |
| | | pickup = 0, // 0-未取件,1-已取件 |
| | | pickupTime = "", // 取件时间为空 |
| | | overTime = response.data.details.datetime |
| | | ?: "", // 超时时间为空,暂时没有这块处理逻辑 |
| | | address = response.data.details.address ?: "", |
| | | remarks = "余额" + response.data.details.balance ?: "", |
| | | address = response.data.details.address |
| | | ?: "", |
| | | remarks = "余额" + response.data.details.balance |
| | | ?: "", |
| | | ) |
| | | if(code.oneLevel.isNotEmpty() && code.secondLevel.isNotEmpty() && code.code.isNotEmpty()) { |
| | | if (code.oneLevel.isNotEmpty() && code.secondLevel.isNotEmpty() && code.code.isNotEmpty()) { |
| | | Core.code.insert(code) |
| | | android.util.Log.d("MainActivity", "历史还款短信已保存: $amount") |
| | | android.util.Log.d( |
| | | "MainActivity", |
| | | "历史还款短信已保存: $amount" |
| | | ) |
| | | } |
| | | } else { |
| | | android.util.Log.d("MainActivity", "发现重复还款短信,跳过保存: $amount") |
| | | android.util.Log.d( |
| | | "MainActivity", |
| | | "发现重复还款短信,跳过保存: $amount" |
| | | ) |
| | | } |
| | | } |
| | | } |
| | | |
| | | "航班" -> { |
| | | val flight = response.data.details.flight ?: "" |
| | | if (flight.isNotEmpty()) { |
| | | val existingCode = |
| | | Core.code.queryByTypeAndCodeAndDate( |
| | | response.data.category, flight, dateString |
| | | ) |
| | | |
| | | if (existingCode == null) { |
| | | val code = Code( |
| | | id = 0, |
| | | category = response.data.category, |
| | | categoryId = 4, // 4-航班类型 |
| | | typeId = 1, //暂时没有根据type分类 |
| | | ruleId = 2, //1-还款类型 |
| | | msgId = msgId, |
| | | createTime = dateString, |
| | | oneLevel = response.data.details.company |
| | | ?: "", |
| | | secondLevel = response.data.details.start + response.data.details.end |
| | | ?: "", |
| | | code = flight, |
| | | pickup = 0, // 0-未取件,1-已取件 |
| | | pickupTime = "", // 取件时间为空 |
| | | overTime = response.data.details.time |
| | | ?: "", // 超时时间为空,暂时没有这块处理逻辑 |
| | | address = response.data.details.address |
| | | ?: "", |
| | | remarks = response.data.details.seat ?: "", |
| | | ) |
| | | if (code.oneLevel != "" && code.secondLevel != "" && code.code != "") { |
| | | Core.code.insert(code) |
| | | } |
| | | } else { |
| | | android.util.Log.d( |
| | | "MainActivity", |
| | | "发现重复还款短信,跳过保存: $flight" |
| | | ) |
| | | } |
| | | } |
| | | } |
| | | |
| | | "火车票" -> { |
| | | val seat = response.data.details.seat ?: "" |
| | | if (seat.isNotEmpty()) { |
| | | val existingCode = |
| | | Core.code.queryByTypeAndCodeAndDate( |
| | | response.data.category, seat, dateString |
| | | ) |
| | | |
| | | if (existingCode == null) { |
| | | val code = Code( |
| | | id = 0, |
| | | category = response.data.category, |
| | | categoryId = 5, // 5-火车票类型 |
| | | typeId = 1, //暂时没有根据type分类 |
| | | ruleId = 2, //1-还款类型 |
| | | msgId = msgId, |
| | | createTime = dateString, |
| | | oneLevel = response.data.details.company |
| | | ?: "", |
| | | secondLevel = response.data.details.company |
| | | ?: "", |
| | | code = seat, |
| | | pickup = 0, // 0-未取件,1-已取件 |
| | | pickupTime = "", // 取件时间为空 |
| | | overTime = response.data.details.time |
| | | ?: "", // 超时时间为空,暂时没有这块处理逻辑 |
| | | address = response.data.details.address |
| | | ?: "", |
| | | remarks = response.data.details.trips ?: "", |
| | | ) |
| | | if (code.oneLevel != "" && code.secondLevel != "" && code.code != "") { |
| | | Core.code.insert(code) |
| | | } |
| | | } else { |
| | | android.util.Log.d( |
| | | "MainActivity", |
| | | "发现重复还款短信,跳过保存: $seat" |
| | | ) |
| | | } |
| | | } |
| | | } |
| | |
| | | try { |
| | | // 取消所有现有的提醒任务 |
| | | androidx.work.WorkManager.getInstance(this).cancelAllWorkByTag("reminder_worker") |
| | | |
| | | |
| | | // 清除旧的提醒偏好设置 |
| | | getSharedPreferences("reminder_prefs", Context.MODE_PRIVATE).edit().clear().apply() |
| | | |
| | | |
| | | // 重新设置提醒任务 |
| | | (application as App).setupReminderWorker() |
| | | |
| | | |
| | | // 检查是否有错过的提醒 |
| | | com.example.firstapp.service.ReminderWorker.checkMissedReminders(this) |
| | | |
| | | |
| | | android.util.Log.d("MainActivity", "已重置提醒计划") |
| | | } catch (e: Exception) { |
| | | android.util.Log.e("MainActivity", "重置提醒计划失败: ${e.message}") |
| | |
| | | const val TYPE_EXPRESS = "express" |
| | | const val TYPE_REPAYMENT = "repayment" |
| | | const val TYPE_INCOME = "income" |
| | | const val TYPE_TRAIN = "train" |
| | | const val TYPE_FLIGHT = "flight" |
| | | } |
| | | |
| | | private var pageType = TYPE_EXPRESS |
| | |
| | | TYPE_EXPRESS -> "是否确认取出所有包裹?" |
| | | TYPE_REPAYMENT -> "是否确认处理所有还款?" |
| | | TYPE_INCOME -> "是否确认处理所有收入?" |
| | | TYPE_TRAIN -> "是否确认处理所有火车票?" |
| | | TYPE_FLIGHT -> "是否确认处理所有机票?" |
| | | else -> "是否确认处理所有项目?" |
| | | } |
| | | } |
| | |
| | | TYPE_EXPRESS -> "全部取件" |
| | | TYPE_REPAYMENT -> "全部还款" |
| | | TYPE_INCOME -> "全部收款" |
| | | TYPE_TRAIN -> "全部处理票务" |
| | | TYPE_FLIGHT -> "全部处理机票" |
| | | else -> "全部处理" |
| | | } |
| | | } |
| | |
| | | TYPE_EXPRESS -> "共${count}个包裹" |
| | | TYPE_REPAYMENT -> "共${count}笔还款" |
| | | TYPE_INCOME -> "共${count}笔收入" |
| | | TYPE_TRAIN -> "共${count}张车票" |
| | | TYPE_FLIGHT -> "共${count}张机票" |
| | | else -> "共${count}个" |
| | | } |
| | | } |
对比新文件 |
| | |
| | | package com.example.firstapp.adapter |
| | | |
| | | import android.view.LayoutInflater |
| | | import android.view.ViewGroup |
| | | import androidx.recyclerview.widget.DiffUtil |
| | | import androidx.recyclerview.widget.LinearLayoutManager |
| | | import androidx.recyclerview.widget.ListAdapter |
| | | import androidx.recyclerview.widget.RecyclerView |
| | | import com.example.firstapp.R |
| | | import com.example.firstapp.databinding.ItemFlightGroupBinding |
| | | import com.example.firstapp.databinding.ItemFlightPackageHomeBinding |
| | | import com.example.firstapp.databinding.ItemFlightBinding |
| | | import com.example.firstapp.model.FlightGroup |
| | | import com.example.firstapp.model.FlightPackage |
| | | |
| | | class FlightAdapter : |
| | | ListAdapter<FlightGroup, FlightAdapter.ViewHolder>(FlightGroupDiffCallback()) { |
| | | |
| | | private var onPackageClickListener: (FlightGroup, FlightPackage) -> Unit = { _, _ -> } |
| | | |
| | | fun setOnPackageClickListener(listener: (FlightGroup, FlightPackage) -> Unit) { |
| | | onPackageClickListener = listener |
| | | } |
| | | |
| | | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { |
| | | val binding = ItemFlightGroupBinding.inflate( |
| | | LayoutInflater.from(parent.context), parent, false |
| | | ) |
| | | return ViewHolder(binding) |
| | | } |
| | | |
| | | override fun onBindViewHolder(holder: ViewHolder, position: Int) { |
| | | val group = getItem(position) |
| | | holder.bind(group) |
| | | holder.setOnPackageClickListener(onPackageClickListener) |
| | | } |
| | | |
| | | |
| | | inner class ViewHolder(private val binding: ItemFlightGroupBinding) : |
| | | RecyclerView.ViewHolder(binding.root) { |
| | | private val packagesAdapter = FlightPackageHomeAdapter { pack -> |
| | | currentGroup?.let { group -> |
| | | onPackageClickListener(group, pack) |
| | | } |
| | | } |
| | | private var currentGroup: FlightGroup? = null |
| | | |
| | | init { |
| | | binding.rvPackages.apply { |
| | | layoutManager = LinearLayoutManager(context) |
| | | adapter = packagesAdapter |
| | | } |
| | | } |
| | | |
| | | fun bind(group: FlightGroup) { |
| | | currentGroup = group |
| | | binding.tvStationName.text = group.stationName |
| | | binding.tvPackageCount.text = "共${group.packages.size}张机票" |
| | | packagesAdapter.submitList(group.packages) |
| | | } |
| | | |
| | | fun setOnPackageClickListener(listener: (FlightGroup, FlightPackage) -> Unit) { |
| | | // 这个方法可以移除,因为我们在构造 FlightPackageHomeAdapter 时已经处理了点击事件 |
| | | // 或者保留这个方法但不做任何操作 |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 首页使用的机票适配器 - 简化版本 |
| | | class FlightPackageHomeAdapter(private val onPackageClick: (FlightPackage) -> Unit) : |
| | | ListAdapter<FlightPackage, FlightPackageHomeAdapter.ViewHolder>(FlightPackageDiffCallback()) { |
| | | |
| | | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { |
| | | val binding = ItemFlightPackageHomeBinding.inflate( |
| | | LayoutInflater.from(parent.context), parent, false |
| | | ) |
| | | return ViewHolder(binding) |
| | | } |
| | | |
| | | override fun onBindViewHolder(holder: ViewHolder, position: Int) { |
| | | val pack = getItem(position) |
| | | holder.bind(pack) |
| | | } |
| | | |
| | | inner class ViewHolder(private val binding: ItemFlightPackageHomeBinding) : |
| | | RecyclerView.ViewHolder(binding.root) { |
| | | |
| | | init { |
| | | binding.root.setOnClickListener { |
| | | val pack = getItem(adapterPosition) |
| | | onPackageClick(pack) |
| | | } |
| | | } |
| | | |
| | | fun bind(pack: FlightPackage) { |
| | | binding.tvCompany.text = pack.company |
| | | binding.tvCreateTime.text = pack.createTime |
| | | binding.tvTrackingNumber.text = pack.trackingNumber |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 取件页面使用的机票适配器 |
| | | class FlightPackageAdapter(private val onPackagePickup: (FlightPackage) -> Unit = { _ -> }) : |
| | | ListAdapter<FlightPackage, FlightPackageAdapter.ViewHolder>(FlightPackageDiffCallback()) { |
| | | |
| | | private var onPackageClickListener: (FlightPackage) -> Unit = {} |
| | | private var stationName: String = "" |
| | | |
| | | fun setStationInfo(station: String) { |
| | | stationName = station |
| | | } |
| | | |
| | | fun setOnPackageClickListener(listener: (FlightPackage) -> Unit) { |
| | | onPackageClickListener = listener |
| | | } |
| | | |
| | | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { |
| | | val binding = ItemFlightBinding.inflate( |
| | | LayoutInflater.from(parent.context), parent, false |
| | | ) |
| | | return ViewHolder(binding) |
| | | } |
| | | |
| | | override fun onBindViewHolder(holder: ViewHolder, position: Int) { |
| | | val pack = getItem(position) |
| | | holder.bind(pack) |
| | | } |
| | | |
| | | inner class ViewHolder(private val binding: ItemFlightBinding) : |
| | | RecyclerView.ViewHolder(binding.root) { |
| | | |
| | | init { |
| | | binding.ivPackageStatus.setOnClickListener { |
| | | val pack = getItem(adapterPosition) |
| | | onPackagePickup(pack) |
| | | } |
| | | |
| | | binding.root.setOnClickListener(null) |
| | | } |
| | | |
| | | fun bind(pack: FlightPackage) { |
| | | binding.tvPackageId.text = pack.id.toString() |
| | | binding.tvCompany.text = pack.company |
| | | binding.tvCreateTime.text = pack.createTime |
| | | binding.tvTrackingNumber.text = pack.trackingNumber |
| | | binding.ivPackageStatus.setImageResource( |
| | | R.drawable.circle |
| | | ) |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | private class FlightGroupDiffCallback : DiffUtil.ItemCallback<FlightGroup>() { |
| | | override fun areItemsTheSame(oldItem: FlightGroup, newItem: FlightGroup): Boolean { |
| | | return oldItem.stationName == newItem.stationName |
| | | } |
| | | |
| | | override fun areContentsTheSame(oldItem: FlightGroup, newItem: FlightGroup): Boolean { |
| | | return oldItem == newItem |
| | | } |
| | | } |
| | | |
| | | private class FlightPackageDiffCallback : DiffUtil.ItemCallback<FlightPackage>() { |
| | | override fun areItemsTheSame(oldItem: FlightPackage, newItem: FlightPackage): Boolean { |
| | | return oldItem.trackingNumber == newItem.trackingNumber |
| | | } |
| | | |
| | | override fun areContentsTheSame(oldItem: FlightPackage, newItem: FlightPackage): Boolean { |
| | | return oldItem == newItem |
| | | } |
| | | } |
对比新文件 |
| | |
| | | package com.example.firstapp.adapter |
| | | |
| | | import android.view.LayoutInflater |
| | | import android.view.ViewGroup |
| | | import androidx.recyclerview.widget.DiffUtil |
| | | import androidx.recyclerview.widget.LinearLayoutManager |
| | | import androidx.recyclerview.widget.ListAdapter |
| | | import androidx.recyclerview.widget.RecyclerView |
| | | import com.example.firstapp.R |
| | | import com.example.firstapp.databinding.ItemTrainGroupBinding |
| | | import com.example.firstapp.databinding.ItemTrainPackageHomeBinding |
| | | import com.example.firstapp.databinding.ItemTrainBinding |
| | | import com.example.firstapp.model.TrainGroup |
| | | import com.example.firstapp.model.TrainPackage |
| | | |
| | | class TrainAdapter : |
| | | ListAdapter<TrainGroup, TrainAdapter.ViewHolder>(TrainGroupDiffCallback()) { |
| | | |
| | | private var onPackageClickListener: (TrainGroup, TrainPackage) -> Unit = { _, _ -> } |
| | | |
| | | fun setOnPackageClickListener(listener: (TrainGroup, TrainPackage) -> Unit) { |
| | | onPackageClickListener = listener |
| | | } |
| | | |
| | | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { |
| | | val binding = ItemTrainGroupBinding.inflate( |
| | | LayoutInflater.from(parent.context), parent, false |
| | | ) |
| | | return ViewHolder(binding) |
| | | } |
| | | |
| | | override fun onBindViewHolder(holder: ViewHolder, position: Int) { |
| | | val group = getItem(position) |
| | | holder.bind(group) |
| | | holder.setOnPackageClickListener(onPackageClickListener) |
| | | } |
| | | |
| | | |
| | | inner class ViewHolder(private val binding: ItemTrainGroupBinding) : |
| | | RecyclerView.ViewHolder(binding.root) { |
| | | private val packagesAdapter = TrainPackageHomeAdapter { pack -> |
| | | currentGroup?.let { group -> |
| | | onPackageClickListener(group, pack) |
| | | } |
| | | } |
| | | private var currentGroup: TrainGroup? = null |
| | | |
| | | init { |
| | | binding.rvPackages.apply { |
| | | layoutManager = LinearLayoutManager(context) |
| | | adapter = packagesAdapter |
| | | } |
| | | } |
| | | |
| | | fun bind(group: TrainGroup) { |
| | | currentGroup = group |
| | | binding.tvStationName.text = group.stationName |
| | | binding.tvPackageCount.text = "共${group.packages.size}张车票" |
| | | packagesAdapter.submitList(group.packages) |
| | | } |
| | | |
| | | fun setOnPackageClickListener(listener: (TrainGroup, TrainPackage) -> Unit) { |
| | | // 这个方法可以移除,因为我们在构造 TrainPackageHomeAdapter 时已经处理了点击事件 |
| | | // 或者保留这个方法但不做任何操作 |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 首页使用的车票适配器 - 简化版本 |
| | | class TrainPackageHomeAdapter(private val onPackageClick: (TrainPackage) -> Unit) : |
| | | ListAdapter<TrainPackage, TrainPackageHomeAdapter.ViewHolder>(TrainPackageDiffCallback()) { |
| | | |
| | | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { |
| | | val binding = ItemTrainPackageHomeBinding.inflate( |
| | | LayoutInflater.from(parent.context), parent, false |
| | | ) |
| | | return ViewHolder(binding) |
| | | } |
| | | |
| | | override fun onBindViewHolder(holder: ViewHolder, position: Int) { |
| | | val pack = getItem(position) |
| | | holder.bind(pack) |
| | | } |
| | | |
| | | inner class ViewHolder(private val binding: ItemTrainPackageHomeBinding) : |
| | | RecyclerView.ViewHolder(binding.root) { |
| | | |
| | | init { |
| | | binding.root.setOnClickListener { |
| | | val pack = getItem(adapterPosition) |
| | | onPackageClick(pack) |
| | | } |
| | | } |
| | | |
| | | fun bind(pack: TrainPackage) { |
| | | binding.tvCompany.text = pack.company |
| | | binding.tvCreateTime.text = pack.createTime |
| | | binding.tvTrackingNumber.text = pack.trackingNumber |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 取件页面使用的车票适配器 |
| | | class TrainPackageAdapter(private val onPackagePickup: (TrainPackage) -> Unit = { _ -> }) : |
| | | ListAdapter<TrainPackage, TrainPackageAdapter.ViewHolder>(TrainPackageDiffCallback()) { |
| | | |
| | | private var onPackageClickListener: (TrainPackage) -> Unit = {} |
| | | private var stationName: String = "" |
| | | |
| | | fun setStationInfo(station: String) { |
| | | stationName = station |
| | | } |
| | | |
| | | fun setOnPackageClickListener(listener: (TrainPackage) -> Unit) { |
| | | onPackageClickListener = listener |
| | | } |
| | | |
| | | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { |
| | | val binding = ItemTrainBinding.inflate( |
| | | LayoutInflater.from(parent.context), parent, false |
| | | ) |
| | | return ViewHolder(binding) |
| | | } |
| | | |
| | | override fun onBindViewHolder(holder: ViewHolder, position: Int) { |
| | | val pack = getItem(position) |
| | | holder.bind(pack) |
| | | } |
| | | |
| | | inner class ViewHolder(private val binding: ItemTrainBinding) : |
| | | RecyclerView.ViewHolder(binding.root) { |
| | | |
| | | init { |
| | | binding.ivPackageStatus.setOnClickListener { |
| | | val pack = getItem(adapterPosition) |
| | | onPackagePickup(pack) |
| | | } |
| | | |
| | | binding.root.setOnClickListener(null) |
| | | } |
| | | |
| | | fun bind(pack: TrainPackage) { |
| | | binding.tvPackageId.text = pack.id.toString() |
| | | binding.tvCompany.text = pack.company |
| | | binding.tvCreateTime.text = pack.createTime |
| | | binding.tvTrackingNumber.text = pack.trackingNumber |
| | | binding.ivPackageStatus.setImageResource( |
| | | R.drawable.circle |
| | | ) |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | private class TrainGroupDiffCallback : DiffUtil.ItemCallback<TrainGroup>() { |
| | | override fun areItemsTheSame(oldItem: TrainGroup, newItem: TrainGroup): Boolean { |
| | | return oldItem.stationName == newItem.stationName |
| | | } |
| | | |
| | | override fun areContentsTheSame(oldItem: TrainGroup, newItem: TrainGroup): Boolean { |
| | | return oldItem == newItem |
| | | } |
| | | } |
| | | |
| | | private class TrainPackageDiffCallback : DiffUtil.ItemCallback<TrainPackage>() { |
| | | override fun areItemsTheSame(oldItem: TrainPackage, newItem: TrainPackage): Boolean { |
| | | return oldItem.trackingNumber == newItem.trackingNumber |
| | | } |
| | | |
| | | override fun areContentsTheSame(oldItem: TrainPackage, newItem: TrainPackage): Boolean { |
| | | return oldItem == newItem |
| | | } |
| | | } |
| | |
| | | val number: String?, |
| | | val datetime: String?, |
| | | val balance: String?, |
| | | val seat: String?, |
| | | val trips: String?, |
| | | val start: String?, |
| | | val end: String?, |
| | | val flight: String?, |
| | | ) |
对比新文件 |
| | |
| | | package com.example.firstapp.model |
| | | |
| | | data class FlightGroup( |
| | | val stationName: String, |
| | | val packages: List<FlightPackage> |
| | | ) |
| | | |
| | | data class FlightPackage( |
| | | var id: Long, |
| | | val company: String, |
| | | val trackingNumber: String, |
| | | val createTime: String |
| | | ) |
对比新文件 |
| | |
| | | package com.example.firstapp.model |
| | | |
| | | data class TrainGroup( |
| | | val stationName: String, |
| | | val packages: List<TrainPackage> |
| | | ) |
| | | |
| | | data class TrainPackage( |
| | | var id: Long, |
| | | val company: String, |
| | | val trackingNumber: String, |
| | | val createTime: String |
| | | ) |
| | |
| | | Core.code.insert(code) |
| | | } |
| | | } |
| | | "航班" -> { |
| | | val code = Code( |
| | | id = 0, |
| | | category = response.data.category, |
| | | categoryId = 4, // 4-航班类型 |
| | | typeId = 1, //暂时没有根据type分类 |
| | | ruleId = 2, //1-还款类型 |
| | | msgId = msgId, |
| | | createTime = createtime, |
| | | oneLevel = response.data.details.company ?: "", |
| | | secondLevel = response.data.details.start +response.data.details.end?: "", |
| | | code = response.data.details.seat ?: "", |
| | | pickup = 0, // 0-未取件,1-已取件 |
| | | pickupTime = "", // 取件时间为空 |
| | | overTime = response.data.details.time |
| | | ?: "", // 超时时间为空,暂时没有这块处理逻辑 |
| | | address = response.data.details.address ?: "", |
| | | remarks = response.data.details.seat ?: "", |
| | | ) |
| | | if(code.oneLevel!="" && code.secondLevel!="" && code.code!="") { |
| | | Core.code.insert(code) |
| | | } |
| | | } |
| | | "火车票" -> { |
| | | val code = Code( |
| | | id = 0, |
| | | category = response.data.category, |
| | | categoryId = 5, // 5-火车票类型 |
| | | typeId = 1, //暂时没有根据type分类 |
| | | ruleId = 2, //1-还款类型 |
| | | msgId = msgId, |
| | | createTime = createtime, |
| | | oneLevel = response.data.details.company ?: "", |
| | | secondLevel = response.data.details.company ?: "", |
| | | code = response.data.details.seat ?: "", |
| | | pickup = 0, // 0-未取件,1-已取件 |
| | | pickupTime = "", // 取件时间为空 |
| | | overTime = response.data.details.time |
| | | ?: "", // 超时时间为空,暂时没有这块处理逻辑 |
| | | address = response.data.details.address ?: "", |
| | | remarks = response.data.details.trips ?: "", |
| | | ) |
| | | if(code.oneLevel!="" && code.secondLevel!="" && code.code!="") { |
| | | Core.code.insert(code) |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 发送广播通知数据已更新 |
| | |
| | | import com.example.firstapp.adapter.FinanceAdapter |
| | | import com.example.firstapp.adapter.CategorySelectorAdapter |
| | | import com.example.firstapp.adapter.IncomeAdapter |
| | | import com.example.firstapp.adapter.TrainAdapter |
| | | import com.example.firstapp.adapter.FlightAdapter |
| | | import com.example.firstapp.database.service.RetrofitClient |
| | | import com.example.firstapp.databinding.FragmentHomeBinding |
| | | import com.example.firstapp.databinding.DialogCategorySelectorBinding |
| | |
| | | private lateinit var expressAdapter: ExpressAdapter |
| | | private lateinit var financeAdapter: FinanceAdapter |
| | | private lateinit var incomeAdapter: IncomeAdapter |
| | | private lateinit var flightAdapter: FinanceAdapter |
| | | private lateinit var trainAdapter: FinanceAdapter |
| | | private lateinit var flightAdapter: FlightAdapter |
| | | private lateinit var trainAdapter: TrainAdapter |
| | | private lateinit var dataUpdateReceiver: BroadcastReceiver |
| | | private lateinit var reminderUpdateReceiver: BroadcastReceiver |
| | | private var reminderBadge: TextView? = null |
| | |
| | | |
| | | binding.flightRecycler.apply { |
| | | layoutManager = LinearLayoutManager(context) |
| | | flightAdapter = FinanceAdapter() |
| | | flightAdapter = FlightAdapter() |
| | | adapter = flightAdapter |
| | | visibility = View.GONE |
| | | |
| | | // 设置点击监听 |
| | | flightAdapter.setOnPackageClickListener { group, pack -> |
| | | // 跳转到航班处理页面 |
| | | val intent = Intent(requireContext(), PickupActivity::class.java).apply { |
| | | putExtra("station_name", group.stationName) |
| | | putExtra("company", pack.company) |
| | | putExtra("page_type", PickupActivity.TYPE_FLIGHT) |
| | | } |
| | | startActivity(intent) |
| | | } |
| | | } |
| | | |
| | | binding.trainRecycler.apply { |
| | | layoutManager = LinearLayoutManager(context) |
| | | trainAdapter = FinanceAdapter() |
| | | trainAdapter = TrainAdapter() |
| | | adapter = trainAdapter |
| | | visibility = View.GONE |
| | | |
| | | // 设置点击监听 |
| | | trainAdapter.setOnPackageClickListener { group, pack -> |
| | | // 跳转到火车票页面 |
| | | val intent = Intent(requireContext(), PickupActivity::class.java).apply { |
| | | putExtra("station_name", group.stationName) |
| | | putExtra("company", pack.company) |
| | | putExtra("page_type", PickupActivity.TYPE_TRAIN) |
| | | } |
| | | startActivity(intent) |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | import kotlinx.coroutines.launch |
| | | import com.example.firstapp.database.repository.ReminderRecordRepository |
| | | import com.example.firstapp.database.entity.ReminderRecord |
| | | import com.example.firstapp.model.TrainGroup |
| | | import com.example.firstapp.model.TrainPackage |
| | | import com.example.firstapp.model.FlightGroup |
| | | import com.example.firstapp.model.FlightPackage |
| | | |
| | | class HomeViewModel : ViewModel() { |
| | | |
| | | private val _expressItems = MutableLiveData<List<ExpressGroup>>() |
| | | private val _financeItems = MutableLiveData<List<FinanceGroup>>() |
| | | private val _incomeItems = MutableLiveData<List<IncomeGroup>>() |
| | | private val _flightItems = MutableLiveData<List<FinanceGroup>>() |
| | | private val _trainItems = MutableLiveData<List<FinanceGroup>>() |
| | | private val _flightItems = MutableLiveData<List<FlightGroup>>() |
| | | private val _trainItems = MutableLiveData<List<TrainGroup>>() |
| | | |
| | | val expressItems: LiveData<List<ExpressGroup>> = _expressItems |
| | | val financeItems: LiveData<List<FinanceGroup>> = _financeItems |
| | | val incomeItems: LiveData<List<IncomeGroup>> = _incomeItems |
| | | val flightItems: LiveData<List<FinanceGroup>> = _flightItems |
| | | val trainItems: LiveData<List<FinanceGroup>> = _trainItems |
| | | val flightItems: LiveData<List<FlightGroup>> = _flightItems |
| | | val trainItems: LiveData<List<TrainGroup>> = _trainItems |
| | | |
| | | private val _categories = MutableLiveData<List<CategoryConfig>>() |
| | | val categories: LiveData<List<CategoryConfig>> = _categories |
| | |
| | | } |
| | | _incomeItems.postValue(groups) |
| | | } |
| | | "火车票" -> { |
| | | // 处理火车票类型 |
| | | val groups = stations.map { station -> |
| | | val packages = Core.code.getPackagesByTypeAndStation(type, station.stationName).map { code -> |
| | | TrainPackage( |
| | | id = code.id, |
| | | company = code.secondLevel, |
| | | trackingNumber = code.code, |
| | | createTime = code.createTime |
| | | ) |
| | | } |
| | | TrainGroup(stationName = station.stationName, packages = packages) |
| | | } |
| | | _trainItems.postValue(groups) |
| | | } |
| | | "航班" -> { |
| | | // 处理航班类型 |
| | | val groups = stations.map { station -> |
| | | val packages = Core.code.getPackagesByTypeAndStation(type, station.stationName).map { code -> |
| | | FlightPackage( |
| | | id = code.id, |
| | | company = code.secondLevel, |
| | | trackingNumber = code.code, |
| | | createTime = code.createTime |
| | | ) |
| | | } |
| | | FlightGroup(stationName = station.stationName, packages = packages) |
| | | } |
| | | _flightItems.postValue(groups) |
| | | } |
| | | else -> { |
| | | // 处理其他类型(还款、航班、火车票) |
| | | // 处理其他类型(还款) |
| | | val groups = stations.map { station -> |
| | | val packages = Core.code.getPackagesByTypeAndStation(type, station.stationName).map { code -> |
| | | FinancePackage( |
| | |
| | | // 根据类型更新对应的 LiveData |
| | | when (type) { |
| | | "还款" -> _financeItems.postValue(groups) |
| | | "航班" -> _flightItems.postValue(groups) |
| | | "火车票" -> _trainItems.postValue(groups) |
| | | } |
| | | } |
| | | } |
| | |
| | | android:layout_height="wrap_content" |
| | | android:background="@null" |
| | | android:hint="邀请码" |
| | | android:inputType="phone" |
| | | android:inputType="textVisiblePassword" |
| | | android:maxLength="11" |
| | | android:textSize="16sp" |
| | | android:padding="12dp"/> |
对比新文件 |
| | |
| | | <?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" |
| | | android:gravity="center_vertical"> |
| | | |
| | | <ImageView |
| | | android:id="@+id/iv_package_status" |
| | | android:layout_width="12dp" |
| | | android:layout_height="12dp" |
| | | android:src="@drawable/circle"/> |
| | | |
| | | <TextView |
| | | android:id="@+id/tv_package_id" |
| | | android:layout_width="0dp" |
| | | android:layout_height="0dp" |
| | | android:visibility="gone"/> |
| | | |
| | | <ImageView |
| | | android:id="@+id/iv_company_logo" |
| | | android:layout_width="20dp" |
| | | android:layout_height="20dp" |
| | | android:layout_marginEnd="6dp"/> |
| | | |
| | | <LinearLayout |
| | | android:layout_width="0dp" |
| | | android:layout_height="wrap_content" |
| | | android:layout_weight="1" |
| | | android:orientation="vertical"> |
| | | |
| | | <TextView |
| | | android:id="@+id/tv_company" |
| | | android:layout_width="wrap_content" |
| | | android:layout_height="wrap_content" |
| | | android:textSize="12sp" |
| | | android:textColor="#333333" |
| | | android:textStyle="bold"/> |
| | | |
| | | <TextView |
| | | android:id="@+id/tv_create_time" |
| | | android:layout_width="wrap_content" |
| | | android:layout_height="wrap_content" |
| | | android:textSize="12sp" |
| | | android:textColor="#666666" |
| | | android:layout_marginTop="4dp"/> |
| | | </LinearLayout> |
| | | |
| | | <TextView |
| | | android:id="@+id/tv_tracking_number" |
| | | android:layout_width="wrap_content" |
| | | android:layout_height="wrap_content" |
| | | android:textSize="25sp" |
| | | android:textColor="#333333" |
| | | android:layout_marginStart="12dp" |
| | | android:textStyle="bold"/> |
| | | |
| | | </LinearLayout> |
对比新文件 |
| | |
| | | <?xml version="1.0" encoding="utf-8"?> |
| | | <com.google.android.material.card.MaterialCardView |
| | | 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" |
| | | app:cardBackgroundColor="@android:color/white" |
| | | app:strokeColor="#FF000000" |
| | | app:strokeWidth="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> |
| | | </com.google.android.material.card.MaterialCardView> |
对比新文件 |
| | |
| | | <?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" |
| | | android:gravity="center_vertical"> |
| | | |
| | | <ImageView |
| | | android:id="@+id/iv_company_logo" |
| | | android:layout_width="20dp" |
| | | android:layout_height="20dp" |
| | | android:layout_marginEnd="6dp"/> |
| | | |
| | | <LinearLayout |
| | | android:layout_width="0dp" |
| | | android:layout_height="wrap_content" |
| | | android:layout_weight="1" |
| | | android:orientation="vertical"> |
| | | |
| | | <TextView |
| | | android:id="@+id/tv_company" |
| | | android:layout_width="wrap_content" |
| | | android:layout_height="wrap_content" |
| | | android:textSize="12sp" |
| | | android:textColor="#333333" |
| | | android:textStyle="bold"/> |
| | | |
| | | <TextView |
| | | android:id="@+id/tv_create_time" |
| | | android:layout_width="wrap_content" |
| | | android:layout_height="wrap_content" |
| | | android:textSize="10sp" |
| | | android:textColor="#666666" |
| | | android:layout_marginTop="4dp"/> |
| | | </LinearLayout> |
| | | |
| | | <TextView |
| | | android:id="@+id/tv_tracking_number" |
| | | android:layout_width="wrap_content" |
| | | android:layout_height="wrap_content" |
| | | android:textSize="25sp" |
| | | android:textColor="#333333" |
| | | android:layout_marginStart="12dp" |
| | | android:textStyle="bold"/> |
| | | |
| | | </LinearLayout> |
对比新文件 |
| | |
| | | <?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" |
| | | android:gravity="center_vertical"> |
| | | |
| | | <ImageView |
| | | android:id="@+id/iv_package_status" |
| | | android:layout_width="12dp" |
| | | android:layout_height="12dp" |
| | | android:src="@drawable/circle"/> |
| | | |
| | | <TextView |
| | | android:id="@+id/tv_package_id" |
| | | android:layout_width="0dp" |
| | | android:layout_height="0dp" |
| | | android:visibility="gone"/> |
| | | |
| | | <ImageView |
| | | android:id="@+id/iv_company_logo" |
| | | android:layout_width="20dp" |
| | | android:layout_height="20dp" |
| | | android:layout_marginEnd="6dp"/> |
| | | |
| | | <LinearLayout |
| | | android:layout_width="0dp" |
| | | android:layout_height="wrap_content" |
| | | android:layout_weight="1" |
| | | android:orientation="vertical"> |
| | | |
| | | <TextView |
| | | android:id="@+id/tv_company" |
| | | android:layout_width="wrap_content" |
| | | android:layout_height="wrap_content" |
| | | android:textSize="12sp" |
| | | android:textColor="#333333" |
| | | android:textStyle="bold"/> |
| | | |
| | | <TextView |
| | | android:id="@+id/tv_create_time" |
| | | android:layout_width="wrap_content" |
| | | android:layout_height="wrap_content" |
| | | android:textSize="12sp" |
| | | android:textColor="#666666" |
| | | android:layout_marginTop="4dp"/> |
| | | </LinearLayout> |
| | | |
| | | <TextView |
| | | android:id="@+id/tv_tracking_number" |
| | | android:layout_width="wrap_content" |
| | | android:layout_height="wrap_content" |
| | | android:textSize="25sp" |
| | | android:textColor="#333333" |
| | | android:layout_marginStart="12dp" |
| | | android:textStyle="bold"/> |
| | | |
| | | </LinearLayout> |
对比新文件 |
| | |
| | | <?xml version="1.0" encoding="utf-8"?> |
| | | <com.google.android.material.card.MaterialCardView |
| | | 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" |
| | | app:cardBackgroundColor="@android:color/white" |
| | | app:strokeColor="#FF000000" |
| | | app:strokeWidth="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> |
| | | </com.google.android.material.card.MaterialCardView> |
对比新文件 |
| | |
| | | <?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" |
| | | android:gravity="center_vertical"> |
| | | |
| | | <ImageView |
| | | android:id="@+id/iv_company_logo" |
| | | android:layout_width="20dp" |
| | | android:layout_height="20dp" |
| | | android:layout_marginEnd="6dp"/> |
| | | |
| | | <LinearLayout |
| | | android:layout_width="0dp" |
| | | android:layout_height="wrap_content" |
| | | android:layout_weight="1" |
| | | android:orientation="vertical"> |
| | | |
| | | <TextView |
| | | android:id="@+id/tv_company" |
| | | android:layout_width="wrap_content" |
| | | android:layout_height="wrap_content" |
| | | android:textSize="12sp" |
| | | android:textColor="#333333" |
| | | android:textStyle="bold"/> |
| | | |
| | | <TextView |
| | | android:id="@+id/tv_create_time" |
| | | android:layout_width="wrap_content" |
| | | android:layout_height="wrap_content" |
| | | android:textSize="10sp" |
| | | android:textColor="#666666" |
| | | android:layout_marginTop="4dp"/> |
| | | </LinearLayout> |
| | | |
| | | <TextView |
| | | android:id="@+id/tv_tracking_number" |
| | | android:layout_width="wrap_content" |
| | | android:layout_height="wrap_content" |
| | | android:textSize="25sp" |
| | | android:textColor="#333333" |
| | | android:layout_marginStart="12dp" |
| | | android:textStyle="bold"/> |
| | | |
| | | </LinearLayout> |