左晓为主开发手持机充值管理机
zuojincheng
2025-04-03 d0a0e8e242e293ad35dfbee1217f1103302818cd
refactor(generallibrary):重构卡片和用户搜索功能

- 重命名 CardListActivity 为 SearchCardListActivity
- 重命名 SearchUserActivity 为 SearchUserListActivity
- 更新相关布局文件和引用
- 优化搜索对话框的显示逻辑
- 新增 CardRefundDialog 用于卡片退款操作
- 重构卡片列表适配器和用户列表适配器
- 更新 BaseApplication 中的 Dao 初始化逻辑
2 文件已重命名
14个文件已修改
1个文件已删除
3个文件已添加
1425 ■■■■ 已修改文件
README.md 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/AndroidManifest.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/java/com/dayu/general/BaseApplication.kt 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/java/com/dayu/general/activity/BSCardFragment.kt 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/java/com/dayu/general/activity/MainActivity.kt 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/java/com/dayu/general/activity/SearchCardListActivity.kt 127 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/java/com/dayu/general/activity/SearchUserListActivity.kt 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/java/com/dayu/general/adapter/BaseRecycleAdapter.kt 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/java/com/dayu/general/adapter/CardListAdapter.kt 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/java/com/dayu/general/adapter/SearchListAdapter.kt 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/java/com/dayu/general/adapter/SearchUserListAdapter.kt 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/java/com/dayu/general/view/CardRefundDialog.kt 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/java/com/dayu/general/view/CardSearchDialog.kt 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/java/com/dayu/general/view/SearchDialog.kt 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/res/layout/activity_card_list.xml 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/res/layout/activity_search_user_ge.xml 42 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/res/layout/dialog_card_refund.xml 205 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/res/layout/fragment_card.xml 302 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/res/layout/item_card_list.xml 76 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/res/layout/item_user_list.xml 26 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
README.md
@@ -111,6 +111,115 @@
  - 自定义绑定适配器
  - 表达式支持
### RecyclerView 列表为空时的实现
在 RecyclerView 适配器中,当列表数据为空时,显示一个空视图(EmptyView)的实现方式:
1. 继承 BaseRecycleAdapter:
```kotlin
class YourAdapter : BaseRecycleAdapter<RecyclerView.ViewHolder>() {
    // 实现必要的方法
}
```
2. 在适配器中定义视图类型常量(已在 BaseRecycleAdapter 中定义):
```kotlin
companion object {
    const val VIEW_TYPE_ITEM = 1
    const val VIEW_TYPE_EMPTY = 0
}
```
3. 重写 getItemViewType 方法:
```kotlin
override fun getItemViewType(position: Int): Int {
    if (dataList.isEmpty()) {
        return VIEW_TYPE_EMPTY
    }
    return VIEW_TYPE_ITEM
}
```
4. 重写 getItemCount 方法:
```kotlin
override fun getItemCount(): Int {
    if (dataList.isEmpty()) {
        return 1  // 返回1表示显示空视图
    }
    return dataList.size
}
```
5. 在 onCreateViewHolder 中处理不同类型的视图:
```kotlin
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
    if (viewType == VIEW_TYPE_EMPTY) {
        val emptyView: ItemNoMoreBinding = DataBindingUtil.inflate(
            (parent.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater)!!,
            R.layout.item_no_more,
            parent,
            false
        )
        return ViewHolderEmpty(emptyView)
    } else {
        val binding = ItemListBinding.inflate(
            parent.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater,
            parent,
            false
        )
        return ItemViewHolder(binding.root)
    }
}
```
6. 重写 onBindViewHolder 方法:
```kotlin
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
    if (holder is ViewHolderEmpty) {
        // 空视图不需要绑定数据
        return
    }
    // 绑定列表项数据
    if (holder is ItemViewHolder) {
        val item = dataList[position]
        holder.bind(item)
    }
}
```
7. 空视图的布局文件示例(item_no_more.xml):
```xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="vertical"
        android:padding="16dp">
        <ImageView
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:src="@drawable/ic_empty" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="暂无数据"
            android:textColor="@color/text_gray"
            android:textSize="14sp" />
    </LinearLayout>
</layout>
```
这种实现方式的优点:
1. 统一的空视图处理逻辑
2. 支持自定义空视图样式
3. 不影响列表正常数据的显示
4. 便于维护和扩展
## 数据库结构
### GeneralLibrary 数据库
generallibrary/src/main/AndroidManifest.xml
@@ -49,7 +49,7 @@
        <!--        </activity>-->
        <activity android:name="com.dayu.general.activity.NewCardActivity" />
        <activity android:name="com.dayu.general.activity.ManageListActivity" />
        <activity android:name="com.dayu.general.activity.SearchUserActivity"/>
        <activity android:name="com.dayu.general.activity.SearchUserListActivity"/>
        <activity android:name="com.dayu.general.activity.NfcWreatActivity"
            android:exported="false"
            android:launchMode="singleTop"
@@ -71,7 +71,7 @@
                <data android:mimeType="text/plain" />
            </intent-filter>
        </activity>
        <activity android:name=".activity.CardListActivity"/>
        <activity android:name=".activity.SearchCardListActivity"/>
generallibrary/src/main/java/com/dayu/general/BaseApplication.kt
@@ -47,7 +47,7 @@
    }
     fun init() {
        projectDataDao = application?.let { BaseDaoSingleton.getInstance(it)?.projectDataDao() }
        projectDataDao = application?.let { BaseDaoSingleton.getInstance(it).projectDataDao() }
        if (projectDataDao != null) {
            val projectDataBean = projectDataDao?.findFirst()
            if (projectDataBean != null) {
generallibrary/src/main/java/com/dayu/general/activity/BSCardFragment.kt
@@ -7,7 +7,6 @@
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.dayu.general.databinding.FragmentCardBinding
import com.tencent.bugly.proguard.v
/**
 * @author: zuo
@@ -33,7 +32,7 @@
    private fun initView() {
        binding?.homeNewCard?.setOnClickListener {
            val intent = Intent(context, SearchUserActivity::class.java).apply {
            val intent = Intent(context, SearchUserListActivity::class.java).apply {
                putExtra("type", "newUser")
            }
            startActivity(intent)
@@ -43,7 +42,7 @@
            startActivity(intent)
        }
        binding?.homeLossLL?.setOnClickListener {
            val intent = Intent(context, CardListActivity::class.java).apply{
            val intent = Intent(context, SearchCardListActivity::class.java).apply{
                putExtra("type", "loss")
            }
            startActivity(intent)
generallibrary/src/main/java/com/dayu/general/activity/MainActivity.kt
@@ -62,9 +62,9 @@
    private fun initView() {
        binding!!.BSCardLL.setOnClickListener { v -> changeBottomState(Tab.BSC) }
        binding!!.rechargeLL.setOnClickListener { v -> changeBottomState(Tab.RECHARGE) }
        binding!!.myLL.setOnClickListener { v -> changeBottomState(Tab.MY) }
        binding!!.BSCardLL.setOnClickListener {  changeBottomState(Tab.BSC) }
        binding!!.rechargeLL.setOnClickListener {  changeBottomState(Tab.RECHARGE) }
        binding!!.myLL.setOnClickListener { changeBottomState(Tab.MY) }
    }
generallibrary/src/main/java/com/dayu/general/activity/SearchCardListActivity.kt
File was renamed from generallibrary/src/main/java/com/dayu/general/activity/CardListActivity.kt
@@ -6,12 +6,14 @@
import com.dayu.baselibrary.utils.ToastUtil
import com.dayu.baselibrary.view.TitleBar.ClickType_LEFT_IMAGE
import com.dayu.baselibrary.view.TitleBar.ClickType_RIGHT_IMAGE
import com.dayu.general.BaseApplication
import com.dayu.general.adapter.CardListAdapter
import com.dayu.general.bean.net.SearchCardResult
import com.dayu.general.databinding.ActivityCardListBinding
import com.dayu.general.view.CardSearchDialog
import com.dayu.general.net.ApiManager
import com.dayu.general.net.BaseResponse
import com.dayu.general.view.CardRefundDialog
import com.dayu.general.view.SearchDialog
import com.scwang.smart.refresh.layout.api.RefreshLayout
import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener
@@ -20,21 +22,21 @@
 * @date: 2023/3/31
 * @description: 卡片列表界面
 */
class CardListActivity : BaseActivity() {
class SearchCardListActivity : BaseActivity() {
    var binding: ActivityCardListBinding? = null
    private var cardAdapter: CardListAdapter? = null
    var searchDialog: CardSearchDialog? = null
    var searchDialog: SearchDialog? = null
    // 分页相关变量
    private var currentPage = 1
    private val pageSize = 20
    private var hasMoreData = true
    // 保存当前搜索条件
    private var currentFarmerId = ""
    private var currentFarmerName = ""
    private var currentCardNumber = ""
    private var currentClientNumber = ""
    private var currentClientName = ""
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
@@ -46,23 +48,23 @@
    }
    fun initView() {
        searchDialog = CardSearchDialog(this)
        searchDialog = SearchDialog(this)
        searchDialog?.show()
        binding?.titleBar?.setOnItemclickListner(ClickType_LEFT_IMAGE) { this.finish() }
        // 设置搜索监听器
        searchDialog?.setOnSearchListener(object : CardSearchDialog.OnSearchListener {
            override fun onSearch(cardNumber: String, clientNumber: String, clientName: String) {
        searchDialog?.setOnSearchListener(object : SearchDialog.OnSearchListener {
            override fun onSearch(farmerId: String, farmerName: String, cardNumber: String) {
                // 保存当前搜索条件
                currentCardNumber = cardNumber
                currentClientNumber = clientNumber
                currentClientName = clientName
                currentFarmerId = farmerId
                currentFarmerName = farmerName
                // 重置分页状态
                currentPage = 1
                hasMoreData = true
                // 执行搜索
                searchCards(cardNumber, clientNumber, clientName, true)
                searchCards(currentFarmerId, currentFarmerName, currentCardNumber, true)
            }
        })
        binding?.titleBar?.setOnItemclickListner(ClickType_RIGHT_IMAGE) {
@@ -72,23 +74,31 @@
    }
    private fun setupRecyclerView() {
        cardAdapter = CardListAdapter()
        cardAdapter = CardListAdapter(this)
        binding?.recyclerView?.apply {
            layoutManager = LinearLayoutManager(this@CardListActivity)
            layoutManager = LinearLayoutManager(this@SearchCardListActivity)
            adapter = cardAdapter
        }
        // 设置列表项点击事件
        cardAdapter?.setOnItemClickListener { card ->
            // 处理卡片点击事件
            ToastUtil.show("已选择卡片:${card.cardNum}")
            // 这里可以添加跳转到卡片详情页面的逻辑
            // val intent = Intent(this, CardDetailActivity::class.java)
            // intent.putExtra("cardNum", card.cardNum)
            // startActivity(intent)
            // 显示退款对话框
            val refundDialog = CardRefundDialog(this)
            refundDialog.show() // 先显示对话框
            refundDialog.setUserInfo(
                card.clientName.toString(),
                card.cardNum.toString(),
                card.money.toString()
            )
            refundDialog.setOnConfirmListener {  refundAmount, remark ->
                // TODO: 处理退款逻辑
                lossPost(card.idCard.toString())
            }
        }
    }
    private fun setupRefreshLayout() {
        binding?.refreshLayout?.apply {
            // 设置刷新和加载更多监听器
@@ -97,14 +107,14 @@
                    // 重置页码并刷新数据
                    currentPage = 1
                    hasMoreData = true
                    searchCards(currentCardNumber, currentClientNumber, currentClientName, true)
                    searchCards(currentFarmerId, currentFarmerName, currentCardNumber, true)
                }
                override fun onLoadMore(refreshLayout: RefreshLayout) {
                    // 如果还有更多数据,加载下一页
                    if (hasMoreData) {
                        currentPage++
                        searchCards(currentCardNumber, currentClientNumber, currentClientName, false)
                        searchCards(currentFarmerId, currentFarmerName, currentCardNumber, false)
                    } else {
                        // 完成加载并提示没有更多数据
                        refreshLayout.finishLoadMore(500, true, false)
@@ -126,21 +136,26 @@
     * @param clientName 客户姓名
     * @param isRefresh 是否为刷新操作
     */
    private fun searchCards(cardNumber: String, clientNumber: String, clientName: String, isRefresh: Boolean = true) {
    private fun searchCards(
        farmerId: String,
        farmerName: String,
        cardNumber: String,
        isRefresh: Boolean = true
    ) {
        val map = mutableMapOf<String, Any>()
        if (cardNumber.isNotEmpty()) {
            map["cardNum"] = cardNumber
        }
        if (clientNumber.isNotEmpty()) {
            map["clientNum"] = clientNumber
        if (farmerId.isNotEmpty()) {
            map["clientNum"] = farmerId
        }
        if (clientName.isNotEmpty()) {
            map["clientName"] = clientName
        if (farmerName.isNotEmpty()) {
            map["clientName"] = farmerName
        }
        // 添加分页参数
        map["pageCurr"] = currentPage
        map["pageSize"] = pageSize
@@ -155,7 +170,7 @@
                override fun onNext(t: BaseResponse<SearchCardResult>) {
                    // 完成刷新或加载动作
                    finishRefreshOrLoad(isRefresh)
                    if (t.success) {
                        // 处理搜索成功的情况
                        val result = t.content
@@ -168,7 +183,7 @@
                                } else {
                                    cardAdapter?.addData(result.obj)
                                }
                                // 判断是否还有更多数据:根据当前页码和总页数判断
                                hasMoreData = currentPage < result.pageTotal
                            } else {
@@ -201,7 +216,40 @@
            }
        )
    }
    private fun lossPost(cardNumber: String) {
        val map = mutableMapOf<String, Any>()
        map["cardNum"] = cardNumber
        map["operator"] = BaseApplication.userId
        ApiManager.getInstance().requestGetLoading(
            this,
            "/sell/card/loss",
            SearchCardResult::class.java,
            map,
            object : SubscriberListener<BaseResponse<SearchCardResult>>() {
                override fun onNext(t: BaseResponse<SearchCardResult>) {
                    if (t.success) {
                    } else {
                        // 处理搜索失败的情况
                        ToastUtil.show(t.msg)
                    }
                }
                override fun onError(e: Throwable?) {
                    super.onError(e)
                    // 完成刷新或加载动作
                    ToastUtil.show("搜索失败: ${e?.message ?: "未知错误"}")
                }
            }
        )
    }
    /**
     * 完成刷新或加载操作
     * @param isRefresh 是否为刷新操作
@@ -213,4 +261,9 @@
            binding?.refreshLayout?.finishLoadMore(true)
        }
    }
    override fun onDestroy() {
        super.onDestroy()
        searchDialog?.dismiss()
    }
}
generallibrary/src/main/java/com/dayu/general/activity/SearchUserListActivity.kt
File was renamed from generallibrary/src/main/java/com/dayu/general/activity/SearchUserActivity.kt
@@ -6,7 +6,7 @@
import com.dayu.baselibrary.utils.ToastUtil
import com.dayu.baselibrary.view.TitleBar.ClickType_LEFT_IMAGE
import com.dayu.baselibrary.view.TitleBar.ClickType_RIGHT_IMAGE
import com.dayu.general.adapter.SearchListAdapter
import com.dayu.general.adapter.SearchUserListAdapter
import com.dayu.general.bean.net.SearchUserResult
import com.dayu.general.databinding.ActivitySearchUserGeBinding
import com.dayu.general.view.SearchDialog
@@ -20,10 +20,10 @@
 * @date: 2023/6/26 16:09
 * @description:搜索用户
 */
class SearchUserActivity : BaseActivity() {
class SearchUserListActivity : BaseActivity() {
    var binding: ActivitySearchUserGeBinding? = null
    private var userAdapter: SearchListAdapter? = null
    private var userAdapter: SearchUserListAdapter? = null
    var searchDialog: SearchDialog? = null
    
    // 分页相关变量
@@ -74,9 +74,9 @@
    }
    private fun setupRecyclerView() {
        userAdapter = SearchListAdapter()
        userAdapter = SearchUserListAdapter()
        binding?.recyclerView?.apply {
            layoutManager = LinearLayoutManager(this@SearchUserActivity)
            layoutManager = LinearLayoutManager(this@SearchUserListActivity)
            adapter = userAdapter
        }
        
@@ -89,6 +89,8 @@
            // intent.putExtra("userId", user.id)
            // startActivity(intent)
        }
    }
    
    private fun setupRefreshLayout() {
generallibrary/src/main/java/com/dayu/general/adapter/BaseRecycleAdapter.kt
@@ -9,27 +9,18 @@
 * Author: zuo
 * Date: 2025/3/10
 */
class BaseRecycleAdapter<T : RecyclerView.ViewHolder>:RecyclerView.Adapter<T>() {
abstract class BaseRecycleAdapter<T : RecyclerView.ViewHolder>:RecyclerView.Adapter<T>() {
    companion object {
        const val VIEW_TYPE_ITEM = 1
        const val VIEW_TYPE_EMPTY = 0
    }
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): T {
        TODO("Not yet implemented")
    abstract override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): T
    }
    abstract override fun getItemCount(): Int
    override fun getItemCount(): Int {
        TODO("Not yet implemented")
    }
    override fun onBindViewHolder(holder: T, position: Int) {
        TODO("Not yet implemented")
    }
//    abstract override fun onBindViewHolder(holder: T, position: Int)
//
    class ViewHolderEmpty(binding: ItemNoMoreBinding) : RecyclerView.ViewHolder(binding.root) {
        var mBinding: ItemNoMoreBinding = binding
        fun getBinding(): ItemNoMoreBinding {
@@ -40,4 +31,4 @@
            this.mBinding = binding
        }
    }
    }
}
generallibrary/src/main/java/com/dayu/general/adapter/CardListAdapter.kt
@@ -1,9 +1,14 @@
package com.dayu.general.adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.RecyclerView
import com.dayu.baselibrary.databinding.ItemNoMoreBinding
import com.dayu.general.R
import com.dayu.general.bean.net.SearchCardResult
import com.dayu.general.databinding.ItemCardListBinding
@@ -12,40 +17,82 @@
 * Author: zuo
 * Date: 2025/3/31
 */
class CardListAdapter : RecyclerView.Adapter<CardListAdapter.CardViewHolder>() {
class CardListAdapter(context: Context) : BaseRecycleAdapter<RecyclerView.ViewHolder>() {
    private val cardList = mutableListOf<SearchCardResult.CardInfo>()
    private var cardList: List<SearchCardResult.CardInfo> = emptyList()
    private var onItemClickListener: ((SearchCardResult.CardInfo) -> Unit)? = null
    var mContext: Context = context
    fun setData(cards: List<SearchCardResult.CardInfo>) {
        cardList.clear()
        cardList.addAll(cards)
    fun setData(data: List<SearchCardResult.CardInfo>) {
        cardList = data
        notifyDataSetChanged()
    }
    fun addData(cards: List<SearchCardResult.CardInfo>) {
        val startPosition = cardList.size
        cardList.addAll(cards)
        notifyItemRangeInserted(startPosition, cards.size)
    fun addData(data: List<SearchCardResult.CardInfo>) {
        val oldSize = cardList.size
        cardList = cardList + data
        notifyItemRangeInserted(oldSize, data.size)
    }
    fun setOnItemClickListener(listener: (SearchCardResult.CardInfo) -> Unit) {
        this.onItemClickListener = listener
        onItemClickListener = listener
    }
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CardViewHolder {
        val binding = ItemCardListBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return CardViewHolder(binding)
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        if (viewType == VIEW_TYPE_EMPTY) {
            val emptyView: ItemNoMoreBinding = DataBindingUtil.inflate(
                (mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater)!!,
                com.dayu.baselibrary.R.layout.item_no_more,
                parent,
                false
            )
            return ViewHolderEmpty(emptyView)
        } else {
            val binding = ItemCardListBinding.inflate(
                mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater,
                parent,
                false
            )
            return CardViewHolder(binding)
        }
    }
    override fun onBindViewHolder(holder: CardViewHolder, position: Int) {
        val card = cardList[position]
        holder.bind(card)
    override fun getItemViewType(position: Int): Int {
        if (cardList.size == 0) {
            return VIEW_TYPE_EMPTY
        } else {
            return VIEW_TYPE_ITEM
        }
    }
    override fun getItemCount(): Int = cardList.size
    override fun getItemCount(): Int {
        //同时这里也需要添加判断,如果mData.size()为0的话,只引入一个布局,就是emptyView
        // 那么,这个recyclerView的itemCount为1
        if (cardList.size == 0) {
            return 1
        }
        return cardList.size
    }
    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        if (holder is ViewHolderEmpty) {
            // 空视图不需要绑定数据
            return
        }
        if (holder is CardViewHolder) {
            val card = cardList[position]
            holder.bind(card)
            holder.itemView.setOnClickListener {
                onItemClickListener?.invoke(card)
            }
        }
    }
    inner class CardViewHolder(private val binding: ItemCardListBinding) : RecyclerView.ViewHolder(binding.root) {
        fun bind(card: SearchCardResult.CardInfo) {
            // 设置数据显示,添加判空处理
            binding.tvCardNumber.text = "卡号:${card.cardNum ?: "无"}"
@@ -55,24 +102,13 @@
            binding.tvClientNum.text = "客户编号:${card.clientNum ?: "无"}"
            binding.tvCardBalance.text = "余额:${card.money ?: "0.00"} 元"
            binding.tvPhone.text = "电话:${formatPhone(card.phone)}"
            // 显示身份证号
            card.idCard?.let { idCard ->
                if (idCard.isNotEmpty()) {
                    binding.tvIdCard.text = "身份证:${formatIdCard(idCard)}"
                    binding.tvIdCard.visibility = View.VISIBLE
                } else {
                    binding.tvIdCard.visibility = View.GONE
                }
            } ?: run {
                binding.tvIdCard.visibility = View.GONE
            }
            binding.tvIdCard.text = "身份证:${formatIdCard( card.idCard)}"
            binding.root.setOnClickListener {
                onItemClickListener?.invoke(card)
            }
        }
        // 格式化身份证号,保护隐私
        private fun formatIdCard(idCard: String?): String {
            return if (!idCard.isNullOrEmpty() && idCard.length >= 18) {
@@ -83,7 +119,7 @@
                idCard ?: "无"
            }
        }
        // 格式化手机号,保护隐私
        private fun formatPhone(phone: String?): String {
            return if (!phone.isNullOrEmpty() && phone.length >= 11) {
@@ -94,5 +130,4 @@
                phone ?: "无"
            }
        }
    }
}
} }
generallibrary/src/main/java/com/dayu/general/adapter/SearchListAdapter.kt
File was deleted
generallibrary/src/main/java/com/dayu/general/adapter/SearchUserListAdapter.kt
New file
@@ -0,0 +1,125 @@
package com.dayu.general.adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.RecyclerView
import com.dayu.baselibrary.databinding.ItemNoMoreBinding
import com.dayu.general.bean.net.SearchUserResult
import com.dayu.general.databinding.ItemUserListBinding
/**
 * Description: 用户列表适配器
 * Author: zuo
 * Date: 2025/3/10
 */
class SearchUserListAdapter : BaseRecycleAdapter<RecyclerView.ViewHolder>() {
    private var userList: List<SearchUserResult.UserInfo> = emptyList()
    private var onItemClickListener: ((SearchUserResult.UserInfo) -> Unit)? = null
    fun setData(data: List<SearchUserResult.UserInfo>) {
        userList = data
        notifyDataSetChanged()
    }
    fun addData(data: List<SearchUserResult.UserInfo>) {
        val oldSize = userList.size
        userList = userList + data
        notifyItemRangeInserted(oldSize, data.size)
    }
    fun setOnItemClickListener(listener: (SearchUserResult.UserInfo) -> Unit) {
        onItemClickListener = listener
    }
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        if (viewType == VIEW_TYPE_EMPTY) {
            val emptyView: ItemNoMoreBinding = DataBindingUtil.inflate(
                (parent.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater)!!,
                com.dayu.baselibrary.R.layout.item_no_more,
                parent,
                false
            )
            return ViewHolderEmpty(emptyView)
        } else {
            val binding = ItemUserListBinding.inflate(
                parent.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater,
                parent,
                false
            )
            return UserViewHolder(binding)
        }
    }
    override fun getItemViewType(position: Int): Int {
        if (userList.size == 0) {
            return VIEW_TYPE_EMPTY
        }else{
            return VIEW_TYPE_ITEM
        }
    }
    override fun getItemCount(): Int {
        //同时这里也需要添加判断,如果mData.size()为0的话,只引入一个布局,就是emptyView
        // 那么,这个recyclerView的itemCount为1
        if (userList.size  == 0) {
            return 1
        }
        return userList.size
    }
    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        if (holder is ViewHolderEmpty) {
            // 空视图不需要绑定数据
            return
        }
        if (holder is UserViewHolder) {
            val card = userList[position]
            holder.bind(card)
            holder.itemView.setOnClickListener {
                onItemClickListener?.invoke(card)
            }
        }
    }
    class UserViewHolder(private val binding: ItemUserListBinding) : RecyclerView.ViewHolder(binding.root) {
        fun bind(user: SearchUserResult.UserInfo) {
            binding.tvName.text = user.name
            binding.tvFarmerId.text = "农户编号:${user.clientNum}"
            binding.tvCardCount.text = "卡片数量:${user.cardCount}"
            binding.tvIdCard.text = "身份证号:${formatIdCard(user.idCard)}"
            binding. tvPhone.text = "联系电话:${formatPhone(user.phone)}"
            binding.tvAddressValue.text = user.address
            binding.tvOperateDate.text = "操作日期:${user.operateDt}"
        }
        // 格式化身份证号,保护隐私
        private fun formatIdCard(idCard: String?): String {
            return if (!idCard.isNullOrEmpty() && idCard.length >= 18) {
                val start = idCard.substring(0, 6)
                val end = idCard.substring(idCard.length - 4)
                "$start****$end"
            } else {
                idCard ?: "无"
            }
        }
        // 格式化手机号,保护隐私
        private fun formatPhone(phone: String?): String {
            return if (!phone.isNullOrEmpty() && phone.length >= 11) {
                val start = phone.substring(0, 3)
                val end = phone.substring(phone.length - 4)
                "$start****$end"
            } else {
                phone ?: "无"
            }
        }
    }
}
generallibrary/src/main/java/com/dayu/general/view/CardRefundDialog.kt
New file
@@ -0,0 +1,85 @@
package com.dayu.general.view
import android.app.Dialog
import android.content.Context
import android.os.Bundle
import android.view.Gravity
import android.view.WindowManager
import com.dayu.general.R
import com.dayu.general.databinding.DialogCardRefundBinding
/**
 *
 */
class CardRefundDialog(context: Context) : Dialog(context) {
    private var binding: DialogCardRefundBinding? = null
    private var onConfirmListener: (( String, String) -> Unit)? = null
    private var username: String? = null
    private var cardNumber: String? = null
    private var balance: String? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DialogCardRefundBinding.inflate(layoutInflater)
        binding?.root?.let { setContentView(it) }
        // 设置对话框宽度为屏幕宽度的80%
        val window = window
        val params = window?.attributes
        params?.width = (context.resources.displayMetrics.widthPixels * 0.85).toInt()
        params?.gravity = Gravity.CENTER
        // 设置背景透明
        window?.setBackgroundDrawableResource(android.R.color.transparent)
        // 设置按钮点击事件
        binding?.btnCancel?.setOnClickListener {
            dismiss()
        }
        binding?.btnConfirm?.setOnClickListener {
            val refundAmount = binding?.etRefundAmount?.text.toString()
            val remark = binding?.etRemark?.text.toString()
            if (refundAmount.isEmpty()) {
                // TODO: 显示错误提示
                return@setOnClickListener
            }
            onConfirmListener?.invoke(refundAmount, remark)
            dismiss()
        }
        // 如果有预设的用户信息,设置它们
        username?.let { username ->
            cardNumber?.let { cardNumber ->
                balance?.let { balance ->
                    setUserInfo(username, cardNumber, balance)
                }
            }
        }
    }
    override fun show() {
        super.show()
        // 清空输入框
        binding?.etRefundAmount?.setText("")
        binding?.etRemark?.setText("")
    }
    fun setUserInfo(username: String, cardNumber: String, balance: String) {
        this.username = username
        this.cardNumber = cardNumber
        this.balance = balance
        binding?.apply {
            tvUsernameValue.text = username
            tvCardNumberValue.text = cardNumber
            etBalance.setText(balance+"元")
        }
    }
    fun setOnConfirmListener(listener: ( String, String) -> Unit) {
        onConfirmListener = listener
    }
}
generallibrary/src/main/java/com/dayu/general/view/CardSearchDialog.kt
@@ -52,6 +52,14 @@
        }
    }
    override fun show() {
        super.show()
        // 清空输入框
        binding.etCardNumber.setText("")
        binding.etClientNumber.setText("")
        binding.etClientName.setText("")
    }
    /**
     * 设置搜索监听器
     */
generallibrary/src/main/java/com/dayu/general/view/SearchDialog.kt
@@ -52,6 +52,14 @@
        }
    }
    override fun show() {
        super.show()
        // 清空输入框
        binding.etFarmerId.setText("")
        binding.etFarmerName.setText("")
        binding.etCardNumber.setText("")
    }
    /**
     * 设置搜索监听器
     */
generallibrary/src/main/res/layout/activity_card_list.xml
@@ -5,7 +5,7 @@
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".activity.CardListActivity">
    tools:context=".activity.SearchCardListActivity">
    <com.dayu.baselibrary.view.TitleBar
        android:id="@+id/title_bar"
@@ -16,30 +16,39 @@
        app:leftImage="@mipmap/icon_back"
        app:rightImage="@mipmap/icon_search" />
    <com.scwang.smart.refresh.layout.SmartRefreshLayout
        android:id="@+id/refresh_layout"
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:srlAccentColor="@color/colorPrimary"
        app:srlEnablePreviewInEditMode="true">
        android:layout_height="0dp"
        android:layout_weight="1">
        <com.scwang.smart.refresh.header.ClassicsHeader
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recycler_view"
        <com.scwang.smart.refresh.layout.SmartRefreshLayout
            android:id="@+id/refresh_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:paddingTop="8dp"
            android:paddingBottom="8dp"
            android:clipToPadding="false"
            android:overScrollMode="never" />
            app:srlAccentColor="@color/colorPrimary"
            app:srlEnablePreviewInEditMode="true">
        <com.scwang.smart.refresh.footer.ClassicsFooter
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
            <com.scwang.smart.refresh.header.ClassicsHeader
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
    </com.scwang.smart.refresh.layout.SmartRefreshLayout>
            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/recycler_view"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:paddingTop="8dp"
                android:paddingBottom="8dp"
                android:clipToPadding="false"
                android:overScrollMode="never" />
            <com.scwang.smart.refresh.footer.ClassicsFooter
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
        </com.scwang.smart.refresh.layout.SmartRefreshLayout>
    </FrameLayout>
</LinearLayout> 
generallibrary/src/main/res/layout/activity_search_user_ge.xml
@@ -16,31 +16,35 @@
        app:leftImage="@mipmap/icon_back"
        app:rightImage="@mipmap/icon_search"/>
    <com.scwang.smart.refresh.layout.SmartRefreshLayout
        android:id="@+id/refreshLayout"
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/titleBar">
        android:layout_height="0dp"
        android:layout_weight="1">
        <com.scwang.smart.refresh.header.ClassicsHeader
        <com.scwang.smart.refresh.layout.SmartRefreshLayout
            android:id="@+id/refreshLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/base_list_bg"
            android:overScrollMode="never"
            android:padding="10dp" />
            android:layout_below="@+id/titleBar">
        <com.scwang.smart.refresh.footer.ClassicsFooter
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </com.scwang.smart.refresh.layout.SmartRefreshLayout>
            <com.scwang.smart.refresh.header.ClassicsHeader
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/recyclerView"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@color/base_list_bg"
                android:overScrollMode="never"
                android:padding="10dp" />
            <com.scwang.smart.refresh.footer.ClassicsFooter
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
        </com.scwang.smart.refresh.layout.SmartRefreshLayout>
    </FrameLayout>
</LinearLayout>
generallibrary/src/main/res/layout/dialog_card_refund.xml
New file
@@ -0,0 +1,205 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:background="@drawable/search_dialog_bg"
    android:padding="20dp">
    <TextView
        android:id="@+id/tv_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="挂失确认"
        android:textColor="@color/black"
        android:textSize="20sp"
        android:textStyle="bold"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <View
        android:id="@+id/divider"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_marginTop="12dp"
        android:background="#E0E0E0"
        app:layout_constraintTop_toBottomOf="@id/tv_title" />
    <LinearLayout
        android:id="@+id/layoutUsername"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:gravity="center_vertical"
        android:orientation="horizontal"
        app:layout_constraintTop_toBottomOf="@id/divider">
        <TextView
            android:id="@+id/tvUsername"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="用户名:"
            android:textColor="#666666"
            android:textSize="14sp" />
        <TextView
            android:id="@+id/tvUsernameValue"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="5dp"
            android:layout_weight="1"
            android:padding="5dp"
            android:textColor="@color/black"
            android:textSize="15sp" />
    </LinearLayout>
    <LinearLayout
        android:id="@+id/layoutCardNumber"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:gravity="center_vertical"
        android:orientation="horizontal"
        app:layout_constraintTop_toBottomOf="@id/layoutUsername">
        <TextView
            android:id="@+id/tvCardNumber"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="卡    号:"
            android:textColor="#666666"
            android:textSize="14sp" />
        <TextView
            android:id="@+id/tvCardNumberValue"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="5dp"
            android:layout_weight="1"
            android:padding="5dp"
            android:textColor="@color/black"
            android:textSize="15sp" />
    </LinearLayout>
    <LinearLayout
        android:id="@+id/layoutBalance"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:gravity="center_vertical"
        android:orientation="horizontal"
        app:layout_constraintTop_toBottomOf="@id/layoutCardNumber">
        <TextView
            android:id="@+id/tvBalance"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="余    额:"
            android:textColor="#666666"
            android:textSize="14sp" />
        <TextView
            android:id="@+id/etBalance"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:singleLine="true"
            android:layout_marginStart="5dp"
            android:textColor="@color/black"
            android:textSize="15sp"
            app:layout_constraintTop_toBottomOf="@id/tvBalance" />
    </LinearLayout>
    <TextView
        android:id="@+id/tvRefundAmount"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="14dp"
        android:text="退还金额"
        android:textColor="#666666"
        android:textSize="14sp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@id/layoutBalance" />
    <EditText
        android:id="@+id/etRefundAmount"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="6dp"
        android:background="@drawable/edit_text_bg"
        android:hint="请输入退还金额(选填)"
        android:inputType="numberDecimal"
        android:padding="12dp"
        android:singleLine="true"
        android:textColorHint="#BBBBBB"
        android:textSize="15sp"
        app:layout_constraintTop_toBottomOf="@id/tvRefundAmount" />
    <TextView
        android:id="@+id/tvRemark"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="14dp"
        android:text="备注"
        android:textColor="#666666"
        android:textSize="14sp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@id/etRefundAmount" />
    <EditText
        android:id="@+id/etRemark"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="6dp"
        android:background="@drawable/edit_text_bg"
        android:hint="请输入备注(选填)"
        android:inputType="textMultiLine"
        android:minLines="2"
        android:padding="12dp"
        android:textColorHint="#BBBBBB"
        android:textSize="15sp"
        app:layout_constraintTop_toBottomOf="@id/tvRemark" />
    <Button
        android:id="@+id/btnCancel"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:layout_marginEnd="6dp"
        android:background="@drawable/cancel_button_ripple"
        android:clickable="true"
        android:focusable="true"
        android:paddingTop="10dp"
        android:paddingBottom="10dp"
        android:stateListAnimator="@null"
        android:text="取消"
        android:textColor="#666666"
        android:textSize="15sp"
        app:layout_constraintEnd_toStartOf="@id/btnConfirm"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintHorizontal_weight="1"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/etRemark" />
    <Button
        android:id="@+id/btnConfirm"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="6dp"
        android:background="@drawable/search_button_ripple"
        android:clickable="true"
        android:elevation="2dp"
        android:focusable="true"
        android:paddingTop="12dp"
        android:paddingBottom="12dp"
        android:stateListAnimator="@null"
        android:text="确定"
        android:textColor="@android:color/white"
        android:textSize="16sp"
        android:textStyle="bold"
        app:layout_constraintBaseline_toBaselineOf="@id/btnCancel"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_weight="1"
        app:layout_constraintStart_toEndOf="@id/btnCancel" />
</androidx.constraintlayout.widget.ConstraintLayout>
generallibrary/src/main/res/layout/fragment_card.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
    android:background="@color/white">
@@ -12,7 +13,8 @@
        android:layout_height="@dimen/dimen_title_height"
        android:background="@color/title_bar_bg"
        android:elevation="4dp"
        app:centerText="制卡" />
        app:centerText="制卡"
        tools:ignore="MissingConstraints" />
    <ScrollView
        android:layout_width="match_parent"
@@ -24,20 +26,20 @@
        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="16dp">
            android:padding="12dp">
            <androidx.cardview.widget.CardView
                android:id="@+id/home_newCard"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="8dp"
                android:layout_marginTop="16dp"
                android:layout_marginEnd="8dp"
                android:layout_marginStart="6dp"
                android:layout_marginTop="12dp"
                android:layout_marginEnd="6dp"
                android:clickable="true"
                android:focusable="true"
                android:foreground="?android:attr/selectableItemBackground"
                app:cardCornerRadius="12dp"
                app:cardElevation="4dp"
                app:cardCornerRadius="10dp"
                app:cardElevation="3dp"
                app:layout_constraintEnd_toStartOf="@+id/home_redCard"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent">
@@ -47,21 +49,21 @@
                    android:layout_height="wrap_content"
                    android:gravity="center"
                    android:orientation="vertical"
                    android:padding="16dp">
                    android:padding="12dp">
                    <ImageView
                        android:layout_width="70dp"
                        android:layout_height="70dp"
                        android:layout_width="55dp"
                        android:layout_height="55dp"
                        android:src="@drawable/home_add" />
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="8dp"
                        android:layout_marginTop="6dp"
                        android:gravity="center"
                        android:text="开卡"
                        android:textColor="@color/text_selecter_color"
                        android:textSize="@dimen/home_text_size" />
                        android:textSize="14sp" />
                </LinearLayout>
            </androidx.cardview.widget.CardView>
@@ -69,15 +71,15 @@
                android:id="@+id/home_recharge"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="8dp"
                android:layout_marginTop="16dp"
                android:layout_marginEnd="8dp"
                android:layout_marginStart="6dp"
                android:layout_marginTop="12dp"
                android:layout_marginEnd="6dp"
                android:clickable="true"
                android:focusable="true"
                android:foreground="?android:attr/selectableItemBackground"
                android:visibility="gone"
                app:cardCornerRadius="12dp"
                app:cardElevation="4dp"
                app:cardCornerRadius="10dp"
                app:cardElevation="3dp"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent">
@@ -87,21 +89,21 @@
                    android:layout_height="wrap_content"
                    android:gravity="center"
                    android:orientation="vertical"
                    android:padding="16dp">
                    android:padding="12dp">
                    <ImageView
                        android:layout_width="70dp"
                        android:layout_height="70dp"
                        android:layout_width="55dp"
                        android:layout_height="55dp"
                        android:src="@drawable/home_recharge" />
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="8dp"
                        android:layout_marginTop="6dp"
                        android:gravity="center"
                        android:text="充值"
                        android:textColor="@color/text_selecter_color"
                        android:textSize="@dimen/home_text_size" />
                        android:textSize="14sp" />
                </LinearLayout>
            </androidx.cardview.widget.CardView>
@@ -109,14 +111,14 @@
                android:id="@+id/home_redCard"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="8dp"
                android:layout_marginTop="16dp"
                android:layout_marginEnd="8dp"
                android:layout_marginStart="6dp"
                android:layout_marginTop="12dp"
                android:layout_marginEnd="6dp"
                android:clickable="true"
                android:focusable="true"
                android:foreground="?android:attr/selectableItemBackground"
                app:cardCornerRadius="12dp"
                app:cardElevation="4dp"
                app:cardCornerRadius="10dp"
                app:cardElevation="3dp"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toEndOf="@+id/home_newCard"
                app:layout_constraintTop_toTopOf="parent">
@@ -126,21 +128,21 @@
                    android:layout_height="wrap_content"
                    android:gravity="center"
                    android:orientation="vertical"
                    android:padding="16dp">
                    android:padding="12dp">
                    <ImageView
                        android:layout_width="70dp"
                        android:layout_height="70dp"
                        android:layout_width="55dp"
                        android:layout_height="55dp"
                        android:src="@drawable/home_read" />
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="8dp"
                        android:layout_marginTop="6dp"
                        android:gravity="center"
                        android:text="读卡"
                        android:textColor="@color/text_selecter_color"
                        android:textSize="@dimen/home_text_size" />
                        android:textSize="14sp" />
                </LinearLayout>
            </androidx.cardview.widget.CardView>
@@ -148,14 +150,14 @@
                android:id="@+id/home_loss"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="8dp"
                android:layout_marginTop="24dp"
                android:layout_marginEnd="8dp"
                android:layout_marginStart="6dp"
                android:layout_marginTop="16dp"
                android:layout_marginEnd="6dp"
                android:clickable="true"
                android:focusable="true"
                android:foreground="?android:attr/selectableItemBackground"
                app:cardCornerRadius="12dp"
                app:cardElevation="4dp"
                app:cardCornerRadius="10dp"
                app:cardElevation="3dp"
                app:layout_constraintEnd_toStartOf="@+id/home_replacement"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/home_newCard">
@@ -166,21 +168,21 @@
                    android:layout_height="wrap_content"
                    android:gravity="center"
                    android:orientation="vertical"
                    android:padding="16dp">
                    android:padding="12dp">
                    <ImageView
                        android:layout_width="70dp"
                        android:layout_height="70dp"
                        android:layout_width="55dp"
                        android:layout_height="55dp"
                        android:src="@drawable/home_report" />
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="8dp"
                        android:layout_marginTop="6dp"
                        android:gravity="center"
                        android:text="挂失"
                        android:textColor="@color/text_selecter_color"
                        android:textSize="@dimen/home_text_size" />
                        android:textSize="14sp" />
                </LinearLayout>
            </androidx.cardview.widget.CardView>
@@ -191,7 +193,7 @@
                android:gravity="center"
                android:text="解除挂失"
                android:textColor="@color/text_selecter_color"
                android:textSize="@dimen/home_text_size"
                android:textSize="14sp"
                android:visibility="gone"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />
@@ -200,14 +202,14 @@
                android:id="@+id/home_replacement"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="8dp"
                android:layout_marginTop="24dp"
                android:layout_marginEnd="8dp"
                android:layout_marginStart="6dp"
                android:layout_marginTop="16dp"
                android:layout_marginEnd="6dp"
                android:clickable="true"
                android:focusable="true"
                android:foreground="?android:attr/selectableItemBackground"
                app:cardCornerRadius="12dp"
                app:cardElevation="4dp"
                app:cardCornerRadius="10dp"
                app:cardElevation="3dp"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toEndOf="@+id/home_loss"
                app:layout_constraintTop_toBottomOf="@+id/home_redCard">
@@ -217,21 +219,138 @@
                    android:layout_height="wrap_content"
                    android:gravity="center"
                    android:orientation="vertical"
                    android:padding="16dp">
                    android:padding="12dp">
                    <ImageView
                        android:layout_width="70dp"
                        android:layout_height="70dp"
                        android:layout_width="55dp"
                        android:layout_height="55dp"
                        android:src="@drawable/home_replacement" />
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="8dp"
                        android:layout_marginTop="6dp"
                        android:gravity="center"
                        android:text="补卡"
                        android:textColor="@color/text_selecter_color"
                        android:textSize="@dimen/home_text_size" />
                        android:textSize="14sp" />
                </LinearLayout>
            </androidx.cardview.widget.CardView>
            <androidx.cardview.widget.CardView
                android:id="@+id/home_reverse"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="6dp"
                android:layout_marginTop="16dp"
                android:layout_marginEnd="6dp"
                android:clickable="true"
                android:focusable="true"
                android:foreground="?android:attr/selectableItemBackground"
                app:cardCornerRadius="10dp"
                app:cardElevation="3dp"
                app:layout_constraintEnd_toStartOf="@+id/home_deduction"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/home_replacement">
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:gravity="center"
                    android:orientation="vertical"
                    android:padding="12dp">
                    <ImageView
                        android:layout_width="55dp"
                        android:layout_height="55dp"
                        android:src="@drawable/home_system" />
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="6dp"
                        android:gravity="center"
                        android:text="冲正"
                        android:textColor="@color/text_selecter_color"
                        android:textSize="14sp" />
                </LinearLayout>
            </androidx.cardview.widget.CardView>
            <androidx.cardview.widget.CardView
                android:id="@+id/home_deduction"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="6dp"
                android:layout_marginTop="16dp"
                android:layout_marginEnd="6dp"
                android:clickable="true"
                android:focusable="true"
                android:foreground="?android:attr/selectableItemBackground"
                app:cardCornerRadius="10dp"
                app:cardElevation="3dp"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toEndOf="@+id/home_reverse"
                app:layout_constraintTop_toBottomOf="@+id/home_replacement">
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:gravity="center"
                    android:orientation="vertical"
                    android:padding="12dp">
                    <ImageView
                        android:layout_width="55dp"
                        android:layout_height="55dp"
                        android:src="@drawable/home_system" />
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="6dp"
                        android:gravity="center"
                        android:text="补扣"
                        android:textColor="@color/text_selecter_color"
                        android:textSize="14sp" />
                </LinearLayout>
            </androidx.cardview.widget.CardView>
            <androidx.cardview.widget.CardView
                android:id="@+id/home_rewrite"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="6dp"
                android:layout_marginTop="16dp"
                android:layout_marginEnd="6dp"
                android:clickable="true"
                android:focusable="true"
                android:foreground="?android:attr/selectableItemBackground"
                app:cardCornerRadius="10dp"
                app:cardElevation="3dp"
                app:layout_constraintEnd_toStartOf="@+id/home_manage"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/home_reverse">
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:gravity="center"
                    android:orientation="vertical"
                    android:padding="12dp">
                    <ImageView
                        android:layout_width="55dp"
                        android:layout_height="55dp"
                        android:src="@drawable/home_system" />
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="6dp"
                        android:gravity="center"
                        android:text="反写"
                        android:textColor="@color/text_selecter_color"
                        android:textSize="14sp" />
                </LinearLayout>
            </androidx.cardview.widget.CardView>
@@ -239,19 +358,19 @@
                android:id="@+id/home_manage"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="8dp"
                android:layout_marginTop="24dp"
                android:layout_marginEnd="8dp"
                android:layout_marginBottom="16dp"
                android:layout_marginStart="6dp"
                android:layout_marginTop="16dp"
                android:layout_marginEnd="6dp"
                android:layout_marginBottom="12dp"
                android:clickable="true"
                android:focusable="true"
                android:foreground="?android:attr/selectableItemBackground"
                app:cardCornerRadius="12dp"
                app:cardElevation="4dp"
                app:cardCornerRadius="10dp"
                app:cardElevation="3dp"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/home_loss"
                app:layout_constraintStart_toEndOf="@+id/home_rewrite"
                app:layout_constraintTop_toBottomOf="@+id/home_deduction"
                app:layout_constraintVertical_bias="0.0">
                <LinearLayout
@@ -259,75 +378,24 @@
                    android:layout_height="wrap_content"
                    android:gravity="center"
                    android:orientation="vertical"
                    android:padding="16dp">
                    android:padding="12dp">
                    <ImageView
                        android:layout_width="70dp"
                        android:layout_height="70dp"
                        android:layout_width="55dp"
                        android:layout_height="55dp"
                        android:src="@drawable/home_system" />
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="8dp"
                        android:layout_marginTop="6dp"
                        android:gravity="center"
                        android:text="制作管理卡"
                        android:textColor="@color/text_selecter_color"
                        android:textSize="@dimen/home_text_size" />
                        android:textSize="14sp" />
                </LinearLayout>
            </androidx.cardview.widget.CardView>
            <TextView
                android:id="@+id/home_parameter"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:text="参数设置"
                android:textColor="@color/text_selecter_color"
                android:textSize="@dimen/home_text_size"
                android:visibility="gone"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />
            <androidx.cardview.widget.CardView
                android:id="@+id/home_my"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="8dp"
                android:layout_marginTop="24dp"
                android:layout_marginEnd="8dp"
                android:clickable="true"
                android:focusable="true"
                android:foreground="?android:attr/selectableItemBackground"
                android:visibility="gone"
                app:cardCornerRadius="12dp"
                app:cardElevation="4dp"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/home_admin">
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:gravity="center"
                    android:orientation="vertical"
                    android:padding="16dp">
                    <ImageView
                        android:layout_width="70dp"
                        android:layout_height="70dp"
                        android:src="@drawable/home_my" />
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="8dp"
                        android:gravity="center"
                        android:text="个人中心"
                        android:textColor="@color/text_selecter_color"
                        android:textSize="@dimen/home_text_size" />
                </LinearLayout>
            </androidx.cardview.widget.CardView>
        </androidx.constraintlayout.widget.ConstraintLayout>
    </ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
generallibrary/src/main/res/layout/item_card_list.xml
@@ -24,7 +24,7 @@
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="卡号:5323281010060000"
                android:text="卡号:"
                android:textColor="@color/black"
                android:textSize="16sp"
                android:textStyle="bold" />
@@ -33,51 +33,36 @@
                android:id="@+id/tv_card_status"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="状态:正常"
                android:text="状态:"
                android:textColor="@color/green"
                android:textSize="14sp" />
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:orientation="horizontal">
            <TextView
                android:id="@+id/tv_card_type"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="卡类型:农户卡"
                android:textColor="@color/black"
                android:textSize="14sp" />
            <TextView
                android:id="@+id/tv_card_balance"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="余额:90.97 元"
                android:textColor="@color/black"
                android:textSize="14sp"
                android:textStyle="bold" />
        </LinearLayout>
        <TextView
            android:id="@+id/tv_client_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="姓名:李四"
            android:layout_marginTop="4dp"
            android:text="姓名:"
            android:textColor="@color/black"
            android:textSize="14sp" />
        <TextView
            android:id="@+id/tv_card_type"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="4dp"
            android:text="卡类型:"
            android:textColor="@color/black"
            android:textSize="14sp" />
        <TextView
            android:id="@+id/tv_client_num"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="4dp"
            android:text="客户编号:281010060002"
            android:text="客户编号:"
            android:textColor="@color/black"
            android:textSize="14sp" />
@@ -86,19 +71,36 @@
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="4dp"
            android:text="电话:156****4561"
            android:text="电话:"
            android:textColor="@color/black"
            android:textSize="14sp" />
        <TextView
            android:id="@+id/tv_id_card"
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="4dp"
            android:text="身份证:3402****1245"
            android:textColor="@color/black"
            android:textSize="14sp"
            android:visibility="visible" />
            android:orientation="horizontal">
            <TextView
                android:id="@+id/tv_id_card"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="身份证:"
                android:textColor="@color/black"
                android:textSize="14sp"
                android:visibility="visible" />
            <TextView
                android:id="@+id/tv_card_balance"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="余额:元"
                android:textColor="@color/black"
                android:textSize="14sp"
                android:textStyle="bold" />
        </LinearLayout>
    </LinearLayout>
</androidx.cardview.widget.CardView> 
generallibrary/src/main/res/layout/item_user_list.xml
@@ -62,14 +62,30 @@
            android:textColor="#666666"
            android:layout_marginBottom="4dp"/>
        <TextView
            android:id="@+id/tvAddress"
        <LinearLayout
            android:id="@+id/llAddress"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="14sp"
            android:textColor="#666666"
            android:orientation="horizontal"
            android:layout_marginBottom="4dp"
            android:visibility="gone"/>
            android:visibility="gone">
            <TextView
                android:id="@+id/tvAddressLabel"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="地址:"
                android:textSize="14sp"
                android:textColor="#666666"/>
            <TextView
                android:id="@+id/tvAddressValue"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="wrap_content"
                android:textSize="14sp"
                android:textColor="#666666"/>
        </LinearLayout>
        <TextView
            android:id="@+id/tvOperateDate"