• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Building a Food Category List Layout
2
3Use the **\<List>** component and **ForEach** loop to build the food category list layout.
4
5
61. Create a page file named **FoodCategoryList.ets** in the **pages** directory and rename the **index.ets** file **FoodDetail.ets**.
7
82. 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.
9   ```ts
10   @Component
11   struct FoodListItem {
12     build() {}
13   }
14
15   @Entry
16   @Component
17   struct FoodList {
18     build() {
19       List() {
20         ListItem() {
21           FoodListItem()
22         }
23       }
24     }
25   }
26   ```
27
283. Import the **FoodData** class and **initializeOnStartup** method.
29
30There are two file access methods in application code:
31- Use a relative path to reference the code file: Use **"../"** for referencing the parent directory and **"./"** (which can also be omitted) for referencing the current directory.
32- Use the absolute path, which is the root path of the current module, to reference the code file, for example, **common/utils/utils**.
33In this example, a relative path is used for access.
34
35   ```
36   import { FoodData } from '../model/FoodData'
37   import { initializeOnStartup } from '../model/FoodDataModels'
38   ```
39
404. 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**.
41   ```ts
42   import { FoodData } from '../model/FoodData'
43   import { initializeOnStartup } from '../model/FoodDataModels'
44
45   @Component
46   struct FoodListItem {
47     private foodItem: FoodData
48     build() {}
49   }
50
51   @Entry
52   @Component
53   struct FoodList {
54     private foodItems: FoodData[] = initializeOnStartup()
55     build() {
56       List() {
57         ListItem() {
58           FoodListItem({ foodItem: this.foodItems[0] })
59         }
60       }
61     }
62   }
63   ```
64
655. 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.
66   ```ts
67   import { FoodData } from '../model/FoodData'
68   import { initializeOnStartup } from '../model/FoodDataModels'
69
70      @Component
71      struct FoodListItem {
72        private foodItem: FoodData
73        build() {
74          Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
75            Image(this.foodItem.image)
76              .objectFit(ImageFit.Contain)
77              .height(40)
78              .width(40)
79              .margin({ right: 16 })
80            Text(this.foodItem.name)
81              .fontSize(14)
82              .flexGrow(1)
83            Text(this.foodItem.calories + ' kcal')
84              .fontSize(14)
85          }
86          .height(64)
87          .margin({ right: 24, left:32 })
88        }
89      }
90
91   @Entry
92      @Component
93      struct FoodList {
94        private foodItems: FoodData[] = initializeOnStartup()
95        build() {
96          List() {
97            ListItem() {
98              FoodListItem({ foodItem: this.foodItems[0] })
99            }
100          }
101        }
102      }
103   ```
104
105
106   ![en-us_image_0000001204776353](figures/en-us_image_0000001204776353.png)
107
1086. 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**.
109
110   ```ts
111   import { FoodData } from '../model/FoodData'
112   import { initializeOnStartup } from '../model/FoodDataModels'
113
114   @Component
115   struct FoodListItem {
116     private foodItem: FoodData
117
118     build() {
119       Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
120         Image(this.foodItem.image)
121           .objectFit(ImageFit.Contain)
122           .height(40)
123           .width(40)
124           .margin({ right: 16 })
125         Text(this.foodItem.name)
126           .fontSize(14)
127           .flexGrow(1)
128         Text(this.foodItem.calories + ' kcal')
129           .fontSize(14)
130       }
131       .height(64)
132       .margin({ right: 24, left: 32 })
133     }
134   }
135
136   @Entry
137   @Component
138   struct FoodList {
139     private foodItems: FoodData[] = initializeOnStartup()
140
141     build() {
142       List() {
143         ListItem() {
144           FoodListItem({ foodItem: this.foodItems[0] })
145         }
146
147         ListItem() {
148           FoodListItem({ foodItem: this.foodItems[1] })
149         }
150       }
151     }
152   }
153   ```
154
155
156      ![en-us_image1_0000001204776353](figures/en-us_image1_0000001204776353.png)
157
1587. Import [ForEach](../quick-start/arkts-rendering-control.md#loop-rendering) so that you do not need to create **FoodListItem** objects one by one.
159
160   ```ts
161   import { FoodData } from '../model/FoodData'
162   import { initializeOnStartup } from '../model/FoodDataModels'
163
164   @Component
165   struct FoodListItem {
166     private foodItem: FoodData
167     build() {
168       Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
169         Image(this.foodItem.image)
170           .objectFit(ImageFit.Contain)
171           .height(40)
172           .width(40)
173           .margin({ right: 16 })
174         Text(this.foodItem.name)
175           .fontSize(14)
176           .flexGrow(1)
177         Text(this.foodItem.calories + ' kcal')
178           .fontSize(14)
179       }
180       .height(64)
181       .margin({ right: 24, left:32 })
182     }
183   }
184
185   @Entry
186   @Component
187   struct FoodList {
188     private foodItems: FoodData[] = initializeOnStartup()
189     build() {
190       List() {
191         ForEach(this.foodItems, item => {
192           ListItem() {
193             FoodListItem({ foodItem: item })
194           }
195         }, item => item.id.toString())
196       }
197     }
198   }
199   ```
200
2018. Add a title for the **FoodList**.
202
203   ```
204   @Entry
205   @Component
206   struct FoodList {
207     private foodItems: FoodData[] = initializeOnStartup()
208
209     build() {
210       Column() {
211         Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
212           Text('Food List')
213             .fontSize(20)
214             .margin({ left: 20 })
215         }
216         .height('7%')
217         .backgroundColor('#FFf1f3f5')
218
219         List() {
220           ForEach(this.foodItems, item => {
221             ListItem() {
222               FoodListItem({ foodItem: item })
223             }
224           }, item => item.id.toString())
225         }
226         .height('93%')
227       }
228     }
229   }
230   ```
231
232     ![en-us_image_0000001169678922](figures/en-us_image_0000001169678922.png)
233