• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import router from '@ohos.router'
17import { Category, FoodData } from '../model/FoodData'
18import { initializeOnStartup } from '../model/FoodDataModels'
19
20class BasicDataSource implements IDataSource {
21  private listeners: DataChangeListener[] = []
22
23  public totalCount(): number {
24    return 0
25  }
26
27  public getData(index: number): any {
28    return undefined
29  }
30
31  registerDataChangeListener(listener: DataChangeListener): void {
32    if (this.listeners.indexOf(listener) < 0) {
33      this.listeners.push(listener)
34    }
35  }
36
37  unregisterDataChangeListener(listener: DataChangeListener): void {
38    const pos = this.listeners.indexOf(listener);
39    if (pos >= 0) {
40      this.listeners.splice(pos, 1)
41    }
42  }
43
44  notifyDataReload(): void {
45    this.listeners.forEach(listener => {
46      listener.onDataReloaded()
47    })
48  }
49
50  notifyDataAdd(index: number): void {
51    this.listeners.forEach(listener => {
52      listener.onDataAdded(index)
53    })
54  }
55
56  notifyDataChange(index: number): void {
57    this.listeners.forEach(listener => {
58      listener.onDataChanged(index)
59    })
60  }
61}
62
63class MyDataSource extends BasicDataSource {
64  public dataArray: string[] = []
65
66  constructor(ele) {
67    super()
68    for (var index = 0;index < ele.length; index++) {
69      this.dataArray.push(ele[index])
70    }
71  }
72
73  public totalCount(): number {
74    return this.dataArray.length
75  }
76
77  public getData(index: number): any {
78    return this.dataArray[index]
79  }
80
81  public addData(index: number, data: string): void {
82    this.dataArray.splice(index, 0)
83    this.notifyDataAdd(index)
84  }
85}
86
87@Component
88struct FoodListItem {
89  private foodItem: FoodData
90
91  build() {
92    Navigator({ target: 'pages/FoodDetail' }) {
93      Row() {
94        Row() {
95          Image(this.foodItem.image)
96            .objectFit(ImageFit.Contain)
97            .autoResize(false)
98            .height(40)
99            .width(40)
100        }
101        .backgroundColor('#FFf1f3f5')
102        .margin({ right: 16 })
103
104        Text(this.foodItem.name)
105          .fontSize(14)
106          .flexGrow(1)
107        Blank()
108        Text(this.foodItem.calories + ' kcal')
109          .fontSize(14)
110      }
111      .alignItems(VerticalAlign.Center)
112      .height(64)
113      .width('100%')
114    }
115    .width('100%')
116    .params({ foodId: this.foodItem })
117    .padding({ right: 24, left: 24 })
118  }
119}
120
121
122@Component
123struct FoodList {
124  private foodItems: FoodData[]
125
126  build() {
127    Column() {
128      Row() {
129        Text('Food List')
130          .fontSize(20)
131          .margin({ left: 20 })
132      }
133      .alignItems(VerticalAlign.Center)
134      .justifyContent(FlexAlign.Start)
135      .height('7%')
136      .width('100%')
137      .backgroundColor('#FFf1f3f5')
138
139      List() {
140        LazyForEach(new MyDataSource(this.foodItems), (item, index) => {
141          ListItem() {
142            FoodListItem({ foodItem: item })
143          }
144          .key('foodListItem' + (index + 1))
145        }, item => item.id.toString())
146      }
147      .width('100%')
148      .height('93%')
149    }
150    .width('100%')
151  }
152}
153
154@Component
155struct FoodGridItem {
156  private foodItem: FoodData
157
158  build() {
159    Column() {
160      Row() {
161        Image(this.foodItem.image)
162          .objectFit(ImageFit.Contain)
163          .height(152)
164          .width('100%')
165      }.backgroundColor('#FFf1f3f5')
166
167      Row() {
168        Text(this.foodItem.name)
169          .fontSize(14)
170          .flexGrow(1)
171          .padding({ left: 8 })
172        Text(this.foodItem.calories + 'kcal')
173          .fontSize(14)
174          .margin({ right: 6 })
175      }
176      .alignItems(VerticalAlign.Center)
177      .justifyContent(FlexAlign.Start)
178      .height(32)
179      .width('100%')
180      .backgroundColor('#FFe5e5e5')
181    }
182    .height(184)
183    .width('100%')
184    .onClick(() => {
185      router.push({ url: 'pages/FoodDetail', params: { foodId: this.foodItem } })
186    })
187  }
188}
189
190@Component
191struct FoodGrid {
192  private foodItems: FoodData[]
193  private gridRowTemplate: string = ''
194  private heightValue: number
195
196  aboutToAppear() {
197    var rows = Math.round(this.foodItems.length / 2);
198    this.gridRowTemplate = '1fr '.repeat(rows);
199    this.heightValue = rows * 192 - 8;
200  }
201
202  build() {
203    Scroll() {
204      Grid() {
205        LazyForEach(new MyDataSource(this.foodItems), (item: FoodData, index) => {
206          GridItem() {
207            FoodGridItem({ foodItem: item })
208          }
209          .key('foodGridItem' + (index + 1))
210        }, (item: FoodData) => item.id.toString())
211      }
212      .rowsTemplate(this.gridRowTemplate)
213      .columnsTemplate('1fr 1fr')
214      .columnsGap(8)
215      .rowsGap(8)
216      .height(this.heightValue)
217    }
218    .scrollBar(BarState.Off)
219    .padding({ left: 16, right: 16 })
220  }
221}
222
223@Component
224struct FoodCategory {
225  private foodItems: FoodData[]
226
227  build() {
228    Tabs() {
229      TabContent() {
230        FoodGrid({ foodItems: this.foodItems })
231      }.tabBar('All')
232
233      TabContent() {
234        FoodGrid({ foodItems: this.foodItems.filter(item => (item.category === Category.Vegetable)) })
235      }.tabBar('Vegetable')
236
237      TabContent() {
238        FoodGrid({ foodItems: this.foodItems.filter(item => (item.category === Category.Fruit)) })
239      }.tabBar('Fruit')
240
241      TabContent() {
242        FoodGrid({ foodItems: this.foodItems.filter(item => (item.category === Category.Nut)) })
243      }.tabBar('Nut')
244
245      TabContent() {
246        FoodGrid({ foodItems: this.foodItems.filter(item => (item.category === Category.Seafood)) })
247      }.tabBar('Seafood')
248
249      TabContent() {
250        FoodGrid({ foodItems: this.foodItems.filter(item => (item.category === Category.Dessert)) })
251      }.tabBar('Dessert')
252    }
253    .width('100%')
254    .barWidth('80%')
255    .barHeight(70)
256    .barMode(BarMode.Scrollable)
257  }
258}
259
260@Entry
261@Component
262struct FoodCategoryList {
263  private foodItems: FoodData[] = initializeOnStartup()
264  @State private showList: boolean = false
265
266  build() {
267    Column() {
268      Stack({ alignContent: Alignment.TopEnd }) {
269        if (this.showList) {
270          FoodList({ foodItems: this.foodItems })
271        } else {
272          FoodCategory({ foodItems: this.foodItems })
273        }
274        Image($r('app.media.Switch'))
275          .height(40)
276          .width(24)
277          .objectFit(ImageFit.Contain)
278          .key('switch')
279          .margin({ top: 15, right: 10 })
280          .onClick(() => {
281            this.showList = !this.showList
282          })
283      }
284    }
285    .width('100%')
286    .height('100%')
287  }
288}
289