【HarmonyOS开发】案例-记账本开发

图片

OpenHarmony最近一段时间,简直火的一塌糊度,学习OpenHarmony相关的技术栈也有一段时间了,做个记账本小应用,将所学知识点融合记录一下。

1、记账本涉及知识点

  •     基础组件(Button、Select、Text、Span、Divider、Image)、容器(Row、Flex、List、Grid、Column)、定位(position)、路由(router)、Toast(promptAction)、Web组件;
  •     自定义弹窗(@CustomDialog);
  •     分布式键值数据库(@ohos.data.distributedKVStore);
  •     Web组件;
  •     OpenHarmony三方库;

2、效果预览

图片

  

图片

图片

  

图片

3、功能点实现简介

3.1 自定义弹窗


// 自定义弹窗定义
@CustomDialog
struct CustomDialogSetting {// 双向绑定传值@Link settingBudgetValue: string// 弹窗控制器,控制打开/关闭,必须传入,且名称必须为:controllercontroller: CustomDialogController// 弹窗中的按钮事件cancel: () => voidconfirm: () => void// 弹窗中的内容描述build() {Column() {Text($r('app.string.budget_setting')).fontSize(18).fontWeight(FontWeight.Bold).margin(12).textAlign(TextAlign.Center).width("100%")TextInput({placeholder: $r('app.string.estimated_amount_tips'),text: this.settingBudgetValue}).type(InputType.Number).height(60).width('90%').onChange((value: string) => {this.settingBudgetValue = value})Flex({ justifyContent: FlexAlign.SpaceAround }) {Button($r('app.string.cancel')).onClick(() => {this.settingBudgetValue = ''this.controller.close()this.cancel()}).backgroundColor(0xffffff).fontColor(Color.Black)Button($r('app.string.confirm')).onClick(() => {this.controller.close()this.confirm()}).backgroundColor(0xffffff).fontColor(AccountBookConstant.FONT_COLOR_BLUE)}.margin(15)}}
}
// 使用自定义弹窗
dialogController: CustomDialogController = new CustomDialogController({builder: CustomDialogSetting({cancel: this.onCancel.bind(this),confirm: this.onAccept.bind(this),settingBudgetValue: $settingBudgetValue}),cancel: this.onCancel,autoCancel: true,alignment: DialogAlignment.Center,gridCount: 4,customStyle: false
})// 开启弹窗
this.dialogController.open()

3.2 悬浮按钮

// 设置按钮, 通过position进行绝对定位
Button({  stateEffect: true }){Image($rawfile('setting.svg')).width(22).height(22)
}.width(42).height(42)
.borderRadius(90)
.shadow({ radius: 10, color: Color.Gray, offsetX: 5, offsetY:5 })
.position({ x: '98%', y: '98%' })
.markAnchor({ x: '98%', y: '98%'})
.margin(10).backgroundColor('#67C23A')
.onClick(() => {if (this.dialogController != undefined) {this.dialogController.open()}
})

3.3  数据存储

// 定义键值对存储类import distributedKVStore from '@ohos.data.distributedKVStore';const BUNDLE_NAME = "baseInfo"let context = getContext(this)
// 数据库对象
let kvManager: distributedKVStore.KVManager | undefined = undefined;
// KVStore数据库
let kvStore: distributedKVStore.SingleKVStore | undefined = undefined;class DistributedUtil {constructor() {this.createKeyValueDB();}async getKvManager(bundleName?: string) {const kvStoreConfig: distributedKVStore.KVManagerConfig = {context: context,bundleName: bundleName || BUNDLE_NAME};try {kvManager = distributedKVStore.createKVManager(kvStoreConfig);}catch (err) {console.error(`error:${err}`)}}// 创建并得到指定类型的KVStore数据库async createKeyValueDB(op?: distributedKVStore.Options) {if (!kvManager) {await this.getKvManager();}try {const options: distributedKVStore.Options = {// 当数据库文件不存在时是否创建数据库,默认为truecreateIfMissing: true,// 设置数据库文件是否加密,默认为false,即不加密encrypt: false,// 设置数据库文件是否备份,默认为true,即备份backup: false,// 设置数据库文件是否自动同步。默认为false,即手动同步autoSync: true,// kvStoreType不填时,默认创建多设备协同数据库kvStoreType: distributedKVStore.KVStoreType.SINGLE_VERSION,// 多设备协同数据库:kvStoreType: distributedKVStore.KVStoreType.DEVICE_COLLABORATION,securityLevel: distributedKVStore.SecurityLevel.S1};kvManager.getKVStore<distributedKVStore.SingleKVStore>('storeId', op || options, (err, store: distributedKVStore.SingleKVStore) => {if (err) {console.error(`Failed to get KVStore: Code:${err.code},message:${err.message}`);return;}console.info('Succeeded in getting KVStore.');kvStore = store;});} catch (e) {console.error(`An unexpected error occurred. Code:${e.code},message:${e.message}`);}return kvStore;}// 删除指定键值的数据async deleteStoreData(key: string) {if (!kvStore) {return;}try {kvStore.delete(key, (err) => {if (err !== undefined) {console.error(`Failed to delete data. Code:${err.code},message:${err.message}`);return;}console.info('Succeeded in deleting data.');});} catch (e) {console.error(`An unexpected error occurred. Code:${e.code},message:${e.message}`);}}// 向键值数据库中插入数据async putStoreData(key: string, value: any) {if (!key || !value) {return}if(!kvStore) {kvStore = await this.createKeyValueDB();}try {kvStore.put(key, value, (err) => {if (err !== undefined) {console.error(`Failed to put data. Code:${err.code},message:${err.message}`);return;}console.info('Succeeded in putting data.');});} catch (e) {console.error(`putStoreData===>An unexpected error occurred. Code:${e.code},message:${e.message}`);}}// 获取指定键的值async getStoreData(key: string) {if (!key) {return}if(!kvStore) {kvStore = await this.createKeyValueDB();}return new Promise((resolve, reject) => {try {kvStore.get(key, (err, data) => {if (err != undefined) {console.error(`Failed to get data. Code:${err.code},message:${err.message}`);reject(err)return;}resolve(data)});} catch (err) {reject(err)console.error('TAG-getStoreData', `Failed to get value, Cause: ${err}`)}});}
}export default new DistributedUtil();
// 使用键值对存储
import distributedUtil from '../../common/distributedStrong'
// 1、增加
distributedUtil.putStoreData('amountRecords', JSON.stringify(dataArray))
// 2、 获取
distributedUtil.getStoreData('amountRecords').then((res: string) => {if(res) {const result = JSON.parse(res)// 处理存储的图片资源,会自动转换为id的形式,无法直接获取展示result.map(item => {item.icon = $rawfile(item.icon.params[0])return item})this.recordsArray = result}
})

3.4 统计图表

3.4.1 定义本地html文件

在resources下创建rawfile文件夹,增加chart.html文件

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>柱状图示例</title><script src="./js/echarts5.4.0.js"></script>
</head>
<body>
<h1>本月支出</h1>
<div id="chartBarContainer" style="width: 400px; height: 300px;"></div><div id="chartPieContainer" style="width: 400px; height: 300px;"></div></body>
<script>function initBarChart(chartData) {const data = JSON.parse(chartData);var chartContainer = document.getElementById('chartBarContainer');var chart = echarts.init(chartContainer);var option = {tooltip: {trigger: 'axis',axisPointer: {type: 'shadow'}},xAxis: {type: 'category',data: data.xAxisData},yAxis: {type: 'value'},series: [{data: data.seriesData,type: 'bar',showBackground: true,stack: 'Total',label: {show: true,position: 'top'},emphasis: {itemStyle: {color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ offset: 0, color: '#2378f7' },{ offset: 0.7, color: '#2378f7' },{ offset: 1, color: '#83bff6' }])}},itemStyle: {borderRadius: [25, 25, 0, 0],color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ offset: 0, color: '#83bff6' },{ offset: 0.5, color: '#188df0' },{ offset: 1, color: '#188df0' }])}}]};chart.setOption(option);}function initPieChart(chartData) {const data = JSON.parse(chartData);var chartContainer = document.getElementById('chartPieContainer');var chart = echarts.init(chartContainer);var option = {tooltip: {trigger: 'item'},legend: {show: false,top: '5%',left: 'center'},series: [{data: data.seriesData,type: 'pie',radius: ['40%', '70%'],avoidLabelOverlap: false,itemStyle: {borderRadius: 10,borderColor: '#fff',borderWidth: 2},startAngle: 180,labelLine: {show: true,length: 20, // 标签线的长度length2: 50 // 标签线的第二段长度},emphasis: {label: {show: true,fontSize: 40,fontWeight: 'bold'}},labelLine: {show: false}}]};chart.setOption(option);}
</script>
</html>

3.4.2 Web组件使用本地文件

import web_webview from '@ohos.web.webview'@Entry
@Component
struct Chart {controllerWeb: web_webview.WebviewController = new web_webview.WebviewController()build() {Web({ src: $rawfile('barChart.html'), controller: this.controllerWeb })}
}

3.4.3 Web组件向H5页面传值,调用H5中的方法

// 初始化柱状图
const codeJS = `initBarChart('${JSON.stringify(this.chartBarData)}')
`
this.controllerWeb.runJavaScript(codeJS)

3.4.4 完整调用代码

import web_webview from '@ohos.web.webview'
import router from '@ohos.router';interface ChartDataType {xAxisData?: Array<string | number>;seriesData?: Array<string | number | any>;
}@Entry
@Component
struct BarChart {controllerWeb: web_webview.WebviewController = new web_webview.WebviewController()private chartBarData: ChartDataType = {xAxisData: ['餐饮', '购物', '教育', '生活', '宠物', '运动', '娱乐', '其他'],seriesData: [10, 20, 15, 30, 10, 20, 15, 30],}private chartPieData: ChartDataType = {seriesData: [{ value: 10, name: '餐饮' },{ value: 20, name: '购物' },{ value: 15, name: '教育' },{ value: 30, name: '生活' },{ value: 10, name: '宠物' },{ value: 20, name: '运动' },{ value: 15, name: '娱乐' },{ value: 30, name: '其他' },],}build() {Column() {Row() {Button() {Image($rawfile('icon_back.png')).width(18)}.backgroundColor(Color.Transparent).padding(10).onClick(() => router.back())Text('图表分析').fontSize(20).fontWeight(FontWeight.Bold)}.padding(10).justifyContent(FlexAlign.SpaceBetween).width('100%')Web({ src: $rawfile('barChart.html'), controller: this.controllerWeb }).verticalScrollBarAccess(true).javaScriptAccess(true).onPageEnd(() => {// 初始化柱状图const codeJS = `initBarChart('${JSON.stringify(this.chartBarData)}')`this.controllerWeb.runJavaScript(codeJS)// 初始化饼图const codeJSPie = `initPieChart('${JSON.stringify(this.chartPieData)}')`this.controllerWeb.runJavaScript(codeJSPie)})}.width('100%').height('100%')}
}

3.4.5 传值注意点总结

  • 传递数据需要通过 JSON.stringify() 转换为字符串;
  • 传递的参数必须使用引号包裹,否则无法调用到H5中的方法;
  • H5中使用传过来的数据,同理,需要使用 JSON.parse() 进行转换;

3.5  自定义键盘

使用Grid布局,通过rowStart、rowEnd、columnStart、columnEnd进行单元格合并。或者使用column和row布局,循环即可。

参考:https://gitee.com/harmonyos/codelabs/tree/master/SimpleCalculator

Grid() {GridItem() {this.GridItemButtonBuilder('7')}.gridItemStyle().onClick(() => { this.clickBtn(7) })GridItem() {this.GridItemButtonBuilder('8')}.gridItemStyle().onClick(() => { this.clickBtn(8) })GridItem() {this.GridItemButtonBuilder('9')}.gridItemStyle().onClick(() => { this.clickBtn(9) })GridItem() {Text(this.time).backgroundColor(Color.White).width('100%').height('100%').textAlign(TextAlign.Center)}.gridItemStyle()GridItem() {this.GridItemButtonBuilder('4')}.gridItemStyle().onClick(() => { this.clickBtn(4) })GridItem() {this.GridItemButtonBuilder('5')}.gridItemStyle().onClick(() => { this.clickBtn(5) })GridItem() {this.GridItemButtonBuilder('6')}.gridItemStyle().onClick(() => { this.clickBtn(6) })GridItem() {this.GridItemButtonBuilder('remove')}.gridItemStyle().onClick(() => { this.clickBtn('remove') })GridItem() {this.GridItemButtonBuilder('1')}.gridItemStyle().onClick(() => { this.clickBtn('1') })GridItem() {this.GridItemButtonBuilder('2')}.gridItemStyle().onClick(() => { this.clickBtn('2') })GridItem() {this.GridItemButtonBuilder('3')}.gridItemStyle().onClick(() => { this.clickBtn('3') })GridItem() {this.GridItemButtonBuilder('保存', '#409EFF')}.rowStart(2).rowEnd(3).columnStart(3).columnEnd(4).onClick(() => { this.clickBtn('save') })GridItem() {this.GridItemButtonBuilder('清空')}.gridItemStyle().onClick(() => { this.clickBtn('clear') })GridItem() {this.GridItemButtonBuilder('0')}.gridItemStyle().onClick(() => { this.clickBtn('0') })GridItem() {this.GridItemButtonBuilder('.')}.gridItemStyle().onClick(() => { this.clickBtn('.') })
}
.height(220)
.columnsTemplate('1fr 1fr 1fr 1fr')
.rowsTemplate('1fr 1fr 1fr 1fr')
.rowsGap(0)
.margin({ top: 0 })

4、扩展(如何使用基础组件自定义柱状图)

  • 使用Stack容器进行堆叠
  • 通过Rect绘制柱子
  • 通过Divider绘制分割线

    一个简单的柱状图就完成了,具体可以参考健康生活,希望ArkUI可以早日集成Echarts类似的图表组件,JS版本的有Chart组件,ArkTs的还未集成,期待官方❤️❤️❤️

@Builder
content(item: OneMealStatisticsInfo) {Column() {if (item.totalFat > 0) {Rect({ width: 14, height: item.totalFat / 200 + 14, radius: 7 }).fill('#FD9A42').padding({ top: 14 }).margin({ bottom: -28 })}if (item.totalProtein > 0) {Rect({ width: 14, height: item.totalProtein / 200 + 14, radius: 7 }).fill('#FBD44E').padding({ top: 14 }).margin({ bottom: -21 })}if (item.totalCarbohydrates > 0) {Rect({ width: 14, height: item.totalCarbohydrates / 200 + 14, radius: 7 }).fill('#73CD57').padding({ top: 7 }).margin({ bottom: -7 })}}.clip(true)}@Builder
legendComponent(item: HistogramLegend) {Text(item.value).fontSize(12).fontColor('#18181A').fontFamily('HarmonyHeTi')
}@Component
struct Histogram {@Consume("dietData") dietData: Array<OneMealStatisticsInfo>@BuilderParam content?: (item: OneMealStatisticsInfo) => void@BuilderParam legendComponent?: (item: HistogramLegend) => voidprivate title: string | Resource = ''private legend: HistogramLegend[] = []build() {Column() {Text(this.title).textAlign(TextAlign.Start).fontSize(24).fontColor('#000000').fontFamily('HarmonyHeTi-Medium').width('100%').height(46)Stack({ alignContent: Alignment.Bottom }) {Column() {ForEach([0, 0, 0, 0, 0, 0], () => {Divider().strokeWidth(1).color('#D8D8D8')})}.height('100%').margin({ top: 20 }).justifyContent(FlexAlign.SpaceBetween)Column() {Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.SpaceEvenly, alignItems: ItemAlign.Start }) {ForEach(this.dietData, (item: OneMealStatisticsInfo) => {if (item.mealFoods.length > 1) {Column() {if (this.content !== undefined) {this.content(item)}Text(item.mealTime.name).fontSize(14).fontColor('#7E7E7E').fontFamily('HarmonyHeTi').margin({ top: 10 })}.justifyContent(FlexAlign.End).height('100%')}})}}.height(236)}.height(190)Row() {ForEach(this.legend, (item: HistogramLegend) => {Row() {Rect({ width: 9, height: 9, radius: 9 }).fill(item.color).margin({ right: 18 })if (this.legendComponent !== undefined) {this.legendComponent(item)}}})}.justifyContent(FlexAlign.SpaceEvenly).width('100%').margin({ top: 70 })}.height('100%').padding({ left: 32, right: 32 }).borderRadius(12).backgroundColor('#FFFFFF')}
}

后面计划基于canvas基础组件实现一个柱状图,不断学习,期望鸿蒙不断强大完善。

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

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

相关文章

TikTok真题第8天 | 418.屏幕可显示句子的数量、395.至少有K个重复字符的最长子串、1010.总持续时间可以被60整除的歌曲对

418.屏幕可显示句子的数量 题目链接&#xff1a;418.sentence-screen-fitting 解法&#xff1a; 这道题&#xff0c;看题解都很难看懂&#xff0c;哪怕看出点门道了&#xff0c;也很难用自己的话解释出来。 有几点必须清楚&#xff1a; &#xff08;1&#xff09;将字符串…

10. Opencv检测并截取图中二维码

1. 说明 在二维码扫描功能开发中,使用相机扫描图片时,往往图片中的信息比较多样,可能会造成二维码检测失败的问题。一种提高检测精度的方式就是把二维码在图片中单独抠出来,去除其它冗余信息,然后再去识别这张提取出来的二维码。本篇博客记录采用的一种实现二维码位置检测…

计算机网络——应用层与网络安全(六)

前言&#xff1a; 前几章我们已经对TCP/IP协议的下四层已经有了一个简单的认识与了解&#xff0c;下面让我们对它的最顶层&#xff0c;应用层进行一个简单的学习与认识&#xff0c;由于计算机网络多样的连接形式、不均匀的终端分布&#xff0c;以及网络的开放性和互联性等特征&…

L1-069:胎压监测

题目描述 小轿车中有一个系统随时监测四个车轮的胎压&#xff0c;如果四轮胎压不是很平衡&#xff0c;则可能对行车造成严重的影响。 让我们把四个车轮 —— 左前轮、右前轮、右后轮、左后轮 —— 顺次编号为 1、2、3、4。本题就请你编写一个监测程序&#xff0c;随时监测四轮的…

GaussDB数据库中的同义词SYNONYM

目录 一、前言 二、GasussDB数据库中的Synonym 1、Synonym的概念 2、语法介绍 3、Synonym的用途 三、Synonym在GaussDB数据库中是如何使用的 1、表的同义词使用&#xff08;示例&#xff09; 2、视图的同义词使用&#xff08;示例&#xff09; 3、函数的同义词使用&am…

分布式IO在工业自动化中的应用

传统的自动化产线及物流系统主要是利用PLC来处理数据&#xff0c;并将这些数据保存在PC当中。但是随着互联网技术的迅速发展&#xff0c;越来越多的系统集成商利用分布式IO模块&#xff0c;实现从控制器到自动化最底层之间的IO通信。 分布式IO在工业自动化中的应用 分布式IO是用…

Vue3+ElementPlus: 给点击按钮添加触发提示

一、需求 在Vue3项目中&#xff0c;有一个下载按钮&#xff0c;当鼠标悬浮在按钮上面时&#xff0c;会出现文字提示用户可以点击按钮进行数据的下载技术栈 Vue3 ElementPlusTooltip组件 ElementPlus中的Tooltip组件 &#xff0c;可用于展示鼠标 hover 时的提示信息 二、实现…

【SD】IP-Adapter 进阶 - 垫图 【1】

目录 关于SD1.5的画风迁移 修改动作-方法一&#xff1a;提示词 修改动作-方法二&#xff1a;openpose 关于SD1.5的画风迁移 1.5测试模型&#xff1a;flat2DAnimerge_v30_2.safetensors [b2c93e7a89] 测试图&#xff1a; 文生图&#xff1a;best quality,masterpiece, co…

GPT-5、开源、更强的ChatGPT!

年终岁尾&#xff0c;正值圣诞节热闹气氛的OpenAI写下了2024年的发展清单。 OpenAI联合创始人兼首席执行官Sam Altman在社交平台公布&#xff0c;AGI&#xff08;稍晚一些&#xff09;、GPT-5、更好的语音模型、更高的费率限制&#xff1b; 更好的GPTs&#xff1b;更好的推理…

weblogic未授权命令执行漏洞(CVE-2020-14882)

漏洞描述&#xff1a; 未经身份验证的远程攻击者可能通过构造特殊的 HTTP GET请求&#xff0c;利用该漏洞在受影响的 weblogic Server 上执行任意代码。 复现过程&#xff1a; 1.访问ip&#xff1a;port/console 2.poc构造 #!/usr/bin/env python3 # -*- coding: utf-8 -*-…

春款来啦~我先冲了

这款假两件设计的连帽风衣外套 宽松版型对身材包容性很强&#xff0c;韩系慵懒风颜色很舒服 时尚百搭怎么穿都好看系列 做了腰部可调节抽绳&#xff0c;想要修身一点的可以自己调节哈 袖口处也做了金属按扣调节&#xff0c;防风保暖 这件风衣也很好搭配&#xff0c;很经典…

css原子化的框架Tailwindcss的使用教程(原始html和vue项目的安装与配置)

安装教程 中文官网教程 原始的HTML里面使用 新建文件夹npm init -y 初始化项目 安装相关依赖 npm install -D tailwindcss postcss-cli autoprefixer初始化两个文件 npx tailwindcss init -p根目录下新建src/style.css tailwind base; tailwind components; tailwind ut…

利用Jmeter做接口测试(功能测试)全流程分析!

利用Jmeter做接口测试怎么做呢&#xff1f;过程真的是超级简单。 明白了原理以后&#xff0c;把零碎的知识点填充进去就可以了。所以在学习的过程中&#xff0c;不管学什么&#xff0c;我一直都强调的是要循序渐进&#xff0c;和明白原理和逻辑。这篇文章就来介绍一下如何利用…

【数据结构】图论与并查集

一、并查集 1.原理 简单的讲并查集&#xff0c;就是查询两个个元素&#xff0c;是否在一个集合当中&#xff0c;这里的集合用树的形式进行表示。并查集的本质就是森林, 即多棵树。 我们再来简单的举个例子: 假设此时的你是大一新生&#xff0c;刚进入大学&#xff0c;肯定是…

什么是骨传导耳机?骨传导能保护听力吗?

骨传导耳机是一种非常特殊的蓝牙耳机&#xff0c;它通过骨传导技术将声音直接传送到内耳。这种技术不同于传统耳机&#xff0c;它不通过空气传送声音&#xff0c;而是通过头骨的振动来传送声音。 并且骨传导耳机能够在一定程度上起到保护听力的作用&#xff0c;主要是因为它们不…

Oracle中null值和空字符串的坑

思考 今天在学习oracle数据库的过程中&#xff0c;发现当对字段进行约束&#xff0c;默认空字符串时&#xff0c;出现报错 --创建employees表 CREATE TABLE employees (id NUMBER,name VARCHAR2(100) ); --对表新增email列&#xff0c;添加约束默认空字符串并且非空 ALTER …

山景32位蓝牙DSP音频应用处理芯片—BP1048B2

由工采网代理的BP1048B2是山景推出的一款高性能32位DSP蓝牙音频应用处理器&#xff1b;该芯片拥有32位RISC内核&#xff0c;支持DSP指令&#xff0c;集成FPU支持浮点运算&#xff0c;可应用于蓝牙K歌宝、蓝牙便携式音箱、蓝牙拖箱、蓝牙SoundBar、包头式蓝牙耳机、各类蓝牙音频…

阿里云PolarDB数据库费用价格表

阿里云数据库PolarDB租用价格表&#xff0c;云数据库PolarDB MySQL版2核4GB&#xff08;通用&#xff09;、2个节点、60 GB存储空间55元5天&#xff0c;云数据库 PolarDB 分布式版标准版2核16G&#xff08;通用&#xff09;57.6元3天&#xff0c;阿里云百科aliyunbaike.com分享…

uniapp中uview组件库的Search 搜索 的用法

目录 基本使用 #设置输入框形状 #是否开启清除控件 #是否开启右边控件 #自定义样式 API #Props #Events 基本使用 通过placeholder参数设置占位内容通过v-model双向绑定一个变量值&#xff0c;设置初始化时搜索框的值&#xff0c;如果初始内容为空&#xff0c;那么请绑…

苹果手机微信内存不足怎么清理?分享简单的解决方法!

我们平时经常使用手机来进行各种各样的活动&#xff0c;尤其是微信&#xff0c;它已经成为了我们生活中不可或缺的一部分。然而&#xff0c;随着时间的推移&#xff0c;微信占用的手机内存会越来越大&#xff0c;从而导致手机出现卡顿、闪退等问题。 当出现微信存储空间不足的…