左晓为主开发手持机充值管理机
zuoxiao
2025-03-31 bd4891e2fd6b773cbb0ec387f6db4bc944fdf51a
feat(generallibrary): 添加卡片列表功能并优化登录逻辑

- 新增卡片列表 Activity 和相关布局文件
- 实现卡片搜索和分页加载功能
- 优化登录逻辑,使用路由管理器跳转到登录页面
-调整 API 基础 URL
10个文件已修改
4个文件已添加
614 ■■■■■ 已修改文件
app/build.gradle 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/AndroidManifest.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/recharge/MyApplication.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
baselibrary/src/main/res/layout/confirm_dialog.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/AndroidManifest.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/java/com/dayu/general/activity/BSCardFragment.kt 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/java/com/dayu/general/activity/CardListActivity.kt 209 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/java/com/dayu/general/activity/MyFragment.kt 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/java/com/dayu/general/net/NetConstans.kt 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/java/com/dayu/general/view/CardSearchDialog.kt 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/res/layout/activity_card_list.xml 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/res/layout/dialog_card_search.xml 142 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/res/layout/item_card_list.xml 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/res/values/colors.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/build.gradle
@@ -3,7 +3,7 @@
android {
    signingConfigs {
        debug {
            storeFile file(myValue)
            storeFile file("${project.rootDir}/dycz.jks")
            storePassword 'dycz@2023'
            keyAlias 'dayu'
            keyPassword 'dycz@2023'
app/src/main/AndroidManifest.xml
@@ -48,6 +48,11 @@
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <!-- 添加自定义action的intent-filter,用于从generallibrary中启动此Activity -->
            <intent-filter>
                <action android:name="com.dayu.recharge.action.LOGIN" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <meta-data
            android:name="BUGLY_APP_VERSION"
app/src/main/java/com/dayu/recharge/MyApplication.java
@@ -1,6 +1,5 @@
package com.dayu.recharge;
import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
@@ -41,6 +40,7 @@
        } catch (Exception e) {
            e.printStackTrace();
        }
        initApplication();
        BaseApplication.getInstance().onCreat(this);
        CrashReport.initCrashReport(getApplicationContext(), "45551598b8", true);
@@ -70,6 +70,7 @@
                        break;
                    case BaseCommon.Generalv1Library:
                        com.dayu.general.BaseApplication.getInstance(this);
                        BusinessProvider.getInstance(this);
                        break;
                }
            }
baselibrary/src/main/res/layout/confirm_dialog.xml
@@ -42,7 +42,7 @@
        <View
            android:layout_width="match_parent"
            android:layout_height="2px"
            android:layout_height="1dp"
            android:layout_marginTop="20dp"
            android:background="@color/line_bg" />
@@ -64,7 +64,7 @@
                android:textSize="20sp" />
            <View
                android:layout_width="2px"
                android:layout_width="1dp"
                android:layout_height="match_parent"
                android:background="@color/line_bg" />
generallibrary/src/main/AndroidManifest.xml
@@ -71,6 +71,7 @@
                <data android:mimeType="text/plain" />
            </intent-filter>
        </activity>
        <activity android:name=".activity.CardListActivity"/>
generallibrary/src/main/java/com/dayu/general/activity/BSCardFragment.kt
@@ -43,7 +43,7 @@
            startActivity(intent)
        }
        binding?.homeLossLL?.setOnClickListener {
            val intent = Intent(context, SearchUserActivity::class.java).apply{
            val intent = Intent(context, CardListActivity::class.java).apply{
                putExtra("type", "loss")
            }
            startActivity(intent)
generallibrary/src/main/java/com/dayu/general/activity/CardListActivity.kt
@@ -1,9 +1,216 @@
package com.dayu.general.activity
class CardListActivity:BaseActivity() {
import android.os.Bundle
import androidx.recyclerview.widget.LinearLayoutManager
import com.dayu.baselibrary.net.subscribers.SubscriberListener
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.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.scwang.smart.refresh.layout.api.RefreshLayout
import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener
/**
 * @author: zuo
 * @date: 2023/3/31
 * @description: 卡片列表界面
 */
class CardListActivity : BaseActivity() {
    var binding: ActivityCardListBinding? = null
    private var cardAdapter: CardListAdapter? = null
    var searchDialog: CardSearchDialog? = null
    // 分页相关变量
    private var currentPage = 1
    private val pageSize = 20
    private var hasMoreData = true
    // 保存当前搜索条件
    private var currentCardNumber = ""
    private var currentClientNumber = ""
    private var currentClientName = ""
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityCardListBinding.inflate(layoutInflater)
        setContentView(binding?.root)
        initView()
        setupRecyclerView()
        setupRefreshLayout()
    }
    fun initView() {
        searchDialog = CardSearchDialog(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) {
                // 保存当前搜索条件
                currentCardNumber = cardNumber
                currentClientNumber = clientNumber
                currentClientName = clientName
                // 重置分页状态
                currentPage = 1
                hasMoreData = true
                // 执行搜索
                searchCards(cardNumber, clientNumber, clientName, true)
            }
        })
        binding?.titleBar?.setOnItemclickListner(ClickType_RIGHT_IMAGE) {
            // 显示搜索对话框
            searchDialog?.show()
        }
    }
    private fun setupRecyclerView() {
        cardAdapter = CardListAdapter()
        binding?.recyclerView?.apply {
            layoutManager = LinearLayoutManager(this@CardListActivity)
            adapter = cardAdapter
        }
        // 设置列表项点击事件
        cardAdapter?.setOnItemClickListener { card ->
            // 处理卡片点击事件
            ToastUtil.show("已选择卡片:${card.cardNum}")
            // 这里可以添加跳转到卡片详情页面的逻辑
            // val intent = Intent(this, CardDetailActivity::class.java)
            // intent.putExtra("cardNum", card.cardNum)
            // startActivity(intent)
        }
    }
    private fun setupRefreshLayout() {
        binding?.refreshLayout?.apply {
            // 设置刷新和加载更多监听器
            setOnRefreshLoadMoreListener(object : OnRefreshLoadMoreListener {
                override fun onRefresh(refreshLayout: RefreshLayout) {
                    // 重置页码并刷新数据
                    currentPage = 1
                    hasMoreData = true
                    searchCards(currentCardNumber, currentClientNumber, currentClientName, true)
                }
                override fun onLoadMore(refreshLayout: RefreshLayout) {
                    // 如果还有更多数据,加载下一页
                    if (hasMoreData) {
                        currentPage++
                        searchCards(currentCardNumber, currentClientNumber, currentClientName, false)
                    } else {
                        // 完成加载并提示没有更多数据
                        refreshLayout.finishLoadMore(500, true, false)
                        ToastUtil.show("没有更多数据了")
                    }
                }
            })
        }
    }
    /**
     * 根据卡号、客户编号和客户姓名搜索卡片
     *
     * 此函数构建一个参数映射,根据提供的卡号、客户编号和客户姓名来搜索卡片
     * 它仅包含有效的、非空的搜索参数,以确保搜索请求的准确性和效率
     *
     * @param cardNumber 卡号
     * @param clientNumber 客户编号
     * @param clientName 客户姓名
     * @param isRefresh 是否为刷新操作
     */
    private fun searchCards(cardNumber: String, clientNumber: String, clientName: String, isRefresh: Boolean = true) {
        val map = mutableMapOf<String, Any>()
        if (cardNumber.isNotEmpty()) {
            map["cardNum"] = cardNumber
        }
        if (clientNumber.isNotEmpty()) {
            map["clientNum"] = clientNumber
        }
        if (clientName.isNotEmpty()) {
            map["clientName"] = clientName
        }
        // 添加分页参数
        map["pageCurr"] = currentPage
        map["pageSize"] = pageSize
        // 使用正确的类型参数
        ApiManager.getInstance().requestGetLoading(
            this,
            "sell/clientcard/getcards",
            SearchCardResult::class.java,
            map,
            object : SubscriberListener<BaseResponse<SearchCardResult>>() {
                override fun onNext(t: BaseResponse<SearchCardResult>) {
                    // 完成刷新或加载动作
                    finishRefreshOrLoad(isRefresh)
                    if (t.success) {
                        // 处理搜索成功的情况
                        val result = t.content
                        if (result != null) {
                            // 处理搜索结果
                            if (result.obj.isNotEmpty()) {
                                // 根据是否为刷新操作决定如何更新数据
                                if (isRefresh) {
                                    cardAdapter?.setData(result.obj)
                                } else {
                                    cardAdapter?.addData(result.obj)
                                }
                                // 判断是否还有更多数据:根据当前页码和总页数判断
                                hasMoreData = currentPage < result.pageTotal
                            } else {
                                if (isRefresh) {
                                    cardAdapter?.setData(emptyList())
                                    ToastUtil.show("未找到匹配的卡片")
                                } else {
                                    hasMoreData = false
                                    ToastUtil.show("没有更多数据了")
                                }
                            }
                        } else {
                            if (isRefresh) {
                                cardAdapter?.setData(emptyList())
                                ToastUtil.show("未找到匹配的卡片")
                            }
                        }
                    } else {
                        // 处理搜索失败的情况
                        ToastUtil.show(t.msg)
                    }
                }
                override fun onError(e: Throwable?) {
                    super.onError(e)
                    // 完成刷新或加载动作
                    finishRefreshOrLoad(isRefresh)
                    ToastUtil.show("搜索失败: ${e?.message ?: "未知错误"}")
                }
            }
        )
    }
    /**
     * 完成刷新或加载操作
     * @param isRefresh 是否为刷新操作
     */
    private fun finishRefreshOrLoad(isRefresh: Boolean) {
        if (isRefresh) {
            binding?.refreshLayout?.finishRefresh(true)
        } else {
            binding?.refreshLayout?.finishLoadMore(true)
        }
    }
}
generallibrary/src/main/java/com/dayu/general/activity/MyFragment.kt
@@ -1,11 +1,12 @@
package com.dayu.general.activity
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.dayu.baselibrary.business.BusinessProvider
import com.dayu.baselibrary.view.ConfirmDialog
import com.dayu.general.BaseApplication
import com.dayu.general.databinding.FragmentMyBinding
@@ -18,7 +19,10 @@
    ): View? {
        binding = FragmentMyBinding.inflate(inflater, container, false)
        binding?.logoutRL?.setOnClickListener {
            logout()
            ConfirmDialog(requireContext(), "提示", "确定要退出登录吗?") {
                logout()
            }.show()
        }
        return binding?.root
    }
@@ -51,10 +55,10 @@
        binding?.myName?.text = "未登录"
        binding?.myPhone?.text = "未登录"
        binding?.myAdName?.text = "未登录"
        var intent= Intent(activity,LoginActivity::class.java)
        startActivity(intent)
        activity?.finish()
        // 使用路由管理器跳转到登录页面
        context?.let {
            BusinessProvider.getBusinessProvider().startLoginNavigotor.navigateToLogin(context)
        }
    }
}
generallibrary/src/main/java/com/dayu/general/net/NetConstans.kt
@@ -7,8 +7,8 @@
 */
class NetConstans {
    companion object {
//        const val BASE_URL: String = "https://no253541tf71.vicp.fun/"
        const val BASE_URL: String = "http://192.168.40.166:54321/"
        const val BASE_URL: String = "https://no253541tf71.vicp.fun/"
//        const val BASE_URL: String = "http://192.168.40.166:54321/"
        const val TOKEN_INVALID: String = "0000"
    }
generallibrary/src/main/java/com/dayu/general/view/CardSearchDialog.kt
New file
@@ -0,0 +1,74 @@
package com.dayu.general.view
import android.app.Dialog
import android.content.Context
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.ViewGroup
import com.dayu.general.databinding.DialogCardSearchBinding
/**
 * 卡片搜索对话框
 * 用于搜索卡号、客户编号、客户姓名
 */
class CardSearchDialog(context: Context) : Dialog(context) {
    private lateinit var binding: DialogCardSearchBinding
    private var onSearchListener: OnSearchListener? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DialogCardSearchBinding.inflate(LayoutInflater.from(context))
        setContentView(binding.root)
        // 设置对话框宽度为屏幕宽度的85%
        window?.apply {
            val params = attributes
            params.width = (context.resources.displayMetrics.widthPixels * 0.85).toInt()
            params.height = ViewGroup.LayoutParams.WRAP_CONTENT
            params.gravity = Gravity.CENTER
            attributes = params
            setBackgroundDrawableResource(android.R.color.transparent)
        }
        // 设置点击外部不取消对话框
        setCanceledOnTouchOutside(false)
        // 设置搜索按钮点击事件
        binding.btnSearch.setOnClickListener {
            val cardNumber = binding.etCardNumber.text.toString().trim()
            val clientNumber = binding.etClientNumber.text.toString().trim()
            val clientName = binding.etClientName.text.toString().trim()
            // 回调搜索事件
            onSearchListener?.onSearch(cardNumber, clientNumber, clientName)
            dismiss()
        }
        // 设置取消按钮点击事件
        binding.tvCancel.setOnClickListener {
            dismiss()
        }
    }
    /**
     * 设置搜索监听器
     */
    fun setOnSearchListener(listener: OnSearchListener) {
        this.onSearchListener = listener
    }
    /**
     * 搜索监听器接口
     */
    interface OnSearchListener {
        /**
         * 搜索回调方法
         * @param cardNumber 卡号
         * @param clientNumber 客户编号
         * @param clientName 客户姓名
         */
        fun onSearch(cardNumber: String, clientNumber: String, clientName: String)
    }
}
generallibrary/src/main/res/layout/activity_card_list.xml
New file
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
    tools:context=".activity.CardListActivity">
    <com.dayu.baselibrary.view.TitleBar
        android:id="@+id/title_bar"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dimen_title_height"
        app:centerText="卡片列表"
        app:layout_constraintTop_toTopOf="parent"
        app:leftImage="@mipmap/icon_back"
        app:rightImage="@mipmap/icon_search" />
    <com.scwang.smart.refresh.layout.SmartRefreshLayout
        android:id="@+id/refresh_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:srlAccentColor="@color/colorPrimary"
        app:srlEnablePreviewInEditMode="true">
        <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"
            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>
</LinearLayout>
generallibrary/src/main/res/layout/dialog_card_search.xml
New file
@@ -0,0 +1,142 @@
<?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" />
    <TextView
        android:id="@+id/tv_card_number_label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="卡号"
        android:textColor="#666666"
        android:textSize="14sp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@id/divider" />
    <EditText
        android:id="@+id/et_card_number"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="6dp"
        android:background="@drawable/edit_text_bg"
        android:hint="请输入卡号"
        android:inputType="text"
        android:singleLine="true"
        android:textColorHint="#BBBBBB"
        android:textSize="15sp"
        app:layout_constraintTop_toBottomOf="@id/tv_card_number_label" />
    <TextView
        android:id="@+id/tv_client_number_label"
        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/et_card_number" />
    <EditText
        android:id="@+id/et_client_number"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="6dp"
        android:background="@drawable/edit_text_bg"
        android:hint="请输入客户编号"
        android:inputType="text"
        android:singleLine="true"
        android:textColorHint="#BBBBBB"
        android:textSize="15sp"
        app:layout_constraintTop_toBottomOf="@id/tv_client_number_label" />
    <TextView
        android:id="@+id/tv_client_name_label"
        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/et_client_number" />
    <EditText
        android:id="@+id/et_client_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="6dp"
        android:background="@drawable/edit_text_bg"
        android:hint="请输入客户姓名"
        android:inputType="text"
        android:singleLine="true"
        android:textColorHint="#BBBBBB"
        android:textSize="15sp"
        app:layout_constraintTop_toBottomOf="@id/tv_client_name_label" />
    <Button
        android:id="@+id/tv_cancel"
        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/btn_search"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintHorizontal_weight="1"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/et_client_name" />
    <Button
        android:id="@+id/btn_search"
        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/tv_cancel"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_weight="1"
        app:layout_constraintStart_toEndOf="@id/tv_cancel" />
</androidx.constraintlayout.widget.ConstraintLayout>
generallibrary/src/main/res/layout/item_card_list.xml
New file
@@ -0,0 +1,104 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginHorizontal="12dp"
    android:layout_marginVertical="6dp"
    app:cardCornerRadius="8dp"
    app:cardElevation="2dp">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="12dp">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <TextView
                android:id="@+id/tv_card_number"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="卡号:5323281010060000"
                android:textColor="@color/black"
                android:textSize="16sp"
                android:textStyle="bold" />
            <TextView
                android:id="@+id/tv_card_status"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                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: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:textColor="@color/black"
            android:textSize="14sp" />
        <TextView
            android:id="@+id/tv_phone"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="4dp"
            android:text="电话:156****4561"
            android:textColor="@color/black"
            android:textSize="14sp" />
        <TextView
            android:id="@+id/tv_id_card"
            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" />
    </LinearLayout>
</androidx.cardview.widget.CardView>
generallibrary/src/main/res/values/colors.xml
@@ -5,5 +5,6 @@
    <color name="white">#fff</color>
    <color name="nav_item_color">#555555</color>
    <color name="base_list_bg">#e6e6e6</color>
    <color name="green">#32CD32</color>
</resources>