HarmonyOS 鸿蒙Next 本地数据库实现《菜谱大全》app(一)

发布于 1周前 作者 sinazl 来自 鸿蒙OS

HarmonyOS 鸿蒙Next 本地数据库实现《菜谱大全》app(一)

cke_723.gif

实现步骤:

1.准备数据库文件menu.db

从网络上免费获取或者花个几块钱就可以买到菜谱的数据库数据。

数据库结构如下:

cke_1444.png

meauID:菜谱id

name:菜谱名称

tags:标签

method:烹饪方法

img:图片

url:H5链接

level:难度

peopleNum:菜量适用人数

taste:口味

prepareTime:准备时间

cookTime:烹饪时间

mainIngredient:主料

accessories:辅料

measure:步骤

techniques:技巧

2.将数据库拷贝到项目代码中

将数据库拷贝到entry–>src–>main–>resources–>rawfile–>rdb–>menu.db

cke_2565.png

3.数据库文件复制到设备本地路径下

api不能直接访问安装包中的数据库文件,所以需要将数据库文件通过代码复制到设备本地路径下。

export class Constant {
//数据库名称
static readonly DB_NAME = “menu.db”
}<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
import { common } from ‘@kit.AbilityKit’;
import { Constant } from ‘…/constant/Constant’;
import fs, { ReadOptions } from ‘@ohos.file.fs’;
/**

  • 将rawfile下的menu.db 写入到手机本地文件中

  • @param context */ export async function saveDB2LocalFile(context: common.UIAbilityContext, copyCallback: (isSuccess: boolean) => void) { let dirPath = context.getApplicationContext().databaseDir + “/entry” if (!fs.accessSync(dirPath)) { fs.mkdirSync(dirPath); } dirPath = dirPath + “/rdb” if (!fs.accessSync(dirPath)) { fs.mkdirSync(dirPath); } //数据库名称 let dbName: string = Constant.DB_NAME if (!fs.accessSync(dirPath + “/” + dbName)) { try { context.resourceManager.getRawFd(‘rdb/’ + dbName, (error, value) => { if (error != null) { console.log(callback getRawFd failed error code: ${error.code}, message: ${error.message}.); } else { console.info(value.length.toString() + “DWSD”) // saveFileToCache(context,value, dbName) let cFile = context.getApplicationContext().databaseDir + “/entry/rdb/” + dbName let cacheFile = fs.openSync(cFile, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE) // 读取缓冲区大小 let bufferSize = 30000 let buffer = new ArrayBuffer(bufferSize); //创建buffer缓冲区 // 要copy的文件的offset和length let currentOffset = value.offset; let lengthNeedToReed = value.length;

       <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> readOption: ReadOptions = {
         offset: currentOffset, <span class="hljs-comment"><span class="hljs-comment">//期望读取文件的位置。可选,默认从当前位置开始读</span></span>
         length: bufferSize <span class="hljs-comment"><span class="hljs-comment">//每次期望读取数据的长度。可选,默认缓冲区长度</span></span>
       }
       <span class="hljs-keyword"><span class="hljs-keyword">while</span></span> (<span class="hljs-literal"><span class="hljs-literal">true</span></span>) {
         <span class="hljs-comment"><span class="hljs-comment">// 读取buffer容量的内容</span></span>
         <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> readLength = fs.readSync(value.fd, buffer, readOption);
         <span class="hljs-comment"><span class="hljs-comment">// 写入buffer容量的内容</span></span>
         fs.writeSync(cacheFile.fd, buffer, { length: readLength }) <span class="hljs-comment"><span class="hljs-comment">//写到cacheFile里</span></span>
         <span class="hljs-comment"><span class="hljs-comment">// 判断后续内容 修改读文件的参数</span></span>
         <span class="hljs-comment"><span class="hljs-comment">// buffer没读满代表文件读完了</span></span>
         <span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (readLength &lt; bufferSize) {
           <span class="hljs-keyword"><span class="hljs-keyword">break</span></span>;
         }
         <span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (readOption.offset) {
           readOption.offset += readLength
         }
       }
       console.log(<span class="hljs-string"><span class="hljs-string">"Copy Success!!!"</span></span>)
       fs.close(cacheFile);
       copyCallback(<span class="hljs-literal"><span class="hljs-literal">true</span></span>)
     }
    

    }); } catch (error) { console.error(callback getRawFd failed, error code: ${error.code}, message: ${error.message}.) } }else { copyCallback(true) } }<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>

4.底部导航栏的实现

通过Tabs组件实现底部导航栏

cke_11933.png

@Entry
@Component
struct Index {
build() {
Stack() {
Column() {
Tabs() {
TabContent() {
}
.tabBar(this.tabBuilder(“菜谱”, 0, $r(“app.media.tab_menu_selected”), $r(“app.media.tab_menu_normal”)))

     TabContent() {
     }
     .tabBar(<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.tabBuilder(<span class="hljs-string"><span class="hljs-string">"初级"</span></span>, <span class="hljs-number"><span class="hljs-number">1</span></span>, $r(<span class="hljs-string"><span class="hljs-string">"app.media.tab_chuji_selected"</span></span>), $r(<span class="hljs-string"><span class="hljs-string">"app.media.tab_chuji_normal"</span></span>)))
     TabContent() {
     }
     .tabBar(<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.tabBuilder(<span class="hljs-string"><span class="hljs-string">"高级"</span></span>, <span class="hljs-number"><span class="hljs-number">2</span></span>, $r(<span class="hljs-string"><span class="hljs-string">"app.media.tab_gaoji_selected"</span></span>), $r(<span class="hljs-string"><span class="hljs-string">"app.media.tab_gaoji_normal"</span></span>)))
   }
   .onChange((index: number) =&gt; {
     <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.currentIndex = index
   })
   .onTabBarClick((index) =&gt; {
     <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.currentIndex = index
   })
   .barPosition(BarPosition.End)
   .barHeight(<span class="hljs-number"><span class="hljs-number">50</span></span>)
   .layoutWeight(<span class="hljs-number"><span class="hljs-number">1</span></span>)
 }.height(<span class="hljs-string"><span class="hljs-string">"100%"</span></span>)

} } @State currentIndex: number = 0

@Builder tabBuilder(title: string, targetIndex: number, selectedImg: Resource, normalImg: Resource) { Column() { Image(this.currentIndex === targetIndex ? selectedImg : normalImg) .size({ width: 25, height: 25 }) Text(title) .fontColor(this.currentIndex === targetIndex ? $r(“app.color.primary”) : $r(“app.color._bfbfbf”)) } .width(‘100%’) .height(50) .justifyContent(FlexAlign.Center) .clickEffect({ level: ClickEffectLevel.HEAVY, scale: 0.6 }) } }<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>

5.配置应用的图标以及名称 

cke_4564.png

cke_7199.png

icon为app图标,label为app在桌面显示的名称。

cke_12415.png

在AppScope下的app.json5配置文件中也需要将icon和label配置

{
“app”: {
“bundleName”: “com.lingmou.lovecook”,
“vendor”: “example”,
“versionCode”: 1000000,
“versionName”: “1.0.0”,
“icon”: “$media:app_icon”,
“label”: “$string:app_name”
}
}<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>


关于HarmonyOS 鸿蒙Next 本地数据库实现《菜谱大全》app(一)的问题,您也可以访问:https://www.itying.com/category-93-b0.html 联系官网客服。

1 回复
回到顶部