From ca8bc638ba9cbca3f5f6a4d497d45f92e70064f3 Mon Sep 17 00:00:00 2001
From: cloudroam <cloudroam>
Date: 星期三, 16 四月 2025 08:44:15 +0800
Subject: [PATCH] add: 火车票和航班处理
---
app/src/main/java/com/example/firstapp/activity/PickupActivity.kt | 8
app/src/main/res/layout/activity_phone_login.xml | 2
app/src/main/res/layout/item_train_package_home.xml | 47 ++
app/src/main/res/layout/item_flight.xml | 59 +++
app/src/main/java/com/example/firstapp/database/response/SmsProcessResponse.kt | 5
app/src/main/java/com/example/firstapp/receiver/SmsReceiver.kt | 46 ++
app/src/main/java/com/example/firstapp/model/TrainGroup.kt | 13
app/src/main/res/layout/item_train_group.xml | 58 +++
app/src/main/java/com/example/firstapp/model/FlightGroup.kt | 13
app/src/main/java/com/example/firstapp/ui/home/HomeViewModel.kt | 46 ++
app/src/main/java/com/example/firstapp/adapter/TrainAdapter.kt | 173 +++++++++
app/src/main/res/layout/item_flight_package_home.xml | 47 ++
app/src/main/java/com/example/firstapp/ui/home/HomeFragment.kt | 32 +
app/src/main/res/layout/item_train.xml | 59 +++
app/src/main/java/com/example/firstapp/MainActivity.kt | 192 ++++++++--
app/src/main/java/com/example/firstapp/adapter/FlightAdapter.kt | 173 +++++++++
app/src/main/res/layout/item_flight_group.xml | 58 +++
17 files changed, 978 insertions(+), 53 deletions(-)
diff --git a/app/src/main/java/com/example/firstapp/MainActivity.kt b/app/src/main/java/com/example/firstapp/MainActivity.kt
index 9c533a8..2e0691f 100644
--- a/app/src/main/java/com/example/firstapp/MainActivity.kt
+++ b/app/src/main/java/com/example/firstapp/MainActivity.kt
@@ -44,8 +44,7 @@
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()
@@ -77,7 +76,7 @@
// 重置提醒计划并检查是否有错过的提醒
resetReminders()
-
+
// 检查权限
if (ContextCompat.checkSelfPermission(
this, Manifest.permission.RECEIVE_SMS
@@ -174,7 +173,7 @@
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())
@@ -193,19 +192,21 @@
// 使用协程处理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(
@@ -217,32 +218,40 @@
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(
@@ -254,31 +263,39 @@
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(
@@ -290,21 +307,114 @@
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"
+ )
}
}
}
@@ -332,16 +442,16 @@
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}")
diff --git a/app/src/main/java/com/example/firstapp/activity/PickupActivity.kt b/app/src/main/java/com/example/firstapp/activity/PickupActivity.kt
index 48a6dc1..8c7cac4 100644
--- a/app/src/main/java/com/example/firstapp/activity/PickupActivity.kt
+++ b/app/src/main/java/com/example/firstapp/activity/PickupActivity.kt
@@ -20,6 +20,8 @@
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
@@ -65,6 +67,8 @@
TYPE_EXPRESS -> "是否确认取出所有包裹?"
TYPE_REPAYMENT -> "是否确认处理所有还款?"
TYPE_INCOME -> "是否确认处理所有收入?"
+ TYPE_TRAIN -> "是否确认处理所有火车票?"
+ TYPE_FLIGHT -> "是否确认处理所有机票?"
else -> "是否确认处理所有项目?"
}
}
@@ -74,6 +78,8 @@
TYPE_EXPRESS -> "全部取件"
TYPE_REPAYMENT -> "全部还款"
TYPE_INCOME -> "全部收款"
+ TYPE_TRAIN -> "全部处理票务"
+ TYPE_FLIGHT -> "全部处理机票"
else -> "全部处理"
}
}
@@ -132,6 +138,8 @@
TYPE_EXPRESS -> "共${count}个包裹"
TYPE_REPAYMENT -> "共${count}笔还款"
TYPE_INCOME -> "共${count}笔收入"
+ TYPE_TRAIN -> "共${count}张车票"
+ TYPE_FLIGHT -> "共${count}张机票"
else -> "共${count}个"
}
}
diff --git a/app/src/main/java/com/example/firstapp/adapter/FlightAdapter.kt b/app/src/main/java/com/example/firstapp/adapter/FlightAdapter.kt
new file mode 100644
index 0000000..2c1365f
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/adapter/FlightAdapter.kt
@@ -0,0 +1,173 @@
+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
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/adapter/TrainAdapter.kt b/app/src/main/java/com/example/firstapp/adapter/TrainAdapter.kt
new file mode 100644
index 0000000..0efd02f
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/adapter/TrainAdapter.kt
@@ -0,0 +1,173 @@
+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
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/database/response/SmsProcessResponse.kt b/app/src/main/java/com/example/firstapp/database/response/SmsProcessResponse.kt
index 523f7aa..c5633f1 100644
--- a/app/src/main/java/com/example/firstapp/database/response/SmsProcessResponse.kt
+++ b/app/src/main/java/com/example/firstapp/database/response/SmsProcessResponse.kt
@@ -28,4 +28,9 @@
val number: String?,
val datetime: String?,
val balance: String?,
+ val seat: String?,
+ val trips: String?,
+ val start: String?,
+ val end: String?,
+ val flight: String?,
)
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/model/FlightGroup.kt b/app/src/main/java/com/example/firstapp/model/FlightGroup.kt
new file mode 100644
index 0000000..5fe244e
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/model/FlightGroup.kt
@@ -0,0 +1,13 @@
+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
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/model/TrainGroup.kt b/app/src/main/java/com/example/firstapp/model/TrainGroup.kt
new file mode 100644
index 0000000..b7f4229
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/model/TrainGroup.kt
@@ -0,0 +1,13 @@
+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
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/receiver/SmsReceiver.kt b/app/src/main/java/com/example/firstapp/receiver/SmsReceiver.kt
index 9a611bb..f0e2073 100644
--- a/app/src/main/java/com/example/firstapp/receiver/SmsReceiver.kt
+++ b/app/src/main/java/com/example/firstapp/receiver/SmsReceiver.kt
@@ -142,6 +142,52 @@
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)
+ }
+ }
}
// 发送广播通知数据已更新
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 edaff47..03440a8 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
@@ -22,6 +22,8 @@
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
@@ -45,8 +47,8 @@
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
@@ -185,16 +187,38 @@
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)
+ }
}
}
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 0601ec9..45b5b0a 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
@@ -21,20 +21,24 @@
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
@@ -105,8 +109,38 @@
}
_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(
@@ -122,8 +156,6 @@
// 根据类型更新对应的 LiveData
when (type) {
"还款" -> _financeItems.postValue(groups)
- "航班" -> _flightItems.postValue(groups)
- "火车票" -> _trainItems.postValue(groups)
}
}
}
diff --git a/app/src/main/res/layout/activity_phone_login.xml b/app/src/main/res/layout/activity_phone_login.xml
index 833feb5..3144a69 100644
--- a/app/src/main/res/layout/activity_phone_login.xml
+++ b/app/src/main/res/layout/activity_phone_login.xml
@@ -97,7 +97,7 @@
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"/>
diff --git a/app/src/main/res/layout/item_flight.xml b/app/src/main/res/layout/item_flight.xml
new file mode 100644
index 0000000..6c4e6cb
--- /dev/null
+++ b/app/src/main/res/layout/item_flight.xml
@@ -0,0 +1,59 @@
+<?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>
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_flight_group.xml b/app/src/main/res/layout/item_flight_group.xml
new file mode 100644
index 0000000..cde9c53
--- /dev/null
+++ b/app/src/main/res/layout/item_flight_group.xml
@@ -0,0 +1,58 @@
+<?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>
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_flight_package_home.xml b/app/src/main/res/layout/item_flight_package_home.xml
new file mode 100644
index 0000000..ef12f23
--- /dev/null
+++ b/app/src/main/res/layout/item_flight_package_home.xml
@@ -0,0 +1,47 @@
+<?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>
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_train.xml b/app/src/main/res/layout/item_train.xml
new file mode 100644
index 0000000..6c4e6cb
--- /dev/null
+++ b/app/src/main/res/layout/item_train.xml
@@ -0,0 +1,59 @@
+<?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>
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_train_group.xml b/app/src/main/res/layout/item_train_group.xml
new file mode 100644
index 0000000..80083d8
--- /dev/null
+++ b/app/src/main/res/layout/item_train_group.xml
@@ -0,0 +1,58 @@
+<?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>
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_train_package_home.xml b/app/src/main/res/layout/item_train_package_home.xml
new file mode 100644
index 0000000..ef12f23
--- /dev/null
+++ b/app/src/main/res/layout/item_train_package_home.xml
@@ -0,0 +1,47 @@
+<?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>
\ No newline at end of file
--
Gitblit v1.9.3