DEV Community

Cover image for HarmonyOS Development: Customize a Dialog that pops up anywhere
程序员一鸣
程序员一鸣

Posted on

HarmonyOS Development: Customize a Dialog that pops up anywhere

Foreword 

this article is based on Api12 

in the development of Hongmeng, there has always been a problem bothering him, and presumably most developers, that is, the dialog custom pop-up window provided by the system cannot be popped up at any position, which is limited the member variables of @ CustomDialog and @ Component struct, which leads to, I want to pop up in the encapsulated tool class or ViewModel, or other places, can only be executed by triggering the UI layer through events or callbacks, which is very inconvenient. In addition, although we can share UI, CustomDialogController needs to be defined everywhere, which is also very redundant. Of course, the dialog itself should pop up at the UI layer. There is no problem with Hongmeng's design, but in order to take into account the ease of use, it should pop up at any position, which is probably very necessary for many people. 

Image description

System custom pop-up window


 

dialogController = new CustomDialogController({
builder: this.customDialog,
autoCancel: true,
})

/*
* Author:AbnerMing
*Description: Custom Dialog
*/
@Builder
customDialog() {
Text ("I am a custom dialog")
.width("100%")
.height(100)
}


This. dialogController. open()//Pop up
This. dialogController. close()//Close
Enter fullscreen mode Exit fullscreen mode

at present, there are two ways to get rid of UI restrictions and pop up at any position. The first is to use window to create a window. This form requires initialization. Whether it depends on window.WindowStage or an ordinary page, it is a front dependency. Of course, there is another point, that is, the pop-up method is slightly stiff, but it can meet the normal needs. The second is through openCustomDialog in promptAction however, this method needs to be in Api11 and above. For the current use requirements, if you want to pop up at any position, it is still recommended to use it. The openCustomDialog method.

openCustomDialog simple to use

The pop-up window is popped up by openCustomDialog and closed by closeCustomDialog.

 

private customDialogComponentId: number = 0

build() {
Column() {
Button ("Simple Demo")
.onClick(() => {
promptAction.openCustomDialog({
builder: () => {
this.customDialogComponent()
}
}).then((dialogId: number) => {
this.customDialogComponentId = dialogId
})
})
}
.width("100%")
.height("100%")
.justifyContent(FlexAlign.Center)
}

@Builder
customDialogComponent() {
Column() {
Text ('spop up '). fontSize (30)
Row({ space: 50 }) {
Button ("Confirm"). onClick()=>{
promptAction.closeCustomDialog(this.customDialogComponentId)
})
Button ("Cancel"). onClick()=>{
promptAction.closeCustomDialog(this.customDialogComponentId)
})
}
}.height(200).padding(5).justifyContent(FlexAlign.SpaceBetween)
}
Enter fullscreen mode Exit fullscreen mode

At present, based on the openCustomDialog method, it has also encapsulated a layer and has supported most common functions in the market, such as information pop-up window, confirmation cancellation form pop-up window, bottom pop-up window, time, city and other styles. Of course, it also supports custom component forms, covering almost all scenarios and can be directly used by friends who need them. 

Central Warehouse Address: 

https://ohpm.openharmony.cn/#/cn/detail/@abner%2Fdialog 

at present, various functions are also listed so that everyone can use them in a targeted way. 

Image description

Quick Use 

method 1: in the Terminal window, run the following command to install the third-party package. DevEco Studio automatically adds the third-party package dependency to the project oh-package.json5. 

Suggestion: Execute the command under the module path used.


ohpm install @abner/dialog
Enter fullscreen mode Exit fullscreen mode

Method 2: Set the three-party package dependency in the project oh-package.json5. The configuration example is as follows:

 

"dependencies": { "@abner/dialog": "^1.1.1"}
Enter fullscreen mode Exit fullscreen mode

initialization 

initialization can change the unified configuration, such as width and height, such as size, such as background, etc., of course, if necessary, if the default style meets the requirements, global initialization can be omitted , you can also modify the style when you call it separately.

 

initDialog(attribute)
Enter fullscreen mode Exit fullscreen mode

Property Introduction 


property Type overview
attribute  FusionAttribute  optional parameter, dialog attribute global configuration, used to modify the pop-up window style, can be configured here according to UI 

FusionAttribute attribute 

FusionAttribute is a global dialog attribute configuration. If the default dialog style is different from the style in your project, you can use this parameter to set it. If you configure the global dialog attribute once, it will take effect in all places on the page, which is convenient for you to use later. 

Property type overview
infoOrConfirmAttribute  ContentAttribute  optional parameters, information or confirmation form pop-up window attribute configuration 
bottomListAttribute  BottomListAttribute  optional parameters, the bottom list pop-up window attribute configuration 
bottomGridAttribute  BottomGridAttribute  optional parameters, bottom grid list pop-up window attribute configuration 
bottomListScrollAttribute BottomListScrollAttribute  optional parameters, sliding list properties at the bottom 
toastAttribute  ToastAttribute  optional parameter, Toast attribute configuration 
loadingAttribute  LoadingAttribute  optional parameters, loading hint 
isUseMainWindow  boolean  whether to use the main window or the child window, the default is the child window. 

ContentAttribute attribute 

ContentAttribute is a pop-up attribute configuration in the form of information or confirmation. 

Property type overview
title  string / Resource  optional parameters, headers, no configuration required in global initialization 
message  string / Resource  optional parameter, description information, no configuration required in global initialization 
cancelText  string / Resource Optional parameters, canceling text 
confirmText  string / Resource  optional parameters, confirmation text 
clickCancelHide  boolean  optional parameters, click to unhide by default 
isHideTitle  boolean  optional parameter, whether to hide the title, default not to hide 
clickCancel  callback  optional parameter, click to cancel callback event 
clickConfirm  callback  optional parameters, click to confirm the callback event 
bottomMenuHeight  Length  optional parameter, bottom button height 
backgroundColor  ResourceColor  optional parameters, background color 
radius  BorderRadiuses / Length  optional parameter, angle 
titleAttribute TitleAttribute  optional Parameters, Title Style Properties 
messageAttribute  MessageAttribute  optional parameters, describing style properties 
dividerHAttribute  DividerHAttribute  optional parameter, Horizontal Split Line Style attribute 
dividerVAttribute  DividerVAttribute  optional Parameter, Vertical Split Line Style Property 
confirmAttribute  ConfirmAttribute  optional Parameters, Confirm Style Properties 
cancelAttribute  CancelAttribute  optional parameters, canceling style attributes 
dialogAttribute  DialogAttribute  optional parameters, popup overall properties 

BottomListAttribute attribute attribute 

BottomListAttribute is the bottom list popup attribute configuration. 

Property Type overview
backgroundColor  ResourceColor  background Color 
items  string[]  list Entry 
itemClick  (position: number)  entry Click Callback 
cancelClick  ()  cancel Click Callback 
isHideCancel  boolean  whether to hide the cancel button 
isTransparent  boolean  transparent display 
itemRadius  Length / BorderRadiuses  the overall angle of the entry after transparency 
cancelRadius  Length / BorderRadiuses  transparent Post Cancel Button Angle 
topLeftRadius  Length dialog左上角角度
topRightRadius Length dialog右上角角度
itemAttr BottomListItem 条目属性
itemDivider ListItemDivider 分割线属性
cancelAttr BottomListCancel 底部取消属性
dialogAttribute DialogAttribute 弹窗总体属性

BottomGridAttribute

属性 类型 概述
items BottomGridModel[] 条目数据,用于网格
itemLineArray Array 条目数据,用户每行展示几个,每行几个就几个数据
columnSize  number  number of columns, 2 columns by default 
barTitleAttr  BarTitleGridAttribute  titlebar property of the edge on the grid 
barHeight  number  the height of the titleBar on the upper edge of the grid 
barCancelTextAttr  BarCancelTextGridAttribute  cancel attribute in titleBar 
barCancelImageAttr  BarCancelImageGridAttribute  cancel the picture attribute in titleBar, and choose one from the text. 
isBarCancelImage  boolean  whether the cancellation in titleBar is the image method, the default is false. 
itemMarginTop  number  item Each row from top 
backgroundColor  ResourceColor  background Color
topLeftRadius  Length  dialog Top Left Angle 
topRightRadius  Length  dialog upper right corner angle 
isHideBar  boolean  whether to hide titlebar 
dialogAttribute  DialogAttribute  global dialog attribute 
isItemAttrGlobal  boolean  whether the entry property is global, the default is 
itemAttr  ItemGridAttribute  item Properties 
itemClick  (position: number)  entry Click Callback 
cancelClick  ()  cancel Click Callback 
dividerColor  ResourceColor  split line color
dividerHeight  number  split line height 
isLastDividerShow  boolean  whether to display the last one. Default display 
dividerMarginTop  Margin / Length  height of dividing line from upper edge 
isShowBottomCancel  boolean  whether to display the bottom cancel button. By default, it is not displayed. 
bottomCancelTextAttr  CancelTextGridAttribute  cancel button properties at the bottom 

ToastAttribute attribute 

property type overview
msg  string / Resource  prompt information, no need for initialization 
duration  number  pop-up time, default 2000 
backgroundColor ResourceColor 背景颜色
fontColor ResourceColor 字体颜色 ,默认ffffff
fontWeight number / FontWeight / string 字体粗细设置,默认400
fontSize number / string / Resource 字体大小,默认16
fontFamily string / Resource 字体样式
borderRadius Length / BorderRadiuses 角度
padding Padding / Length 内边距
flexAlign FlexAlign 位置方向
leftSrc PixelMap / ResourceStr/ DrawableDescriptor Picture on the left 
rightSrc  PixelMap / ResourceStr/ DrawableDescriptor  picture on the right 
topSrc  PixelMap / ResourceStr/ DrawableDescriptor  picture above 
bottomSrc  PixelMap / ResourceStr/ DrawableDescriptor  picture below 
imageMargin  Length  picture Distance Text Distance 
imageWidth  Length  picture Width 
imageHeight  Length  picture height 
imageAlt  string /Resource  the percentage bitmap displayed when loading 

DialogAttribute attribute 

each pop-up window has a dialogAttribute attribute to control the overall pop-up window style. 

Property Type overview
windowAlignment  DialogAlignment  pop-up window position 
dialogDismiss  (action? :DismissDialogAction) => void  dialog hidden state callback 
dialogAppear  () => void  dialog display callback 
windowBottomAnimation  boolean  whether to turn on bottom animation 
isPrivacyMode  boolean  whether to prevent screenshots, the default is not 
isSystemAnimation  boolean  whether the system is animated or not, the default is both 

code Case 

1. Information pop-up window


 

showDialogInfo({
Title: "I am the title",
Message: "I am a description",
clickConfirm: () => {
//Confirm
Console.log (===Confirm)
//Hide()//Hide
}
})
Enter fullscreen mode Exit fullscreen mode

2. Confirm/cancel pop-up window


 

showDialogConfirm({
Title: "I am a title",
Message: "I am a description",
clickCancel: () => {
//Cancel
Console.log ("===Cancel")
//Hide()//Hide
},
clickConfirm: () => {
//Confirm
Console.log (===Confirm)
//Hide()//Hide
}
})
Enter fullscreen mode Exit fullscreen mode

3. Bottom List


 

showDialogBottomList({
Items: ["I am item one", "I am item two"],
itemClick: (position: number) => {
console.log("==========:" + position)
}
})
Enter fullscreen mode Exit fullscreen mode

4. Confirm the prompt information pop-up window


 

showDialogConfirm({
Title: "I am a title",
Message: "I am a description",
isShowInformation: true, //Display Information
informationAttribute: {
checkboxSelect: true, //Is it selected by default
iconAttribute: {
srcSelect: $r("app.media.startIcon"), //Select
srcUnselected: $r("app.media.loading001"), //Not selected
},
onChange: (isChange) => {
//Clicking changed the status
console.log("===" + isChange)
}
},
clickCancel: () => {
//Cancel
//hide()
Console.log ("===Cancel")
},
clickConfirm: () => {
//Confirm
Console.log (===Confirm)
}
})
Enter fullscreen mode Exit fullscreen mode

5. Bottom List


 

showDialogBottomList({
Items: ["I am item one", "I am item two"],
itemClick: (position: number) => {
console.log("==========:" + position)
}
})
Enter fullscreen mode Exit fullscreen mode

6. The bottom list is transparent

showDialogBottomList({
Items: ["I am item one", "I am item two"],
itemClick: (position: number) => {
console.log("==========:" + position)
},
isTransparent: true,
dialogAttribute: {
dialogMarginLeft: 20,
dialogMarginRight: 20
}
})
Enter fullscreen mode Exit fullscreen mode

7. Bottom List Multi-style


 

showDialogBottomList({
ItemModels: [new BottomListModel ("Item 1", {fontColor: Color. Red}), new BottomListModel ("Item 2")],
itemClick: (position: number) => {
hide()
}
})
Enter fullscreen mode Exit fullscreen mode

8. Bottom Grid List


 

showDialogBottomGrid({
columnSize: 4,
Items: [new BottomGridModel ("WeChat", $r ("app. media. app_icon")),
New BottomGridModel ("Moments", $r ("app. media. app_icon"),
new BottomGridModel("QQ", $r("app.media.app_icon")),
New BottomGridModel ("QQ Space", $r ("app. media. app_icon"),
New BottomGridModel (Weibo, $r (app. media. app_icon)),
New BottomGridModel (Weibo, $r (app. media. app_icon)),
New BottomGridModel (Weibo, $r (app. media. app_icon)),
New BottomGridModel ("Weibo", $r ("app. media. app_icon")
],
itemClick: (position) => {
console.log("==============:" + position)
}
})
Enter fullscreen mode Exit fullscreen mode

9. The bottom grid is distinguished by rows


 

showDialogBottomGrid({
columnSize: 4,
isShowBottomCancel: true,
isHideBar: true,
itemLineArray: [
[new BottomGridModel ("Test", $r ("app. media. app_icon")),
New BottomGridModel ("Test", $r ("app. media. app_icon")),
[new BottomGridModel ("Test", $r ("app. media. app_icon")),
New BottomGridModel ("Test", $r ("app. media. app_icon"),
New BottomGridModel ("Test", $r ("app. media. app_icon"))
],
itemClick: (position) => {
console.log("==============" + position)
}
})
Enter fullscreen mode Exit fullscreen mode

10. Custom Component Pop-up Window 

the first thing to do is to customize a global Components , you can pass in custom components, or write the layout directly.

 

/*
* Author:AbnerMing
*Description: Custom pop ups, self defined layout
*/
@Builder
function BuilderDialog() {
Column() {
Text ("I am a custom pop-up")
.margin({ top: 30 })
Row() {
Button ("Cancel"). onClick()=>{
//Hide dialog
hide()
})
Button ("OK")
.margin({ left: 30 })
}.margin({ top: 20 })
.margin({ top: 30 })
}.backgroundColor(Color.White)
.width("60%")
}
Enter fullscreen mode Exit fullscreen mode

Code call

 

showDialog(wrapBuilder(BuilderDialog))
Enter fullscreen mode Exit fullscreen mode

11. Custom Component Pop-up Parameters 

the first thing to do is to customize a global Components , you can pass in custom components, or write the layout directly.

 

class DialogParams {
title? : string
}

@Builder
function BuilderDialogParams(params: DialogParams) {
Column() {
Text(params.title)
.margin({ top: 30 })
Row() {
Button ("Cancel"). onClick()=>{
//Hide dialog
hide()
})
Button ("OK")
.margin({ left: 30 })
}.margin({ top: 20 })
.margin({ top: 30 })
}.backgroundColor(Color.White)
.width("60%")
}
Enter fullscreen mode Exit fullscreen mode

Code call

 

let params = new DialogParams()
Params. title="I am the passed parameter"
showDialogParams(wrapBuilder(BuilderDialogParams), params)
Enter fullscreen mode Exit fullscreen mode

12. toast Tips


 

Toast ("I am an ordinary toast")
Enter fullscreen mode Exit fullscreen mode

13. toast changes the background


 

Toast ("I am a background changing Toast", {backgroundColor: Color. Red})
Enter fullscreen mode Exit fullscreen mode

14. toast changes position


 

Toast ("I am a relocated Toast", {alignment: DialogAlignment. Center})
Enter fullscreen mode Exit fullscreen mode

15. toast picture setting


 

Toast ("Toast Set Icon", {leftSrc: $r ("app. media. app_icon")})
Enter fullscreen mode Exit fullscreen mode

16. Bottom List


 

showDialogBottomListScroll({
Items: ["Male", "Female"],
titleBarAttribute: {
Title Text: "Choose Gender"
},
confirmClick: (value, index) => {
console.log(value + "=========" + index)
}
})
Enter fullscreen mode Exit fullscreen mode

17. The bottom double list is not linked


 

showDialogBottomListScroll({
selected: [1, 2],
Items: [["First Column 1", "First Column 2"], ["Second Column 1", "Second Column 2", "Second Column 3"],
titleBarAttribute: {
Title Text: "Bottom dual list not linked"
},
confirmClick: (value, index) => {
console.log(value + "=========" + index)
}
})
Enter fullscreen mode Exit fullscreen mode

18. Bottom double list linkage


 

showDialogBottomListScroll({
items: this.doubleList,
titleBarAttribute: {
Title Text: "Bottom Double List Linkage"
},
confirmClick: (value, index) => {
console.log(value + "=========" + index)
}
})
Enter fullscreen mode Exit fullscreen mode

19, the bottom three list linkage


 

showDialogBottomListScroll({
items: this.thirdList,
titleBarAttribute: {
Title Text: "Bottom Three List Linkage",
},
confirmClick: (value, index) => {
console.log(value + "=========" + index)
}
})
Enter fullscreen mode Exit fullscreen mode

20, year, month, day, hour, minute and second time pop-up window


 

showDialogTime({
titleBarAttribute: {
Title Text: "Year Month Day Hour Minute Second Pop up",
},
timeAttribute: {
timeType: TimeDialogType.YMDHMS,
},
timeConfirmClick: (date) => {
//Time callback
Console.log (===time result:+date)
},
confirmClick: (value, index) => {
//Content and index callbacks
Console.log ("===Content result:"+value+"===Index result:"+index)
}
})
Enter fullscreen mode Exit fullscreen mode

21, year, month, day, pop-up window


 

showDialogTime({
titleBarAttribute: {
Title Text: "Month Day Hour Time Pop up",
},
timeAttribute: {
timeType: TimeDialogType.YMDHM
},
timeConfirmClick: (date) => {
//Time callback
Console.log (===time result:+date)
},
confirmClick: (value, index) => {
//Content and index callbacks
Console.log ("===Content result:"+value+"===Index result:"+index)
}
})
Enter fullscreen mode Exit fullscreen mode

22, year, month, pop-up window


 

showDialogTime({
titleBarAttribute: {
Title Text: "Year Month Day Pop up",
},
timeAttribute: {
startTime: "2022-6-12",
endTime: "2025-8-20",
},
timeConfirmClick: (date) => {
//Time callback
},
confirmClick: (value, index) => {
//Content and index callbacks
}
})
Enter fullscreen mode Exit fullscreen mode

23, month and day pop-up window


 

showDialogTime({
titleBarAttribute: {
Title Text: "Month Day Pop up",
},
timeAttribute: {
timeType: TimeDialogType.MD
},
timeConfirmClick: (date) => {
//Time callback
},
confirmClick: (value, index) => {
//Content and index callbacks
}
})
Enter fullscreen mode Exit fullscreen mode

24, minutes and seconds pop-up window


 

showDialogTime({
titleBarAttribute: {
Title Text: "Hours, minutes, seconds - Pop up",
},
timeAttribute: {
timeType: TimeDialogType.HMS,
},
timeConfirmClick: (date) => {
//Time callback
},
confirmClick: (value, index) => {
//Content and index callbacks
}
})
Enter fullscreen mode Exit fullscreen mode

25, city address pop-up window


 

showDialogAddress({
titleBarAttribute: {
Title Text: "City Address Pop up",
},
confirmClick: (value, index) => {
}
})
Enter fullscreen mode Exit fullscreen mode

26. PopupWindow pops up

First of all, to define the pop-up components, custom can be, support custom component form, pass in can be

 

/**
* AUTHOR:AbnerMing
*INTRODUCE: Popup pop-up box, customizable, any component
* */
@Builder
function BuilderWindowView() {
Text ("I am any component")
.backgroundColor(Color.Pink)
}
Enter fullscreen mode Exit fullscreen mode

arbitrary position


 

showPopupWindow({
  view: wrapBuilder(BuilderWindowView),
  x: 60,
  y: 300
})
Enter fullscreen mode Exit fullscreen mode

top


 

showPopupWindow({
  id: "popupTop",
  view: wrapBuilder(BuilderWindowView)
})
Enter fullscreen mode Exit fullscreen mode

down


 

showPopupWindow({
  id: "popupBottom",
  view: wrapBuilder(BuilderWindowView),
  direction: PopupDirection.BOTTOM
})
Enter fullscreen mode Exit fullscreen mode

left


 

showPopupWindow({
  id: "popupLeft",
  view: wrapBuilder(BuilderWindowView),
  direction: PopupDirection.LEFT
})
Enter fullscreen mode Exit fullscreen mode

right


 

showPopupWindow({
  id: "popupRight",
  view: wrapBuilder(BuilderWindowView),
  direction: PopupDirection.RIGHT
})
Enter fullscreen mode Exit fullscreen mode

top Left


 

showPopupWindow({
  id: "popupTopLeft",
  view: wrapBuilder(BuilderWindowView),
  direction: PopupDirection.TOP_LEFT
})
Enter fullscreen mode Exit fullscreen mode

top Right


 

showPopupWindow({
  id: "popupTopRight",
  view: wrapBuilder(BuilderWindowView),
  direction: PopupDirection.TOP_RIGHT
})
Enter fullscreen mode Exit fullscreen mode

lower left


 

showPopupWindow({
  id: "popupBottomLeft",
  view: wrapBuilder(BuilderWindowView),
  direction: PopupDirection.BOTTOM_LEFT
})
Enter fullscreen mode Exit fullscreen mode

lower right


 

showPopupWindow({
  id: "popupBottomRight",
  view: wrapBuilder(BuilderWindowView),
  direction: PopupDirection.BOTTOM_RIGHT
})
Enter fullscreen mode Exit fullscreen mode

carry parameters


 

class WindowParams {
  title?: string
}

@Builder
  function BuilderWindowParams(params: WindowParams) {
    Text(params.title)
      .backgroundColor(Color.Pink)
  }


let params = new WindowParams()
params.title = "params"
showPopupWindow({
  id: "popupParams",
  params: params,
  viewParams: wrapBuilder(BuilderWindowParams),
  direction: PopupDirection.BOTTOM
})
Enter fullscreen mode Exit fullscreen mode

use summary 

each pop-up window has a unified hiding, just call the hide method directly. If you want the animation effect of the bottom pop-up window, there are currently two ways, one is the system's own, the other is custom, the system's own, animation is, the whole background slides together, the custom is that the background does not move, only the pop-up components move, the specific effect to use, mainly depends on your own needs, in addition, the pop-up animation at the bottom also encapsulates an animation component. BottomAnimationView can easily realize animation. You can also use it if you need it. There are also cases in related Demo. 

It should be noted that if there is a floating window in your project, it may appear that the pop-up pop-up window is in the window of the floating window. In order to solve this problem, you can choose whether to pop up the main window or the sub-window.

initDialog({
      isUseMainWindow:true
    })
Enter fullscreen mode Exit fullscreen mode

Top comments (0)