img

目录

  • 案例介绍
  • 代码实现
  • 1. 定义数据模型
  • 2. 创建主页面组件
  • 代码详解
  • 1. 网格系统设计
  • 2. 响应式布局实现
  • 3. 数值卡片实现
  • 总结

案例介绍

本篇文章将介绍如何使用GridRow组件创建一个响应式的数据仪表盘布局。通过不同类型的数据卡片展示各种指标,如销售额、用户数、订单量等,实现直观的数据可视化效果。

代码实现

1. 定义数据模型

// 数据卡片类型
enum CardType {
  NUMBER,  // 数值型
  CHART,   // 图表型
  LIST     // 列表型
}

// 数据趋势
enum Trend {
  UP,      // 上升
  DOWN,    // 下降
  FLAT     // 持平
}

// 数据卡片接口
interface DashboardCard {
  id: number;
  title: string;
  type: CardType;
  value?: string;
  trend?: Trend;
  percentage?: number;
  color: string;
  span: number;  // 占据的列数
  data?: any[];  // 图表或列表数据
}

2. 创建主页面组件

@Entry
@Component
struct DashboardPage {
  // 仪表盘数据
  @State cardList: DashboardCard[] = [
    {
      id: 1,
      title: '总销售额',
      type: CardType.NUMBER,
      value: '¥126,560',
      trend: Trend.UP,
      percentage: 12.5,
      color: '#4CAF50',
      span: 6
    },
    {
      id: 2,
      title: '用户数',
      type: CardType.NUMBER,
      value: '8,846',
      trend: Trend.UP,
      percentage: 5.2,
      color: '#2196F3',
      span: 6
    },
    // ... 更多卡片数据
  ];
  
  // 当前窗口宽度
  @State windowWidth: number = 0;
  
  build() {
    Column() {
      // 标题栏
      Row() {
        Text('数据仪表盘').fontSize(24).fontWeight(FontWeight.Bold)
      }
      .width('100%')
      .padding({ top: 16, bottom: 16 })
      
      // 仪表盘网格
      GridRow({
        columns: 12,  // 使用12列网格系统
        gutter: 16
      }) {
        ForEach(this.cardList, (card: DashboardCard) => {
          GridItem({ span: this.windowWidth <= 600 ? 12 : card.span }) {
            // 根据卡片类型渲染不同的内容
            if (card.type === CardType.NUMBER) {
              this.renderNumberCard(card)
            }
            // ... 其他类型卡片的渲染
          }
        })
      }
      .width('100%')
      .padding(16)
    }
    .width('100%')
    .backgroundColor('#F5F5F5')
  }
  
  // 渲染数值型卡片
  @Builder
  renderNumberCard(card: DashboardCard) {
    Column() {
      Row() {
        Text(card.title)
          .fontSize(16)
          .opacity(0.6)
        Blank()
        // 根据趋势显示不同的图标
        if (card.trend === Trend.UP) {
          Text('↑').fontSize(16).fontColor(card.color)
        } else if (card.trend === Trend.DOWN) {
          Text('↓').fontSize(16).fontColor('#FF5722')
        } else {
          Text('-').fontSize(16).fontColor('#757575')
        }
      }
      .width('100%')
      
      Text(card.value)
        .fontSize(28)
        .fontWeight(FontWeight.Bold)
        .margin({ top: 8, bottom: 8 })
      
      Row() {
        Text(`${card.percentage}%`)
          .fontSize(14)
          .fontColor(card.trend === Trend.UP ? card.color : 
                    (card.trend === Trend.DOWN ? '#FF5722' : '#757575'))
        
        Text('较上期')
          .fontSize(14)
          .opacity(0.6)
          .margin({ left: 4 })
      }
      .width('100%')
    }
    .width('100%')
    .padding(16)
    .backgroundColor(Color.White)
    .borderRadius(8)
  }
}

代码详解

1. 网格系统设计

GridRow({
  columns: 12,  // 使用12列网格系统
  gutter: 16
})

采用12列网格系统的优势:

  1. 灵活分配:12可被2、3、4、6整除,便于划分布局
  2. 响应式:通过span属性控制卡片占据的列数
  3. 统一间距:使用gutter设置卡片间的统一间距

2. 响应式布局实现

GridItem({ span: this.windowWidth <= 600 ? 12 : card.span })

响应式布局策略:

  • 小屏幕(≤600px):卡片占据全部12列
  • 大屏幕(>600px):根据卡片预设的span值分配列数

3. 数值卡片实现

数值卡片包含三个部分:

  1. 标题行:显示卡片标题和趋势图标
  2. 数值行:大字号显示当前值
  3. 趋势行:显示变化百分比和比较文本

总结

本篇文章展示了如何使用GridRow组件创建响应式数据仪表盘布局。通过12列网格系统和响应式设计,实现了灵活的卡片布局。数值型卡片的实现展示了如何组织和展示数据指标,为用户提供直观的数据展示效果。这种布局方式不仅适用于数据仪表盘,也可以应用于其他需要网格布局的场景。

Logo

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

更多推荐