• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Building a Food Category List Layout
2
3
4Use the List component and ForEach loop to build the food category list layout.
5
6
71. Create a page file named FoodCategoryList.ets in the pages directory, rename the index.ets file FoodDetail.ets, and add the renamed file to the "pages" tag in the config.json file. The first page under the tag is the home page.
8
9   ```
10   "js": [
11     {
12       "pages": [
13         "pages/FoodCategoryList",
14         "pages/FoodDetail"
15       ],
16   ]
17   ```
18
192. Create a List component named FoodList as the page entry point. Then, add a ListItem component named FoodListItem as its child component. The List component is used to display data of the same type. Its child component \<ListItem> is used to display specific items in the list.
20
21   ```
22   @Component
23   struct FoodListItem {
24     build() {}
25   }
26
27   @Entry
28   @Component
29   struct FoodList {
30     build() {
31       List() {
32         ListItem() {
33           FoodListItem()
34         }
35       }
36     }
37   }
38   ```
39
403. Import the FoodData class and initializeOnStartup method.
41
42   ```
43   import { FoodData } from '../model/FoodData'
44   import { initializeOnStartup } from '../model/FoodDataModels'
45   ```
46
474. Configure the FoodList and FoodListItem components to pass values. Create a member variable named foodItems of the FoodData[] type in the FoodList component and invoke the initializeOnStartup method to assign a value to the variable. Create a member variable foodItem of the FoodData type in the FoodListItem component. Pass the foodItems[0] of the first element in the parent foodItems array as a parameter to FoodListItem.
48
49   ```
50   import { FoodData } from '../model/FoodData'
51   import { initializeOnStartup } from '../model/FoodDataModels'
52
53   @Component
54   struct FoodListItem {
55     private foodItem: FoodData
56     build() {}
57   }
58
59   @Entry
60   @Component
61   struct FoodList {
62     private foodItems: FoodData[] = initializeOnStartup()
63     build() {
64       List() {
65         ListItem() {
66           FoodListItem({ foodItem: this.foodItems[0] })
67         }
68       }
69     }
70   }
71   ```
72
735. Declare the UI layout of the FoodListItem child component. Create a Flex component, including the food image thumbnail, food name, and calories in the food.
74
75   ```
76   import { FoodData } from '../model/FoodData'
77   import { initializeOnStartup } from '../model/FoodDataModels'
78
79   @Component
80   struct FoodListItem {
81     private foodItem: FoodData
82     build() {
83       Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
84         Image(this.foodItem.image)
85           .objectFit(ImageFit.Contain)
86           .height(40)
87           .width(40)
88           .backgroundColor('#FFf1f3f5')
89           .margin({ right: 16 })
90         Text(this.foodItem.name)
91           .fontSize(14)
92           .flexGrow(1)
93         Text(this.foodItem.calories + ' kcal')
94           .fontSize(14)
95       }
96       .height(64)
97       .margin({ right: 24, left:32 })
98     }
99   }
100
101   @Entry
102   @Component
103   struct FoodList {
104     private foodItems: FoodData[] = initializeOnStartup()
105     build() {
106       List() {
107         ListItem() {
108           FoodListItem({ foodItem: this.foodItems[0] })
109         }
110       }
111     }
112   }
113   ```
114
115   ![en-us_image_0000001267887833](figures/en-us_image_0000001267887833.png)
116
1176. Create two FoodListItem objects. Create two FoodListItem objects in the List component and pass the first element this.foodItems[0] and the second element foodItem: this.foodItems[1] to the FoodListItem.
118
119   ```
120   import { FoodData } from '../model/FoodData'
121   import { initializeOnStartup } from '../model/FoodDataModels'
122
123   @Component
124   struct FoodListItem {
125       private foodItem: FoodData
126       build() {
127           Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
128               Image(this.foodItem.image)
129                   .objectFit(ImageFit.Contain)
130                   .height(40)
131                   .width(40)
132                   .backgroundColor('#FFf1f3f5')
133                   .margin({ right: 16 })
134               Text(this.foodItem.name)
135                   .fontSize(14)
136                   .flexGrow(1)
137               Text(this.foodItem.calories + ' kcal')
138                   .fontSize(14)
139           }
140           .height(64)
141           .margin({ right: 24, left:32 })
142       }
143   }
144
145   @Entry
146   @Component
147   struct FoodList {
148     private foodItems: FoodData[] = initializeOnStartup()
149     build() {
150       List() {
151         ListItem() {
152           FoodListItem({ foodItem: this.foodItems[0] })
153         }
154         ListItem() {
155           FoodListItem({ foodItem: this.foodItems[1] })
156         }
157       }
158     }
159   }
160   ```
161
162   ![en-us_image_0000001267767849](figures/en-us_image_0000001267767849.png)
163
1647. Import ForEach so that you do not need to create FoodListItem objects one by one.
165
166   ```
167   ForEach(
168       arr: any[], // Array to be iterated
169       itemGenerator: (item: any) => void, // child component generator
170       keyGenerator?: (item: any) => string // (optional) Unique key generator, which is recommended.
171   )
172   ```
173
174   The ForEach group has three parameters. The first parameter is the array to be traversed, the second parameter is the lambda function for generating child components, and the third parameter is the key value generator. The third parameter is optional. Yet, for performance reasons, it is strongly recommended that you provide it. keyGenerator enables the development framework to better recognize array changes without having to rebuild all nodes after item changes.
175
176   Traverse the foodItems array to cyclically create the ListItem component. Pass each item in foodItems as a parameter to the FoodListItem component.
177
178
179   ```
180   ForEach(this.foodItems, item => {
181       ListItem() {
182           FoodListItem({ foodItem: item })
183       }
184   }, item => item.id.toString())
185   ```
186
187   The code is as follows:
188
189
190   ```
191   import { FoodData } from '../model/FoodData'
192   import { initializeOnStartup } from '../model/FoodDataModels'
193
194   @Component
195   struct FoodListItem {
196     private foodItem: FoodData
197     build() {
198       Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
199         Image(this.foodItem.image)
200           .objectFit(ImageFit.Contain)
201           .height(40)
202           .width(40)
203           .backgroundColor('#FFf1f3f5')
204           .margin({ right: 16 })
205         Text(this.foodItem.name)
206           .fontSize(14)
207           .flexGrow(1)
208         Text(this.foodItem.calories + ' kcal')
209           .fontSize(14)
210       }
211       .height(64)
212       .margin({ right: 24, left:32 })
213     }
214   }
215
216   @Entry
217   @Component
218   struct FoodList {
219     private foodItems: FoodData[] = initializeOnStartup()
220     build() {
221       List() {
222         ForEach(this.foodItems, item => {
223           ListItem() {
224             FoodListItem({ foodItem: item })
225           }
226         }, item => item.id.toString())
227       }
228     }
229   }
230   ```
231
2328. Add a title for the FoodList.
233
234   ```
235   @Entry
236   @Component
237   struct FoodList {
238     private foodItems: FoodData[] = initializeOnStartup()
239     build() {
240       Column() {
241         Flex({justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center}) {
242           Text('Food List')
243             .fontSize(20)
244             .margin({ left:20 })
245         }
246         .height('7%')
247         .backgroundColor('#FFf1f3f5')
248         List() {
249           ForEach(this.foodItems, item => {
250             ListItem() {
251               FoodListItem({ foodItem: item })
252             }
253           }, item => item.id.toString())
254         }
255         .height('93%')
256       }
257     }
258   }
259   ```
260
261   ![en-us_image_0000001267607877](figures/en-us_image_0000001267607877.png)
262