화어하모니OS 개발: Tabs 컴포넌트 심층 가이드

화어하모니OS 개발: Tabs 컴포넌트 심층 가이드

소개

모바일 앱 디자인에서 탭(Tabs)은 사용자가 다른 콘텐츠 영역을 전환하는 데 중요한 인터페이스 요소입니다. 화어하모니OS 운영체제에서 제공하는 Tabs 컴포넌트는 개발자가 고도로 맞춤화된 탭 인터페이스를 생성할 수 있도록 지원합니다. 본문에서는 DevEco Studio를 통해 Tabs 컴포넌트의 사용법을 상세히 소개하며, 기본 설정, 동적 탭 생성, 그리고 고유한 시각 효과를 구현하기 위한 커스텀 컴포넌트 활용 방법을 다룹니다.

Tabs 컴포넌트 기초

Tabs 컴포넌트는 개발자가 스크롤 가능한 탭 그룹을 생성하고 각 탭에 해당하는 다른 콘텐츠 영역을 연결할 수 있게 해줍니다.

기본 사용법

예제 1: 기본 Tabs 탭 생성
@Entry
@Component
struct MainView {
  build() {
    Tabs() {
      TabContent() {
        Text('탐색 콘텐츠') // 단 하나의 자식 컴포넌트만 허용
      }
      .tabBar('탐색') // 네비게이션 설정

      TabContent() {
        Text('트렌드 콘텐츠') // 단 하나의 자식 컴포넌트만 허용
      }
      .tabBar('트렌드')

      TabContent() {
        Text('핫토픽 콘텐츠') // 단 하나의 자식 컴포넌트만 허용
      }
      .tabBar('핫토픽')

      TabContent() {
        Text('프로필 콘텐츠') // 단 하나의 자식 컴포넌트만 허용
      }
      .tabBar('프로필')
    }
  }
}

이 예제에서는 네 개의 탭을 포함하는 Tabs 컴포넌트를 생성했으며, 각 탭은 서로 다른 주제의 텍스트 콘텐츠를 표시합니다.

네비게이션 설정

예제 2: Tabs 네비게이션 속성 설정
@Entry
@Component
struct MainView {
  build() {
    Tabs({
      barPosition: BarPosition.Start // 네비게이션 위치
    })
    {
      TabContent() {
        Text('탐색 콘텐츠')
      }
      .tabBar('탐색')

      TabContent() {
        Text('트렌드 콘텐츠')
      }
      .tabBar('트렌드')

      TabContent() {
        Text('핫토픽 콘텐츠')
      }
      .tabBar('핫토픽')

      TabContent() {
        Text('프로필 콘텐츠')
      }
      .tabBar('프로필')
    }
    .vertical(false) // 네비게이션 수직/수평 설정
    .scrollable(false) // 제스처 스크롤 활성화 여부
    .animationDuration(0) // 클릭 시 슬라이딩 애니메이션 시간
  }
}

이 예제에서는 Tabs 컴포넌트의 네비게이션 속성을 설정했으며, 네비게이션 위치, 스크롤 제스처 및 애니메이션 시간이 포함됩니다.

동적 Tabs 생성

예제 3: ForEach를 사용한 동적 Tabs 생성
@Entry
@Component
struct MainView {
  tabTitles: string[] = [
    '탐색', '트렌드', '핫토픽', '기술', '엔터테인먼트',
    '스포츠', '교육', '건강', '금융', '여행'
  ]

  build() {
    Tabs() {
      ForEach(this.tabTitles, (title: string, index) => {
        TabContent() {
          Text(`${title} 콘텐츠`)
        }
        .tabBar(title)
      })
    }
    .barMode(BarMode.Scrollable) // 스크롤 가능한 네비게이션 바 구현
  }
}

이 예제에서는 ForEach 루프를 사용하여 10개의 탭을 동적으로 생성했으며, 각 탭의 제목은 tabTitles 배열에서 가져옵니다.

Tabs 스타일 커스터마이징

예제 4: Tabs 스타일 커스터마이징
@Entry
@Component
struct MainView {
  @Builder
  customTabBuilder(title: string, icon: ResourceStr) {
    Column() {
      Image(icon)
        .width(30)
      Text(title)
    }
  }

  build() {
    Tabs({
      barPosition: BarPosition.End
    })
    {
      TabContent() {
        Text('메시지 콘텐츠')
      }
      .tabBar(this.customTabBuilder('메시지', $r('app.media.icon_message')))

      TabContent() {
        Text('설정 콘텐츠')
      }
      .tabBar(this.customTabBuilder('설정', $r('app.media.icon_settings')))
    }
  }
}

이 예제에서는 @Builder 함수 customTabBuilder를 정의하여 각 탭의 스타일을 커스터마이징하며, 이미지와 텍스트를 포함합니다.

상태 관리

예제 5: Tabs 활성 상태 관리
@Entry
@Component
struct MainView {
  @State activeIndex: number = 0

  @Builder
  customTabBuilder(itemIndex: number, title: string, normalIcon: ResourceStr, activeIcon: ResourceStr) {
    Column() {
      Image(itemIndex == this.activeIndex ? activeIcon : normalIcon)
        .width(30)
      Text(title)
        .fontColor(itemIndex == this.activeIndex ? Color.Red : Color.Black)
    }
  }

  build() {
    Tabs()
    {
      TabContent() {
        Text('메시지 콘텐츠')
      }
      .tabBar(this.customTabBuilder(0, '메시지', $r('app.media.icon_message'), $r('app.media.icon_message_active')))

      TabContent() {
        Text('설정 콘텐츠')
      }
      .tabBar(this.customTabBuilder(1, '설정', $r('app.media.icon_settings'), $r('app.media.icon_settings_active')))
    }
    .onChange((index: number) => {
      this.activeIndex = index
    })
    .animationDuration(0)
    .scrollable(false)
  }
}

이 예제에서는 @State 속성 activeIndex를 사용하여 현재 활성화된 탭의 인덱스를 저장하고, onChange 이벤트에서 이 인덱스를 업데이트합니다.

특수 모양의 탭

예제 6: 특수 모양의 탭 추가
@Entry
@Component
struct MainView {
  @State activeIndex: number = 0

  @Builder
  customTabBuilder(itemIndex: number, title: string, normalIcon: ResourceStr, activeIcon: ResourceStr) {
    Column() {
      Image(itemIndex == this.activeIndex ? activeIcon : normalIcon)
        .width(30)
      Text(title)
        .fontColor(itemIndex == this.activeIndex ? Color.Red : Color.Black)
    }
  }

  @Builder
  specialTabBuilder() {
    Image($r('app.media.special_icon'))
      .width(40)
      .margin({ bottom: 10 })
  }

  build() {
    Tabs()
    {
      TabContent() {
        Text('홈 콘텐츠')
      }
      .tabBar(this.customTabBuilder(0, '홈', $r('app.media.icon_home'), $r('app.media.icon_home_active')))

      TabContent() {
        Text('카테고리 콘텐츠')
      }
      .tabBar(this.customTabBuilder(1, '카테고리', $r('app.media.icon_category'), $r('app.media.icon_category_active')))

      TabContent() {
        Text('이벤트 콘텐츠')
      }
      .tabBar(this.specialTabBuilder())

      TabContent() {
        Text('장바구니 콘텐츠')
      }
      .tabBar(this.customTabBuilder(3, '장바구니', $r('app.media.icon_cart'), $r('app.media.icon_cart_active')))

      TabContent() {
        Text('프로필 콘텐츠')
      }
      .tabBar(this.customTabBuilder(4, '프로필', $r('app.media.icon_profile'), $r('app.media.icon_profile_active')))
    }
    .onChange((index: number) => {
      this.activeIndex = index
    })
    .animationDuration(0)
    .scrollable(false)
  }
}

이 예제에서는 특수 모양의 탭을 추가하고 specialTabBuilder 함수를 사용하여 그 스타일을 커스터마이징합니다.

태그: 화어하모니OS DevEco Studio Tabs 컴포넌트 하모니OS 개발 커스텀 UI

7월 12일 16:48에 게시됨