Kotlin高仿微信-第6篇-主页-我的

news2025/1/17 15:14:11

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

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

效果图:

实现代码:

<?xml version="1.0" encoding="utf-8"?>
<layout>
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="100dp">


        <TextView
            android:layout_width="match_parent"
            android:layout_height="0.5dp"
            android:layout_marginStart="80dp"
            android:layout_marginTop="10dp"
            android:layout_marginEnd="20dp"
            android:background="@color/gray"
            android:text="-"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/me_personal_avatar" />

        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/me_personal_avatar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:foreground="?selectableItemBackground"
            android:layout_marginTop="36dp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">

            <androidx.appcompat.widget.AppCompatImageView
                android:id="@+id/me_personal_img"
                android:layout_width="80dp"
                android:layout_height="80dp"
                android:layout_marginStart="22dp"
                android:scaleType="center"
                android:src="@drawable/contacts_default_icon"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <androidx.appcompat.widget.AppCompatImageView
                android:id="@+id/me_personal_right"
                android:layout_width="20dp"
                android:layout_height="20dp"
                android:layout_marginRight="10dp"
                android:src="@drawable/me_base_arrowright"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintTop_toTopOf="@+id/me_personal_account" />

            <androidx.appcompat.widget.AppCompatTextView
                android:id="@+id/me_personal_account"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="10dp"
                android:layout_marginBottom="10dp"
                android:text="账号:"
                android:textColor="@color/gray"
                android:textSize="18sp"
                app:layout_constraintBottom_toBottomOf="@+id/me_personal_img"
                app:layout_constraintStart_toEndOf="@+id/me_personal_img" />

            <androidx.appcompat.widget.AppCompatTextView
                android:id="@+id/me_personal_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="10dp"
                android:layout_marginTop="10dp"
                android:text="昵称"
                android:textColor="@color/black"
                android:textSize="22sp"
                android:textStyle="bold"
                app:layout_constraintStart_toEndOf="@+id/me_personal_img"
                app:layout_constraintTop_toTopOf="@+id/me_personal_img" />

        </androidx.constraintlayout.widget.ConstraintLayout>

        <com.wn.wechatclientdemo.view.LineBaseView
            android:id="@+id/me_payment"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/me_personal_avatar"
            android:layout_marginTop="22dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>


        <com.wn.wechatclientdemo.view.LineBaseView
            android:id="@+id/me_scan"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/me_payment"
            android:layout_marginTop="6dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

        <com.wn.wechatclientdemo.view.LineBaseView
            android:id="@+id/me_moments"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/me_scan"
            android:layout_marginTop="6dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>


        <com.wn.wechatclientdemo.view.LineBaseView
            android:id="@+id/me_setting"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/me_moments"
            android:layout_marginTop="6dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

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

/**
 * Author : wangning
 * Email : maoning20080809@163.com
 * Date : 2022/4/21 12:24
 * Description : 一行通用控件, 左边一个图标, 右边一个箭头, 中间有标题和描述
 */
class LineBaseView : LinearLayout {

    constructor(context:Context) : this(context, null)

    constructor(context: Context, attributeSet: AttributeSet?) : this(context, attributeSet, 0)

    constructor(context: Context, attributeSet: AttributeSet? , defStyleAttr : Int) : super(context, attributeSet, defStyleAttr){
    }

    var baseView : View? = null

    init {
        baseView = LayoutInflater.from(context).inflate(R.layout.wc_line_base_view, this)
    }

    fun builder() : Builder{
        return Builder(line_base_left, line_base_right, line_base_title, line_base_content, line_base_root, line_base_dividing)
    }

    class Builder(leftImageView : ImageView, rightImageView : ImageView, titleTextView : TextView,
                  contentTextView : TextView, rootView : ConstraintLayout, dividingView : TextView) {
        private var leftImageView : ImageView = leftImageView
        private var rightImageView = rightImageView
        private var titleTextView = titleTextView
        private var contentTextView = contentTextView
        private var rootView = rootView
        private var dividingView = dividingView


        fun setLeftImage(resId : Int) : Builder{
            leftImageView.setImageResource(resId)
            return this
        }

        fun setLeftClick(onClickListener: OnClickListener) : Builder{
            leftImageView.setOnClickListener(onClickListener)
            return this
        }

        fun hideLeftImage() : Builder {
            leftImageView.visibility = GONE
            return this
        }

        fun setTitle(resId: Int) : Builder {
            titleTextView.text = WcApp.getContext().resources.getString(resId)
            return this
        }

        fun setTitle(title: String) : Builder {
            titleTextView.text = title
            return this
        }

        fun setTitleColor(colorId : Int) : Builder {
            titleTextView.setTextColor(WcApp.getContext().resources.getColor(colorId))
            return this
        }

        fun setTitleSize(size : Float) : Builder{
            titleTextView.setTextSize(size)
            return this
        }

        fun setContentSize(size : Float) : Builder{
            contentTextView.setTextSize(size)
            return this
        }

        fun setContentColor(colorId : Int) : Builder {
            contentTextView.setTextColor(WcApp.getContext().resources.getColor(colorId))
            return this
        }

        fun setContent(resId : Int) : Builder {
            contentTextView.text = WcApp.getContext().resources.getString(resId)
            return this
        }

        fun setContent(content : String) : Builder {
            contentTextView.text = content
            return this
        }

        fun hideContent() : Builder{
            contentTextView.visibility = GONE
            return this
        }

        fun showContent() : Builder{
            contentTextView.visibility = VISIBLE
            return this
        }

        fun setRightImage(resId : Int) : Builder{
            rightImageView.setImageResource(resId)
            return this
        }

        fun setRightClick(onClickListener: OnClickListener) : Builder {
            rightImageView.setOnClickListener(onClickListener)
            return this
        }

        fun hideRightImage() : Builder {
            rightImageView.visibility = GONE
            return this
        }

        fun setRootClick(onClickListener: OnClickListener) : Builder {
            rootView.setOnClickListener(onClickListener)
            return this
        }

        fun hideDevideingView() : Builder{
            dividingView.visibility = View.GONE
            return this
        }


    }

}

/**
 * author : wangning
 * email : maoning20080809@163.com
 * Date : 2022/4/7 13:12
 * description : 我的页面
 */
class MeFragment : BaseDataBindingFragment<WcFragmentMeBinding>() {

    override fun getLayoutRes()= R.layout.wc_fragment_me

    //文件存储权限
    private val REQ_CODE_STORAGE = 1
    private val userViewModel : UserViewModel by viewModels()

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

        initView()

        me_personal_avatar.setOnClickListener {
            Navigation.findNavController(it).navigate(R.id.action_me_personal)
        }

        //handlePermission()
        initData()

        //先判断是否已经注册
        if(!EventBus.getDefault().isRegistered(this)){
            EventBus.getDefault().register(this)
        }

    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onMessageCallback(obj: Any) {
        if(obj == null){
            return
        }
        if(obj is EventMsgBean){
            if(obj.type == EventMsgBean.TYPE_REFRESH_USER_NAME){
                //刷新昵称
                me_personal_name.text = obj.obj as String
            } else if(obj.type == EventMsgBean.TYPE_REFRESH_AVATAR){
                //刷新头像
                GlideUtils.load(me_personal_img, obj.obj as String)
            }
        }

    }

    override fun onDestroy() {
        super.onDestroy()
        EventBus.getDefault().unregister(this)
    }

    fun initView() {

        //支付
        me_payment.builder()
            .setLeftImage(R.drawable.me_base_payment)
            .setTitle(BaseUtils.getString(R.string.me_base_payment))
            .hideContent()
            .setRootClick {
                Navigation.findNavController(it).navigate(R.id.action_me_payment)
            }

        /*//收藏
        me_collection.builder()
            .setLeftImage(R.drawable.me_base_collection)
            .setTitle(BaseUtils.getString(R.string.me_base_collection))
            .hideContent()
            .setRootClick {
                Navigation.findNavController(it).navigate(R.id.action_me_collection)
            }*/

        //朋友圈
        me_moments.builder()
            .setLeftImage(R.drawable.me_base_moments)
            .setTitle(BaseUtils.getString(R.string.me_base_moments))
            .hideContent()
            .setRootClick {
                //旧的没实现 navCollection?.navigate(R.id.action_me_moments)
                Navigation.findNavController(it).navigate(R.id.action_discover_moments)
            }

        //扫一扫
        me_scan.builder()
            .setLeftImage(R.drawable.wc_moments_scan)
            .setTitle(BaseUtils.getString(R.string.me_moments_sanc))
            .hideContent()
            .setRootClick {
                Navigation.findNavController(it).navigate(R.id.nav_qrcode_scan)
            }

        /*//视频号
        me_video.builder()
            .setLeftImage(R.drawable.me_base_video)
            .setTitle(BaseUtils.getString(R.string.me_base_video))
            .hideContent()
            .setRootClick {
                Navigation.findNavController(it).navigate(R.id.action_me_video)
            }*/

        //卡包
        /*me_card_bag.builder()
            .setLeftImage(R.drawable.me_base_card_bag)
            .setTitle(BaseUtils.getString(R.string.me_base_card_bag))
            .hideContent()
            .setRootClick {
                Navigation.findNavController(it).navigate(R.id.action_me_card_bag)
            }*/

        /*//表情
        me_expression.builder()
            .setLeftImage(R.drawable.me_base_expression)
            .setTitle(BaseUtils.getString(R.string.me_base_expression))
            .hideContent()
            .setRootClick {
                Navigation.findNavController(it).navigate(R.id.action_me_expression)
            }*/

        //设置
        me_setting.builder()
            .setLeftImage(R.drawable.me_base_setting)
            .setTitle(BaseUtils.getString(R.string.me_base_setting))
            .hideContent()
            .setRootClick {
                Navigation.findNavController(it).navigate(R.id.action_me_setting)
            }
    }

    fun initData(){
        var account = DataStoreUtils.getAccount()
        userViewModel.getUserLocal(account)
        userViewModel.userBeanLocal.observe(viewLifecycleOwner){
            if(it == null) return@observe
            me_personal_name.text = it.nickName
            var accountResult = getString(R.string.wc_me_show_account, it.account)
            me_personal_account.text = accountResult
            GlideUtils.load(me_personal_img, it.getReallyAvatar(), R.drawable.contacts_default_icon)
        }

        userViewModel.avatarFilePathLiveData.observe(viewLifecycleOwner){
            if(!TextUtils.isEmpty(it)){
                GlideUtils.load(me_personal_img, it)
            }
        }
    }

  

    //授权成功,刷新页面
    fun refresh(){
        initData()
    }


}

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

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

相关文章

【信管2.3】项目生命周期

项目生命周期上一篇文章内容有点多呀&#xff0c;消化完了吗&#xff1f;其实吧&#xff0c;最主要的就是那三种组织形式而已&#xff0c;别的真没什么&#xff0c;记住它们的优缺点和项目经理的权力大小就可以了。今天我们轻松点&#xff0c;虽说还是挺重要的&#xff0c;但要…

在 Docker 容器内集成 Crontab 定时任务

本文内容Crontab 基础知识Crontab 日志问题参考链接有时候&#xff0c;我们需要在容器内执行某种定时任务。譬如&#xff0c;Kerberos 客户端从 KDC 中获取到的 TGT 默认有效期为 10 个小时&#xff0c;一旦这个票据失效&#xff0c;我们将无法使用单点登录功能。此时&#xff…

谈前端测试的重要性

如果正确完成前端测试&#xff0c;将使我们的用户感到满意&#xff0c;并在使用我们的应用程序时获得良好的性能体验。 根据 Bob 大叔的说法&#xff0c;测试是系统的一部分&#xff1b;许多开发人员认为相反&#xff0c;因为他们没有部署。他宣称这是一个灾难性的观点&#x…

数据可视化之平台数据分析

一 前言 近年来&#xff0c;随着网络技术和电子商务的发展&#xff0c;对科学数据分析的研究提出了更高的要求&#xff0c;数据分析技术随之发展起来。我们可以通过数据分析技术&#xff0c;发现大量金融、通信和商业数据中隐含的规律&#xff0c;从而为决策提供依据。这已成为…

HTML5期末考核大作业 基于HTML+CSS+JavaScript仿王者荣耀首页 游戏网站开发 游戏官网设计与实现

&#x1f389;精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

Native 内存warp

Native 启动-动态/静态&libc &linker https://www.cnblogs.com/ilocker/p/4645308.html https://www.cnblogs.com/ilocker/p/4645308.html 修改LD_PRELOAD hook java native 库函数 https://blog.csdn.net/m0_57036414/article/details/126811772 Native malloc_debug …

如何用潜类别混合效应模型(Latent Class Mixed Model ,LCMM)分析老年痴呆年龄数据

全文下载链接&#xff1a;http://tecdat.cn/?p24647线性混合模型假设 N 个受试者的群体是同质的&#xff0c;并且在群体水平上由独特的曲线 Xi(t)β 描述&#xff08;点击文末“阅读原文”获取完整代码数据&#xff09;。相关视频背景和定义相比之下&#xff0c;潜在类别混合模…

国鸿氢能冲刺港股:年亏损7亿 云浮工业园与青岛城投是股东

雷递网 雷建平 11月28日国鸿氢能科技&#xff08;嘉兴&#xff09;股份有限公司&#xff08;简称&#xff1a;“国鸿氢能”&#xff09;日前递交招股书&#xff0c;准备在港交所上市。年亏损7亿国鸿氢能成立于2015年6月&#xff0c;是一家以氢燃料电池为核心产品的企业&#x…

MySQL监控主从复制

show slave status; show slave status; 不够准确 使用下面的

JetpackCompose从入门到实战学习笔记3——Text的简单使用

JetpackCompose从入门到实战学习笔记3——Text的简单使用 上一篇文章我们讲解了modifier的一些简单用法&#xff0c;本篇就开始讲解基础控件Text的一些简单用法. 1.源码分析&#xff1a; Composable fun Text(text: AnnotatedString,//要显示的文本modifier: Modifier Modi…

【PAT乙级】一百一十道真题刷后大汇总——C/C++

技巧总结避免精度丢失查询数据是否存在容器之间的比较是否相等缓存区中字符残留问题巧妙输入巧妙使用hash数组简单数学质数俩数最大公约与最小公倍数因子常用的头文件及其内部函数< map >< set >< pair >< string >< vector >< algorithm >…

算法排序基础(全版)

一、简单排序 这大概是我整理的最全的有关算法排序的内容啦&#xff01;欢迎大家前来学习&#xff0c;同时也希望多多支持一下博主哦&#xff01; ​ 在我们的程序中&#xff0c;排序是非常常见的一种需求&#xff0c;提供一些数据元素&#xff0c;把这些数据元素按照一定的规则…

【C++ STL容器】:vector存放数据以及存放自定义的数据类型

前言 时不可以苟遇&#xff0c;道不可以虚行。 STL 中最常用的容器为&#xff1a;vector&#xff0c;暂且把它理解为我们之前学过的数组Array。 一、创建一个vector容器&#xff08;数组&#xff09; 添加头文件&#xff1a;#include <vector> vector<int> v;二、…

VauditDemo靶场代码审计

靶场搭建 将下载好的VAuditDemo_Debug目录复制到phpstudy的www目录下&#xff0c;然后将其文件名字修改成VAuditDemo&#xff0c;当然你也可以修改成其他的 运行phpstudy并且访问install目录下的install.php&#xff0c;这里我访问的是http://127.0.0.1/VAuditDemo/install/in…

Linux 性能分析工具- Atop安装和使用

Atop下载&#xff1a;Atoptool.nl 安装时&#xff0c;可能会出现报错&#xff1a;error: Failed dependencies 提示很需要安装python3&#xff0c;所以yum -y install python3&#xff0c;然后再装atop就没问题了。 atop 常用命令 您可在打开日志文件后&#xff0c;使用以下命…

R语言使用马尔可夫链对营销中的渠道归因建模

介绍 在这篇文章中&#xff0c;我们看看什么是渠道归因&#xff0c;以及它如何与马尔可夫链的概念联系起来。最近我们被客户要求撰写关于马尔可夫链的研究报告&#xff0c;包括一些图形和统计输出。我们还将通过一个电子商务公司的案例研究来理解这个概念如何在理论上和实践上…

QT开发教程:QScroller实现home界面滑动效果

在上章我们学习了QScroller实现home界面滑动效果,但是该界面是实现的上下滑动效果,如果想模拟手机home滑动界面,则需要实现左右滑动效果. 本章,则重写QStackedWidget类,来真正的模拟手机,来实现home界面左右滑动效果. 1.SmoothStackedWidget类实现 demo界面如下图所示(创建了…

[附源码]计算机毕业设计springboot第三方游戏零售平台

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Discourse 在 2022-11 的最新版本中提供了新的边栏

官方有关这个边栏的说明和解释文章请参考链接&#xff1a; Try out the new sidebar and notification menus! - announcements - Discourse Meta 中的内容。 在这个新设计的边栏中包含了一些所有人都需要使用的快捷链接&#xff0c;同时还包括一些定义的快捷分类链接和 Tag 链…

haproxy keepalive实践

1 安装haproxy wget http://download.openpkg.org/components/cache/haproxy/haproxy-2.6.6.tar.gz tar -zxvf haproxy-2.6.6.tar.gz cd haproxy-2.6.6 mkdir -p /app/haproxy # 安装依赖,解决haproxy.c:80:31的问题 sudo yum -y install gcc openssl-devel pcre-devel system…