Kotlin高仿微信-第16篇-单聊-红包

news2024/11/27 23:54:15

 Kotlin高仿微信-项目实践58篇详细讲解了各个功能点,包括:注册、登录、主页、单聊(文本、表情、语音、图片、小视频、视频通话、语音通话、红包、转账)、群聊、个人信息、朋友圈、支付服务、扫一扫、搜索好友、添加好友、开通VIP等众多功能。

Kotlin高仿微信-项目实践58篇,点击查看详情

效果图:

 

 

实现代码:

我的红包页面

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="right">


    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/login_root_layout"
        android:layout_width="240dp"
        android:layout_height="90dp"
        android:background="@drawable/wc_redpacket_right_normal">


        <TextView
            android:id="@+id/redpacket_content"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:text="恭喜发财,大吉大利"
            android:textColor="#ffffff"
            android:textSize="16sp"
            android:textStyle="bold"
            app:layout_constraintBottom_toBottomOf="@+id/redpacket_icon"
            app:layout_constraintStart_toEndOf="@+id/redpacket_icon"
            app:layout_constraintTop_toTopOf="@+id/redpacket_icon" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="0.2dp"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="10dp"
            android:background="#ffffff"
            app:layout_constraintBottom_toTopOf="@+id/redpacket_tip"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/redpacket_icon" />

        <TextView
            android:id="@+id/redpacket_tip"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:layout_marginBottom="6dp"
            android:text="私人红包"
            android:textColor="#d9d6c3"
            android:textSize="10sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent" />

        <androidx.appcompat.widget.AppCompatImageView
            android:id="@+id/redpacket_icon"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="18dp"
            android:layout_marginTop="10dp"
            android:src="@drawable/wc_redpacket_icon"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</RelativeLayout>

好友的红包页面:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="http://schemas.android.com/apk/res-auto">

    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/other_redpacket_root_layout"
        android:layout_width="240dp"
        android:layout_height="90dp"
        android:background="@drawable/wc_redpacket_left_normal">


        <androidx.appcompat.widget.AppCompatImageView
            android:id="@+id/other_redpacket_icon"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="18dp"
            android:layout_marginTop="10dp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            android:background="@drawable/wc_redpacket_icon"/>

        <TextView
            android:id="@+id/redpacket_content"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="恭喜发财,大吉大利"
            android:textSize="16sp"
            android:textColor="#ffffff"
            android:textStyle="bold"
            android:layout_marginLeft="10dp"
            app:layout_constraintStart_toEndOf="@+id/other_redpacket_icon"
            app:layout_constraintTop_toTopOf="@+id/other_redpacket_icon"
            app:layout_constraintBottom_toBottomOf="@+id/other_redpacket_icon"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="0.2dp"
            android:background="#ffffff"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="10dp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/other_redpacket_icon"
            app:layout_constraintBottom_toTopOf="@+id/redpacket_tip"/>

        <TextView
            android:id="@+id/redpacket_tip"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            android:layout_marginBottom="6dp"
            android:layout_marginLeft="20dp"
            android:text="私人红包"
            android:textSize="10sp"
            android:textColor="#d9d6c3"/>

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

/**
 * Author : wangning
 * Email : maoning20080809@163.com
 * Date : 2022/5/29 18:09
 * Description : 红包页面
 */
class RedpacketFragment : BaseDataBindingFragment<WcRedpacketMainBinding>(),MyDispatchTouchEventListener {

    override fun getLayoutRes() = R.layout.wc_redpacket_main

    private var navController : NavController? = null

    companion object {
        const val REDPACKET_BALANCE = "redpacket_balance"
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        super.builder().setTitleContent(R.string.wc_base_top_redpacket)

        navController = findNavController()
        redpacket_balance.showSoftInputOnFocus = false
        num_keyboard_view.initEditText(redpacket_balance)
        num_keyboard_view.setRechargeBackground(R.drawable.wc_base_red_selector)
        num_keyboard_view.setValue(R.string.wc_confirm)
        num_keyboard_view.visibility = View.GONE

        redpacket_balance.setOnClickListener {
            showNumKeyboardView()
            SoftInputUtils.hideSoftInput(redpacket_greetings)
        }

        num_keyboard_item_recharge.setOnClickListener {
            hideNumKeyboardView()
        }
        redpacket_main_root.setOnClickListener {
            hideNumKeyboardView()
            SoftInputUtils.hideSoftInput(redpacket_greetings)
        }
        redpacket_greetings.setOnClickListener {
            hideNumKeyboardView()
        }

        redpacket_balance.addTextChangedListener(object : TextWatcher{
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {

            }
            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
                if(TextUtils.isEmpty(s)){
                    redpacket_result_balance.text = ""
                } else {
                    var balance = s.toString().toFloat()
                    redpacket_result_balance.text = CommonUtils.Base.getFormatBalanceUnit(balance)
                }
            }

            override fun afterTextChanged(s: Editable?) {

            }
        })

        redpacket_ok.setOnClickListener {
            var balance = redpacket_balance.text?.toString()?.trim()!!
            if(TextUtils.isEmpty(balance)){
                ToastUtils.makeText(requireActivity(), "请输入红包金额")
            } else {
                TagUtils.d("发送红包:${balance}")
                if(!UserRepository.judgeBalanceAvailable(balance.toFloat())){
                    ToastUtils.makeText(R.string.wc_payment_balance_available)
                } else {
                    navController?.previousBackStackEntry?.savedStateHandle?.set(REDPACKET_BALANCE, redpacket_balance.text.toString().toFloat())
                    navController?.popBackStack()
                }
            }
        }
    }

    override fun onResume() {
        super.onResume()

        redpacket_balance.isFocusableInTouchMode = true
        redpacket_balance.requestFocus()
        redpacket_balance.setOnKeyListener { view, i, keyEvent ->
            if (i == KeyEvent.KEYCODE_BACK && keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
                if(num_keyboard_view.visibility == View.VISIBLE){
                    hideNumKeyboardView()
                    true
                } else {
                    false
                }
            } else {
                false
            }
        }
    }

    override fun dispatchTouchEvent(ev: MotionEvent) {
        if (ev.action == MotionEvent.ACTION_DOWN) {
            if (SoftInputUtils.isInput(rechange_balance, ev)) {
                num_keyboard_view?.visibility = View.GONE
            }
        }
    }

    private fun hideNumKeyboardView(){
        num_keyboard_view.visibility = View.GONE
    }

    private fun showNumKeyboardView(){
        num_keyboard_view.visibility = View.VISIBLE
    }

}
//发送文本、红包、表情
private fun sendMessage(chatBean: ChatBean){
    if(chatBean == null){
        ToastUtils.makeText(requireActivity(), "发送信息不能为空")
        return
    }
    var content = chatBean.content
    if(TextUtils.isEmpty(content)){
        ToastUtils.makeText(requireActivity(), "发送信息不能为空")
    } else {
        ChatManagerUtils.getInstance().sendMessage(toUserId, content)
        chat_content.setText("")
        CoroutineScope(Dispatchers.IO).launch {
            if(chatBean.contentType == ChatBean.CONTENT_TYPE_REDPACKET){
                var content = chatBean.content
                chatBean.content = CommonUtils.Chat.getRedpacket(content).toString()
            } else if(chatBean.contentType == ChatBean.CONTENT_TYPE_TRANSFER){
                var content = chatBean.content
                chatBean.content = CommonUtils.Chat.getTransfer(content).toString()
            }
            ChatRepository.insertChat(chatBean)
        }
        refreshBase(chatBean)
    }
}


/**
 * 刷新发送、接收聊天信息
 * @param chatBean ChatBean
 */
private fun refreshBase(chatBean: ChatBean){
    CoroutineScope(Dispatchers.Main).launch {
        //chatViewModel.insertChat(chatBean)
        TagUtils.d("ChatFragment refreshBase 刷新聊天信息 ")
        adapter.refresh(chatBean)
        if(chatBean.contentType == ChatBean.CONTENT_TYPE_LOCATION){
            delay(200)
        }
        swipe_target.scrollToPosition(adapter.itemCount -1)
    }
}

插入本地数据库:

fun insertChat(chatBean: ChatBean) : Long {
    var chatListLocal = getAllChat()
    if(chatListLocal == null || chatListLocal.size < 1){
        return WcDatabase.getInstance(WcApp.getContext()).chatDao().insertChat(chatBean)
    }
    var resultList = chatListLocal.filter {
        it.messageId.equals(chatBean.messageId)
    }
    //过滤重复数据
    if(resultList.size > 0){
        return 0
    }
    return WcDatabase.getInstance(WcApp.getContext()).chatDao().insertChat(chatBean)
}

接收红包:

if(content.startsWith(CommonUtils.Chat.REDPACKET_MARK)){
    //发送红包, 去掉redpacket###写入数据库
    content = CommonUtils.Chat.getRedpacket(content).toString()
    var chatBean = CommonUtils.Chat.getChatBean(fromUser, toUser, userType, content, ChatBean.CONTENT_TYPE_REDPACKET, "",0.0, 0.0)
    ChatRepository.insertChat(chatBean)
    chatBean.isReceive = true
    EventBus.getDefault().post(chatBean)
} 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/49697.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Pandas数据处理100例】(九十六):Pandas使用cumsum()函数计算某列的累计和

前言 大家好,我是阿光。 本专栏整理了《Pandas数据分析处理》,内包含了各种常见的数据处理,以及Pandas内置函数的使用方法,帮助我们快速便捷的处理表格数据。 正在更新中~ ✨ 🚨 我的项目环境: 平台:Windows10语言环境:python3.7编译器:PyCharmPandas版本:1.3.5N…

c#机器学习之opencv(1)-opencvsharp显示图片与边缘提取

目录Using块概念using 添加到局部变量声明。安装opencvsharp显示图片边缘检测Using块 概念 有时你的代码需要非托管的资源&#xff0c;如文件句柄、 COM 包装器或 SQL 连接。 一个Using块确保一个或多个此类资源的释放你的代码完成与之时。 这使它们可用于其他代码使用。 托管…

一个新公众号怎么吸粉?教你几招

都说万事开头难&#xff0c;但我不觉得啊&#xff0c;关键是要找对方法&#xff01; 企业和品牌创建初期都会经历公众号启动期&#xff0c;一个新公众号必将会经历艰难的涨粉阶段。 想必下面这两种情况你也深有体会&#xff1a; 即使每天坚持更新&#xff0c;但是后台文章阅读…

迷宫问题(只有一条路径)【dfs 判断是否继续dfs 的三种方法】

dfs、bfs的迷宫问题1. 迷宫问题&#xff08;只有一条路径&#xff09;dfs迷宫问题总结&#xff1a;三种dfs判断法三&#xff1a;1. List<类> 存储过程节点2. dfs的返回值是 boolendfs的结构是 if(合法)if(走到节点)return true&#xff1b;法一&#xff1a;1. 两个数组&a…

腾讯云数据库SaaS致力于构建数据库分布式云,为更多更广的用户提供服务

大数据时代&#xff0c;数据库 SaaS 是企业实现降本增效和业务创新的重要抓手。在腾讯全球数字生态大会数据库 SaaS 专场上&#xff0c;腾讯云发布了多项数据库 SaaS 产品能力升级&#xff0c;并重点分享了其在上云、日常运维、数据库迁移等多方面的实践应用&#xff0c;为广大…

手把手教你实现一个防抖函数(debounce)

前言&#xff1a;防抖函数在日常开发中属于是一个非常非常重要的知识点。通常在一个项目的最开始构建的时候&#xff0c;都会在 utils文件夹下备上这样一个函数&#xff0c;来为以后做准备。 &#xff08;tips&#xff1a;utils 在大部分翻译软件内好像都叫跑龙套的&#xff0c…

<数据库视图>--数据库的“眼镜”(世界杯例题篇),查阅必备

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 秩沅 原创 **收录于专栏 数据库干货铺 ⭐外模式—视图⭐ 文章目录⭐外模式---视图⭐一&#xff0c;概念提炼二&#xff0c;视图的创…

一文解决Linux Conntrack:为什么它会崩溃,如何避免这个问题

前言 连接跟踪&#xff08;“conntrack”&#xff09;是 Linux 内核网络栈的核心特性。它允许内核跟踪所有的逻辑网络连接或数据包流&#xff0c;从而识别组成每个流的所有数据包&#xff0c;以便能够统一的处理它们。 Conntrack 是一个重要的内核特性&#xff0c;它支撑了一…

mysql进阶学习 - concat函数

目录指导: 语法:作用:说明:实例说明:相关问题:语法: concat(str1, str2, ...)作用: 将多个字符串拼接成一个字符串 说明: 该函数中的参数至少有一个参数, 否则会报错;该函数在拼接之前会将所有的参数转换为字符串类型;该函数如果某个参数为NULL, 则返回NULL值. 实例说明: 说…

blender 烘焙贴图

文章目录烘焙基础色贴图查看烘焙结果图片保存图片烘焙其他类型的贴图烘焙法线贴图TexTools插件ID Map制作ID Map使用ID Map烘焙基础色贴图 1 只有CY渲染器可以烘焙贴图 2 首先在材质栏里创建一个新的图像纹理节点&#xff0c;不需要和任何节点连接&#xff0c;点击新建&#x…

gdb常用调试命令 + 多进程调试命令

要使用 gdb 调试&#xff0c;必须在gcc / g 生成执行文件时&#xff0c;加上 -g 选项&#xff0c;那么在生成的时候&#xff0c;就会在该执行文件中加入一些debug信息。 gcc -g -o test test.c 目录 1、常用调试命令 (1) 进入 / 退出调试模式 (2) 开始调试 2、多进程调试命…

mybatis学习:二、 Mybatis的Dao开发、mybatis-config.xml文件的详情

3. Mybatis的Dao开发 ​ 使用Mybatis开发Dao&#xff0c;通常有两个方法&#xff0c;即原始Dao开发方法和Mapper接口开发方法。 3.1 Mybatis的核心对象 SqlSessionFactoryBuilder ​ SqlSessionFactoryBuilder用于创建SqlSessionFacoty&#xff0c;SqlSessionFacoty一旦创建完…

nginx学习使用

nginx学习使用一、nginx安装与使用1、linux安装2、linux卸载3、升级4、linux环境下&#xff0c;把nginx设置为开启自启动二、nginx常用命令1、部署命令2、其他命令三、配置文件解析1、系统配置2、各配置指令详解3、日志配置4、跟据上面的命令&#xff0c;实现一个代理配置案例5…

2022FW柯罗芭KLOVA 用极简主义演绎服装美学

万物伊始&#xff0c;一切都是最简单的&#xff0c;后疫情时代&#xff0c;时尚似乎也开始化繁为简&#xff0c;回归本真。LESS IS MORE 诉说着真实的高贵&#xff0c;从不喧哗&#xff0c;服装里讲究的极简风&#xff0c;正是当下时尚和生活方式的最佳体现。 款式极简 极简又高…

Spring Boot中添加Thymeleaf模板

Spring Boot中添加Thymeleaf模板 前面我们讲解了Spring Boot项目的创建、Spring Boot结构信息&#xff0c;自动配置功能等&#xff0c;那么Springboot创建出来&#xff0c;我们最终是要做web开发的&#xff0c;所以我们这章讲解如何用SpringBoot做web开发。 一. Web开发方式 …

Maven 高级篇,Maven常用操作、高级操作、nexus私服搭建

&#x1f600;&#x1f600;&#x1f600;创作不易&#xff0c;各位看官点赞收藏. Maven 高级篇 文章目录Maven 高级篇1、Maven 安装2、Maven 核心概念2.1、坐标2.2、基础操作2.3、依赖2.4、继承2.5、生命周期3、Maven 深入3.1、Spring Boot 打包3.2、超级 POM3.3、build 标签…

计算机网络第八章知识点回顾(自顶向下)

1. 网络安全 1.1 什么是网络安全&#xff1f; 1.2网络中的通信安全 1.2.1 安全攻击的类型&#xff1a;被动攻击 1.2.2 安全攻击的类型&#xff1a;主动攻击 1.3 常见的安全机制 2. 密码学术语 2.1 密码学术语&#xff08;图示&#xff09; 2.2加密算法的分类 2.3 传统加密方法&…

专访D-Wave CEO:量子计算的过去、现在和未来

&#xff08;图片来源&#xff1a;网络&#xff09; 量子计算可能成为一项颠覆性技术&#xff1a;它建立在听起来非常奇特的物理学基础上&#xff0c;并有望以前所未有的速度和效率解决某些类别的问题。一些人认为&#xff0c;目前在量子计算领域的承诺太多&#xff0c;交付却不…

【wms平台化】一个简单的wms九表架构

仓库管理软件的未来有几个方向&#xff1a;平台化、行业化、一体化、精简化。 然而其中行业化跟精简化&#xff0c;其实都离不开平台化。 也就是说&#xff0c;不论wms软件如何发展&#xff0c;唯有平台化一择。 在本人从事的传统型wms项目中&#xff0c;对于库存的定义是【在…

ch1_系统启动_setup.S

1 功能分析 大写的.s 后缀名&#xff0c; 是为了说明是一个16位&#xff0c; 实模式下的汇编语言&#xff0c; 小写的 s 是保护模式下的汇编语言&#xff1b; 1.1 使用中断&#xff0c;读取机器参数 setup.S 是一个操作系统的加载程序&#xff0c; 主要作用使用 ROM BIOS 中…