当前位置: 首页 > news >正文

搭建广告展示页Start

想自定义广告-

场景: app冷启动/热启动-有广告需求,就打开广告页,没有的话就去登录或者主页

  • 有的app有的需要广告页,有的不需要,搞个配置呗!!!
  1. 通过首选项配置存储我们的一些常用配置,比如要不要广告页,还有广告页的路由地址,点击广告页跳转的链接,广告页倒计时的秒数
  2. 在入口处进行判断是否需要广告页,需要的话,跳转广告页-广告页根据设置的参数进行渲染
  3. 广告页能不能设置???--- 因为运营人员肯定不能每次都去改我们底层的代码-这里我还可以设置成动态的-就是初始化的时候通过请求去读一下云端的请求,然后把我们的图片和一些参数配置下来,这样每次你启动app就是运营人员给你配置的广告和设置了

1.新建一个关于广告类的数据模型

export class AdvertClass {showAd: boolean = false // 是否展示广告isFull: boolean = true // 是否全屏adTime: number = 5 // 倒计时数据adUrl?: string = "" // 要跳转的连接adImg?: ResourceStr = "" // 图片连接
}// 全屏广告 半屏广告

2.在utils中新建一个关于读取首选项的类,用来读取和设置首选项的广告设置- utils/setting.ets


export const defaultAd: AdvertClass = {showAd: true,isFull: true,adTime: 5,adImg: $r('[basic].media.start')
}export const USER_SETTING = 'fast_driver_setting' // 用来存储用户设置的首选项的keyexport const USER_SETTING_AD = 'fast_driver_setting_ad' // 用来存储用户设置广告首选项的key// 负责首选项的读取
export class UserSetting {context: Contextconstructor(context: Context) {this.context = context}// 获取仓库getStore() {return preferences.getPreferencesSync(this.context || getContext(), {name: USER_SETTING})}// 设置用户广告async setUserAd(ad: AdvertClass) {const store = this.getStore()store.putSync(USER_SETTING_AD, ad)await store.flush() // 让外界能够控制自己的流程}// 获取用户广告getUserAd() {const store = this.getStore()return store.getSync(USER_SETTING_AD, defaultAd) as AdvertClass}
}export const userSetting = new UserSetting(getContext()) // 导出一个单例

3.实现Start页的页面结构及倒计时逻辑

import { window } from '@kit.ArkUI'
import { AdvertClass, UserSetting } from 'home'@Entry
@Component
struct Start {userSetting: UserSetting = new UserSetting(getContext(this))@StateadObj: AdvertClass = {showAd: false,adTime: 0}timer: number = -1closeWin() {window.findWindow("ad_window").destroyWindow()}async aboutToAppear() {this.adObj = await this.userSetting.getUserAd()this.timer = setInterval(() => {if (this.adObj.adTime === 0) {clearInterval(this.timer)this.closeWin()return}this.adObj.adTime--}, 1000)}aboutToDisappear(): void {clearInterval(this.timer)}build() {Stack({ alignContent: Alignment.TopEnd }) {Image(this.adObj.adImg).objectFit(ImageFit.Cover)Text(`${this.adObj.adTime}秒后跳过`).padding({ left: 10, right: 10 }).margin({ right: 20, top: 20 }).height(30).fontSize(14).borderRadius(15).backgroundColor($r('[basic].color.MW')).textAlign(TextAlign.Center).onClick(() => {this.closeWin()})}.height('100%').width('100%').padding({ top: 40 })}
}

4.封装window窗口广告模式

import { display, window } from '@kit.ArkUI'
import { util } from '@kit.ArkTS'export class AdManager {context?: Context // 是给ability使用的private winNames: string [] = []// 展示广告 采用windows窗口的创建和销毁的方式async showAd(url: string, width?: number, height?: number) {if (url) {let name = `win_${util.generateRandomUUID()}`const win = await window.createWindow({name,windowType: window.WindowType.TYPE_DIALOG,ctx: this.context || getContext()})if (width && width >= 320 && height && height >= 240) {const screen = display.getDefaultDisplaySync()let mainWidth = vp2px(width)let mainHeight = vp2px(height)win.resizeAsync(mainWidth, mainHeight)win.moveWindowToAsync((screen.width - mainWidth) / 2, (screen.height - mainHeight) / 2)}await win.showWindow() // 展示窗口win.setUIContent(url) // 设置地址this.winNames.push(name)return name}return ""}// 关闭广告async closeAd(name?: string) {if (name) {window.findWindow(name).destroyWindow()this.winNames = this.winNames.filter(item => item !== name) //清空数组内容} else {// 不传就认为 想关闭所有let index = 0while (index < this.winNames.length) {await window.findWindow(this.winNames[index]).destroyWindow()index++}this.winNames = [] // 清空数组}}
}export const adManger = new AdManager()

5.采用与页面解耦的模式实现广告

import { AdvertClass } from '../viewmodels'
import { ComponentContent, promptAction, window } from '@kit.ArkUI'
import { util } from '@kit.ArkTS'// 展示广告的结构最重要写的代码
@Builder
function AdBuilder(ad: AdvertClass) {Column() {Image(ad.adImg).width("100%").height("100%").objectFit(ImageFit.Cover).borderRadius(10)Row() {Image($r("app.media.ic_btn_close")).width(14).aspectRatio(1).fillColor("#ccc")}.width(30).aspectRatio(1).justifyContent(FlexAlign.Center).borderRadius(15).border({color: '#ff343232',width: 2}).margin({top: 40}).onClick(() => {if (ad.dialogName) {adManagerFinal.closeAd(ad.dialogName) //  ? name从哪里进来}})}.width(ad.isFull ? "100%" : "80%").height(ad.isFull ? "100%" : "50%")
}export class AdManagerFinal {context?: Context// 所有的弹窗都放到这个map中 通过name来标识private map: Map<string, ComponentContent<AdvertClass>> = new Map()// 实际上需要广告async showAd(ad: AdvertClass) {// 按照文档实现// UIContext上下文必须得等到页面初始化之后才可以进行获取// 生成一个namelet name = `dialog_${util.generateRandomUUID()}`// 通过当前的主窗口来获取const mainWin = await window.getLastWindow(this.context || getContext())let uiContext = mainWin.getUIContext() // 拿到UIContextlet promptAction = uiContext.getPromptAction();ad.dialogName = name // 目的是将dialog的弹窗名称传递到builder中let contentNode = new ComponentContent(uiContext, wrapBuilder(AdBuilder), ad);let options: promptAction.BaseDialogOptions = {alignment: DialogAlignment.Center,autoCancel: false};this.map.set(name, contentNode) // 将key/value写入到map中promptAction.openCustomDialog(contentNode, options);// 一般半屏广告 是得用户手动点击才能关闭的 一般不会自动关闭// setTimeout(() => {//   promptAction.closeCustomDialog(contentNode)// }, 2000)}async closeAd(name: string) {if (name) {const mainWin = await window.getLastWindow(this.context || getContext())let uiContext = mainWin.getUIContext() // 拿到UIContextlet promptAction = uiContext.getPromptAction();promptAction.closeCustomDialog(this.map.get(name))// 清理mapthis.map.delete(name) // 删除已经关闭的弹窗}}
}export const adManagerFinal = new AdManagerFinal()

6.完整代码-EntryAbility

 async onWindowStageCreate(windowStage: window.WindowStage): Promise<void> {// Main window is created, set main page for this abilityhilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');// 开启全屏const win = windowStage.getMainWindowSync()win.setWindowLayoutFullScreen(true)// 获取安全区域const top = win.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM).topRectAppStorage.setOrCreate<number>('safeTop', px2vp(top.height))const bottom = win.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR).bottomRectAppStorage.setOrCreate<number>('safeBottom', px2vp(bottom.height))windowStage.loadContent('pages/Index', (err) => {if (err.code) {hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');return;}hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.');getUser.initUser()auth.initUser()});//广告// 发起一个向云端获取广告数据的请求const userSetting = new UserSetting(this.context)const result = await new Promise<AdvertClass>((resolve, reject) => {setTimeout(() => {resolve({showAd: true,adTime: 5,adImg: $r('[basic].media.start')} as AdvertClass)}, 1000)})await userSetting.setUserAd(result) // 写入首选项if (result.showAd) {const win = await windowStage.createSubWindow("ad_window")await win.showWindow()win.setUIContent("pages/StartPage")}}

相关文章:

搭建广告展示页Start

想自定义广告- 场景&#xff1a; app冷启动/热启动-有广告需求&#xff0c;就打开广告页&#xff0c;没有的话就去登录或者主页 有的app有的需要广告页&#xff0c;有的不需要&#xff0c;搞个配置呗&#xff01;&#xff01;&#xff01; 通过首选项配置存储我们的一些常用…...

无极低码基础版(部署版)课程计划

基础版(部署版)使用指南 特点 简单:1分钟学会无需编码:会SQL即可适合人群:纯小白0代码写服务1. 本地环境安装 JDKMySQLRedisTomcat2. 环境变量配置 JDK无极低码授权3. 配置文件修改 4. 服务启动 5. 服务发布示例 服务手动注册SQL语句注册6. 新增接口示例 正常新增非空参…...

Word文档功能快捷键大全

以下是 Microsoft Word 的全面快捷键大全&#xff0c;涵盖了文档操作、文本编辑、格式化、导航等多种功能&#xff0c;帮助你提高工作效率。 Word 全面快捷键和快捷方式表 功能类别快捷键/快捷方式功能描述基本文档操作Ctrl N新建文档Ctrl O打开文档Ctrl S保存文档F12另存…...

题目:1297. 子串的最大出现次数

> Problem: 1297. 子串的最大出现次数 题目&#xff1a;1297. 子串的最大出现次数 题目描述 给定一个字符串 s&#xff0c;要求找到满足以下条件的任意子串的出现次数&#xff0c;并返回该子串的最大出现次数&#xff1a; 子串中不同字母的数目必须小于等于 maxLetters。…...

一力破万法,高并发系统优化通解思路

高并发系统优化&#xff1a;从理论到Java实践 针对高并发场景&#xff0c;以下策略能够有效提升系统的稳定性和响应速度&#xff1a; 加集群 结果&#xff1a;通过增加服务器数量&#xff0c;实现负载均衡&#xff0c;提高系统整体处理能力。过程&#xff1a; 配置负载均衡器&…...

P8635 [蓝桥杯 2016 省 AB] 四平方和

对于一个给定的正整数&#xff0c;可能存在多种平方和的表示法。 要求你对 44个数排序使得 0≤a≤b≤c≤d。 输入 #1复制 5 输出 #1 0 0 1 2 输入 #2 12 输出 #2 0 2 2 2 输入 #3 773535 输出 #3 1 1 267 838 代码 #include<bits/stdc.h> using namespace …...

ElasticSearch是什么?

1.概述 Elasticsearch 是一个基于 Apache Lucene 构建的开源分布式搜索引擎和分析引擎。它专为云计算环境设计&#xff0c;提供了一个分布式的、高可用的实时分析和搜索平台。Elasticsearch 可以处理大量数据&#xff0c;并且具备横向扩展能力&#xff0c;能够通过增加更多的硬…...

2024年四非边缘鼠鼠计算机保研回忆(记录版 碎碎念)

Hi&#xff0c;大家好&#xff0c;我是半亩花海。写下这篇博客时已然是金秋十月&#xff0c;心中的石头终于落地&#xff0c;恍惚间百感交集。对于保研这条路&#xff0c;我处于摸着石头过河、冲击、随缘的这些状态。计算机保研向来比其他专业难&#xff0c;今年形势更是艰难。…...

clickhouse常用脚本语句

1.创建库和删除库 drop database IF EXISTS rt_db CREATE DATABASE rt_db ENGINE = Ordinary; CREATE DATABASE rt_db ENGINE = Atomic;2.创建表 CREATE TABLE IF NOT EXISTS intellect_alarm_info ( `id` UInt64 , `client_info_id...

GeneMark软件的秘钥gm_key失效怎么办?

GeneMark软件的gm_key失效怎么办 1. 下载网址&#xff08;为软件的下载界面&#xff09;&#xff1a;http://topaz.gatech.edu/GeneMark/license_download.cgi 2.下载界面 根据自己的需求下载对应的版本和类型的gm_key秘钥 3.填写注册信息 4. 点击下载软件和密钥 5. 将秘钥…...

线性回归逻辑回归-笔记

一、线性回归&#xff08;Linear Regression&#xff09; 1. 定义 线性回归是一种用于回归问题的算法&#xff0c;旨在找到输入特征与输出值之间的线性关系。它试图通过拟合一条直线来最小化预测值与真实值之间的误差。 2. 模型表示 线性回归模型假设目标变量&#xff08;输…...

如何将数据从 AWS S3 导入到 Elastic Cloud - 第 1 部分:Elastic Serverless Forwarder

作者&#xff1a;来自 Elastic Hemendra Singh Lodhi 这是多部分博客系列的第一部分&#xff0c;探讨了将数据从 AWS S3 导入 Elastic Cloud 的不同选项。 Elasticsearch 提供了多种从 AWS S3 存储桶导入数据的选项&#xff0c;允许客户根据其特定需求和架构策略选择最合适的方…...

Linux基础-正则表达式

正则表达式概述 正则表达式是处理字符串的一种工具&#xff0c;可以用于查找、删除、替换特定的字符串&#xff0c;主要用于文件内容的处理。与之不同的是&#xff0c;通配符则用于文件名称的匹配。正则表达式通过使用特殊符号&#xff0c;帮助用户轻松实现对文本的操作。 一…...

【HTML格式PPT离线到本地浏览】

文章目录 概要实现细节小结 概要 最近在上课时总是出现网络不稳定导致的PPT无法浏览的情况出现&#xff0c;就想到下载到电脑上。但是PPT是一个HTML的网页&#xff0c;无法通过保存网页&#xff08;右键另存为mhtml只能保存当前页&#xff09;的形式全部下载下来&#xff0c;试…...

如何在Vue项目中封装axios

文章目录 一、axios简介基本使用 二、封装axios的原因三、封装axios的方法1. 设置接口请求前缀2. 设置请求头和超时时间3. 封装请求方法4. 添加请求拦截器5. 添加响应拦截器小结 一、axios简介 axios 是一个基于 XMLHttpRequest 的轻量级HTTP客户端&#xff0c;适用于浏览器和…...

linux 配置ssh免密登录

一、 cd /root/.ssh/ #不存在就创建mkdir /root/.ssh ssh-keygen #连续按4个回车 ll二、将公钥发送到目标服务器下 #公钥上传到目标服务器 ssh-copy-id root192.168.31.142 #回车完也是要输入密码的 #测试一下免密登录&#xff1a; ssh root192.168.31.142 成功...

【AI绘画】Midjourney进阶:三分线构图详解

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AI绘画 | Midjourney 文章目录 &#x1f4af;前言&#x1f4af;什么是构图为什么Midjourney要使用构图 &#x1f4af;三分线构图特点使用场景提示词书写技巧测试 &#x1f4af;小结 &#x1f4af;前言 【AI绘画】Midjourney进阶&a…...

享元模式(C++)

定义&#xff1a;享元模式是一种结构型设计模式&#xff0c;它使用共享对象&#xff0c;用以尽可能减少内存使用和提高性能。享元模式通过共享已经存在的对象实例&#xff0c;而不是每次需要时都创建新对象实例&#xff0c;从而避免大量重复对象的开销。 对比&#xff1a; 与单…...

开发一个UniApp需要多长时间

开发一个UniApp所需的时间因项目的规模、复杂度、开发团队的经验水平以及开发过程中的需求变更等多种因素而异。因此&#xff0c;很难给出一个确切的时间范围。然而&#xff0c;我们可以从以下几个方面来大致估算开发时间&#xff1a; 项目规划与需求分析&#xff1a; 在项目开…...

服务器源IP暴露后的安全风险及防御措施

在互联网安全领域&#xff0c;服务器的源IP地址泄露可能成为黑客攻击的切入点。本文将列举十种常见的攻击类型&#xff0c;并提供相应的防御建议&#xff0c;帮助管理员们更好地保护服务器免受潜在威胁。 一、引言 服务器源IP地址的暴露意味着攻击者可以直接针对服务器发起攻击…...

如何快速掌握Sionna:下一代无线通信仿真的终极指南

如何快速掌握Sionna&#xff1a;下一代无线通信仿真的终极指南 【免费下载链接】sionna Sionna: An Open-Source Library for Next-Generation Physical Layer Research 项目地址: https://gitcode.com/gh_mirrors/si/sionna Sionna是一个基于TensorFlow的开源Python库&…...

CC Switch模型测试功能:构建可靠AI服务的全周期验证方法论

CC Switch模型测试功能&#xff1a;构建可靠AI服务的全周期验证方法论 【免费下载链接】cc-switch A cross-platform desktop All-in-One assistant tool for Claude Code, Codex & Gemini CLI. 项目地址: https://gitcode.com/GitHub_Trending/cc/cc-switch [问题发…...

Linux服务器无GPU也能跑!Ollama部署DeepSeek-R1模型存储路径自定义与性能调优指南

Linux服务器无GPU高效部署DeepSeek-R1模型全攻略&#xff1a;从存储路径优化到性能调优 当你在云服务器或老旧设备上尝试运行AI模型时&#xff0c;是否经常遇到存储空间不足或性能低下的困扰&#xff1f;本文将带你深入探索如何在无GPU的Linux环境中&#xff0c;通过Ollama高效…...

Multisim 13.0 仿真 LC 振荡器:从起振到稳定,手把手教你分析波形与频率稳定度

Multisim 13.0 仿真 LC 振荡器&#xff1a;从起振到稳定&#xff0c;手把手教你分析波形与频率稳定度 在电子工程领域&#xff0c;LC振荡器作为基础电路之一&#xff0c;其设计与分析能力是每位硬件工程师的必修课。Multisim作为业界广泛使用的电路仿真软件&#xff0c;为我们…...

如何快速掌握PathOfBuilding:流放之路终极角色构建规划神器

如何快速掌握PathOfBuilding&#xff1a;流放之路终极角色构建规划神器 【免费下载链接】PathOfBuilding Offline build planner for Path of Exile. 项目地址: https://gitcode.com/GitHub_Trending/pa/PathOfBuilding 还在为《流放之路》复杂的天赋树和装备搭配而头疼…...

PyTorch Geometric安装避坑指南:从依赖冲突到版本匹配,手把手带你搞定PyG环境

PyTorch Geometric安装避坑指南&#xff1a;从依赖冲突到版本匹配 每次打开终端准备安装PyTorch Geometric&#xff08;PyG&#xff09;时&#xff0c;那种既期待又忐忑的心情&#xff0c;相信很多图神经网络&#xff08;GNN&#xff09;开发者都深有体会。明明按照官方文档一…...

IndexTTS-2-LLM优化指南:提升合成速度与音频质量的技巧

IndexTTS-2-LLM优化指南&#xff1a;提升合成速度与音频质量的技巧 当你第一次使用IndexTTS-2-LLM生成语音时&#xff0c;可能会被它自然流畅的效果所吸引。但用了一段时间后&#xff0c;你可能会发现两个问题&#xff1a;生成一段稍长的文本需要等待好几秒&#xff0c;或者在…...

低成本AI助手方案:OpenClaw+GLM-4.7-Flash替代ChatGPT Plus

低成本AI助手方案&#xff1a;OpenClawGLM-4.7-Flash替代ChatGPT Plus 1. 为什么选择自建AI助手&#xff1f; 去年我开始频繁使用ChatGPT Plus处理日常工作&#xff0c;但每月20美元的订阅费用加上额外API调用&#xff0c;账单经常突破50美元。更让我困扰的是&#xff0c;处理…...

LLM4Decompile:用AI魔法让二进制代码重获新生![特殊字符]

LLM4Decompile&#xff1a;用AI魔法让二进制代码重获新生&#xff01;&#x1f680; 【免费下载链接】LLM4Decompile LLM4Decompile是前端技术的革新之作&#xff0c;面向软件逆向工程领域的革命性工具。此开源项目利用大型语言模型深入二进制世界的奥秘&#xff0c;将复杂的机…...

RMBG-2.0场景应用:广告素材制作,快速分离主体与背景

RMBG-2.0场景应用&#xff1a;广告素材制作&#xff0c;快速分离主体与背景 1. 广告设计中的背景移除痛点 在广告设计领域&#xff0c;背景移除是最常见也最耗时的任务之一。设计师们经常面临这样的困境&#xff1a; 时间成本高&#xff1a;一张普通商品图手动抠图需要5-10分…...