左晓为主开发手持机充值管理机
feat(generallibrary): 新增挂失功能并优化相关界面- 新增 LossCardActivity 和 CardWriteSuccessActivity
- 实现卡片挂失功能和写卡成功页面
- 优化充值界面布局- 调整卡片信息显示逻辑
- 修复部分 UI样式问题
10个文件已修改
4个文件已添加
2017 ■■■■ 已修改文件
README.md 374 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/AndroidManifest.xml 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/java/com/dayu/general/activity/BSCardFragment.kt 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/java/com/dayu/general/activity/LossCardActivity.kt 306 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/java/com/dayu/general/activity/RechargeDetailActivity.kt 254 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/java/com/dayu/general/activity/RechargeFragment.kt 84 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/java/com/dayu/general/activity/SearchUserListActivity.kt 52 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/java/com/dayu/general/bean/net/CardInfoResult.kt 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/java/com/dayu/general/view/CardRefundDialog.kt 78 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/res/drawable/edit_text_bg.xml 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/res/layout/activity_card_list.xml 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/res/layout/activity_card_write_success.xml 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/res/layout/activity_recharge_detail.xml 407 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
generallibrary/src/main/res/layout/fragment_recharge.xml 328 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
README.md
@@ -317,8 +317,17 @@
2. 点击事件监听
```kotlin
// 方式1:使用类型常量(推荐)
titleBar.setOnItemclickListner(TitleBar.ClickType_LEFT_IMAGE) { finish() }
titleBar.setOnItemclickListner(TitleBar.ClickType_RIGHT_TEXT) { showMenu() }
titleBar.setOnItemclickListner(TitleBar.ClickType_LEFT_IMAGE) {
    finish()
}
titleBar.setOnItemclickListner(TitleBar.ClickType_RIGHT_TEXT) {
    showMenu()
}
// 或者使用完整的OnClickListener
titleBar.setOnItemclickListner(TitleBar.ClickType_LEFT_IMAGE, View.OnClickListener {
    finish()
})
// 方式2:使用位置和类型常量(已废弃)
titleBar.setOnItemclickListner(TitleBar.IMAGE, TitleBar.LEFT) { finish() }
@@ -352,6 +361,173 @@
2. 设置文本或图片时,如果传入null或0,对应的视图将被隐藏
3. 组件默认使用垂直线性布局,确保在布局文件中设置合适的高度
#### 常见使用示例
```kotlin
// 在Activity的initView方法中设置
private fun initView() {
    // 设置返回按钮点击事件
    binding.titleBar.setOnItemclickListner(TitleBar.ClickType_LEFT_IMAGE) {
        finish()
    }
    // 设置右侧文本按钮点击事件
    binding.titleBar.setOnItemclickListner(TitleBar.ClickType_RIGHT_TEXT) {
        // 处理右侧按钮点击逻辑
        handleRightButtonClick()
    }
}
```
## 支付方式动态获取功能
项目中实现了支付方式的动态获取和显示功能,支持从服务器获取支付方式列表并动态创建RadioButton。
### 数据结构
```kotlin
// 支付方式数据类
data class PaymentMethod(
    val id: Long,
    val name: String,
    val remarks: String,
    val deleted: Int
)
// 支付方式接口返回数据类
data class PaymentMethodResponse(
    val itemTotal: Any?,
    val obj: List<PaymentMethod>,
    val pageCurr: Any?,
    val pageSize: Any?,
    val pageTotal: Any?
)
```
### 使用方式
#### 1. 在Activity中添加支付方式相关属性
```kotlin
class YourActivity : AppCompatActivity() {
    // 支付方式相关属性
    private var paymentMethod: String = "现金"
    private var paymentId: Long = 0
    private var paymentMethodList: List<PaymentMethod> = listOf()
    // ... 其他代码
}
```
#### 2. 获取支付方式列表
```kotlin
/**
 * 获取支付方式列表
 */
private fun getPaymentMethods() {
    ApiManager.getInstance().requestGetLoading(
        this,
        "sell/paymentmethod/get",
        PaymentMethodResponse::class.java,
        null,
        object : SubscriberListener<BaseResponse<PaymentMethodResponse>>() {
            override fun onNext(response: BaseResponse<PaymentMethodResponse>) {
                if (response.success) {
                    val paymentMethods = response.content?.obj ?: listOf()
                    if (paymentMethods.isNotEmpty()) {
                        paymentMethodList = paymentMethods
                        updatePaymentMethodRadioGroup()
                    }
                } else {
                    Toast.makeText(this@YourActivity, "获取支付方式失败: ${response.msg}", Toast.LENGTH_SHORT).show()
                }
            }
            override fun onError(e: Throwable?) {
                super.onError(e)
                Toast.makeText(this@YourActivity, "获取支付方式失败: ${e?.message ?: "网络异常"}", Toast.LENGTH_SHORT).show()
            }
        }
    )
}
```
#### 3. 动态创建RadioButton
```kotlin
/**
 * 更新支付方式RadioGroup
 */
private fun updatePaymentMethodRadioGroup() {
    // 清空原有RadioButton
    binding.paymentMethodRadioGroup.removeAllViews()
    // 动态添加RadioButton
    paymentMethodList.forEachIndexed { index, method ->
        val radioButton = RadioButton(this)
        radioButton.id = View.generateViewId()
        radioButton.layoutParams = LinearLayout.LayoutParams(0, resources.getDimensionPixelSize(R.dimen.dimen_40), 1.0f)
        // 设置样式
        radioButton.text = method.name
        radioButton.background = resources.getDrawable(R.drawable.radio_selector)
        radioButton.buttonDrawable = null
        radioButton.gravity = Gravity.CENTER
        radioButton.setTextColor(resources.getColorStateList(R.color.radio_button_text_color))
        radioButton.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14f)
        // 添加到RadioGroup
        binding.paymentMethodRadioGroup.addView(radioButton)
        // 默认选中第一个
        if (index == 0) {
            radioButton.isChecked = true
            paymentMethod = method.name
            paymentId = method.id
        }
    }
    // 设置选择监听
    binding.paymentMethodRadioGroup.setOnCheckedChangeListener { group, checkedId ->
        for (i in 0 until group.childCount) {
            val radioButton = group.getChildAt(i) as RadioButton
            if (radioButton.id == checkedId) {
                paymentMethod = radioButton.text.toString()
                paymentId = paymentMethodList[i].id
                break
            }
        }
    }
}
```
#### 4. 布局文件配置
```xml
<RadioGroup
    android:id="@+id/paymentMethodRadioGroup"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <!-- 动态添加RadioButton,不需要预定义 -->
</RadioGroup>
```
### 功能特点
1. **动态获取**: 从服务器动态获取支付方式列表,支持后台配置
2. **自动布局**: 根据支付方式数量自动调整RadioButton布局
3. **样式统一**: 所有动态创建的RadioButton使用统一的样式
4. **默认选择**: 自动选中第一个支付方式作为默认选项
5. **事件处理**: 支持选择变化监听,实时更新当前选中的支付方式
### 注意事项
1. 确保在调用`getPaymentMethods()`前已经初始化了相关的UI组件
2. 动态创建的RadioButton需要设置唯一的ID,使用`View.generateViewId()`
3. 在Activity销毁时注意清理相关资源,避免内存泄漏
4. 网络请求失败时要有相应的错误处理机制
## 注意事项
1. 数据库迁移
@@ -371,6 +547,200 @@
   - 确保异常信息被正确记录和上报
   - 避免异常信息泄露敏感数据
5. API异常处理最佳实践
   - 针对特定错误码提供友好的用户提示
   - 区分网络异常、业务异常和系统异常
   - 异常发生后及时重置UI状态,允许用户重试
   - 提供明确的操作指引,如"请先进行开卡操作"
### API异常处理示例
```kotlin
// 在API回调中处理不同类型的异常
object : SubscriberListener<BaseResponse<YourDataType>>() {
    override fun onNext(response: BaseResponse<YourDataType>) {
        if (response.success) {
            // 处理成功情况
            handleSuccess(response.content)
        } else {
            // 处理业务异常
            handleBusinessError(response.code, response.msg)
        }
    }
    override fun onError(e: Throwable?) {
        super.onError(e)
        // 处理网络异常
        handleNetworkError(e)
        // 重置UI状态
        resetViewState()
    }
}
// 业务异常处理方法
private fun handleBusinessError(code: String?, msg: String?) {
    when (code) {
        "1081" -> ToastUtil.show("该卡片未在系统中注册,请先进行开卡操作")
        "1001" -> ToastUtil.show("权限不足,请联系管理员")
        "1002" -> ToastUtil.show("账户余额不足")
        else -> {
            val errorMsg = when {
                msg.isNullOrBlank() -> "操作失败,请重试"
                msg.contains("数据不存在") -> "数据不存在,请检查输入信息"
                msg.contains("网络") -> "网络连接异常,请检查网络后重试"
                msg.contains("超时") -> "请求超时,请重试"
                else -> "操作失败: $msg"
            }
            ToastUtil.show(errorMsg)
        }
    }
    // 重置界面状态
    resetViewState()
}
// 网络异常处理方法
private fun handleNetworkError(e: Throwable?) {
    val errorMsg = when {
        e?.message?.contains("timeout") == true -> "网络请求超时,请检查网络连接"
        e?.message?.contains("network") == true -> "网络连接失败,请检查网络设置"
        e?.message?.contains("host") == true -> "服务器连接失败,请稍后重试"
        else -> "网络异常: ${e?.message ?: "未知错误"}"
    }
    ToastUtil.show(errorMsg)
}
### Dialog弹窗使用最佳实践
项目中提供了多种Dialog组件,用于不同的交互场景。推荐使用项目已有的Dialog组件来保持UI风格的一致性。
#### 常用Dialog组件
1. **ConfirmDialog**: 确认对话框,用于重要操作的二次确认
2. **TipDialog**: 提示对话框,用于显示提示信息
3. **EdtDialog**: 输入对话框,用于获取用户输入
4. **自定义Dialog**: 继承Dialog类实现特定功能
#### ConfirmDialog使用示例
```kotlin
// 基本用法 - 只显示消息
val dialog = ConfirmDialog(context, "操作成功")
dialog.show()
// 带标题的用法
val dialog = ConfirmDialog(context, "提示", "确认要删除这条记录吗?") {
    // 点击确认按钮的回调
    deleteRecord()
    dialog.dismiss()
}
dialog.show()
// 在异常处理中使用
private fun handleError(title: String, message: String) {
    activity?.let { activity ->
        val confirmDialog = ConfirmDialog(activity, title, message) {
            // 点击确认后的操作
            resetViewState()
        }
        confirmDialog.show()
    }
}
```
#### TipDialog使用示例
```kotlin
// 简单提示
val tipDialog = TipDialog(context, "操作完成")
tipDialog.show()
// 带回调的提示
val tipDialog = TipDialog(context, "确认退出应用?", object : TipUtil.TipListener {
    override fun onCancle() {
        // 取消操作
    }
})
tipDialog.show()
```
#### 自定义Dialog最佳实践
```kotlin
class CustomDialog(context: Context) : Dialog(context, R.style.ws_pay_showSelfDialog) {
    private lateinit var binding: DialogCustomBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DialogCustomBinding.inflate(layoutInflater)
        setContentView(binding.root)
        // 设置对话框属性
        setupDialog()
        // 初始化视图
        initViews()
    }
    private fun setupDialog() {
        // 设置对话框宽度为屏幕宽度的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)
    }
    private fun initViews() {
        binding.btnConfirm.setOnClickListener {
            // 处理确认逻辑
            dismiss()
        }
        binding.btnCancel.setOnClickListener {
            dismiss()
        }
    }
}
```
#### Dialog使用注意事项
1. **内存泄漏防护**: 确保在Activity销毁时关闭Dialog
```kotlin
override fun onDestroy() {
    super.onDestroy()
    dialog?.dismiss()
}
```
2. **生命周期管理**: 在Fragment中使用Dialog时注意生命周期
```kotlin
// 在Fragment中安全显示Dialog
activity?.let { activity ->
    if (!activity.isFinishing && !activity.isDestroyed) {
        dialog.show()
    }
}
```
3. **样式一致性**: 使用项目统一的Dialog样式
```kotlin
// 使用项目定义的Dialog样式
super(context, R.style.ws_pay_showSelfDialog)
```
4. **用户体验优化**:
   - 重要操作使用ConfirmDialog进行二次确认
   - 错误信息使用带标题的Dialog,提供清晰的错误分类
   - 长时间操作显示加载Dialog,避免用户误操作
## 贡献指南
1. Fork 项目
generallibrary/src/main/AndroidManifest.xml
@@ -42,6 +42,7 @@
        <activity android:name="com.dayu.general.activity.NewCardActivity" />
        <activity android:name="com.dayu.general.activity.ManageListActivity" />
        <activity android:name="com.dayu.general.activity.SearchUserListActivity" />
        <activity android:name="com.dayu.general.activity.RechargeDetailActivity" />
        <activity
            android:name="com.dayu.general.activity.NfcWreatActivity"
            android:exported="false"
@@ -90,6 +91,8 @@
        <!-- 写卡成功页面 -->
        <activity android:name=".activity.CardWriteSuccessActivity" />
        <!-- 挂失页面 -->
        <activity android:name=".activity.LossCardActivity"/>
        <meta-data
            android:name="BUGLY_APP_VERSION"
generallibrary/src/main/java/com/dayu/general/activity/BSCardFragment.kt
@@ -42,9 +42,7 @@
            startActivity(intent)
        }
        binding.homeLossLL.setOnClickListener {
            val intent = Intent(context, SearchCardListActivity::class.java).apply{
                putExtra("type", "loss")
            }
            val intent = Intent(context, LossCardActivity::class.java)
            startActivity(intent)
        }
        binding.homeReplaceLL.setOnClickListener{
generallibrary/src/main/java/com/dayu/general/activity/LossCardActivity.kt
New file
@@ -0,0 +1,306 @@
package com.dayu.general.activity
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.BaseApplication
import com.dayu.general.adapter.CardListAdapter
import com.dayu.general.bean.net.SearchCardResult
import com.dayu.general.databinding.ActivityCardListBinding
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
/**
 * Description:
 * Author: zuo
 * Date: 2025/6/11
 */
class LossCardActivity : BaseActivity() {
    var binding: ActivityCardListBinding? = null
    private var cardAdapter: CardListAdapter? = 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 = ""
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityCardListBinding.inflate(layoutInflater)
        setContentView(binding?.root)
        initView()
        setupRecyclerView()
        setupRefreshLayout()
        // 确保Footer初始状态正确
        binding?.refreshLayout?.setEnableLoadMore(true)
    }
    fun initView() {
        searchDialog = SearchDialog(this)
        searchDialog?.show()
        binding?.titleBar?.setOnItemclickListner(ClickType_LEFT_IMAGE) { this.finish() }
        // 设置搜索监听器
        searchDialog?.setOnSearchListener(object : SearchDialog.OnSearchListener {
            override fun onSearch(farmerId: String, farmerName: String, cardNumber: String) {
                // 保存当前搜索条件
                currentCardNumber = cardNumber
                currentFarmerId = farmerId
                currentFarmerName = farmerName
                // 重置分页状态
                currentPage = 1
                hasMoreData = true
                // 重置无更多数据状态
                binding?.refreshLayout?.resetNoMoreData()
                // 执行搜索
                searchCards(currentFarmerId, currentFarmerName, currentCardNumber, true)
            }
        })
        binding?.titleBar?.setOnItemclickListner(ClickType_RIGHT_IMAGE) {
            // 显示搜索对话框
            searchDialog?.show()
        }
    }
    private fun setupRecyclerView() {
        cardAdapter = CardListAdapter(this)
        binding?.recyclerView?.apply {
            layoutManager = LinearLayoutManager(this@LossCardActivity)
            adapter = cardAdapter
        }
        // 设置列表项点击事件
        cardAdapter?.setOnItemClickListener { card ->
            // 显示退款对话框
            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 {
            // 设置Footer跟随功能,确保无更多数据时Footer能正确显示
            setEnableFooterFollowWhenNoMoreData(true)
            // 设置加载更多完成后滚动内容显示新数据
            setEnableScrollContentWhenLoaded(true)
            // 禁用纯滚动模式,确保Footer能正常工作
            setEnableOverScrollDrag(false)
            // 设置刷新和加载更多监听器
            setOnRefreshLoadMoreListener(object : OnRefreshLoadMoreListener {
                override fun onRefresh(refreshLayout: RefreshLayout) {
                    // 重置页码并刷新数据
                    currentPage = 1
                    hasMoreData = true
                    // 重置无更多数据状态
                    refreshLayout.resetNoMoreData()
                    searchCards(currentFarmerId, currentFarmerName, currentCardNumber, true)
                }
                override fun onLoadMore(refreshLayout: RefreshLayout) {
                    // 如果还有更多数据,加载下一页
                    if (hasMoreData) {
                        currentPage++
                        searchCards(currentFarmerId, currentFarmerName, currentCardNumber, false)
                    } else {
                        // 完成加载并显示已到底状态
                        refreshLayout.finishLoadMoreWithNoMoreData()
                    }
                }
            })
        }
    }
    /**
     * 根据卡号、客户编号和客户姓名搜索卡片
     *
     * 此函数构建一个参数映射,根据提供的卡号、客户编号和客户姓名来搜索卡片
     * 它仅包含有效的、非空的搜索参数,以确保搜索请求的准确性和效率
     *
     * @param cardNumber 卡号
     * @param clientNumber 客户编号
     * @param clientName 客户姓名
     * @param isRefresh 是否为刷新操作
     */
    private fun searchCards(
        farmerId: String,
        farmerName: String,
        cardNumber: String,
        isRefresh: Boolean = true
    ) {
        val map = mutableMapOf<String, Any>()
        if (cardNumber.isNotEmpty()) {
            map["cardNum"] = cardNumber
        }
        if (farmerId.isNotEmpty()) {
            map["clientNum"] = farmerId
        }
        if (farmerName.isNotEmpty()) {
            map["clientName"] = farmerName
        }
        // 添加分页参数
        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>) {
                    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
                                // 完成刷新或加载动作
                                if (isRefresh) {
                                    binding?.refreshLayout?.finishRefresh(true)
                                } else {
                                    // 如果没有更多数据了,设置已到底状态
                                    if (!hasMoreData) {
                                        binding?.refreshLayout?.finishLoadMoreWithNoMoreData()
                                    } else {
                                        binding?.refreshLayout?.finishLoadMore(true)
                                    }
                                }
                            } else {
                                if (isRefresh) {
                                    cardAdapter?.setData(emptyList())
                                    binding?.refreshLayout?.finishRefresh(true)
                                    ToastUtil.show("未找到匹配的卡片")
                                } else {
                                    hasMoreData = false
                                    // 使用finishLoadMoreWithNoMoreData显示已到底状态
                                    binding?.refreshLayout?.finishLoadMoreWithNoMoreData()
                                }
                            }
                        } else {
                            if (isRefresh) {
                                cardAdapter?.setData(emptyList())
                                binding?.refreshLayout?.finishRefresh(true)
                                ToastUtil.show("未找到匹配的卡片")
                            } else {
                                hasMoreData = false
                                binding?.refreshLayout?.finishLoadMoreWithNoMoreData()
                            }
                        }
                    } else {
                        // 处理搜索失败的情况
                        finishRefreshOrLoad(isRefresh)
                        ToastUtil.show(t.msg)
                    }
                }
                override fun onError(e: Throwable?) {
                    super.onError(e)
                    // 完成刷新或加载动作
                    finishRefreshOrLoad(isRefresh)
                    ToastUtil.show("搜索失败: ${e?.message ?: "未知错误"}")
                }
            }
        )
    }
    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 是否为刷新操作
     */
    private fun finishRefreshOrLoad(isRefresh: Boolean) {
        if (isRefresh) {
            binding?.refreshLayout?.finishRefresh(true)
        } else {
            // 如果没有更多数据,不在这里调用finishLoadMore,由具体逻辑调用finishLoadMoreWithNoMoreData
            // 如果有更多数据,则正常调用finishLoadMore
            if (hasMoreData) {
                binding?.refreshLayout?.finishLoadMore(true)
            }
            // 注意:当hasMoreData为false时,不调用任何finish方法,
            // 因为已经在具体逻辑中调用了finishLoadMoreWithNoMoreData()
        }
    }
    override fun onDestroy() {
        super.onDestroy()
        searchDialog?.dismiss()
    }
}
generallibrary/src/main/java/com/dayu/general/activity/RechargeDetailActivity.kt
New file
@@ -0,0 +1,254 @@
package com.dayu.general.activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.util.TypedValue
import android.view.View
import android.widget.RadioButton
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.dayu.baselibrary.net.subscribers.SubscriberListener
import com.dayu.baselibrary.utils.ToastUtil
import com.dayu.baselibrary.view.TitleBar
import com.dayu.general.R
import com.dayu.general.bean.net.CardInfoResult
import com.dayu.general.bean.net.PaymentMethod
import com.dayu.general.bean.net.PaymentMethodResponse
import com.dayu.general.databinding.ActivityRechargeDetailBinding
import com.dayu.general.net.ApiManager
import com.dayu.general.net.BaseResponse
class RechargeDetailActivity : AppCompatActivity() {
    private lateinit var binding: ActivityRechargeDetailBinding
    private var cardInfo: CardInfoResult? = null
    private var cardAddress: String? = null
    // 支付方式相关属性
    private var paymentMethod: String = "现金"
    private var paymentId: Long = 0
    private var paymentMethodList: List<PaymentMethod> = listOf()
    companion object {
        private const val EXTRA_CARD_INFO = "extra_card_info"
        private const val EXTRA_CARD_ADDRESS = "extra_card_address"
        fun start(context: Context, cardInfo: CardInfoResult?, cardAddress: String?) {
            val intent = Intent(context, RechargeDetailActivity::class.java)
            intent.putExtra(EXTRA_CARD_INFO, cardInfo)
            intent.putExtra(EXTRA_CARD_ADDRESS, cardAddress)
            context.startActivity(intent)
        }
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityRechargeDetailBinding.inflate(layoutInflater)
        setContentView(binding.root)
        // 隐藏默认ActionBar
        supportActionBar?.hide()
        // 获取传递的数据
        cardInfo = intent.getSerializableExtra(EXTRA_CARD_INFO) as? CardInfoResult
        cardAddress = intent.getStringExtra(EXTRA_CARD_ADDRESS)
        initView()
        displayCardInfo()
        // 获取支付方式
        getPaymentMethods()
    }
    private fun initView() {
        // 设置TitleBar的返回按钮点击事件
        binding.titleBar.setOnItemclickListner(TitleBar.ClickType_LEFT_IMAGE) {
            finish()
        }
        // 设置按钮点击事件
        binding.rechargeRegistBtn.setOnClickListener {
            // 处理写卡逻辑
            handleWriteCard()
        }
    }
    /**
     * 获取支付方式列表
     */
    private fun getPaymentMethods() {
        ApiManager.getInstance().requestGetLoading(
            this,
            "sell/paymentmethod/get",
            PaymentMethodResponse::class.java,
            null,
            object : SubscriberListener<BaseResponse<PaymentMethodResponse>>() {
                override fun onNext(response: BaseResponse<PaymentMethodResponse>) {
                    if (response.success) {
                        // 获取支付方式列表
                        val paymentMethods = response.content?.obj ?: listOf()
                        if (paymentMethods.isNotEmpty()) {
                            paymentMethodList = paymentMethods
                            // 更新支付方式显示
                            updatePaymentMethodRadioGroup()
                        }
                    } else {
                        Toast.makeText(
                            this@RechargeDetailActivity,
                            "获取支付方式失败: ${response.msg}",
                            Toast.LENGTH_SHORT
                        ).show()
                    }
                }
                override fun onError(e: Throwable?) {
                    super.onError(e)
                    Toast.makeText(
                        this@RechargeDetailActivity,
                        "获取支付方式失败: ${e?.message ?: "网络异常"}",
                        Toast.LENGTH_SHORT
                    ).show()
                }
            }
        )
    }
    /**
     * 更新支付方式RadioGroup
     */
    private fun updatePaymentMethodRadioGroup() {
        // 清空原有RadioButton
        binding.newCardPaymentMethod.removeAllViews()
        // 动态添加RadioButton
        paymentMethodList.forEachIndexed { index, method ->
            val radioButton = RadioButton(this)
            radioButton.id = View.generateViewId() // 生成唯一ID
            radioButton.layoutParams = android.widget.LinearLayout.LayoutParams(
                0,
                resources.getDimensionPixelSize(R.dimen.dimen_40),
                1.0f
            )
            // 如果不是最后一个按钮,添加右边距
            if (index < paymentMethodList.size - 1) {
                (radioButton.layoutParams as android.widget.LinearLayout.LayoutParams).rightMargin =
                    resources.getDimensionPixelSize(R.dimen.dimen_15)
            }
            radioButton.text = method.name
            radioButton.background = resources.getDrawable(R.drawable.radio_selector)
            radioButton.buttonDrawable = null
            radioButton.gravity = android.view.Gravity.CENTER
            radioButton.setTextColor(resources.getColorStateList(R.color.radio_button_text_color))
            radioButton.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14f)
            // 添加到RadioGroup
            binding.newCardPaymentMethod.addView(radioButton)
            // 默认选中第一个
            if (index == 0) {
                radioButton.isChecked = true
                paymentMethod = method.name
                paymentId = method.id
            }
        }
        // 设置支付方式选择监听
        binding.newCardPaymentMethod.setOnCheckedChangeListener { group, checkedId ->
            // 根据选中的ID获取支付方式
            for (i in 0 until group.childCount) {
                val radioButton = group.getChildAt(i) as RadioButton
                if (radioButton.id == checkedId) {
                    paymentMethod = radioButton.text.toString()
                    paymentId = paymentMethodList[i].id
                    break
                }
            }
        }
    }
    private fun displayCardInfo() {
        if (cardInfo == null) {
            ToastUtil.show("卡信息为空")
            finish()
            return
        }
        cardInfo?.let { info ->
            // 设置卡片信息
            binding.redInitCode.text = cardAddress ?: ""
            binding.userName.text = info.userName ?: ""
            binding.redCardNum.text = info.cardNum ?: ""
            binding.redRemainderBlance.text = "${info.balance ?: 0} 元"
            // 设置卡状态和对应颜色
            val cardStatus = when (info.status) {
                1 -> "正常"
                2 -> "挂失"
                3 -> "锁定"
                4 -> "无效卡片"
                else -> "未知"
            }
            binding.redStatu.text = cardStatus
            // 根据卡状态设置不同颜色
            val statusColor = when (info.status) {
                1 -> android.graphics.Color.parseColor("#4CAF50") // 绿色-正常
                2 -> android.graphics.Color.parseColor("#FF9800") // 橙色-挂失
                3 -> android.graphics.Color.parseColor("#F44336") // 红色-锁定
                else -> android.graphics.Color.parseColor("#757575") // 灰色-未知
            }
            binding.redStatu.setTextColor(statusColor)
        }
    }
    private fun handleWriteCard() {
        // 验证充值金额
        val rechargeAmountStr = binding.rechargeMorny.text.toString().trim()
        if (rechargeAmountStr.isEmpty()) {
            ToastUtil.show("请输入充值金额")
            return
        }
        val rechargeAmount = try {
            rechargeAmountStr.toDouble()
        } catch (e: NumberFormatException) {
            ToastUtil.show("请输入有效的充值金额")
            return
        }
        if (rechargeAmount <= 0) {
            ToastUtil.show("充值金额必须大于0")
            return
        }
        // 获取赠送金额(可选)
        val bonusAmountStr = binding.rechargeWater.text.toString().trim()
        val bonusAmount = if (bonusAmountStr.isNotEmpty()) {
            try {
                bonusAmountStr.toDouble()
            } catch (e: NumberFormatException) {
                0.0
            }
        } else {
            0.0
        }
        // 显示确认信息
        val totalAmount = rechargeAmount + bonusAmount
        val confirmMessage = """
            确认充值信息:
            卡号:${cardAddress}
            充值金额:${rechargeAmount}元
            赠送金额:${bonusAmount}元
            总金额:${totalAmount}元
            支付方式:${paymentMethod}
        """.trimIndent()
        ToastUtil.show(confirmMessage)
        // TODO: 调用写卡API
        // 这里可以添加实际的写卡逻辑
    }
}
generallibrary/src/main/java/com/dayu/general/activity/RechargeFragment.kt
@@ -9,6 +9,7 @@
import com.dayu.baselibrary.net.subscribers.SubscriberListener
import com.dayu.baselibrary.tools.nfc.NfcReadAdapter
import com.dayu.baselibrary.utils.ToastUtil
import com.dayu.baselibrary.view.ConfirmDialog
import com.dayu.general.bean.net.CardInfoResult
import com.dayu.general.databinding.FragmentRechargeBinding
import com.dayu.general.net.ApiManager
@@ -18,7 +19,6 @@
class RechargeFragment : Fragment() {
    var binding: FragmentRechargeBinding? = null
    private var cardNumber: String? = null
    private var cardInfo: CardInfoResult? = null
    override fun onCreateView(
        inflater: LayoutInflater,
@@ -38,7 +38,6 @@
    private fun initView() {
        // 初始化界面显示读卡状态
        binding?.rechargeReadLL?.visibility = View.VISIBLE
        binding?.rechargeTextLL?.visibility = View.GONE
    }
    
@@ -46,8 +45,6 @@
    private fun resetView() {
        // 重置界面显示读卡状态
        binding?.rechargeReadLL?.visibility = View.VISIBLE
        binding?.rechargeTextLL?.visibility = View.GONE
        cardInfo = null
    }
    
    /**
@@ -71,10 +68,7 @@
                    ToastUtil.show("读卡失败,请重新刷卡")
                    return
                }
                // 显示读到的卡号
                binding?.redInitCode?.text = cardNumber
                // 根据卡号获取卡片详细信息
                getCardInfo(cardNumber!!)
            } catch (e: Exception) {
@@ -89,28 +83,29 @@
     */
    private fun getCardInfo(cardNumber: String) {
        activity?.let { activity ->
            val map = mutableMapOf<String, Any>()
            map["cardAddr"] = cardNumber
            ApiManager.getInstance().requestGetLoading(
                activity,
                "card/getCardInfo/$cardNumber",  // 假设API路径
                "terminal/card/readCard",  // 假设API路径
                CardInfoResult::class.java,
                null,
                map,
                object : SubscriberListener<BaseResponse<CardInfoResult>>() {
                    override fun onNext(t: BaseResponse<CardInfoResult>) {
                        if (t.success) {
                            // 保存卡片信息
                            cardInfo = t.content
                            // 显示卡片信息
                            displayCardInfo(t.content)
                            // 跳转到充值详情页面
                            RechargeDetailActivity.start(activity, t.content, cardNumber)
                        } else {
                            // 处理获取失败的情况
                            ToastUtil.show(t.msg)
                            binding?.redStatu?.text = "卡状态异常"
                            handleCardInfoError(t.code, t.msg)
                        }
                    }
                    override fun onError(e: Throwable?) {
                        super.onError(e)
                        ToastUtil.show("获取卡信息失败: ${e?.message ?: "未知错误"}")
                        ToastUtil.show("获取卡信息失败: ${e?.message ?: "网络异常,请检查网络连接"}")
                        // 重置界面状态
                        resetView()
                    }
                }
            )
@@ -118,35 +113,38 @@
    }
    
    /**
     * 显示卡片信息
     * 处理卡信息获取错误
     */
    private fun displayCardInfo(cardInfo: CardInfoResult?) {
        if (cardInfo == null) {
            ToastUtil.show("卡信息为空")
            return
    private fun handleCardInfoError(code: String?, msg: String?) {
        val errorTitle: String
        val errorMessage: String
        when (code) {
            "1001" -> {
                // 数据不存在的特殊处理
                errorTitle = "卡片未注册"
                errorMessage = "该卡片未在系统中注册,请先进行开卡操作后再充值。"
            }
            else -> {
                // 其他错误的通用处理
                errorTitle = "获取卡信息失败"
                errorMessage = when {
                    msg.isNullOrBlank() -> "获取卡信息失败,请重新刷卡重试。"
                    msg.contains("数据不存在") -> "该卡片未在系统中注册,请先进行开卡操作后再充值。"
                    msg.contains("网络") -> "网络连接异常,请检查网络连接后重新刷卡。"
                    msg.contains("超时") -> "网络请求超时,请重新刷卡重试。"
                    else -> "获取卡信息失败:$msg\n\n请重新刷卡重试。"
                }
            }
        }
        
        // 切换到显示信息界面
        binding?.rechargeReadLL?.visibility = View.GONE
        binding?.rechargeTextLL?.visibility = View.VISIBLE
        // 设置卡片信息
        binding?.userName?.text = cardInfo.userName ?: ""
        binding?.redUserCode?.text = cardInfo.userCode ?: ""
        binding?.redRemainderBlance?.text = "${cardInfo.balance ?: 0} 元"
        // 设置卡状态
        val cardStatus = when(cardInfo.status) {
            1 -> "正常"
            2 -> "挂失"
            3 -> "锁定"
            else -> "未知"
        // 显示确认对话框
        activity?.let { activity ->
            val confirmDialog = ConfirmDialog(activity, errorTitle, errorMessage) {
                // 点击确认按钮后关闭对话框并重置界面
                resetView()
            }
            confirmDialog.show()
        }
        binding?.redStatu?.text = cardStatus
    }
}
generallibrary/src/main/java/com/dayu/general/activity/SearchUserListActivity.kt
@@ -44,6 +44,9 @@
        initView()
        setupRecyclerView()
        setupRefreshLayout()
        // 确保Footer初始状态正确
        binding?.refreshLayout?.setEnableLoadMore(true)
    }
@@ -62,6 +65,9 @@
                // 重置分页状态
                currentPage = 1
                hasMoreData = true
                // 重置无更多数据状态
                binding?.refreshLayout?.resetNoMoreData()
                // 执行搜索
                searchUser(farmerId, farmerName, cardNumber, true)
@@ -95,12 +101,21 @@
    private fun setupRefreshLayout() {
        binding?.refreshLayout?.apply {
            // 设置Footer跟随功能,确保无更多数据时Footer能正确显示
            setEnableFooterFollowWhenNoMoreData(true)
            // 设置加载更多完成后滚动内容显示新数据
            setEnableScrollContentWhenLoaded(true)
            // 禁用纯滚动模式,确保Footer能正常工作
            setEnableOverScrollDrag(false)
            // 设置刷新和加载更多监听器
            setOnRefreshLoadMoreListener(object : OnRefreshLoadMoreListener {
                override fun onRefresh(refreshLayout: RefreshLayout) {
                    // 重置页码并刷新数据
                    currentPage = 1
                    hasMoreData = true
                    // 重置无更多数据状态
                    refreshLayout.resetNoMoreData()
                    searchUser(currentFarmerId, currentFarmerName, currentCardNumber, true)
                }
@@ -110,9 +125,8 @@
                        currentPage++
                        searchUser(currentFarmerId, currentFarmerName, currentCardNumber, false)
                    } else {
                        // 完成加载并提示没有更多数据
                        refreshLayout.finishLoadMore(500, true, false)
                        ToastUtil.show("没有更多数据了")
                        // 完成加载并显示已到底状态
                        refreshLayout.finishLoadMoreWithNoMoreData()
                    }
                }
            })
@@ -162,9 +176,6 @@
            map,
            object : SubscriberListener<BaseResponse<SearchUserResult>>() {
                override fun onNext(t: BaseResponse<SearchUserResult>) {
                    // 完成刷新或加载动作
                    finishRefreshOrLoad(isRefresh)
                    if (t.success) {
                        // 处理搜索成功的情况
                        val result = t.content
@@ -180,23 +191,42 @@
                                // 判断是否还有更多数据:根据当前页码和总页数判断
                                hasMoreData = currentPage < result.pageTotal
                                // 完成刷新或加载动作
                                if (isRefresh) {
                                    binding?.refreshLayout?.finishRefresh(true)
                                } else {
                                    // 如果没有更多数据了,设置已到底状态
                                    if (!hasMoreData) {
                                        binding?.refreshLayout?.finishLoadMoreWithNoMoreData()
                                    } else {
                                        binding?.refreshLayout?.finishLoadMore(true)
                                    }
                                }
                            } else {
                                if (isRefresh) {
                                    userAdapter?.setData(emptyList())
                                    binding?.refreshLayout?.finishRefresh(true)
                                    ToastUtil.show("未找到匹配的用户")
                                } else {
                                    hasMoreData = false
                                    ToastUtil.show("没有更多数据了")
                                    // 使用finishLoadMoreWithNoMoreData显示已到底状态
                                    binding?.refreshLayout?.finishLoadMoreWithNoMoreData()
                                }
                            }
                        } else {
                            if (isRefresh) {
                                userAdapter?.setData(emptyList())
                                binding?.refreshLayout?.finishRefresh(true)
                                ToastUtil.show("未找到匹配的用户")
                            } else {
                                hasMoreData = false
                                binding?.refreshLayout?.finishLoadMoreWithNoMoreData()
                            }
                        }
                    } else {
                        // 处理搜索失败的情况
                        finishRefreshOrLoad(isRefresh)
                        ToastUtil.show(t.msg)
                    }
                }
@@ -219,7 +249,13 @@
        if (isRefresh) {
            binding?.refreshLayout?.finishRefresh(true)
        } else {
            binding?.refreshLayout?.finishLoadMore(true)
            // 如果没有更多数据,不在这里调用finishLoadMore,由具体逻辑调用finishLoadMoreWithNoMoreData
            // 如果有更多数据,则正常调用finishLoadMore
            if (hasMoreData) {
                binding?.refreshLayout?.finishLoadMore(true)
            }
            // 注意:当hasMoreData为false时,不调用任何finish方法,
            // 因为已经在具体逻辑中调用了finishLoadMoreWithNoMoreData()
        }
    }
generallibrary/src/main/java/com/dayu/general/bean/net/CardInfoResult.kt
@@ -1,10 +1,12 @@
package com.dayu.general.bean.net
import java.io.Serializable
/**
 * 卡片信息结果实体类
 */
data class CardInfoResult(
    val cardId: String? = null,      // 卡号
    val cardNum: String? = null,      // 卡号
    val userName: String? = null,     // 用户姓名
    val userCode: String? = null,     // 用户编号
    val phone: String? = null,        // 手机号
@@ -13,4 +15,4 @@
    val status: Int? = 0,             // 卡状态: 1-正常, 2-挂失, 3-锁定
    val createTime: String? = null,   // 创建时间
    val updateTime: String? = null    // 更新时间
)
) : Serializable
generallibrary/src/main/java/com/dayu/general/view/CardRefundDialog.kt
@@ -5,15 +5,21 @@
import android.os.Bundle
import android.view.Gravity
import android.view.WindowManager
import com.dayu.baselibrary.net.subscribers.SubscriberListener
import com.dayu.baselibrary.utils.ToastUtil
import com.dayu.general.BaseApplication
import com.dayu.general.R
import com.dayu.general.databinding.DialogCardRefundBinding
import com.dayu.general.net.ApiManager
import com.dayu.general.net.BaseResponse
/**
 *
 *卡片挂失对话框
 */
class CardRefundDialog(context: Context) : Dialog(context) {
    private var binding: DialogCardRefundBinding? = null
    private var onConfirmListener: (( String, String) -> Unit)? = null
    private var onConfirmListener: ((String, String) -> Unit)? = null
    private var onSuccessListener: (() -> Unit)? = null
    private var username: String? = null
    private var cardNumber: String? = null
    private var balance: String? = null
@@ -40,14 +46,9 @@
        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()
            // 调用挂失接口
            callReportLossApi(refundAmount, remark)
        }
        // 如果有预设的用户信息,设置它们
@@ -71,15 +72,66 @@
        this.username = username
        this.cardNumber = cardNumber
        this.balance = balance
        binding?.apply {
            tvUsernameValue.text = username
            tvCardNumberValue.text = cardNumber
            etBalance.setText(balance+"元")
            etBalance.setText(balance + "元")
        }
    }
    fun setOnConfirmListener(listener: ( String, String) -> Unit) {
    fun setOnConfirmListener(listener: (String, String) -> Unit) {
        onConfirmListener = listener
    }
    fun setOnSuccessListener(listener: () -> Unit) {
        onSuccessListener = listener
    }
    /**
     * 调用挂失接口
     */
    private fun callReportLossApi(refundAmount: String, remark: String) {
        val params = mutableMapOf<String, Any>()
        params["cardNum"] = cardNumber ?: ""
        // 处理余额格式,去除千位分隔符逗号和"元"字符
        val balanceValue = balance?.replace("元", "")?.replace(",", "")?.toFloatOrNull() ?: 0f
        params["money"] = balanceValue
        params["refund"] = refundAmount.toFloatOrNull() ?: 0f
        params["remarks"] = remark.ifEmpty { "挂失" }
        params["operator"] = BaseApplication.userId
        ApiManager.getInstance().requestPostLoading(
            context,
            "terminal/card/termReportLoss",
            ReportLossResult::class.java,
            params,
            object : SubscriberListener<BaseResponse<ReportLossResult>>() {
                override fun onNext(response: BaseResponse<ReportLossResult>) {
                    if (response.success && response.code == "0001") {
                        ToastUtil.show("挂失成功")
                        onConfirmListener?.invoke(refundAmount, remark)
                        onSuccessListener?.invoke()
                        dismiss()
                    } else {
                        ToastUtil.show(response.msg ?: "挂失失败")
                    }
                }
                override fun onError(e: Throwable?) {
                    super.onError(e)
                    ToastUtil.show("挂失失败: ${e?.message ?: "网络错误"}")
                }
            }
        )
    }
    /**
     * 挂失接口返回结果
     */
    data class ReportLossResult(
        val content: Boolean? = null
    )
generallibrary/src/main/res/drawable/edit_text_bg.xml
@@ -1,14 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="#FFFFFF" />
    <corners android:radius="8dp" />
    <stroke
        android:width="1dp"
        android:color="#E0E0E0" />
    <padding
        android:bottom="8dp"
        android:left="12dp"
        android:right="12dp"
        android:top="8dp" />
</shape>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_focused="true">
        <shape android:shape="rectangle">
            <solid android:color="@android:color/white" />
            <stroke android:width="2dp" android:color="@color/base_blue_bg" />
            <corners android:radius="8dp" />
        </shape>
    </item>
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@android:color/white" />
            <stroke android:width="1dp" android:color="#e0e0e0" />
            <corners android:radius="8dp" />
        </shape>
    </item>
</selector>
generallibrary/src/main/res/layout/activity_card_list.xml
@@ -43,8 +43,10 @@
                android:overScrollMode="never" />
            <com.scwang.smart.refresh.footer.ClassicsFooter
                android:id="@+id/footer"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
                android:layout_height="wrap_content"
                app:srlClassicsSpinnerStyle="Translate" />
        </com.scwang.smart.refresh.layout.SmartRefreshLayout>
generallibrary/src/main/res/layout/activity_card_write_success.xml
New file
@@ -0,0 +1,88 @@
<?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="match_parent"
    android:background="@color/colorBackground">
    <com.dayu.baselibrary.view.TitleBar
        android:id="@+id/titleBar"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dimen_title_height"
        android:background="@color/title_bar_bg"
        android:elevation="4dp"
        app:centerText="写卡结果"
        app:leftImage="@mipmap/icon_back"
        app:layout_constraintTop_toTopOf="parent" />
    <androidx.cardview.widget.CardView
        android:id="@+id/successContainer"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginStart="16dp"
        android:layout_marginTop="24dp"
        android:layout_marginEnd="16dp"
        android:layout_marginBottom="80dp"
        app:cardBackgroundColor="@android:color/white"
        app:cardCornerRadius="12dp"
        app:cardElevation="4dp"
        app:layout_constraintBottom_toTopOf="@id/btnConfirm"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/titleBar">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:orientation="vertical"
            android:padding="32dp">
            <ImageView
                android:id="@+id/successIcon"
                android:layout_width="150dp"
                android:layout_height="150dp"
                android:scaleType="fitCenter"
                android:src="@drawable/icon_success" />
            <TextView
                android:id="@+id/successTitle"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="24dp"
                android:text="写卡成功"
                android:textColor="#4CAF50"
                android:textSize="24sp"
                android:textStyle="bold" />
            <TextView
                android:id="@+id/successMessage"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="16dp"
                android:gravity="center"
                android:text="卡片信息已成功写入\n请妥善保管您的卡片"
                android:textColor="#666666"
                android:textSize="16sp"
                android:lineSpacingExtra="4dp" />
        </LinearLayout>
    </androidx.cardview.widget.CardView>
    <Button
        android:id="@+id/btnConfirm"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="32dp"
        android:layout_marginEnd="32dp"
        android:layout_marginBottom="24dp"
        android:background="@drawable/bg_button_primary"
        android:text="确定"
        android:textColor="@android:color/white"
        android:textSize="18sp"
        android:textStyle="bold"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
generallibrary/src/main/res/layout/activity_recharge_detail.xml
New file
@@ -0,0 +1,407 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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="match_parent"
    android:background="@color/base_green_bg">
    <com.dayu.baselibrary.view.TitleBar
        android:id="@+id/titleBar"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dimen_title_height"
        android:background="@color/title_bar_bg"
        android:elevation="4dp"
        app:centerText="充值"
        app:leftImage="@mipmap/icon_back"
        app:layout_constraintTop_toTopOf="parent" />
    <ScrollView
        android:id="@+id/recharge_scrollView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/titleBar"
        android:layout_above="@+id/recharge_registBtn"
        android:fillViewport="true"
        android:scrollbars="none">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:padding="12dp">
            <!-- 卡片信息卡片 -->
            <androidx.cardview.widget.CardView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="10dp"
                app:cardCornerRadius="8dp"
                app:cardElevation="2dp"
                app:cardBackgroundColor="@android:color/white">
                <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"
                        android:layout_marginBottom="12dp">
                        <View
                            android:layout_width="3dp"
                            android:layout_height="16dp"
                            android:background="@color/base_blue_bg"
                            android:layout_marginEnd="8dp"
                            android:layout_gravity="center_vertical" />
                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="卡片信息"
                            android:textColor="#333333"
                            android:textSize="16sp"
                            android:textStyle="bold"
                            android:layout_gravity="center_vertical" />
                    </LinearLayout>
                    <!-- 姓名和用户编号合并为一行 -->
                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="40dp"
                        android:layout_marginBottom="6dp"
                        android:orientation="horizontal"
                        android:background="@drawable/item_bg_selector"
                        android:paddingLeft="12dp"
                        android:paddingRight="12dp"
                        android:gravity="center_vertical">
                        <TextView
                            android:layout_width="70dp"
                            android:layout_height="wrap_content"
                            android:text="姓名:"
                            android:textColor="#666666"
                            android:textSize="13sp" />
                        <TextView
                            android:id="@+id/userName"
                            android:layout_width="0dp"
                            android:layout_height="wrap_content"
                            android:layout_weight="1"
                            android:textColor="#333333"
                            android:textSize="14sp" />
                        <TextView
                            android:layout_width="70dp"
                            android:layout_height="wrap_content"
                            android:text="卡状态:"
                            android:textColor="#666666"
                            android:textSize="13sp" />
                        <TextView
                            android:id="@+id/red_statu"
                            android:layout_width="0dp"
                            android:layout_height="wrap_content"
                            android:layout_weight="1"
                            android:textColor="@color/red"
                            android:textSize="14sp"
                            android:textStyle="bold" />
                    </LinearLayout>
                    <!-- 卡号 -->
                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="40dp"
                        android:layout_marginBottom="6dp"
                        android:orientation="horizontal"
                        android:background="@drawable/item_bg_selector"
                        android:paddingLeft="12dp"
                        android:paddingRight="12dp"
                        android:gravity="center_vertical">
                        <TextView
                            android:layout_width="70dp"
                            android:layout_height="wrap_content"
                            android:text="卡地址:"
                            android:textColor="#666666"
                            android:textSize="13sp" />
                        <TextView
                            android:id="@+id/red_initCode"
                            android:layout_width="0dp"
                            android:layout_height="wrap_content"
                            android:layout_weight="1"
                            android:text=""
                            android:textColor="#333333"
                            android:textSize="14sp"
                            android:textStyle="bold" />
                    </LinearLayout>
                    <!-- 卡状态 -->
                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="40dp"
                        android:layout_marginBottom="6dp"
                        android:orientation="horizontal"
                        android:background="@drawable/item_bg_selector"
                        android:paddingLeft="12dp"
                        android:paddingRight="12dp"
                        android:gravity="center_vertical">
                        <TextView
                            android:layout_width="70dp"
                            android:layout_height="wrap_content"
                            android:text="卡编号:"
                            android:textColor="#666666"
                            android:textSize="13sp"
                         />
                        <TextView
                            android:id="@+id/red_cardNum"
                            android:layout_width="0dp"
                            android:layout_height="wrap_content"
                            android:layout_weight="1"
                            android:text=""
                            android:textColor="#333333"
                            android:textSize="14sp" />
                    </LinearLayout>
                    <!-- 当前余额 -->
                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="40dp"
                        android:orientation="horizontal"
                        android:background="@drawable/item_bg_selector"
                        android:paddingLeft="12dp"
                        android:paddingRight="12dp"
                        android:gravity="center_vertical">
                        <TextView
                            android:layout_width="70dp"
                            android:layout_height="wrap_content"
                            android:text="当前余额:"
                            android:textColor="#666666"
                            android:textSize="13sp" />
                        <TextView
                            android:id="@+id/red_remainder_blance"
                            android:layout_width="0dp"
                            android:layout_height="wrap_content"
                            android:layout_weight="1"
                            android:textColor="@color/base_blue_bg"
                            android:textSize="16sp"
                            android:textStyle="bold" />
                    </LinearLayout>
                </LinearLayout>
            </androidx.cardview.widget.CardView>
            <!-- 充值信息卡片 -->
            <androidx.cardview.widget.CardView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="10dp"
                app:cardCornerRadius="8dp"
                app:cardElevation="2dp"
                app:cardBackgroundColor="@android:color/white">
                <LinearLayout
                    android:id="@+id/recharge_LL"
                    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"
                        android:layout_marginBottom="12dp">
                        <View
                            android:layout_width="3dp"
                            android:layout_height="16dp"
                            android:background="@color/red"
                            android:layout_marginEnd="8dp"
                            android:layout_gravity="center_vertical" />
                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="充值信息"
                            android:textColor="#333333"
                            android:textSize="16sp"
                            android:textStyle="bold"
                            android:layout_gravity="center_vertical" />
                    </LinearLayout>
                    <!-- 充值金额和赠送金额合并为一行 -->
                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:orientation="horizontal"
                        android:layout_marginBottom="8dp">
                        <LinearLayout
                            android:layout_width="0dp"
                            android:layout_height="wrap_content"
                            android:layout_weight="1"
                            android:orientation="vertical"
                            android:layout_marginEnd="8dp">
                            <TextView
                                android:id="@+id/recharge_tx"
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:layout_marginBottom="6dp"
                                android:text="充值金额(元):"
                                android:textColor="@color/red"
                                android:textSize="14sp"
                                android:textStyle="bold" />
                            <EditText
                                android:id="@+id/recharge_morny"
                                android:layout_width="match_parent"
                                android:layout_height="42dp"
                                android:background="@drawable/edit_text_bg"
                                android:hint="请输入充值金额"
                                android:inputType="numberDecimal"
                                android:padding="12dp"
                                android:textSize="14sp"
                                android:maxLines="1" />
                        </LinearLayout>
                        <LinearLayout
                            android:layout_width="0dp"
                            android:layout_height="wrap_content"
                            android:layout_weight="1"
                            android:orientation="vertical"
                            android:layout_marginStart="8dp">
                            <TextView
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:layout_marginBottom="6dp"
                                android:text="赠送金额(元):"
                                android:textColor="#666666"
                                android:textSize="14sp" />
                            <EditText
                                android:id="@+id/recharge_water"
                                android:layout_width="match_parent"
                                android:layout_height="42dp"
                                android:background="@drawable/edit_text_bg"
                                android:hint="赠送金额(选填)"
                                android:inputType="numberDecimal"
                                android:padding="12dp"
                                android:textSize="14sp"
                                android:maxLines="1" />
                        </LinearLayout>
                    </LinearLayout>
                </LinearLayout>
            </androidx.cardview.widget.CardView>
            <!-- 支付方式卡片 -->
            <androidx.cardview.widget.CardView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:cardCornerRadius="8dp"
                app:cardElevation="2dp"
                app:cardBackgroundColor="@android:color/white">
                <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"
                        android:layout_marginBottom="12dp">
                        <View
                            android:layout_width="3dp"
                            android:layout_height="16dp"
                            android:background="@color/base_blue_bg"
                            android:layout_marginEnd="8dp"
                            android:layout_gravity="center_vertical" />
                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="支付方式"
                            android:textColor="#333333"
                            android:textSize="16sp"
                            android:textStyle="bold"
                            android:layout_gravity="center_vertical" />
                    </LinearLayout>
                    <RadioGroup
                        android:id="@+id/newCard_paymentMethod"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:orientation="horizontal">
                        <RadioButton
                            android:id="@+id/newCard_cashPayment"
                            android:layout_width="0dp"
                            android:layout_height="42dp"
                            android:layout_marginEnd="8dp"
                            android:layout_weight="1"
                            android:background="@drawable/radio_selector"
                            android:button="@null"
                            android:checked="true"
                            android:gravity="center"
                            android:text="现金"
                            android:textColor="@color/radio_button_text_color"
                            android:textSize="14sp" />
                        <RadioButton
                            android:id="@+id/newCard_posPayment"
                            android:layout_width="0dp"
                            android:layout_height="42dp"
                            android:layout_marginEnd="8dp"
                            android:layout_weight="1"
                            android:background="@drawable/radio_selector"
                            android:button="@null"
                            android:gravity="center"
                            android:text="POS机"
                            android:textColor="@color/radio_button_text_color"
                            android:textSize="14sp" />
                        <RadioButton
                            android:id="@+id/newCard_bankTransfer"
                            android:layout_width="0dp"
                            android:layout_height="42dp"
                            android:layout_weight="1"
                            android:background="@drawable/radio_selector"
                            android:button="@null"
                            android:gravity="center"
                            android:text="银行转账"
                            android:textColor="@color/radio_button_text_color"
                            android:textSize="14sp" />
                    </RadioGroup>
                </LinearLayout>
            </androidx.cardview.widget.CardView>
        </LinearLayout>
    </ScrollView>
    <Button
        android:id="@+id/recharge_registBtn"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_alignParentBottom="true"
        android:layout_marginLeft="12dp"
        android:layout_marginTop="6dp"
        android:layout_marginRight="12dp"
        android:layout_marginBottom="12dp"
        android:background="@drawable/recharge_button_ripple"
        android:elevation="4dp"
        android:gravity="center"
        android:text="确认充值(写卡)"
        android:textColor="@color/white"
        android:textSize="16sp"
        android:textStyle="bold" />
</RelativeLayout>
generallibrary/src/main/res/layout/fragment_recharge.xml
@@ -5,7 +5,6 @@
    android:layout_height="match_parent"
    android:background="@color/base_green_bg">
    <LinearLayout
        android:id="@+id/recharge_read_LL"
        android:layout_width="match_parent"
@@ -19,7 +18,6 @@
            android:layout_height="match_parent"
            android:layout_margin="16dp"
            app:cardCornerRadius="8dp"
            app:cardElevation="2dp">
            <RelativeLayout
@@ -53,7 +51,6 @@
                        android:layout_centerVertical="true"
                        android:layout_marginBottom="40dp"
                        android:gravity="center"
                        android:text="请将卡贴在设备上进行读卡"
                        android:textColor="#333333"
                        android:textSize="@dimen/text_size"
@@ -67,323 +64,22 @@
                        android:layout_gravity="center"
                        android:scaleType="fitCenter"
                        android:src="@mipmap/nfc_write" />
                    <!-- 显示读到的卡号 -->
                    <TextView
                        android:id="@+id/red_initCode"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="20dp"
                        android:gravity="center"
                        android:text=""
                        android:textColor="#333333"
                        android:textSize="@dimen/new_card_size"
                        android:textStyle="bold" />
                </LinearLayout>
            </RelativeLayout>
        </androidx.cardview.widget.CardView>
    </LinearLayout>
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/recharge_registBtn"
        android:fillViewport="true"
        android:visibility="gone">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:padding="16dp">
            <LinearLayout
                android:id="@+id/recharge_text_LL"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:visibility="visible">
                <androidx.cardview.widget.CardView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginBottom="10dp"
                    app:cardCornerRadius="8dp"
                    app:cardElevation="2dp">
                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:orientation="vertical"
                        android:padding="12dp">
                        <TextView
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:layout_marginBottom="12dp"
                            android:text="卡片信息"
                            android:textColor="#333333"
                            android:textSize="16sp"
                            android:textStyle="bold" />
                        <LinearLayout
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:layout_marginBottom="5dp"
                            android:orientation="horizontal">
                            <TextView
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:text="卡号:"
                                android:textColor="#666666"
                                android:textSize="@dimen/text_size" />
                            <TextView
                                android:id="@+id/red_initCode"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content"
                                android:text=""
                                android:textColor="#333333"
                                android:textSize="@dimen/new_card_size" />
                        </LinearLayout>
                        <LinearLayout
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:layout_marginBottom="5dp"
                            android:orientation="horizontal">
                            <TextView
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:text="卡状态:"
                                android:textColor="#666666"
                                android:textSize="@dimen/text_size" />
                            <TextView
                                android:id="@+id/red_statu"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content"
                                android:textColor="@color/red"
                                android:textSize="@dimen/new_card_size" />
                        </LinearLayout>
                        <LinearLayout
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:layout_marginBottom="5dp"
                            android:orientation="horizontal">
                            <TextView
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:text="姓名:"
                                android:textColor="#666666"
                                android:textSize="@dimen/new_card_size" />
                            <TextView
                                android:id="@+id/userName"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content"
                                android:textColor="#333333"
                                android:textSize="@dimen/new_card_size" />
                        </LinearLayout>
                        <LinearLayout
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:layout_marginBottom="5dp"
                            android:orientation="horizontal">
                            <TextView
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:text="用户编号:"
                                android:textColor="#666666"
                                android:textSize="@dimen/text_size" />
                            <TextView
                                android:id="@+id/red_userCode"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content"
                                android:text=""
                                android:textColor="#333333"
                                android:textSize="@dimen/new_card_size" />
                        </LinearLayout>
                        <LinearLayout
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:layout_marginBottom="5dp"
                            android:orientation="horizontal"
                            android:visibility="visible">
                            <TextView
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:text="当前余额:"
                                android:textColor="#666666"
                                android:textSize="@dimen/text_size" />
                            <TextView
                                android:id="@+id/red_remainder_blance"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content"
                                android:textColor="#333333"
                                android:textSize="@dimen/new_card_size" />
                        </LinearLayout>
                    </LinearLayout>
                </androidx.cardview.widget.CardView>
                <androidx.cardview.widget.CardView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    app:cardCornerRadius="8dp"
                    app:cardElevation="2dp">
                    <LinearLayout
                        android:id="@+id/recharge_LL"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:orientation="vertical"
                        android:padding="12dp">
                        <TextView
                            android:id="@+id/red_recharge_water"
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:layout_marginBottom="8dp"
                            android:text="充值水量:"
                            android:textColor="#333333"
                            android:textSize="@dimen/text_size"
                            android:visibility="gone" />
                        <LinearLayout
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:background="@color/base_green_bg"
                            android:orientation="vertical"
                            android:padding="12dp">
                            <TextView
                                android:id="@+id/recharge_tx"
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:layout_marginBottom="8dp"
                                android:text="充值金额(元):"
                                android:textColor="@color/red"
                                android:textSize="@dimen/new_card_size"
                                android:textStyle="bold" />
                            <EditText
                                android:id="@+id/recharge_morny"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content"
                                android:background="@android:color/white"
                                android:hint="请输入充值的金额"
                                android:inputType="numberDecimal"
                                android:padding="5dp"
                                android:textSize="@dimen/new_card_size" />
                            <EditText
                                android:id="@+id/recharge_water"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content"
                                android:layout_marginTop="5dp"
                                android:background="@android:color/white"
                                android:hint="请输入赠送的金额(选填)"
                                android:inputType="numberDecimal"
                                android:padding="5dp"
                                android:textSize="@dimen/new_card_size" />
                        </LinearLayout>
                    </LinearLayout>
                </androidx.cardview.widget.CardView>
                <androidx.cardview.widget.CardView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="10dp"
                    app:cardCornerRadius="8dp"
                    app:cardElevation="2dp">
                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:orientation="vertical"
                        android:padding="12dp">
                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_marginBottom="10dp"
                            android:text="支付方式"
                            android:textColor="#333333"
                            android:textSize="18sp"
                            android:textStyle="bold" />
                        <RadioGroup
                            android:id="@+id/newCard_paymentMethod"
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:orientation="horizontal">
                            <RadioButton
                                android:id="@+id/newCard_cashPayment"
                                android:layout_width="0dp"
                                android:layout_height="40dp"
                                android:layout_marginRight="15dp"
                                android:layout_weight="1"
                                android:background="@drawable/radio_selector"
                                android:button="@null"
                                android:checked="true"
                                android:gravity="center"
                                android:text="现金"
                                android:textColor="@color/radio_button_text_color"
                                android:textSize="@dimen/new_card_size" />
                            <RadioButton
                                android:id="@+id/newCard_posPayment"
                                android:layout_width="0dp"
                                android:layout_height="40dp"
                                android:layout_marginRight="15dp"
                                android:layout_weight="1"
                                android:background="@drawable/radio_selector"
                                android:button="@null"
                                android:gravity="center"
                                android:text="POS机"
                                android:textColor="@color/radio_button_text_color"
                                android:textSize="@dimen/new_card_size" />
                            <RadioButton
                                android:id="@+id/newCard_bankTransfer"
                                android:layout_width="0dp"
                                android:layout_height="40dp"
                                android:layout_weight="1"
                                android:background="@drawable/radio_selector"
                                android:button="@null"
                                android:gravity="center"
                                android:text="银行转账"
                                android:textColor="@color/radio_button_text_color"
                                android:textSize="@dimen/new_card_size" />
                        </RadioGroup>
                    </LinearLayout>
                </androidx.cardview.widget.CardView>
            </LinearLayout>
        </LinearLayout>
    </ScrollView>
    <Button
        android:id="@+id/recharge_registBtn"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_alignParentBottom="true"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="10dp"
        android:layout_marginRight="16dp"
        android:layout_marginBottom="10dp"
        android:background="@drawable/recharge_button_ripple"
        android:elevation="2dp"
        android:gravity="center"
        android:text="下一步(写卡)"
        android:textColor="@color/white"
        android:textSize="@dimen/new_card_size"
        android:textStyle="bold"
        android:visibility="gone" />
</RelativeLayout>