#HarmonyOS NEXT体验官#AtomGit-X项目实战讲解 原创

前端甄子丹
发布于 2024-7-30 17:49
浏览
0收藏

AtomGit-X

跨平台的开源AtomGit客户端App,更好的体验,更丰富的功能,旨在更好的日常管理和维护

本项目为OpenHarmony/HarmonyOS Next应用,基于ArkTS语言和OpenHarmony/HarmonyOS的API
11进行编写,使用了MVVM(Model、View、ViewModel)进行架构的搭建,数据来自AtomGit的OpenAPI。很好的利用OpenHarmony的技术特性。

AtomGit 是开放原子开源基金会旗下的具有自主核心技术的开源代码托管平台,为开源软件、开源硬件、开源芯片等各类开源项目提供基于
Git 协议的源码托管服务,推动创新资源共建共享。

架构设计

#HarmonyOS NEXT体验官#AtomGit-X项目实战讲解-鸿蒙开发者社区

API文档

https://docs.atomgit.com/category/api/

功能规划

实现的可以打对号
UI仿照Gitee和Github
代码仿照Gitee

1.安全登陆-OAuth登陆
2.access_token的缓存和access_token过期后用refresh_token获取access_token
3.个人信息的查看与修改(用户基本信息,昵称,头像,简介等)
4.我的关注(关注列表,用户基本信息)
5.我的粉丝(粉丝列表,用户基本信息)
6.仓库的基本信息查看(Commit记录,仓库README)
7.仓库的搜索(条件搜索,模糊搜索)
8.用户搜索()
9.PR(PR列表,合并PR)
10.组织(获取个人组织列表,组织成员资料,创建组织,退出组织)
11.仓库数据( 指数,获取目录Tree)
12.动态(Star了仓库用户,Watch了仓库用户,列出用户动态)
13.主题切换
14.历史阅读
15.个人信息的查看与修改
16.灰度APP(一些节假日)
17.关于
18.退出登陆
19.一多适配
20.账号密码登陆

部分功能点介绍

侧边栏SideBarContainer :提供侧边栏可以显示和隐藏的侧边栏容器,通过子组件定义侧边栏和内容区,第一个子组件表示侧边栏,第二个子组件表示内容区。

接口说明

SideBarContainer( type?: SideBarContainerType )

参数:

参数名 参数类型 必填 参数描述
type SideBarContainerType 设置侧边栏的显示类型。默认值:SideBarContainerType.Embed

属性说明

名称 参数类型 描述
showSideBar boolean 设置是否显示侧边栏。默认值:true
controlButton ButtonStyle 设置侧边栏控制按钮的属性。
showControlButton boolean 设置是否显示控制按钮。默认值:true
sideBarWidth number | Length9+ 设置侧边栏的宽度。默认值:200单位:vp**说明:**设置为小于0的值时按默认值显示。受最小宽度和最大宽度限制,不在限制区域内取最近的点。sideBarWidth优先于侧边栏子组件width,sideBarWidth未设置时默认值优先级高于侧边栏子组件width。
minSideBarWidth number | Length9+ 设置侧边栏最小宽度。默认值:200,单位vp**说明:**设置为小于0的值时按默认值显示。值不能超过侧边栏容器本身宽度,超过使用侧边栏容器本身宽度。minSideBarWidth优先于侧边栏子组件minWidth,minSideBarWidth未设置时默认值优先级高于侧边栏子组件minWidth。
maxSideBarWidth number | Length9+ 设置侧边栏最大宽度。默认值:280,单位vp**说明:**设置为小于0的值时按默认值显示。值不能超过侧边栏容器本身宽度,超过使用侧边栏容器本身宽度。maxSideBarWidth优先于侧边栏子组件maxWidth,maxSideBarWidth未设置时默认值优先级高于侧边栏子组件maxWidth。
autoHide9+ boolean 设置当侧边栏拖拽到小于最小宽度后,是否自动隐藏。默认值:true**说明:**受minSideBarWidth属性方法影响,minSideBarWidth属性方法未设置值使用默认值。拖拽过程中判断是否要自动隐藏。小于最小宽度时需要阻尼效果触发隐藏(越界一段距离)
sideBarPosition9+ SideBarPosition 设置侧边栏显示位置。默认值:SideBarPosition.Start

效果

#HarmonyOS NEXT体验官#AtomGit-X项目实战讲解-鸿蒙开发者社区
#HarmonyOS NEXT体验官#AtomGit-X项目实战讲解-鸿蒙开发者社区

关键代码

//SideBarContainer 组件
SideBarContainer(SideBarContainerType.Overlay) {
      //侧边栏组件内的第一个组件为侧边栏内的内容
      //侧边栏组件,传入viewModel对象
      SideBarComponent({ viewModel: $mainViewModel,theme: this.themeClassa.data })

      //后续的组件为页面的内容

      //在Stack容器内有一个满屏幕的半透明组件,用于在侧边栏开启时形成阴影效果
      Stack() {
        Column() {
          //顶部工具栏
          TopNavigation({ theme: this.themeClassa.data })
          tabs({ mainViewModel: $mainViewModel, theme: this.themeClassa.data })
        }
        .width('100%')
        .height('100%')
        .backgroundColor($r("app.color.bg_default"))

        //判断当前侧边栏是否展开
        if (this.sideBarShow) {
          //全屏的半透明组件,用于在侧边栏展开时形成阴影效果
          Column() {
          }
          .width('100%')
          .height('100%')
          .backgroundColor($r("app.color.mask_default"))
          .onClick((() => {
            this.sideBarShow = !this.sideBarShow
          }))
        }
      }
      .width('100%')
      .height('100%')
    }
    .width('100%')
    .height('100%')
    .sideBarWidth(240)
    .minSideBarWidth(160)
    .maxSideBarWidth(300)
    .showSideBar(this.sideBarShow)
    //设置选项按钮的位置
    .controlButton({
      width: 30,
      height: 30,
      top: 20,
    })
    //监听侧边栏的状态,控制阴影的显影
    .onChange((value) => {
      this.sideBarShow = value
    })
//侧边栏组件
@Component
export default struct SideBarComponent {
  @Link viewModel: MainViewModel //组件所在页面的viewModel对象
  @ObjectLink @Watch('change') theme: themeClassw
  @State sliderList: objType[][] = []

  change() {
    this.setSliderList()
  }

  //设置循环数组
  setSliderList() {
    this.sliderList.length = 0
    this.sliderList.push([
      {
        icon: this.theme.icon_home, title: '主页', callback: () => {
        this.viewModel.onMyProfile()
      }
      },
      {
        icon: this.theme.icon_news, title: '动态', callback: () => {
        this.viewModel.onMyActivities()
      }
      },{
      icon: this.theme.icon_news, title: '组织', callback: () => {
        this.viewModel.onMyOrganizations()
      }
    }
    ],
      [
        {
          icon: this.theme.icon_repo, title: '我的仓库', callback: () => {
          this.viewModel.onMyRepos(this.viewModel.myProfile.login)
        }
        },
        {
          icon: this.theme.icon_fan, title: '我的粉丝', callback: () => {
          this.viewModel.onMyFans()
        }
        },
        {
          icon: this.theme.icon_follow, title: '我的关注', callback: () => {
          this.viewModel.onMyWatches()
        }
        },
        {
          icon: this.theme.icon_history, title: '历史阅读', callback: () => {
          // this.viewModel.onMyWatches()
        }
        }
      ],
      [
        {
          icon: this.theme.icon_theme, title: '主题切换', callback: () => {
          this.viewModel.onTheme()
        }
        },
        {
          icon: this.theme.icon_account, title: '切换账号', callback: () => {
          // this.viewModel.onMyProfile()
        }
        },
        {
          icon: this.theme.icon_logout, title: '退出登录', callback: () => {
          this.viewModel.onLogout()
          router.pushUrl({ url: Pages.webLogin })
        }
        },
        {
          icon: this.theme.icon_tip, title: '关于', callback: () => {
          this.viewModel.onAbout()
        }
        }
      ])
  }

  aboutToAppear(): void {
    this.setSliderList()
  }

  @Builder
  sliderItem(icon: Resource | null, title: string) {
    Row() {
      Row() {
        Image(icon)
          .width(20)
          .height(20)
          .margin({ top: 16, bottom: 18 })

        Text(title)
          .fontColor($r("app.color.text_ultrastrong"))
          .margin({ left: 12 })
      }

      Image($r('app.media.arrow')).width(16)
    }.width('100%').justifyContent(FlexAlign.SpaceBetween).padding({ left: 10, right: 10 })
  }

  build() {
    // Column() {
    Stack({ alignContent: Alignment.Top }) {
      //各个选项
      //TODO 用res中的常量替换下面选项的名字

      Column() {
        List() {
          ListItem() {
            Column() {
              ForEach(this.sliderList, (list: objType[]) => {
                ForEach(list, (item: objType) => {
                  Row() {
                    this.sliderItem(item.icon, item.title)
                  }.width('100%')
                  .onClick(() => {
                    item.callback()
                  })
                })
                Divider()
                  .color($r("app.color.boarder_medium"))
                  .margin({ top: 10, bottom: 10 })
              })
            }
          }
        }.margin({ top: 70 }).scrollBar(BarState.Off)
      }.width('100%').margin({ top: 96, left: 10, right: 10, bottom: 10 }).backgroundColor(Color.White).borderRadius(10)

      //用户基本信息
      Row() {
        //用户头像(url)
        Image(this.viewModel.myProfile.avatar_url)
          .width(70)
          .height(70)
          .margin({ top: 12, left: 10 })//设置圆形裁剪
          .clip(new Circle({ width: `100%`, height: `100%` }))

        //用户名
        Text(this.viewModel.myProfile.name)
          .fontColor(Color.Black)
          .fontWeight(FontWeight.Bold)
          .fontSize('22fp')
          .margin({ left: 20, top: 10 })
          .width(100)
          .maxLines(1)
          .textOverflow({ overflow: TextOverflow.Ellipsis })
      }
      .width('100%')
      .padding({ top: 70 })
      .margin({ bottom: 16 })
    }.padding(10)
    .width('100%')
    .height('100%')
    .backgroundColor('#FAFAFA')
  }
}

参考

SideBarContainer-容器组件-ArkTS组件-ArkUI(方舟UI框架)-应用框架 | 华为开发者联盟 (huawei.com)

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
1
收藏
回复
举报
回复
    相关推荐