在實現用戶協議彈窗時,通常我們會想到使用系統自定義彈窗,併在彈窗中點擊跳轉到Web頁面。但在HarmonyOS中,由於系統彈窗的顯示優先順序高於其他組件,即使跳轉到Web頁面,彈窗依然會顯示在最上層。 為瞭解決這個問題,我們可以自定義一個組件來模擬彈窗,這樣當跳轉到Web頁面時,Web內容會覆蓋這個模 ...
在實現用戶協議彈窗時,通常我們會想到使用系統自定義彈窗,併在彈窗中點擊跳轉到Web頁面。但在HarmonyOS中,由於系統彈窗的顯示優先順序高於其他組件,即使跳轉到Web頁面,彈窗依然會顯示在最上層。
為瞭解決這個問題,我們可以自定義一個組件來模擬彈窗,這樣當跳轉到Web頁面時,Web內容會覆蓋這個模擬的彈窗。
效果圖如下:
首先,我們來看程式的入口代碼。最外層使用了一個RelativeContainer容器組件,通過showAgreePrivacyPolicy變數控制隱私政策彈窗的顯示狀態。每次啟動應用時,該變數預設設置為true,以顯示隱私政策彈窗。在實際開發中,你可以通過preferences保存這個變數的狀態。
struct Index {
@State showAgreePrivacyPolicy:boolean=true;
build() {
RelativeContainer(){
Row({space:10}){
Image($r('app.media.app_icon')).width(60).height(60)
Column({space:5}){
Text($r('app.string.app_name')).fontSize(22).fontColor($r('app.color.title_color'))
Text($r('app.string.launcher_tip')).fontSize(14).fontColor($r('app.color.other_color'))
}.alignItems(HorizontalAlign.Start)
}.alignRules({
bottom: {anchor: "__container__", align: VerticalAlign.Bottom},
middle: { anchor: '__container__', align: HorizontalAlign.Center } //以父容器為錨點,水平方向居中對齊
}).margin({
bottom:30
})
if(this.showAgreePrivacyPolicy){//通過變數控制隱私政策彈窗是否顯示
PrivacyPolicyDialog({
cancel:this.onCancel.bind(this),//取消按鈕點擊
confirm:this.onAgree.bind(this),//確定按鈕點擊
})
}
}.width('100%')
.height('100%').backgroundColor($r('app.color.white'))
}
onCancel():void {
(getContext(this) as common.UIAbilityContext)?.terminateSelf()
}
onAgree():void {//同意隱私政策
this.showAgreePrivacyPolicy = false;
}
}
接下來是PrivacyPolicyDialog組件代碼:
- 根組件填充100%寬高,設置黑色背景,透明度30%
- 內容區域使用Stack組件,背景為白色,圓角邊框,寬度占父組件的80%。
- 文字內容用Text和Span組件包裹,支持滾動功能。點擊用戶協議和隱私政策的文字時,使用router打開Web頁面。
@Component
export default struct PrivacyPolicyDialog{
cancel!: () => void
confirm!: () => void
build() {
Stack(){
Column() {
Text($r('app.string.simple_user_policy')).fontSize(18).fontColor($r('app.color.title_color')).margin({ top: 30, bottom: 19 })
Scroll(){
Text(){
Span($r('app.string.privacy_policy_start'))
Span($r('app.string.user_agreement_two')).fontColor($r('app.color.mainColor')).onClick(() => {
this.openWebUrl("/useragreement.html");
})
Span($r('app.string.and'))
Span($r('app.string.privacy_policy_two')).fontColor($r('app.color.mainColor')).onClick(() => {
this.openWebUrl("/privacypolicy.html");
})
Span($r('app.string.simple_privacy_policy'))
}.fontSize(16).fontColor($r('app.color.body_color')).margin({
left:25,
right:25
})
}.height(120)
Column(){
Button($r('app.string.disagree_privacy_policy')).onClick(() => {
this.cancel();
}).fontColor($r('app.color.other_color')).fontSize(15).backgroundColor(Color.Transparent)
Button($r('app.string.agree_privacy_policy')).onClick(() => {
this.confirm();
}).fontColor($r('app.color.white')).fontSize(17)
.linearGradient({
direction: GradientDirection.Right, colors:[[$r('app.color.start_main_color'),0.0],[$r('app.color.end_main_color'),1.0]]
}).width('80%').margin({
top:15,bottom:21
}).borderRadius(24)
}
}.backgroundColor($r('app.color.white')).borderRadius(13).width('80%')
}.width('100%')
.height('100%').backgroundColor("#4D000000")//黑色背景 透明度約為 30%
}
openWebUrl(urlSuffix:string){
let url= "https://www.srzs.top"+urlSuffix;
router.pushUrl({
url: 'pages/WebViewPage',
params:{
data1: 'message',
url: url // 傳遞的 URL 參數
}
}, router.RouterMode.Single)
}
}
WebViewPage展示Web網頁的代碼就不貼出來了,大家可直接下載源碼。還有載入網頁一定要網路許可權,在entry/module.json5這個文件中配置。
源碼下載
如果您想第一時間看我的後期文章,掃碼關註公眾號
安輝編程筆記 - 開發技術分享
掃描二維碼加關註