0 评论

0 收藏

分享

[Android开发相关技术] 【07】AI辅助编程完整的安卓二次商业实战-字体大小调整-跳转重影bug修复-替换剩余图标

【07】AI辅助编程完整的安卓二次商业实战-字体大小调整-跳转重影bug修复-替换剩余图标以及打包apk-优雅草卓伊凡
引言
本次二开布局没有变,但是下一次整体布局会有变,不过本次开发发现朋友圈跳转功能的流程步骤也做了一定的变化。原生项目复杂就复杂于就算一个颜色的改动可能都比较麻烦,不像普通web项目或者vue项目,其次原生项目安卓Android的环境配置是很复杂的,很多人 第一步可以搞一周 甚至一个月都搞不成功,再次之前说了可以用trae辅助我们编程,但是真正的开发和调试还是得Android studio 离开Android studio 原生安卓项目也是没法运行的,至少trae满足不了,vs要满足也比较麻烦,本篇改颜色和主页图标,本项目代码 毫不夸张的说 就是WhatsApp的初期代码,历史大概有15年了。
本篇【07】核心重点还有最后那个步骤也就是打包,然后本次ui改版和细微细微调整暂时告一段落,下一步后面8开始就是真正很复杂的的二次开发功能开发了,届时卓伊凡分享
项目技术栈优雅草蜻蜓I即时通讯水银版 - 技术栈列表
概述:本项目是一个基于微服务架构的现代即时通讯解决方案。2025年8月进行了大规模技术升级与重构,并于8-9月期间集中进行兼容性调整与Bug修复,旨在提升系统稳定性、可维护性和未来扩展性。

一、 移动客户端 (Android)
  • 开发语言: Java
  • 开发模式: 原生开发
  • 兼容性底座: 最低支持 Android API 5 (Android 5.0)
  • 核心框架升级:
    • 项目已从原生的 Android Support 库全面升级到 AndroidX,以获得更好的性能和维护性。
  • 推送集成:
    • 集成 极光推送 (JPush) SDK,用于处理应用在后台或进程被杀时的消息离线推送。


二、 服务端 (Backend)
  • 核心语言: Java
  • 主要框架: Spring Boot
    • 用于构建和编排所有业务逻辑和业务流程,提供RESTful API接口,是连接各个微服务的核心枢纽。
  • JDK 版本:
    • 当前版本: JDK 1.8
    • 未来计划: 已有明确计划升级至 JDK 17(因时间安排暂未执行,旨在获得新的语言特性和性能提升)。


三、 微服务与基础设施 (Microservices & Infrastructure)
本次升级的核心是将单体服务拆解为独立、可扩展的微服务。
  • 即时通讯服务:
    • 协议: XMPP (Extensible Messaging and Presence Protocol)
    • 实现: 独立部署的 XMPP 服务,负责最核心的点对点、群组聊天等实时消息分发。
  • 消息回执服务:
    • 实现: Tigase Server 7.1.3
    • 职责: 专门处理消息的已发送、已送达、已阅读等状态回执,确保消息的可达性。
  • 消息队列服务:
    • 组件: RocketMQ 4.3.2 (rocketmq-all-4.3.2)
    • 职责: 处理服务间的异步通信、流量削峰、任务队列等,保证系统的高可用和高性能。
  • 上传服务:
    • 实现: 独立制作的 Upload 服务
    • 职责: 专门处理图片、文件、语音等附件的上传、存储和管理,与主业务逻辑解耦。
  • 推送服务:
    • 实现: 独立制作的 Push 服务
    • 集成: 内部封装了 极光推送 SDK,负责将消息通过系统通道推送给Android客户端。
  • 缓存与队列服务:
    • 组件: Redis
    • 职责: 用作高速缓存,提升访问速度;同时处理临时消息队列和会话状态存储。


四、 数据存储 (Data Storage)
  • 主数据库:
    • 组件: MongoDB
    • 版本升级: 已从旧的 3.4.0 成功升级至 4.0 版本。
    • 用途: 存储非结构化的聊天记录、用户动态、群组信息等海量数据,利用其灵活的Schema特性适应IM业务的快速迭代。
  • 关系型数据库:
    • 可能选项: MySQL8.0 下一步做改进的。
    • 可能用途: 存储用户账户、好友关系、群组列表等结构化数据。


总结与技术亮点
  • 架构现代化: 从可能存在的单体架构成功转型为微服务架构,服务间通过 RocketMQ 和 HTTP API 进行通信,解耦彻底。
  • 技术债务清理: 积极处理历史技术债务,包括 AndroidX 迁移和 MongoDB 大版本升级,为未来开发铺平道路。
  • 专业化分工: 每个核心功能(通讯、上传、推送、回执)都由独立服务承担,职责单一,更易于扩展、部署和故障排查。
  • 成熟组件选型: 选用 RocketMQ, Redis, Tigase 等经过大规模实践验证的中间件,保证了系统底层的稳定性和可靠性。
  • 明确的发展规划: 已有清晰的 JDK 17 升级计划,显示出团队对技术演进的前瞻性。
详细步骤解析
修改字体成添加朋友那个字体一样,否则看上去不协调说
查看添加朋友页面的布局文件,找到标题栏中“添加朋友”文字的字体大小设置。
toolName: search_codebase
status: success
query: 添加朋友页面 标题 字体大小
查看添加朋友页面的完整布局文件,找到标题栏中“添加朋友”文字的字体大小设置。
toolName: view_files
status: success
filePath: g:\clone\2025qingting—android\skWeiChatBaidu\src\main\res\layout\activity_add_friend.xml
查看通用标题栏布局文件 a_view_actionbar.xml,因为添加朋友页面的标题栏是通过 include 引入的,其中包含了”添加朋友”文字。
toolName: view_files
status: success
filePath: g:\clone\2025qingting—android\skWeiChatBaidu\src\main\res\layout\a_view_actionbar.xml
查看dimens.xml文件,找到标题居中文字的尺寸定义title_center_text_size,这就是”添加朋友”的字体大小。
toolName: search_codebase
status: success
query: title_center_text_size dimens.xml
添加朋友页面中”添加朋友”四个字的字体大小是 18sp。
通过查看代码文件可知:
  • 在 activity_add_friend.xml 中,页面标题栏是通过 include 引入 a_view_actionbar.xml 实现的。
  • 在 a_view_actionbar.xml 中,标题居中的 TextView (id=”tv_title_center”) 设置了字体大小为 @dimen/title_center_text_size。
  • 在 dimens.xml 文件中,title_center_text_size 的具体定义为 18sp。
查看添加朋友页面和我的页面的布局文件,找到需要修改字体大小的文本视图。
toolName: view_files
status: success
filePath: g:\clone\2025qingting—android\skWeiChatBaidu\src\main\res\layout\activity_add_friend.xml
g:\clone\2025qingting—android\skWeiChatBaidu\src\main\res\layout\fragment_me.xml
查看styles.xml文件,了解IMTbleLine_TextName样式的当前字体大小定义。
toolName: view_files
status: success
filePath: g:\clone\2025qingting—android\skWeiChatBaidu\src\main\res\values\styles.xml
查看dimens.xml文件,了解sp_15_text_size和用户提到的pop_window的定义。
toolName: view_files
status: success
filePath: g:\clone\2025qingting—android\skWeiChatBaidu\src\main\res\values\dimens.xml
修改activity_add_friend.xml文件,将”扫一扫”、”手机通讯录”、”邀请手机联系人”的字体大小从15sp改为18sp。
toolName: edit_file_update
status: success
filePath: g:\clone\2025qingting—android\skWeiChatBaidu\src\main\res\layout\activity_add_friend.xml
changes:
newStr: <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center_vertical" android:text="@string/scanning" android:textColor="@color/color_33" android:textSize="18sp" />
oldStr: <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center_vertical" android:text="@string/scanning" android:textColor="@color/color_33" android:textSize="15sp" />
newStr: <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center_vertical" android:text="@string/hint542" android:textColor="@color/color_33" android:textSize="18sp" />
oldStr: <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center_vertical" android:text="@string/hint542" android:textColor="@color/color_33" android:textSize="15sp" />
newStr: <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center_vertical" android:text="@string/hint543" android:textColor="@color/color_33" android:textSize="18sp" />
oldStr: <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center_vertical" android:text="@string/hint543" android:textColor="@color/color_33" android:textSize="15sp" />
修改fragment_me.xml文件,为”我的收藏”、”隐私管理”、”安全中心”、”深色模式”的TextView添加android:textSize=”18sp”属性。
toolName: edit_file_update
status: success
filePath: g:\clone\2025qingting—android\skWeiChatBaidu\src\main\res\layout\fragment_me.xml
changes:
newStr: <TextView style="@style/IMTbleLine_TextName" android:layout_centerVertical="true" android:layout_marginLeft="17dp" android:layout_weight="1" android:gravity="center_vertical" android:text="@string/my_collection" android:textSize="18sp" />
oldStr: <TextView style="@style/IMTbleLine_TextName" android:layout_centerVertical="true" android:layout_marginLeft="17dp" android:layout_weight="1" android:gravity="center_vertical" android:text="@string/my_collection" />
newStr: <TextView android:id="@+id/privacySetting_text" style="@style/IMTbleLine_TextName" android:layout_centerVertical="true" android:layout_marginLeft="20dp" android:layout_weight="1" android:gravity="center_vertical" android:text="@string/private_settings" android:textSize="18sp" />
oldStr: <TextView android:id="@+id/privacySetting_text" style="@style/IMTbleLine_TextName" android:layout_centerVertical="true" android:layout_marginLeft="20dp" android:layout_weight="1" android:gravity="center_vertical" android:text="@string/private_settings" />
newStr: <TextView style="@style/IMTbleLine_TextName" android:layout_centerVertical="true" android:layout_marginLeft="20dp" android:layout_weight="1" android:gravity="center_vertical" android:text="@string/secure_settings" android:textSize="18sp" />
oldStr: <TextView style="@style/IMTbleLine_TextName" android:layout_centerVertical="true" android:layout_marginLeft="20dp" android:layout_weight="1" android:gravity="center_vertical" android:text="@string/secure_settings" />
newStr: <TextView android:id="@+id/TuiGuangTv" style="@style/IMTbleLine_TextName" android:layout_centerVertical="true" android:layout_marginLeft="20dp" android:layout_weight="1" android:gravity="center_vertical" android:text="@string/shense_moshi" android:textSize="18sp" />
oldStr: <TextView android:id="@+id/TuiGuangTv" style="@style/IMTbleLine_TextName" android:layout_centerVertical="true" android:layout_marginLeft="20dp" android:layout_weight="1" android:gravity="center_vertical" android:text="@string/shense_moshi" />
已成功修改所有指定文本的字体大小为18sp。具体修改如下:
  • 在添加朋友页面(activity_add_friend.xml)中:
    • “扫一扫”文本的字体大小从15sp改为18sp
    • “手机通讯录”文本的字体大小从15sp改为18sp
    • “邀请手机联系人”文本的字体大小从15sp改为18sp
  • 在我的页面(fragment_me.xml)中:
    • 为”我的收藏”文本添加了android:textSize=”18sp”
    • 为”隐私管理”文本添加了android:textSize=”18sp”
    • 为”安全中心”文本添加了android:textSize=”18sp”
    • 为”深色模式”文本添加了android:textSize=”18sp”

所有文本现在都使用18sp的字体大小,与页面标题字体大小保持协调一致。
基本上 这两个 问题 是一样的 都是改这行代码即可
然后现在来观察 复现重影bug
这个是个比较麻烦的问题。
我需要先了解项目的底部导航结构和相关代码,以查找导致重影bug的原因。
toolName: search_codebase
status: success
query: 底部导航 菜单 Fragment切换
我发现MainActivity.java中有changeFragment方法,这可能与底部导航菜单切换有关。让我继续查看该文件的完整内容,特别是与底部导航和Fragment切换相关的部分。
toolName: view_files
status: success
filePath: g:\clone\2025qingting—android\skWeiChatBaidu\src\main\java\com\guantaoyunxin\app\ui\MainActivity.java
我需要查看MainActivity.java中与底部导航和Fragment切换相关的更多代码,特别是初始化视图和处理导航点击事件的部分。
toolName: view_files
status: success
filePath: g:\clone\2025qingting—android\skWeiChatBaidu\src\main\java\com\guantaoyunxin\app\ui\MainActivity.java
我需要查看MainActivity.java中初始化底部导航栏和处理Fragment切换的完整代码,特别是initView方法和mRadioGroup的初始化部分。
toolName: view_files
status: success
filePath: g:\clone\2025qingting—android\skWeiChatBaidu\src\main\java\com\guantaoyunxin\app\ui\MainActivity.java
我需要查看MainActivity.java中的initView方法,因为这应该包含了底部导航栏的初始化代码,这可能与重影bug有关。
toolName: view_files
status: success
filePath: g:\clone\2025qingting—android\skWeiChatBaidu\src\main\res\layout\activity_main.xml
我需要查看底部导航栏的具体布局文件layout_main_footbar.xml,以了解导航栏的结构。
toolName: view_files
status: success
filePath: g:\clone\2025qingting—android\skWeiChatBaidu\src\main\res\layout\layout_main_footbar.xml
我需要查看MainActivity.java的更多内容,特别是initView方法和底部导航栏的初始化代码,这与重影bug可能相关。
toolName: view_files
status: success
filePath: g:\clone\2025qingting—android\skWeiChatBaidu\src\main\java\com\sky\weichat\MainActivity.java
文件路径不正确,我需要搜索项目中的MainActivity文件来找到正确的路径。
toolName: search_codebase
status: success
query: MainActivity
我找到了正确的MainActivity.java路径,现在需要查看initView方法和changeFragment方法,以分析底部导航菜单切换的逻辑。
toolName: view_files
status: success
filePath: g:\clone\2025qingting—android\skWeiChatBaidu\src\main\java\com\guantaoyunxin\app\ui\MainActivity.java
我需要查看几个主要Fragment的代码,特别是MessageFragment、NewFriendFragment和MeFragment的onCreateView方法,以了解它们是如何处理视图初始化和标题栏的,这与重影bug相关。
toolName: search_codebase
status: success
query: MessageFragment onCreateView
我需要查看Fragment中initActionBar方法的实现,这可能与标题栏重影问题相关。
toolName: search_codebase
status: success
query: initActionBar
我需要查看几个主要Fragment的布局文件,特别是它们是如何包含标题栏的,这可能与标题栏重影问题相关。让我先查看MessageFragment的布局文件。
toolName: search_codebase
status: success
query: fragment_message layout
现在我了解到每个Fragment都包含自己的标题栏布局,这很可能是导致重影问题的原因。让我查看EasyFragment中的视图缓存实现,因为它可能与Fragment切换时的视图管理相关。
toolName: search_codebase
status: success
query: EasyFragment cacheView
基于我对代码的分析,我找到了可能导致重影问题的原因。每个Fragment都包含自己的标题栏布局,并且EasyFragment实现了视图缓存机制。现在我需要查看MainActivity中完整的changeFragment方法实现,这是解决问题的关键。
toolName: view_files
status: success
filePath: g:\clone\2025qingting—android\skWeiChatBaidu\src\main\java\com\guantaoyunxin\app\ui\MainActivity.java
通过分析代码,我已经发现了导致重影bug的原因。每个Fragment都包含自己的标题栏布局,当使用hide/show机制切换Fragment时,所有Fragment的视图都保存在内存中,这导致了标题栏重叠。让我查看完整的activity_main.xml文件,看看Activity是否有统一的标题栏布局。
toolName: view_files
status: success
filePath: g:\clone\2025qingting—android\skWeiChatBaidu\src\main\res\layout\activity_main.xml
现在我已经找到了导致重影bug的根本原因。activity_main.xml非常简单,只包含一个用于显示Fragment的FrameLayout和底部导航栏。而每个Fragment都包含自己的标题栏布局,当使用hide/show机制切换Fragment时,所有Fragment的视图都保存在内存中,这导致了标题栏重叠。让我修改MainActivity的changeFragment方法来解决这个问题。
toolName: edit_file_update
status: success
filePath: g:\clone\2025qingting—android\skWeiChatBaidu\src\main\java\com\guantaoyunxin\app\ui\MainActivity.java
changes:
newStr: /**
* 切换Fragment */private void changeFragment(int checkedId) {    if (mLastFragmentId == checkedId) {        return;    }    // 特殊处理:点击发现按钮直接跳转到心情广场页面    if (checkedId == R.id.rb_tab_3) {        startActivity(new Intent(this, com.guantaoyunxin.app.ui.life.LifeCircleActivity.class));        // 取消选中状态,否则再次点击时不会触发事件        mRadioGroup.clearCheck();        mLastFragmentId = -1;        return;    }    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();    Fragment fragment = getSupportFragmentManager().findFragmentByTag(String.valueOf(checkedId));    if (fragment == null) {        switch (checkedId) {            case R.id.rb_tab_1:                fragment = new MessageFragment();                break;            case R.id.rb_tab_2:                fragment = new NewFriendFragment();                break;            case R.id.rb_tab_3:                fragment = new FaXianFragment();                break;            case R.id.rb_tab_4:                fragment = new MeFragment();                break;            case R.id.rb_tab_5:                fragment = new H5Fragment();                break;        }    }    assert fragment != null;    // 先隐藏所有已添加的Fragment,解决标题栏重影问题    List<Fragment> fragments = getSupportFragmentManager().getFragments();    for (Fragment f : fragments) {        if (f != null && !f.isHidden()) {            transaction.hide(f);        }    }    if (!fragment.isAdded()) {        // 未添加则添加        transaction.add(R.id.main_content, fragment, String.valueOf(checkedId));    } else {        // 已添加则显示        transaction.show(fragment);    }    transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); // 添加动画    transaction.commitNowAllowingStateLoss();    mLastFragmentId = checkedId;}
oldStr: /**
* 切换Fragment */private void changeFragment(int checkedId) {    if (mLastFragmentId == checkedId) {        return;    }    // 特殊处理:点击发现按钮直接跳转到心情广场页面    if (checkedId == R.id.rb_tab_3) {        startActivity(new Intent(this, com.guantaoyunxin.app.ui.life.LifeCircleActivity.class));        // 取消选中状态,否则再次点击时不会触发事件        mRadioGroup.clearCheck();        mLastFragmentId = -1;        return;    }    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();    Fragment fragment = getSupportFragmentManager().findFragmentByTag(String.valueOf(checkedId));    if (fragment == null) {        switch (checkedId) {            case R.id.rb_tab_1:                fragment = new MessageFragment();                break;            case R.id.rb_tab_2:                fragment = new NewFriendFragment();
// NewFriendFragment friendFragment = (NewFriendFragment) fragment.getChildFragmentManager().getFragments();
// friendFragment.setFirst(); //调用子Fragment UsingFragment中的initData2()
break;
case R.id.rb_tab_3:
fragment = new FaXianFragment();
break;
case R.id.rb_tab_4:
fragment = new MeFragment();
break;
case R.id.rb_tab_5:
fragment = new H5Fragment();
break;
}
}
    // fragment = null;    assert fragment != null;    if (!fragment.isAdded()) {// 未添加 add        transaction.add(R.id.main_content, fragment, String.valueOf(checkedId));    }    Fragment lastFragment = getSupportFragmentManager().findFragmentByTag(String.valueOf(mLastFragmentId));    if (lastFragment != null) {        transaction.hide(lastFragment);    }    // 以防万一出现last和current都是同一个fragment的情况,先hide再show,    transaction.show(fragment);
// if (checkedId == R.id.rb_tab_1) {
// MessageFragment messageFragment = (MessageFragment) fragment;
// messageFragment.setFirst();
// } else if (checkedId == R.id.rb_tab_2) {
// NewFriendFragment newFriendFragment = (NewFriendFragment) fragment;
// newFriendFragment.setFirst();
// }
    transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);// 添加动画    transaction.commitNowAllowingStateLoss();    mLastFragmentId = checkedId;}
我已经修改了changeFragment方法,使其在切换Fragment时隐藏所有当前显示的Fragment,而不仅仅是上一个Fragment。但我还需要解决第一次点击不能正常跳转的问题。让我再查看一下MainActivity中Fragment初始化的相关代码。
toolName: view_files
status: success
filePath: g:\clone\2025qingting—android\skWeiChatBaidu\src\main\java\com\guantaoyunxin\app\ui\MainActivity.java
我已经看到修改后的changeFragment方法,但我还需要查看initView方法中Fragment初始化的相关代码,以解决第一次点击不能正常跳转的问题。
toolName: view_files
status: success
filePath: g:\clone\2025qingting—android\skWeiChatBaidu\src\main\java\com\guantaoyunxin\app\ui\MainActivity.java
我需要找到initView方法的实现代码,这可能与Fragment初始化和第一次点击不能正常跳转的问题有关。让我再查看MainActivity中的其他部分。
toolName: view_files
status: success
filePath: g:\clone\2025qingting—android\skWeiChatBaidu\src\main\java\com\guantaoyunxin\app\ui\MainActivity.java
我需要继续查找MainActivity中的initView方法实现,这可能与第一次点击不能正常跳转的问题有关。让我查看文件的其他部分。
toolName: view_files
status: success
filePath: g:\clone\2025qingting—android\skWeiChatBaidu\src\main\java\com\guantaoyunxin\app\ui\MainActivity.java
我需要继续查找MainActivity中的initView方法实现。让我查看文件的更多部分,特别是可能包含initView方法的区域。
toolName: search_by_regex
status: success
query: private void initView()
我找到了MainActivity.java中的initView方法,位于第682行。现在我需要查看这个方法的具体实现,以了解Fragment初始化和底部导航的逻辑,这对于解决第一次点击不能正常跳转的问题至关重要。
toolName: view_files
status: success
filePath: g:\clone\2025qingting—android\skWeiChatBaidu\src\main\java\com\guantaoyunxin\app\ui\MainActivity.java
我已经找到了MainActivity.java中的initView方法实现,看到了底部导航栏的初始化和Fragment切换逻辑。现在我需要查看changeFragment方法的完整实现,特别是Fragment显示和添加的部分,以解决第一次点击不能正常跳转的问题。
toolName: view_files
status: success
filePath: g:\clone\2025qingting—android\skWeiChatBaidu\src\main\java\com\guantaoyunxin\app\ui\MainActivity.java
现在我已经看到了完整的changeFragment方法实现。通过分析代码,我发现问题可能与Fragment初始化和状态管理有关。让我先查看isCreate变量的定义和使用情况,这可能是导致第一次点击不能正常跳转的关键因素。
toolName: search_by_regex
status: success
query: private boolean isCreate
我找到了isCreate变量的定义。现在我需要查看MainActivity.java中isCreate变量的所有使用情况,以了解它在Fragment初始化和状态管理中的具体作用,这可能是解决第一次点击不能正常跳转问题的关键。
toolName: search_by_regex
status: success
query: isCreate
我找到了isCreate变量的所有使用位置。现在我需要查看这些使用位置的完整上下文,特别是第861行和第882行附近的代码,以更好地理解isCreate在Fragment初始化流程中的作用,这对解决第一次点击不能正常跳转的问题很关键。
toolName: view_files
status: success
filePath: g:\clone\2025qingting—android\skWeiChatBaidu\src\main\java\com\guantaoyunxin\app\ui\MainActivity.java
通过对isCreate变量的分析,我发现问题可能在于Fragment初始化的时序和状态管理。现在我需要修改initView方法,确保Fragment能够正确初始化和显示,解决第一次点击不能正常跳转的问题。
toolName: edit_file_update
status: success
filePath: g:\clone\2025qingting—android\skWeiChatBaidu\src\main\java\com\guantaoyunxin\app\ui\MainActivity.java
changes:
newStr: private void initView() {
// 适配系统导航栏,直接对main_rg这个RadioGroup进行paddingBottom处理
mRadioGroup = (RadioGroup) findViewById(R.id.main_rg);
if (mRadioGroup != null) {
NavigationBarUtils.adaptNavigationBar(this, mRadioGroup);
Log.d(TAG, “直接对main_rg RadioGroup进行导航栏适配,当前API Level: “ + android.os.Build.VERSION.SDK_INT);
} else {
Log.w(TAG, “未找到main_rg RadioGroup,无法进行导航栏适配”);
}
    getSupportActionBar().hide();    mRbTab1 = (RadioButton) findViewById(R.id.rb_tab_1);    mRbTab2 = (RadioButton) findViewById(R.id.rb_tab_2);    mRbTab3 = (RadioButton) findViewById(R.id.rb_tab_3);    mRbTab4 = (RadioButton) findViewById(R.id.rb_tab_4);    mTvMessageNum = (TextView) findViewById(R.id.main_tab_one_tv);    mTvNewFriendNum = (TextView) findViewById(R.id.main_tab_two_tv);    Friend newFriend = FriendDao.getInstance().getFriend(coreManager.getSelf().getUserId(), Friend.ID_NEW_FRIEND_MESSAGE);    if (newFriend != null) {        updateNewFriendMsgNum(newFriend.getUnReadNum());    } else {        updateNewFriendMsgNum(0);    }    mTvCircleNum = (TextView) findViewById(R.id.main_tab_three_tv);    mTvCircleNum2 = (TextView) findViewById(R.id.main_tab_three_tv2);    mRadioGroup.setOnCheckedChangeListener((group, checkedId) -> {        hideInput();        if (checkedId > 0 && mCurrtTabId != checkedId) {            mCurrtTabId = checkedId;            changeFragment(checkedId);            if (checkedId == R.id.rb_tab_1) {                updateNumData();            }            JCVideoPlayer.releaseAllVideos();        }    });    isCreate = false;    // 直接调用changeFragment方法初始化第一个Fragment,避免toggle触发的问题    changeFragment(R.id.rb_tab_1);    // 设置默认选中状态    mRbTab1.setChecked(true);    mCurrtTabId = R.id.rb_tab_1;
oldStr: private void initView() {
// 适配系统导航栏,直接对main_rg这个RadioGroup进行paddingBottom处理
mRadioGroup = (RadioGroup) findViewById(R.id.main_rg);
if (mRadioGroup != null) {
NavigationBarUtils.adaptNavigationBar(this, mRadioGroup);
Log.d(TAG, “直接对main_rg RadioGroup进行导航栏适配,当前API Level: “ + android.os.Build.VERSION.SDK_INT);
} else {
Log.w(TAG, “未找到main_rg RadioGroup,无法进行导航栏适配”);
}
    getSupportActionBar().hide();    mRbTab1 = (RadioButton) findViewById(R.id.rb_tab_1);    mRbTab2 = (RadioButton) findViewById(R.id.rb_tab_2);    mRbTab3 = (RadioButton) findViewById(R.id.rb_tab_3);    mRbTab4 = (RadioButton) findViewById(R.id.rb_tab_4);    mTvMessageNum = (TextView) findViewById(R.id.main_tab_one_tv);    mTvNewFriendNum = (TextView) findViewById(R.id.main_tab_two_tv);    Friend newFriend = FriendDao.getInstance().getFriend(coreManager.getSelf().getUserId(), Friend.ID_NEW_FRIEND_MESSAGE);    if (newFriend != null) {        updateNewFriendMsgNum(newFriend.getUnReadNum());    } else {        updateNewFriendMsgNum(0);    }    mTvCircleNum = (TextView) findViewById(R.id.main_tab_three_tv);    mTvCircleNum2 = (TextView) findViewById(R.id.main_tab_three_tv2);    mRadioGroup.setOnCheckedChangeListener((group, checkedId) -> {        hideInput();        if (checkedId > 0 && mCurrtTabId != checkedId) {            mCurrtTabId = checkedId;            changeFragment(checkedId);            if (checkedId == R.id.rb_tab_1) {                updateNumData();            }            JCVideoPlayer.releaseAllVideos();        }    });    isCreate = false;    //  修改白屏bug    mRbTab1.toggle();    // initFragment();
我已经解决了您报告的重影bug和第一次点击不能正常跳转的问题。
修复内容如下:
  • 标题栏重影问题:
    • 修改了MainActivity.java中的changeFragment方法
    • 实现了先隐藏所有已添加Fragment的逻辑,确保在显示新Fragment前没有其他Fragment可见
    • 通过遍历getSupportFragmentManager().getFragments()并对非隐藏状态的Fragment执行hide操作
  • 第一次点击不能正常跳转问题:
    • 修改了MainActivity.java中的initView方法
    • 移除了原来使用mRbTab1.toggle()触发Fragment切换的方式
    • 改为直接调用changeFragment(R.id.rb_tab_1)方法初始化第一个Fragment
    • 显式设置mRbTab1.setChecked(true)和mCurrtTabId = R.id.rb_tab_1确保状态正确

这些修改确保了Fragment切换时的状态一致性,解决了标题栏重影问题,同时修复了第一次点击不能正常跳转的问题。现在底部导航栏的切换应该能够正常工作,不会出现页面跳转延迟或标题栏重影的情况。
经过测试已经ok,现在剩下最后一版图标就是聊天框中的图标了
我需要查找聊天界面中点击+按钮后出现的功能图标文件信息。首先搜索与聊天界面相关的代码,特别是包含更多功能按钮的部分。
toolName: search_codebase
status: success
query: 聊天界面 更多按钮 语音电话 视频通话 转账 相册 拍摄 名片 收藏 联系人
从搜索结果中发现ChatBottomView.java和ChatToolsView.java可能包含更多按钮及相关功能的实现。我需要查看这些文件,特别是ChatToolsView.java,以找到包含语音电话、视频通话、转账等功能图标的实现代码。
toolName: search_by_regex
status: success
query: ChatToolsView
我需要查看ChatToolsView.java的完整实现,特别是init方法,因为从ChatBottomView中可以看到ChatToolsView通过init方法初始化,并传入了监听器和相关参数,这应该包含了所有功能按钮的实现。
toolName: view_files
status: success
filePath: g:\clone\2025qingting—android\skWeiChatBaidu\src\main\java\com\guantaoyunxin\app\view\ChatToolsView.java
我已经看到ChatToolsView.java中定义了loadData()方法,其中包含了语音电话按钮的图标定义(R.mipmap.icon_yuyin_dianhua)。我需要继续查看文件的其余部分,找到其他功能按钮(视频通话、转账、相册、拍摄、名片、收藏、联系人)的图标定义。
toolName: view_files
status: success
filePath: g:\clone\2025qingting—android\skWeiChatBaidu\src\main\java\com\guantaoyunxin\app\view\ChatToolsView.java
在聊天界面点击+更多按钮后显示的功能图标信息如下:
功能
图标文件名
文件类型
对应功能方法

语音电话
R.mipmap.icon_yuyin_dianhua
mipmap资源
listener.clickAudio()

视频通话
R.drawable.im_tool_audio_button_bg_new
drawable资源
listener.clickVideoChat()

转账
R.drawable.im_tool_transfer_button_bg_new
drawable资源
listener.clickTransferMoney()

相册
R.mipmap.im_tool_photo_button_bg_new
mipmap资源
listener.clickPhoto()

拍摄
R.drawable.im_tool_camera_button_bg_new
drawable资源
listener.clickCamera()

名片
R.drawable.im_tool_card_button_bg_new
drawable资源
listener.clickCard()

收藏
R.drawable.im_tool_collection_new
drawable资源
listener.clickCollection()

联系人
R.drawable.im_tool_contacts_button_bg_new
drawable资源
listener.clickContact()

这些图标文件位于Android项目的res目录下,其中:
  • mipmap类型图标文件位于res/mipmap目录
  • drawable类型图标文件位于res/drawable目录
所有功能按钮在ChatToolsView.java的loadData()方法中通过Item对象统一管理,并在点击时调用相应的监听器方法执行具体操作。
我需要查看项目资源文件目录结构,特别是res/mipmap和res/drawable目录,以获取聊天界面更多功能按钮图标的具体路径。
toolName: view_folder
status: success
g:\clone\2025qingting—android\skWeiChatBaidu\src\main\res
我需要查看mipmap目录下的具体文件,以获取聊天界面更多功能按钮中mipmap类型图标的具体文件路径。
toolName: view_folder
status: success
g:\clone\2025qingting—android\skWeiChatBaidu\src\main\res\mipmap-xhdpi
我需要查看drawable目录下的具体文件,以获取聊天界面更多功能按钮中drawable类型图标的具体文件路径。
toolName: view_folder
status: success
g:\clone\2025qingting—android\skWeiChatBaidu\src\main\res\drawable
已为您找到聊天界面更多功能按钮图标的具体文件路径:
  • 语音电话:R.mipmap.icon_yuyin_dianhua - 文件路径为 g:\clone\2025qingting--android\skWeiChatBaidu\src\main\res\mipmap-xhdpi\icon_yuyin_dianhua.png
  • 视频通话:R.drawable.im_tool_audio_button_bg_new - 在drawable目录下有相关imtool*文件,但未找到完全匹配的文件名
  • 转账:R.drawable.im_tool_transfer_button_bg_new - 在drawable目录下有相关imtool*文件,但未找到完全匹配的文件名
  • 相册:R.mipmap.im_tool_photo_button_bg_new - 文件路径为 g:\clone\2025qingting--android\skWeiChatBaidu\src\main\res\mipmap-xhdpi\im_tool_photo_button_bg_new.png
  • 拍摄:R.drawable.im_tool_camera_button_bg_new - 在drawable目录下有相关imtool*文件,但未找到完全匹配的文件名
  • 名片:R.drawable.im_tool_card_button_bg_new - 在drawable目录下有相关imtool*文件,但未找到完全匹配的文件名
  • 收藏:R.drawable.im_tool_collection_new - 在drawable目录下有相关imtool*文件,但未找到完全匹配的文件名
  • 联系人:R.drawable.im_tool_contacts_button_bg_new - 在drawable目录下有相关imtool*文件,但未找到完全匹配的文件名
注意:
  • mipmap类型的图标文件已在mipmap-xhdpi目录中找到对应.png文件
  • drawable类型的图标可能位于其他分辨率的drawable目录(如drawable-xhdpi、drawable-xxhdpi等)或通过XML文件定义
  • 在drawable目录下找到了一些相关的imtool*背景文件,如im_tool_local_button_bg.xml、im_tool_photo_button_bg.xml等
按照我们之前的方法这个很好搞定,
感觉这个就是 之前的代码 写的 技术债务太多了,他们居然没有放在一起
我需要查看drawable-xhdpi目录,因为这是Android项目中常用的图标存放目录,可能包含聊天界面更多功能按钮的其他图标文件。
toolName: view_folder
status: success
g:\clone\2025qingting—android\skWeiChatBaidu\src\main\res\drawable-xhdpi
已为您找到聊天界面更多功能按钮的所有图标文件路径:
  • 语音电话:
    • 资源ID:R.mipmap.icon_yuyin_dianhua
    • 文件路径:g:\clone\2025qingting--android\skWeiChatBaidu\src\main\res\mipmap-xhdpi\icon_yuyin_dianhua.png
  • 视频通话:
    • 资源ID:R.drawable.im_tool_audio_button_bg_new
    • 文件路径:g:\clone\2025qingting--android\skWeiChatBaidu\src\main\res\drawable-xhdpi\im_tool_audio_button_bg_new.png
  • 转账:
    • 资源ID:R.drawable.im_tool_transfer_button_bg_new
    • 文件路径:g:\clone\2025qingting--android\skWeiChatBaidu\src\main\res\drawable-xhdpi\im_tool_transfer_button_bg_new.png
  • 相册:
    • 资源ID:R.mipmap.im_tool_photo_button_bg_new
    • 文件路径:g:\clone\2025qingting--android\skWeiChatBaidu\src\main\res\mipmap-xhdpi\im_tool_photo_button_bg_new.png
  • 拍摄:
    • 资源ID:R.drawable.im_tool_camera_button_bg_new
    • 文件路径:g:\clone\2025qingting--android\skWeiChatBaidu\src\main\res\drawable-xhdpi\im_tool_camera_button_bg_new.png
  • 名片:
    • 资源ID:R.drawable.im_tool_card_button_bg_new
    • 文件路径:g:\clone\2025qingting--android\skWeiChatBaidu\src\main\res\drawable-xhdpi\im_tool_card_button_bg_new.png
  • 收藏:
    • 资源ID:R.drawable.im_tool_collection_new
    • 文件路径:g:\clone\2025qingting--android\skWeiChatBaidu\src\main\res\drawable-xhdpi\im_tool_collection_new.png
  • 联系人:
    • 资源ID:R.drawable.im_tool_contacts_button_bg_new
    • 文件路径:g:\clone\2025qingting--android\skWeiChatBaidu\src\main\res\drawable-xhdpi\im_tool_contacts_button_bg_new.png

这些图标文件在项目中分别存放在res/mipmap-xhdpi和res/drawable-xhdpi目录下,其中语音电话和相册图标使用mipmap类型,其余图标使用drawable类型。
ok 这里我们替换图片就不用讲了 不过可以额外补个知识,可以检索这篇知识
接下来重磅步骤,打包apk,打包apk分release 包和 debug包,由于我们的包是要正式上架的所以打包是release包
在Android Studio中使用JKS文件打包正式release包的具体步骤如下:
1. 配置签名信息在模块级build.gradle中添加签名配置:android {    signingConfigs {        release {            storeFile file('path/to/your/keystore.jks')  // JKS文件路径            storePassword 'your_store_password'          // 密钥库密码            keyAlias 'your_key_alias'                    // 密钥别名            keyPassword 'your_key_password'              // 密钥密码        }    }    buildTypes {        release {            signingConfig signingConfigs.release            minifyEnabled true            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'        }    }}2. 在Android Studio中生成Signed APK方法一:通过菜单生成
  • 点击菜单栏 Build → Generate Signed Bundle / APK...
  • 选择 APK,点击 Next
  • 选择 Use existing,点击 Choose existing... 选择您的JKS文件
  • 输入密钥库密码和密钥密码
  • 选择 release 构建类型
  • 选择目标文件夹和构建变体
  • 点击 Finish 开始构建
方法二:直接构建
  • 在右上角构建变体选择器中选择 release 构建类型
  • 点击 Build → Build Bundle(s) / APK(s) → Build APK(s)
3. 查找生成的APK
构建完成后,APK文件通常位于:
app/build/outputs/apk/release/app-release.apk4. 安全建议使用gradle.properties存储敏感信息:
在项目根目录的 gradle.properties 文件中添加:
MYAPP_RELEASE_STORE_FILE=your_keystore.jksMYAPP_RELEASE_STORE_PASSWORD=your_store_passwordMYAPP_RELEASE_KEY_ALIAS=your_key_aliasMYAPP_RELEASE_KEY_PASSWORD=your_key_password
然后在build.gradle中引用:
signingConfigs {    release {        storeFile file(MYAPP_RELEASE_STORE_FILE)        storePassword MYAPP_RELEASE_STORE_PASSWORD        keyAlias MYAPP_RELEASE_KEY_ALIAS        keyPassword MYAPP_RELEASE_KEY_PASSWORD    }}5. 验证签名
使用以下命令验证APK签名:
jarsigner -verify -verbose -certs your-app.apk
我们采用第2个模式的方法1,打包方式有很多种
点击后gradle会开始构建打包 ,但是我们有签名文件 构建正式包因此不选这个
选择apk
然后选择本地的证书信息
选择release 包
成功打包完成,不过我发现,忘记改版本号了,打包一定要改版本号

优雅草论坛2022年8月11日大改,优雅草论坛变回只服务于客户的提问交流论坛,详情查看优雅草8月11日大改,原因详情查优雅草外卖乐关闭

回复

举报 使用道具

全部回复
暂无回帖,快来参与回复吧
yac2025
优雅草的临时工
主题 335
回复 0
粉丝 0