0


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

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

  1. Row官方说自身属性是可获焦的,但是单独使用是没法获焦的,所以必须在里面添加一个可获焦的子view,但是通常所有的子view都是由获焦和离焦状态的,所以不能所有的子view都加上focusable=true,这里可以通过@Consume来同步整个组件内部的焦点状态, 注意这个修饰符达到同步的前提是参数名一模一样!!!
@Component
export struct RowFocusable {compWidth: Length ='90vp'compHeight: Length ='28vp'compBorderRadius: Length ='14vp'alignItems: VerticalAlign = VerticalAlign.Center
  justifyContent: FlexAlign = FlexAlign.Center

  @Consume focusState: number

  @Builder doAddChild(){}
  @BuilderParam addChild:()=>void=this.doAddChild;build(){Row(){//扯淡的玩意,容器布局的子节点没有获焦能力的话,容器布局就不会获焦,//但是子节点能获焦的话,那其他所有有焦点态的子节点也必须设置可获焦,那走焦的时候会在子节点之间走动,不合理,非常的不合理,//竟然没有父组件拦截焦点的方法Text('').focusable(true).onFocus(()=>{this.focusState = ComponentsConstants.FOCUS_STATE_FOCUSED}).onBlur(()=>{this.focusState = ComponentsConstants.FOCUS_STATE_NORMAL}).width('0vp')this.addChild()}.width(this.compWidth).height(this.compHeight).justifyContent(this.justifyContent).alignItems(this.alignItems).focusOnTouch(true).borderWidth(2).borderRadius(this.compBorderRadius).borderStyle(BorderStyle.Solid).onFocus(()=>{}).onBlur(()=>{}).stateStyles({focused:{.backgroundColor($r('app.color.transparent')},normal:{.backgroundColor($r('app.color.transparent')},})}}

自定义component 后面直接设置基础属性,像上面这种只有一个@BuildParam方法的可以直接这样写,在大括号后面接上需要添加的子组件即可:

@Component
export struct ImageButton {btnWidth: Length ='90vp'btnHeight: Length ='28vp'imgWidth: Length ='15vp'imgHeight: Length ='15vp'tvCfg: TextFocusConfig |undefined=undefinedimgCfg: ImageFocusConfig |undefined=undefined
  @Provide focusState: number = ComponentsConstants.FOCUS_STATE_NORMAL

  @Builder buildImage(){ImageFocusable({imgCfg:this.imgCfg}).width(this.imgWidth).height(this.imgHeight)}

  @Builder buildText(){TextFocusable({tvCfg:this.tvCfg})}build(){RowFocusable({compWidth:this.btnWidth,compHeight:this.btnHeight }){this.buildImage()this.buildText()}}}//自定义,统一设置占位图
@Component
export struct ImageFocusable {

  @Consume focusState: number
  imgCfg: ImageFocusConfig|undefinedbuild(){Image(this.focusState==ComponentsConstants.FOCUS_STATE_FOCUSED?this.imgCfg.imgResFocused :this.imgCfg.imgResNormal).objectFit(ImageFit.Contain).enabled(true).alt($r('app.media.poster_placeholder'))}}//这里定义成config类,是为了方便组件层级太深时,更好的透传,比如上面ImageButtonexportclassImageFocusConfig{imgResNormal: ResourceStr
  imgResFocused: ResourceStr

  constructor(imgResNormal,imgResFocused){this.imgResNormal = imgResNormal
    this.imgResFocused = imgResFocused
  }}

@Component
export struct TextFocusable {
  @Consume focusState: number

  tvCfg: TextFocusConfig |undefinedbuild(){if(this.tvCfg !=null){Text(this.tvCfg!.text).fontColor(this.focusState == ComponentsConstants.FOCUS_STATE_FOCUSED?this.tvCfg!.focusColor :this.tvCfg.normalColor).textAlign(this.tvCfg.textAlign).maxLines(this.tvCfg.maxLine).textOverflow({overflow:this.tvCfg.textOverFlow}).align(Alignment.Center).width(this.tvCfg.width).height(this.tvCfg.height).fontSize(this.tvCfg.textSize)}}}exportclassTextFocusConfig{text: ResourceStr
  textSize: Length
  width: Length
  height: Length
  normalColor: ResourceColor
  focusColor: ResourceColor
  selectColor: ResourceColor
  textAlign: TextAlign
  maxLine: number
  textOverFlow: TextOverflow

  constructor()constructor(text?)constructor(text?, tvSize?)constructor(text?, tvSize?, width?, height?)constructor(text?, tvSize?, width?, height?, normalColor?, focusColor?, selectColor?)constructor(text?, tvSize?, width?, height?, normalColor?, focusColor?, selectColor?, textAlign?, maxLine?, textOverFlow?){this.text = text ??''this.textSize = tvSize ??'14vp'this.width = width ??'auto'this.height = height ??'auto'this.normalColor = normalColor ??$r('app.color.white_70')this.focusColor = focusColor ??$r('app.color.white_100')this.selectColor = selectColor ??$r('app.color.tv_color_selected')this.textAlign = textAlign ?? TextAlign.Start
    this.maxLine = maxLine ??1this.textOverFlow = textOverFlow ?? TextOverflow.Ellipsis
  }setText(text): TextFocusConfig {this.text = text
    returnthis}setTextSize(size): TextFocusConfig {this.textSize = size
    returnthis}setWith(w): TextFocusConfig {this.width = w
    returnthis}setHeight(h): TextFocusConfig {this.height = h
    returnthis}}

像自定义text这种组件,很多属性都没法直接设置,所以需要添加自己命名的属性,然后也没有焦点态的方法,所以只能通过@Consume focusState: number 来同步父子组件之间的焦点状态,另外封装成config的好处还是挺多的,自我挖掘吧

标签: harmonyos 华为

本文转载自: https://blog.csdn.net/qq_36635270/article/details/140660832
版权归原作者 熊佳龙 所有, 如有侵权,请联系我们删除。

“鸿蒙9+在TV端焦点封装控制”的评论:

还没有评论