项目需要制作一个如下图的点单页面,基于API12写了基于二维列表和IDataSource的两种写法
一、二维列表
二维列表的思路较为简单,其中的一维索引指定了侧边栏的索引,二维索引为具体的商品数据,侧边栏通过List实现,并通过scrollToIndex控制scroll控制器控制商品栏跳转到指定目录下,右侧则通过onScrollIndex检查结束位置的索引获取服务器上的数据按需获取减轻服务器压力。切换顶部tabs会清空itemList,但是这种实现方式在数据较多的时候内存占用较大。最初尝试过三维列表存储顶部、侧边导航栏具体数据,但在模拟器中@State装饰器似乎不能检测到第三维的数据更改,所以放弃三维列表存储页面的数据。
具体实现如下,未引用额外的文件。
import { Api, ApiUrls, Data, setTitle } from '@ohos/common';
import { LengthMetrics } from '@kit.ArkUI';
@Entry
@Component
export struct OrderPage {
// 商品分类信息
@State productCate: Data[] = [];
// 店铺列表
@State shopList: Data[] = [];
// 顶部栏Index
@State currentIndex: number = 0;
// 侧边栏Index,索引代表顶部Index
@State sCurrentIndex: number[] = [];
// 商品列表,二维数组,一维索引代表侧边Index,其中Array代表具体数据
@State itemList: Data[][] = [];
// 控制侧边栏隐显
@State showRightSide: boolean = false;
// 侧栏滚动控制器
private listScroller: Scroller = new Scroller();
aboutToAppear(): void {
this.fetchShopList();
this.fetchProductCate().then(() => {
// 调取数据后执行,将侧边栏Index根据顶部数量置空
this.sCurrentIndex = new Array(this.productCate.length).fill(0);
// 初始化当前tab下itemList
this.itemList = this.initializeItemList((this.productCate[this.currentIndex].effect_cate_list as Data[]).length);
this.fetchProductList(this.currentIndex, this.sCurrentIndex[this.currentIndex]);
});
}
@Builder
TabBuilder(title_cn: string, title_en: string, targetIndex: number, isLast: boolean) {
Column() {
Text(title_cn)
.fontColor(this.currentIndex === targetIndex ? '#333333' : '#999999')
.fontSize(14)
Text(title_en)
.fontColor(this.currentIndex === targetIndex ? '#333333' : '#999999')
.fontSize(12)
}
.border({
width: {
right: !isLast ? 1 : 0
},
color: '#d1cac1'
})
.height('100%')
.width('100%')
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
}
@Builder
// targetIndex: 侧边Index, Index: 顶部index
sTabBuilder(title: string, targetIndex: number, index: number) {
Column() {
Text(title)
.fontColor(this.sCurrentIndex[index] === targetIndex ? '#ff6827' : '#666056')
.fontSize(14)
}
.onClick(() => {
this.sCurrentIndex[index] = targetIndex;
if (!this.itemList[targetIndex].length) {
this.fetchProductList(index, targetIndex)
}
this.listScroller.scrollToIndex(targetIndex)
})
.height(45)
.width('100%')
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
.backgroundColor(this.sCurrentIndex[this.currentIndex] === targetIndex ? Color.White : '#f5f5f5')
}
@Builder
ListGroupHeader(title: string) {
Text(title)
.fontSize(12)
.fontColor('#666056')
.margin({
top: 15,
left: 11
})
}
build() {
NavDestination() {
Flex({ direction: FlexDirection.Column, space: { main: LengthMetrics.vp(10) } }) {
// 顶部图片+文字
Column() {
Image($rawfile('OrderPage/background.png'))
.position({
x: 0,
y: 0
})
.width('100%')
Row() {
Column() {
Text('汤头泡泡')
.fontSize(20)
.fontColor(Color.White)
Row({ space: 5 }) {
Text(this.shopList.length ? this.shopList[0].title as string : '')
.fontSize(14)
.fontColor(Color.White)
// Polyline({ width: 8, height: 12 })
// .points([[0, 0], [7, 5.5], [0, 11]])
// .fillOpacity(0)
// .stroke(Color.White)
// .strokeWidth(2)
}
}
.alignItems(HorizontalAlign.Start)
Button('门店自取', { type: ButtonType.Normal })
.borderRadius(3)
.fontSize(14)
.fontColor(Color.White)
.backgroundColor('#ff6827')
}
.height('100%')
.width('100%')
.padding(15)
.justifyContent(FlexAlign.SpaceBetween)
.alignItems(VerticalAlign.Center)
.backgroundColor('#4c000000')
}
.height(132)
// 顶tabs栏
Tabs() {
ForEach(this.productCate, (item: Data, index: number) => {
TabContent() {
if (this.currentIndex === index) {
Flex({ direction: FlexDirection.Column }) {
// 商品列表
Flex() {
List({ initialIndex: this.sCurrentIndex[index] }) {
ForEach(item.effect_cate_list as Data[], (sItem: Data, sIndex: number) => {
this.sTabBuilder(sItem.title as string, sIndex, index)
}, () => index.toString())
}
.height('100%')
.scrollBar(BarState.Off)
.flexBasis(88)
List({ scroller: this.listScroller }) {
// 在这里通过index跳转看看能不能跳转到相应的项
if (this.showRightSide) {
ForEach(this.itemList, (sItem: Data[], sIndex: number) => {
ListItemGroup({
header: this.ListGroupHeader((this.productCate[index].effect_cate_list as Data[])[sIndex].title as string)
}) {
// rItem为右侧数据项
ForEach(sItem, (rItem: Data, rIndex: number) => {
ListItem() {
productItem({ item: rItem, isTop: this.itemList[sIndex][0] === rItem })
}
})
}
})
}
}
.onScrollIndex((firstIndex: number, lastIndex: number, centerIndex: number) => {
this.sCurrentIndex[this.currentIndex] = lastIndex;
if (!this.itemList[lastIndex].length) {
this.fetchProductList(this.currentIndex, lastIndex)
}
})
.flexGrow(1)
.sticky(StickyStyle.Header)
.height('100%')
.backgroundColor(Color.White)
}
// 底部购物车
Flex() {
}
.height(49)
.width('100%')
.backgroundColor(Color.Blue)
}
}
}
.tabBar(this.TabBuilder(item.title as string, item.sub_title as string, index,
index === this.productCate.length - 1 ? true : false))
}, (item: Data) => item.title as string)
}
.scrollable(false)
.onChange((index) => {
this.currentIndex = index;
// 重新生成itemList
this.showRightSide = false;
this.itemList = this.initializeItemList((this.productCate[index].effect_cate_list as Data[]).length);
this.fetchProductList(this.currentIndex, this.sCurrentIndex[this.currentIndex]);
})
.divider({
strokeWidth: 10,
color: '#f5f5f5'
})
.barHeight(50)
.flexGrow(1)
.backgroundColor(Color.White)
}
.backgroundColor('#f5f5f5')
}
.title(setTitle('门店点单'))
}
initializeItemList(length: number) {
return new Array(length).fill(null).map(() => []);
};
async fetchShopList() {
const res = await Api("GET", ApiUrls.shopList, {}, false)
this.shopList = (res.results as Data).data as Data[];
}
async fetchProductCate() {
const res = await Api("GET", ApiUrls.productCate, {}, false)
this.productCate = (res.results as Data).data as Data[];
}
// 接受顶部和侧边栏的index,从productCate中读取数据
async fetchProductList(topIndex: number, sideIndex: number) {
const params: Data = {
'cate_id': this.productCate[topIndex].id?.toString(),
'effect_cate_id': (this.productCate[topIndex].effect_cate_list as Data[])[sideIndex].id?.toString()
};
const res = await Api("GET", ApiUrls.shopProductList, params, false);
// 拼接新获取的数据到现有的列表中
this.itemList[sideIndex] = (res.results as Data).data as Data[];
if (!this.showRightSide) {
this.showRightSide = true;
}
}
}
@Component
struct productItem {
@Prop item: Data;
@Prop isTop: boolean;
build() {
Flex({ direction: FlexDirection.Row }) {
Image((this.item.cover as Data[])[0].source as string)
.flexBasis(80)
.height(80)
Column() {
Text(this.item.title as string)
.fontSize(14)
.fontColor('#333333')
if ((this.item.posts_list as Data[]).length > 0) {
Text(`本膳食依据${(this.item.posts_list as Data[])[0].reference as string}所记载的${(this.item.posts_list as Data[])[0].reference_title as string},采用西点工艺制成。`)
.maxLines(2)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontSize(11)
.fontColor('#666056')
.margin({
top: 2
})
.width(165)
}
Row() {
Text() {
Span('¥')
.fontSize(12)
Span(this.item.sku_min_price as string)
.fontSize(17)
}
.fontColor('#333333')
Button('选规格')
.fontSize(13)
.height(21)
.backgroundColor('#ff6827')
}
.width(165)
.justifyContent(FlexAlign.SpaceBetween)
}
.height(80)
.justifyContent(FlexAlign.SpaceBetween)
.alignItems(HorizontalAlign.Start)
.flexGrow(1)
.padding({
left: 10
})
}
.padding({
top: this.isTop ? 11 : 16,
bottom: 15,
left: 10
})
.border({
width: {
bottom: 1
},
color: '#eeeeee'
})
}
}
二、懒加载的实现
ArkTS包含懒加载的渲染模式,基于懒加载对二维数组做了一定的优化,注意forEach中嵌套lazyforeach这种做法会导致懒加载功能失效(询问工程师得到的)。当然通过if渲染切换页签是不算的。官网上是用string做的例子,这里尝试用二维数组实现。
首先是type.ets文件,这里我踩了几个坑(不仔细看官方文档的后果),在IDataSource 里面,totalCount的结果是懒加载会渲染的总条目数,getData是循环时得到的具体项,这个地方不要修改,如果有需要得到数据的需求可以自己重新写几个public方法,我这里写了totalChildCount和getChildData。
type Data = Record<string, string | boolean | number | undefined | object | object[]>;
type ApiEndpoints = Record<string, string>;
class BasicDataSource implements IDataSource {
private listeners: DataChangeListener[] = [];
private originDataArray: Data[] | string[] = [];
public totalCount(): number {
return 0;
}
public getData(index: number): Data | string | Data[] {
return this.originDataArray[index];
}
// 该方法为框架侧调用,为LazyForEach组件向其数据源处添加listener监听
registerDataChangeListener(listener: DataChangeListener): void {
if (this.listeners.indexOf(listener) < 0) {
console.info('add listener');
this.listeners.push(listener);
}
}
// 该方法为框架侧调用,为对应的LazyForEach组件在数据源处去除listener监听
unregisterDataChangeListener(listener: DataChangeListener): void {
const pos = this.listeners.indexOf(listener);
if (pos >= 0) {
console.info('remove listener');
this.listeners.splice(pos, 1);
}
}
// 通知LazyForEach组件需要重载所有子组件
notifyDataReload(): void {
this.listeners.forEach(listener => {
listener.onDataReloaded();
})
}
// 通知LazyForEach组件需要在index对应索引处添加子组件
notifyDataAdd(index: number): void {
this.listeners.forEach(listener => {
listener.onDataAdd(index);
})
}
// 通知LazyForEach组件在index对应索引处数据有变化,需要重建该子组件
notifyDataChange(index: number): void {
this.listeners.forEach(listener => {
listener.onDataChange(index);
})
}
// 通知LazyForEach组件需要在index对应索引处删除该子组件
notifyDataDelete(index: number): void {
this.listeners.forEach(listener => {
listener.onDataDelete(index);
})
}
// 通知LazyForEach组件将from索引和to索引处的子组件进行交换
notifyDataMove(from: number, to: number): void {
this.listeners.forEach(listener => {
listener.onDataMove(from, to);
})
}
}
@Observed class ProductInfoSource extends BasicDataSource {
private dataArray: Data[] = [];
public totalCount(): number {
return this.dataArray.length;
}
public getData(index: number): Data {
return this.dataArray[index];
}
public addData(index: number, data: Data): void {
this.dataArray.splice(index, 0, data);
this.notifyDataAdd(index);
}
public pushData(data: Data): void {
this.dataArray.push(data);
this.notifyDataAdd(this.dataArray.length - 1);
}
public pushDataList(data: Data[]): void {
// 添加新数据
const startIndex = this.dataArray.length;
this.dataArray = [...this.dataArray, ...data];
// 通知每个新增数据项
for (let i = 0; i < data.length; i++) {
this.notifyDataAdd(startIndex + i);
}
}
public clearDataList(): void {
this.dataArray = [];
}
}
@Observed class ProductInfoSourceArray extends BasicDataSource {
private dataArray: Data[][] = [];
// 操作前先更新firstIndex
private firstIndex: number = 0;
// 懒加载渲染数目基于totalcount
public totalCount(): number {
return this.dataArray.length;
}
public childCount(): number {
return this.dataArray[this.firstIndex].length;
}
// 防数组越界在调用时实现
public nextChildCount(): number {
return this.dataArray[this.firstIndex + 1].length;
}
public preChildCount(): number {
return this.dataArray[this.firstIndex - 1].length;
}
// 懒加载渲染数据基于getData
public getData(index: number): Data[] {
return this.dataArray[index];
}
public getChildData(index: number): Data {
return this.dataArray[this.firstIndex][index];
}
public updateIndex(index: number): void {
this.firstIndex = index;
}
public addData(index: number, data: Data): void {
this.dataArray[this.firstIndex].splice(index, 0, data);
this.notifyDataChange(index);
}
public pushData(data: Data): void {
this.dataArray[this.firstIndex].push(data);
this.notifyDataChange(this.firstIndex);
}
public refreshDataList(data: Data[]): void {
// 添加新数据
this.dataArray[this.firstIndex] = data;
console.log(JSON.stringify(this.dataArray[this.firstIndex]))
// 通知修改项的下标
this.notifyDataChange(this.firstIndex);
}
public initialize(length: number): void {
this.dataArray = new Array(length).fill(null).map(() => []);
for (let index = 0; index < length; index++) {
this.notifyDataAdd(index);
}
}
public clearDataList(): void {
this.dataArray = [];
}
}
export {
Data,
ApiEndpoints,
ProductInfoSource,
ProductInfoSourceArray
}
然后这里是基于懒加载的渲染方法,OrderPage.ets,后续优化内容我就不更新了
import { Api, ApiUrls, Data, ProductInfoSourceArray, setTitle } from '@ohos/common';
import { LengthMetrics } from '@kit.ArkUI';
@Entry
@Component
export struct OrderPage {
// 商品分类信息
@State productCate: Data[] = [];
// 店铺列表
@State shopList: Data[] = [];
// 顶部栏Index
@State currentIndex: number = 0;
// 侧边栏Index,索引代表顶部Index
@State sCurrentIndex: number[] = [];
// 商品列表,二维数组,一维索引代表侧边Index,其中Array代表具体数据
@State itemList: Data[][] = [];
// 懒加载列表
@State lazyItemList: ProductInfoSourceArray = new ProductInfoSourceArray();
// 控制侧边栏隐显
@State showRightSide: boolean = false;
// 侧栏滚动控制器
private listScroller: Scroller = new Scroller();
aboutToAppear(): void {
this.fetchShopList();
this.fetchProductCate().then(() => {
// 调取数据后执行,将侧边栏Index根据顶部数量置空
this.sCurrentIndex = new Array(this.productCate.length).fill(0);
// 初始化当前tab下lazyItemList
this.lazyItemList.initialize((this.productCate[this.currentIndex].effect_cate_list as Data[]).length);
this.lazyItemList.updateIndex(this.sCurrentIndex[this.currentIndex])
if (!this.lazyItemList.childCount()) {
this.fetchProductList(this.currentIndex, this.sCurrentIndex[this.currentIndex]);
}
// 如果不是最后一个
if (this.sCurrentIndex[this.currentIndex] !== this.lazyItemList.totalCount() - 1 ) {
// 当下一页没有数据时
if (!this.lazyItemList.nextChildCount()) {
this.fetchProductList(this.currentIndex, this.sCurrentIndex[this.currentIndex] + 1);
}
}
// 不是第一个
if (this.sCurrentIndex[this.currentIndex] !== 0 ) {
// 当上一页没有数据时
if (!this.lazyItemList.preChildCount()) {
this.fetchProductList(this.currentIndex, this.sCurrentIndex[this.currentIndex] - 1);
}
}
});
}
@Builder
TabBuilder(title_cn: string, title_en: string, targetIndex: number, isLast: boolean) {
Column() {
Text(title_cn)
.fontColor(this.currentIndex === targetIndex ? '#333333' : '#999999')
.fontSize(14)
Text(title_en)
.fontColor(this.currentIndex === targetIndex ? '#333333' : '#999999')
.fontSize(12)
}
.border({
width: {
right: !isLast ? 1 : 0
},
color: '#d1cac1'
})
.height('100%')
.width('100%')
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
}
@Builder
// targetIndex: 侧边Index, Index: 顶部index
sTabBuilder(title: string, targetIndex: number, index: number) {
Column() {
Text(title)
.fontColor(this.sCurrentIndex[index] === targetIndex ? '#ff6827' : '#666056')
.fontSize(14)
}
.onClick(() => {
this.sCurrentIndex[index] = targetIndex;
this.lazyItemList.updateIndex(targetIndex)
if (!this.lazyItemList.childCount()) {
this.fetchProductList(this.currentIndex, targetIndex);
}
// 如果不是最后一个
if (targetIndex !== this.lazyItemList.totalCount() - 1 ) {
// 当下一页没有数据时
if (!this.lazyItemList.nextChildCount()) {
this.fetchProductList(this.currentIndex, targetIndex + 1);
}
}
// 不是第一个
if (targetIndex !== 0 ) {
// 当上一页没有数据时
if (!this.lazyItemList.preChildCount()) {
this.fetchProductList(this.currentIndex, targetIndex - 1);
}
}
this.listScroller.scrollToIndex(targetIndex)
})
.height(45)
.width('100%')
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
.backgroundColor(this.sCurrentIndex[this.currentIndex] === targetIndex ? Color.White : '#f5f5f5')
}
@Builder
ListGroupHeader(title: string) {
Text(title)
.fontSize(12)
.fontColor('#666056')
.margin({
top: 15,
left: 11
})
}
build() {
NavDestination() {
Flex({ direction: FlexDirection.Column, space: { main: LengthMetrics.vp(10) } }) {
// 顶部图片+文字
Column() {
Image($rawfile('OrderPage/background.png'))
.position({
x: 0,
y: 0
})
.width('100%')
Row() {
Column() {
Text('汤头泡泡')
.fontSize(20)
.fontColor(Color.White)
Row({ space: 5 }) {
Text(this.shopList.length ? this.shopList[0].title as string : '')
.fontSize(14)
.fontColor(Color.White)
// Polyline({ width: 8, height: 12 })
// .points([[0, 0], [7, 5.5], [0, 11]])
// .fillOpacity(0)
// .stroke(Color.White)
// .strokeWidth(2)
}
.onClick( () => {
// TODO 切换门店
})
}
.alignItems(HorizontalAlign.Start)
Button('门店自取', { type: ButtonType.Normal })
.borderRadius(3)
.fontSize(14)
.height(25)
.fontColor(Color.White)
.backgroundColor('#ff6827')
}
.height('100%')
.width('100%')
.padding(15)
.justifyContent(FlexAlign.SpaceBetween)
.alignItems(VerticalAlign.Center)
.backgroundColor('#4c000000')
}
.height(132)
// 顶tabs栏
Tabs() {
ForEach(this.productCate, (item: Data, index: number) => {
TabContent() {
if (this.currentIndex === index) {
Flex({ direction: FlexDirection.Column }) {
// 商品列表
Flex() {
List({ initialIndex: this.sCurrentIndex[index] }) {
ForEach(item.effect_cate_list as Data[], (sItem: Data, sIndex: number) => {
this.sTabBuilder(sItem.title as string, sIndex, index)
}, () => index.toString())
}
.height('100%')
.scrollBar(BarState.Off)
.flexBasis(88)
List({ scroller: this.listScroller }) {
// 在这里通过index跳转到相应的项
if (this.showRightSide) {
LazyForEach(this.lazyItemList, (sItem: Data[], sIndex: number) => {
ListItemGroup({
header: this.ListGroupHeader((this.productCate[index].effect_cate_list as Data[])[sIndex].title as string)
}) {
// rItem为右侧数据项
ForEach(sItem, (rItem: Data, rIndex: number) => {
ListItem() {
productItem({ item: rItem, isTop: this.lazyItemList.getChildData(0) === rItem })
}
})
}
})
}
}
.onScrollIndex((firstIndex: number, lastIndex: number, centerIndex: number) => {
this.sCurrentIndex[this.currentIndex] = lastIndex;
this.lazyItemList.updateIndex(lastIndex)
if (!this.lazyItemList.childCount()) {
this.fetchProductList(this.currentIndex, lastIndex);
}
// 如果不是最后一个
if (lastIndex !== this.lazyItemList.totalCount() - 1 ) {
// 当下一页没有数据时
if (!this.lazyItemList.nextChildCount()) {
this.fetchProductList(this.currentIndex, lastIndex + 1);
}
}
// 不是第一个
if (lastIndex !== 0 ) {
// 当上一页没有数据时
if (!this.lazyItemList.preChildCount()) {
this.fetchProductList(this.currentIndex, lastIndex - 1);
}
}
})
// 调整组的数量
.cachedCount(1)
.flexGrow(1)
.sticky(StickyStyle.Header)
.height('100%')
.backgroundColor(Color.White)
}
// 底部购物车
Flex() {
// TODO 购物车功能实现
}
.height(49)
.width('100%')
.backgroundColor(Color.Blue)
}
}
}
.tabBar(this.TabBuilder(item.title as string, item.sub_title as string, index,
index === this.productCate.length - 1 ? true : false))
}, (item: Data) => item.title as string)
}
.scrollable(false)
.onChange((index) => {
this.currentIndex = index;
// 重新生成itemList
this.showRightSide = false;
this.lazyItemList.clearDataList();
this.lazyItemList.initialize((this.productCate[index].effect_cate_list as Data[]).length);
this.fetchProductList(this.currentIndex, this.sCurrentIndex[this.currentIndex]);
})
.divider({
strokeWidth: 10,
color: '#f5f5f5'
})
.barHeight(50)
.flexGrow(1)
.backgroundColor(Color.White)
}
.backgroundColor('#f5f5f5')
}
.title(setTitle('门店点单'))
}
initializeItemList(length: number) {
return new Array(length).fill(null).map(() => []);
};
async fetchShopList() {
const res = await Api("GET", ApiUrls.shopList, {}, false)
this.shopList = (res.results as Data).data as Data[];
}
async fetchProductCate() {
const res = await Api("GET", ApiUrls.productCate, {}, false)
this.productCate = (res.results as Data).data as Data[];
}
// 接受顶部和侧边栏的index,从productCate中读取数据
async fetchProductList(topIndex: number, sideIndex: number) {
const params: Data = {
'cate_id': this.productCate[topIndex].id?.toString(),
'effect_cate_id': (this.productCate[topIndex].effect_cate_list as Data[])[sideIndex].id?.toString()
};
const res = await Api("GET", ApiUrls.shopProductList, params, false);
// 拼接新获取的数据到现有的列表中
this.lazyItemList.updateIndex(sideIndex);
this.lazyItemList.refreshDataList((res.results as Data).data as Data[])
if (!this.showRightSide) {
this.showRightSide = true;
}
}
}
@Component
struct productItem {
@Prop item: Data;
@Prop isTop: boolean;
build() {
Flex({ direction: FlexDirection.Row }) {
Image((this.item.cover as Data[])[0].source as string)
.flexBasis(80)
.height(80)
Column() {
Text(this.item.title as string)
.fontSize(14)
.fontColor('#333333')
if ((this.item.posts_list as Data[]).length > 0) {
Text(`本膳食依据${(this.item.posts_list as Data[])[0].reference as string}所记载的${(this.item.posts_list as Data[])[0].reference_title as string},采用西点工艺制成。`)
.maxLines(2)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontSize(11)
.fontColor('#666056')
.margin({
top: 2
})
.width(165)
}
Row() {
Text() {
Span('¥')
.fontSize(12)
Span(this.item.sku_min_price as string)
.fontSize(17)
}
.fontColor('#333333')
Button('选规格')
.fontSize(13)
.height(21)
.backgroundColor('#ff6827')
}
.width(165)
.justifyContent(FlexAlign.SpaceBetween)
}
.height(80)
.justifyContent(FlexAlign.SpaceBetween)
.alignItems(HorizontalAlign.Start)
.flexGrow(1)
.padding({
left: 10
})
}
.padding({
top: this.isTop ? 11 : 16,
bottom: 15,
left: 10
})
.border({
width: {
bottom: 1
},
color: '#eeeeee'
})
}
}