鸿蒙9+在TV端焦点封装控制

打印 上一主题 下一主题

主题 834|帖子 834|积分 2504

鸿蒙9+ 现在不支持鸿蒙体系电视,但是以后肯定是必须会支持的,以是直接学arkts就完事了,现在的api9+对焦点控制还是不够直接简便,估计还在完善中,但是可以通过自定义component来实现一下
首先踩坑:

  • Row官方说自身属性是可获焦的,但是单独利用是没法获焦的,以是必须在里面添加一个可获焦的子view,但是通常所有的子view都是由获焦和离焦状态的,以是不能所有的子view都加上focusable=true,这里可以通过@Consume来同步整个组件内部的焦点状态, 注意这个修饰符达到同步的条件是参数名千篇一律!!!
  1. @Component
  2. export struct RowFocusable {
  3.   compWidth: Length = '90vp'
  4.   compHeight: Length = '28vp'
  5.   compBorderRadius: Length = '14vp'
  6.   alignItems: VerticalAlign = VerticalAlign.Center
  7.   justifyContent: FlexAlign = FlexAlign.Center
  8.   @Consume focusState: number
  9.   @Builder doAddChild(){}
  10.   @BuilderParam addChild: () => void = this.doAddChild;
  11.   build() {
  12.     Row() {
  13.       //扯淡的玩意,容器布局的子节点没有获焦能力的话,容器布局就不会获焦,
  14.       //但是子节点能获焦的话,那其他所有有焦点态的子节点也必须设置可获焦,那走焦的时候会在子节点之间走动,不合理,非常的不合理,
  15.       //竟然没有父组件拦截焦点的方法
  16.       Text('').focusable(true)
  17.         .onFocus(()=>{
  18.           this.focusState = ComponentsConstants.FOCUS_STATE_FOCUSED
  19.         })
  20.         .onBlur(()=>{
  21.           this.focusState = ComponentsConstants.FOCUS_STATE_NORMAL
  22.         }).width('0vp')
  23.       this.addChild()
  24.     }
  25.     .width(this.compWidth).height(this.compHeight)
  26.     .justifyContent(this.justifyContent)
  27.     .alignItems(this.alignItems)
  28.     .focusOnTouch(true)
  29.     .borderWidth(2)
  30.     .borderRadius(this.compBorderRadius)
  31.     .borderStyle(BorderStyle.Solid)
  32.     .onFocus(()=>{
  33.     })
  34.     .onBlur(()=>{
  35.     })
  36.     .stateStyles({
  37.       focused: {
  38.         .backgroundColor($r('app.color.transparent')
  39.       },
  40.       normal: {
  41.         .backgroundColor($r('app.color.transparent')
  42.       },
  43.     })
  44.   }
  45. }
复制代码
自定义component 反面直接设置底子属性,像上面这种只有一个@BuildParam方法的可以直接这样写,在大括号反面接上必要添加的子组件即可:
  1. @Component
  2. export struct ImageButton {
  3.   btnWidth: Length = '90vp'
  4.   btnHeight: Length = '28vp'
  5.   imgWidth: Length = '15vp'
  6.   imgHeight: Length = '15vp'
  7.   tvCfg: TextFocusConfig | undefined = undefined
  8.   imgCfg: ImageFocusConfig | undefined = undefined
  9.   @Provide focusState: number = ComponentsConstants.FOCUS_STATE_NORMAL
  10.   @Builder buildImage() {
  11.     ImageFocusable({imgCfg: this.imgCfg}).width(this.imgWidth).height(this.imgHeight)
  12.   }
  13.   @Builder buildText() {
  14.     TextFocusable({tvCfg: this.tvCfg})
  15.   }
  16.   build() {
  17.     RowFocusable({ compWidth: this.btnWidth, compHeight: this.btnHeight }) {
  18.       this.buildImage()
  19.       this.buildText()
  20.     }
  21.   }
  22. }
  23. //自定义,统一设置占位图
  24. @Component
  25. export struct ImageFocusable {
  26.   @Consume focusState: number
  27.   imgCfg: ImageFocusConfig|undefined
  28.   build() {
  29.     Image(this.focusState==ComponentsConstants.FOCUS_STATE_FOCUSED ? this.imgCfg.imgResFocused : this.imgCfg.imgResNormal)
  30.       .objectFit(ImageFit.Contain)
  31.       .enabled(true)
  32.       .alt($r('app.media.poster_placeholder'))
  33.   }
  34. }
  35. //这里定义成config类,是为了方便组件层级太深时,更好的透传,比如上面ImageButton
  36. export class ImageFocusConfig {
  37.   imgResNormal: ResourceStr
  38.   imgResFocused: ResourceStr
  39.   constructor(imgResNormal,imgResFocused) {
  40.     this.imgResNormal = imgResNormal
  41.     this.imgResFocused = imgResFocused
  42.   }
  43. }
  44. @Component
  45. export struct TextFocusable {
  46.   @Consume focusState: number
  47.   tvCfg: TextFocusConfig | undefined
  48.   build() {
  49.     if (this.tvCfg != null) {
  50.       Text(this.tvCfg!.text)
  51.         .fontColor(this.focusState == ComponentsConstants.FOCUS_STATE_FOCUSED ? this.tvCfg!.focusColor : this.tvCfg.normalColor)
  52.         .textAlign(this.tvCfg.textAlign)
  53.         .maxLines(this.tvCfg.maxLine)
  54.         .textOverflow({overflow: this.tvCfg.textOverFlow})
  55.         .align(Alignment.Center)
  56.         .width(this.tvCfg.width)
  57.         .height(this.tvCfg.height)
  58.         .fontSize(this.tvCfg.textSize)
  59.     }
  60.   }
  61. }
  62. export class TextFocusConfig {
  63.   text: ResourceStr
  64.   textSize: Length
  65.   width: Length
  66.   height: Length
  67.   normalColor: ResourceColor
  68.   focusColor: ResourceColor
  69.   selectColor: ResourceColor
  70.   textAlign: TextAlign
  71.   maxLine: number
  72.   textOverFlow: TextOverflow
  73.   constructor()
  74.   constructor(text?)
  75.   constructor(text?, tvSize?)
  76.   constructor(text?, tvSize?, width?, height?)
  77.   constructor(text?, tvSize?, width?, height?, normalColor?, focusColor?, selectColor?)
  78.   constructor(text?, tvSize?, width?, height?, normalColor?, focusColor?, selectColor?, textAlign?, maxLine?, textOverFlow?) {
  79.     this.text = text ?? ''
  80.     this.textSize = tvSize ?? '14vp'
  81.     this.width = width ?? 'auto'
  82.     this.height = height ?? 'auto'
  83.     this.normalColor = normalColor ?? $r('app.color.white_70')
  84.     this.focusColor = focusColor ?? $r('app.color.white_100')
  85.     this.selectColor = selectColor ?? $r('app.color.tv_color_selected')
  86.     this.textAlign = textAlign ?? TextAlign.Start
  87.     this.maxLine = maxLine ?? 1
  88.     this.textOverFlow = textOverFlow ?? TextOverflow.Ellipsis
  89.   }
  90.   setText(text): TextFocusConfig {
  91.     this.text = text
  92.     return this
  93.   }
  94.   setTextSize(size): TextFocusConfig {
  95.     this.textSize = size
  96.     return this
  97.   }
  98.   setWith(w): TextFocusConfig {
  99.     this.width = w
  100.     return this
  101.   }
  102.   setHeight(h): TextFocusConfig {
  103.     this.height = h
  104.     return this
  105.   }
  106. }
复制代码
像自定义text这种组件,很多属性都没法直接设置,以是必要添加自己定名的属性,然后也没有焦点态的方法,以是只能通过@Consume focusState: number 来同步父子组件之间的焦点状态,别的封装成config的利益还是挺多的,自我挖掘吧

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

南七星之家

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表