当前位置: 首页 > 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地址的暴露意味着攻击者可以直接针对服务器发起攻击…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M&#xff1a;百万&#xff08;Million&#xff09; B&#xff1a;十亿&#xff08;Billion&#xff09; 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的&#xff0c;但是一个参数所表示多少字节不一定&#xff0c;需要看这个参数以什么…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

线程同步:确保多线程程序的安全与高效!

全文目录&#xff1a; 开篇语前序前言第一部分&#xff1a;线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分&#xff1a;synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分&#xff…...

渲染学进阶内容——模型

最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

Reasoning over Uncertain Text by Generative Large Language Models

https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...