设计概述

基于HarmonyOS 5和HarmonyOS Design规范,我们将创建一个功能完善的房屋出租查询小程序,包含房源浏览、地图找房、筛选搜索和收藏管理等功能。

核心功能实现

1. 主界面设计 (ArkUI)

// MainPage.ets
@Entry
@Component
struct MainPage {
  @State currentTab: number = 0
  
  build() {
    Column() {
      // 顶部搜索栏
      Search({
        placeholder: '输入小区、地铁或商圈',
        controller: new SearchController()
      })
      .width('90%')
      .margin(20)
      .onSubmit((value: string) => {
        router.push({
          url: 'pages/SearchResultPage',
          params: { keyword: value }
        })
      })
      
      // 快捷筛选入口
      QuickFilterBar()
        .margin({ bottom: 12 })
      
      // 内容区
      Tabs({ barPosition: BarPosition.Start }) {
        TabContent() {
          HouseList()
        }.tabBar('房源列表')
        
        TabContent() {
          MapView()
        }.tabBar('地图找房')
        
        TabContent() {
          FavoritesList()
        }.tabBar('我的收藏')
      }
      .barWidth('100%')
      .barHeight(48)
      .onChange((index: number) => {
        this.currentTab = index
      })
    }
    .width('100%')
    .height('100%')
  }
}

2. 房源卡片组件

// HouseCard.ets
@Component
export struct HouseCard {
  private houseInfo: HouseInfo
  
  build() {
    Column() {
      // 房源图片
      Stack() {
        Image(this.houseInfo.images[0])
          .width('100%')
          .height(180)
          .objectFit(ImageFit.Cover)
          .borderRadius(8)
        
        // 价格标签
        Text(this.houseInfo.price)
          .fontSize(18)
          .fontColor(Color.White)
          .backgroundColor('#6200EE')
          .padding(8)
          .borderRadius(4)
          .position({ x: '80%', y: '80%' })
      }
      .margin({ bottom: 8 })
      
      // 房源基本信息
      Text(this.houseInfo.title)
        .fontSize(16)
        .fontWeight(FontWeight.Medium)
        .margin({ bottom: 4 })
      
      Row() {
        Text(`${this.houseInfo.area}㎡`)
        Text(`| ${this.houseInfo.layout}`)
        Text(`| ${this.houseInfo.district}`)
      }
      .fontSize(14)
      .fontColor('#666666')
      .margin({ bottom: 8 })
      
      // 房源标签
      Wrap() {
        ForEach(this.houseInfo.tags, (tag) => {
          Text(tag)
            .fontSize(12)
            .padding(4)
            .backgroundColor('#F5F5F5')
            .borderRadius(4)
            .margin({ right: 4, bottom: 4 })
        })
      }
    }
    .padding(12)
    .backgroundColor(Color.White)
    .borderRadius(8)
    .shadow({ radius: 4, color: '#1A000000', offsetX: 1, offsetY: 1 })
    .onClick(() => {
      router.push({
        url: 'pages/HouseDetailPage',
        params: { houseId: this.houseInfo.id }
      })
    })
  }
}

3. 地图找房功能

// MapView.ets
@Component
struct MapView {
  @State mapController: map.MapController = new map.MapController()
  @State markers: Array<map.Marker> = []
  
  aboutToAppear() {
    // 加载房源位置数据
    this.loadHouseMarkers()
  }
  
  private loadHouseMarkers() {
    // 模拟房源位置数据
    this.markers = [
      {
        position: { latitude: 39.90469, longitude: 116.40717 },
        icon: $r('app.media.map_marker'),
        title: '朝阳区两居室',
        snippet: '¥6500/月'
      }
      // 更多标记...
    ]
  }
  
  build() {
    Column() {
      Map({
        controller: this.mapController,
        markers: this.markers
      })
      .width('100%')
      .height('80%')
      .zoom(12)
      .center({ latitude: 39.90469, longitude: 116.40717 })
      .onMarkerClick((marker) => {
        // 点击标记跳转到详情页
        router.push({
          url: 'pages/HouseDetailPage',
          params: { houseId: marker.id }
        })
      })
      
      // 地图控制按钮
      Row() {
        Button('定位')
          .onClick(() => {
            this.mapController.animateTo({
              latitude: 39.90469, 
              longitude: 116.40717
            })
          })
        
        Button('筛选')
          .margin({ left: 12 })
          .onClick(() => {
            // 打开筛选面板
          })
      }
      .margin(12)
    }
  }
}

4. 房源筛选功能

// FilterPanel.ets
@Component
struct FilterPanel {
  @State priceRange: [number, number] = [2000, 8000]
  @State selectedLayouts: Array<string> = []
  @State selectedFeatures: Array<string> = []
  
  build() {
    Column() {
      // 价格区间
      Text('价格区间')
        .fontSize(16)
        .fontWeight(FontWeight.Medium)
        .margin({ bottom: 8 })
      
      Slider({
        value: this.priceRange[0],
        min: 1000,
        max: 15000,
        step: 500,
        style: SliderStyle.OutSet
      })
      .onChange((value: number) => {
        this.priceRange = [value, this.priceRange[1]]
      })
      
      Slider({
        value: this.priceRange[1],
        min: 1000,
        max: 15000,
        step: 500,
        style: SliderStyle.OutSet
      })
      .onChange((value: number) => {
        this.priceRange = [this.priceRange[0], value]
      })
      
      Text(`${this.priceRange[0]} - ${this.priceRange[1]} 元`)
        .fontSize(14)
        .margin({ top: 8, bottom: 16 })
      
      // 户型选择
      Text('户型')
        .fontSize(16)
        .fontWeight(FontWeight.Medium)
        .margin({ bottom: 8 })
      
      Wrap() {
        ForEach(['一居', '两居', '三居', '四居+'], (layout) => {
          Chip({
            label: layout,
            selected: this.selectedLayouts.includes(layout)
          })
          .onClick(() => {
            if (this.selectedLayouts.includes(layout)) {
              this.selectedLayouts = this.selectedLayouts.filter(item => item !== layout)
            } else {
              this.selectedLayouts.push(layout)
            }
          })
          .margin({ right: 8, bottom: 8 })
        })
      }
      .margin({ bottom: 16 })
      
      // 特色筛选
      Text('特色')
        .fontSize(16)
        .fontWeight(FontWeight.Medium)
        .margin({ bottom: 8 })
      
      Wrap() {
        ForEach(['近地铁', '精装修', '可短租', '独立卫浴'], (feature) => {
          Chip({
            label: feature,
            selected: this.selectedFeatures.includes(feature)
          })
          .onClick(() => {
            if (this.selectedFeatures.includes(feature)) {
              this.selectedFeatures = this.selectedFeatures.filter(item => item !== feature)
            } else {
              this.selectedFeatures.push(feature)
            }
          })
          .margin({ right: 8, bottom: 8 })
        })
      }
      
      // 操作按钮
      Row() {
        Button('重置')
          .layoutWeight(1)
          .backgroundColor('#F5F5F5')
          .onClick(() => {
            this.priceRange = [2000, 8000]
            this.selectedLayouts = []
            this.selectedFeatures = []
          })
        
        Button('确定')
          .layoutWeight(1)
          .backgroundColor('#6200EE')
          .fontColor(Color.White)
          .margin({ left: 16 })
          .onClick(() => {
            // 应用筛选条件
            postEvent('filterChanged', {
              priceRange: this.priceRange,
              layouts: this.selectedLayouts,
              features: this.selectedFeatures
            })
          })
      }
      .margin({ top: 20 })
      .width('100%')
    }
    .padding(16)
    .backgroundColor(Color.White)
  }
}

5. 房源详情页

// HouseDetailPage.ets
@Entry
@Component
struct HouseDetailPage {
  @State houseDetail: HouseDetail = {
    id: 1,
    title: '朝阳区精装两居室',
    price: '¥6500/月',
    area: 85,
    layout: '2室1厅1卫',
    floor: '中层/共18层',
    orientation: '南',
    district: '朝阳区',
    address: '朝阳门外大街10号',
    tags: ['近地铁', '精装修', '电梯房'],
    images: [
      $r('app.media.house1'),
      $r('app.media.house2')
    ],
    facilities: ['空调', '洗衣机', '冰箱', '热水器'],
    description: '房屋朝南,采光良好...',
    contact: '王先生 138****1234'
  }
  
  @State currentImageIndex: number = 0
  @State isFavorited: boolean = false
  
  build() {
    Scroll() {
      Column() {
        // 图片轮播
        Swiper() {
          ForEach(this.houseDetail.images, (img, index) => {
            Image(img)
              .width('100%')
              .height(300)
              .objectFit(ImageFit.Cover)
          })
        }
        .indicator(true)
        .autoPlay(false)
        .height(300)
        
        // 基本信息
        Column() {
          Row() {
            Text(this.houseDetail.price)
              .fontSize(24)
              .fontColor('#FF5722')
            
            Text(` ${this.houseDetail.area}㎡`)
              .fontSize(18)
              .fontColor('#666666')
              .margin({ left: 8 })
          }
          .margin({ top: 16, bottom: 8 })
          
          Text(this.houseDetail.title)
            .fontSize(20)
            .fontWeight(FontWeight.Medium)
            .margin({ bottom: 8 })
          
          Text(`${this.houseDetail.layout} | ${this.houseDetail.floor} | ${this.houseDetail.orientation}`)
            .fontSize(16)
            .fontColor('#666666')
            .margin({ bottom: 8 })
          
          Text(this.houseDetail.address)
            .fontSize(14)
            .fontColor('#666666')
            .margin({ bottom: 12 })
          
          // 标签
          Wrap() {
            ForEach(this.houseDetail.tags, (tag) => {
              Text(tag)
                .fontSize(12)
                .padding(4)
                .backgroundColor('#F5F5F5')
                .borderRadius(4)
                .margin({ right: 4, bottom: 4 })
            })
          }
          .margin({ bottom: 16 })
        }
        .padding(16)
        .backgroundColor(Color.White)
        
        // 房屋设施
        FacilityList({ facilities: this.houseDetail.facilities })
          .margin({ top: 12 })
        
        // 房屋描述
        Text('房屋描述')
          .fontSize(18)
          .fontWeight(FontWeight.Medium)
          .margin({ top: 16, bottom: 8, left: 16 })
        
        Text(this.houseDetail.description)
          .fontSize(16)
          .lineHeight(24)
          .padding(16)
          .backgroundColor(Color.White)
          .borderRadius(8)
          .margin({ bottom: 16 })
        
        // 联系房东
        ContactCard({ contact: this.houseDetail.contact })
          .margin({ bottom: 20 })
      }
    }
    .width('100%')
    .height('100%')
  }
}

设计要点

  1. ​界面设计原则​​:

    • 使用HarmonyOS Design的卡片式布局和阴影效果
    • 采用清晰的视觉层次和信息分组
    • 确保关键信息(价格、位置等)突出显示
  2. ​交互设计优化​​:

    // 自定义点击效果
    @Extend(Component) function cardClickEffect() {
      .onTouch((event: TouchEvent) => {
        if (event.type === TouchType.Down) {
          animateTo({ duration: 100 }, () => {
            this.opacity(0.8)
            this.scale({ x: 0.98, y: 0.98 })
          })
        } else if (event.type === TouchType.Up || event.type === TouchType.Cancel) {
          animateTo({ duration: 100 }, () => {
            this.opacity(1)
            this.scale({ x: 1, y: 1 })
          })
        }
      })
    }
  3. ​数据管理​​:

    // 使用AppStorage管理收藏状态
    AppStorage.SetOrCreate<Array<number>>('favoriteHouses', []);
    
    @Component
    struct FavoriteButton {
      private houseId: number
      @StorageLink('favoriteHouses') favoriteHouses: Array<number> = []
      
      build() {
        Image(this.favoriteHouses.includes(this.houseId) ? 
          $r('app.media.ic_favorite_filled') : 
          $r('app.media.ic_favorite_outline'))
          .width(24)
          .height(24)
          .onClick(() => {
            if (this.favoriteHouses.includes(this.houseId)) {
              this.favoriteHouses = this.favoriteHouses.filter(id => id !== this.houseId)
            } else {
              this.favoriteHouses.push(this.houseId)
            }
          })
      }
    }
  4. ​性能优化​​:

    // 图片懒加载
    @Component
    struct LazyImage {
      @State isLoaded: boolean = false
      private src: Resource
      
      aboutToAppear() {
        ImageProcessor.load(this.src).then(() => {
          this.isLoaded = true
        })
      }
      
      build() {
        Image(this.isLoaded ? this.src : $r('app.media.placeholder'))
          .width('100%')
          .height(180)
          .objectFit(ImageFit.Cover)
      }
    }

总结

通过HarmonyOS 5的ArkUI框架和分布式能力,结合HarmonyOS Design的设计规范,我们实现了一个功能完善的房屋出租查询小程序,具有以下特点:

  1. ​多维度房源展示​​:列表、地图、收藏等多种浏览方式
  2. ​智能筛选系统​​:支持价格、户型、特色等多条件筛选
  3. ​完善的详情信息​​:包含图片、描述、设施等完整信息
  4. ​良好的用户体验​​:符合HarmonyOS Design规范的交互和视觉设计
  5. ​跨设备协同​​:支持手机与平板间的数据同步和协同操作

这种小程序既可以帮助租房者快速找到合适房源,也可以为房东提供高效的展示平台,具有良好的实用价值。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐