web程序設(shè)計與實(shí)踐做網(wǎng)站搜索引擎關(guān)鍵詞優(yōu)化技巧
一、背景
列表頁面:List組件和Grid組件;
頁簽切換:Tabs組件;
二、列表頁面
在我們常用的手機(jī)應(yīng)用中,經(jīng)常會見到一些數(shù)據(jù)列表,如設(shè)置頁面、通訊錄、商品列表等。下圖中兩個頁面都包含列表,“首頁”頁面中包含兩個網(wǎng)格布局,“商城”頁面中包含一個商品列表。
上圖中的列表中都包含一系列相同寬度的列表項(xiàng),連續(xù)、多行呈現(xiàn)同類數(shù)據(jù),例如圖片和文本。常見的列表有線性列表(List列表)和網(wǎng)格布局(Grid列表):
2.1、List組件
List是很常用的滾動類容器組件,一般和子組件ListItem一起使用,List列表中的每一個列表項(xiàng)對應(yīng)一個ListItem組件。
2.1.1、使用ForEach渲染列表
列表往往由多個列表項(xiàng)組成,所以我們需要在List組件中使用多個ListItem組件來構(gòu)建列表,這就會導(dǎo)致代碼的冗余。使用循環(huán)渲染(ForEach)遍歷數(shù)組的方式構(gòu)建列表,可以減少重復(fù)代碼,示例代碼如下:
@Entry
@Component
struct ListDemo {private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]build() {Column() {List({ space: 10 }) {ForEach(this.arr, (item: number) => {ListItem() {Text(`${item}`).width('100%').height(100).fontSize(20).fontColor(Color.White).textAlign(TextAlign.Center).borderRadius(10).backgroundColor(0x007DFF)}}, item => item)}}.padding(12).height('100%').backgroundColor(0xF1F3F5)}
}
?效果如下:
2.1.2、設(shè)置列表分割線
List組件子組件ListItem之間默認(rèn)是沒有分割線的,部分場景子組件ListItem間需要設(shè)置分割線,這時候您可以使用List組件的divider屬性。divider屬性包含四個參數(shù):
- strokeWidth: 分割線的線寬。
- color: 分割線的顏色。
- startMargin:分割線距離列表側(cè)邊起始端的距離。
- endMargin: 分割線距離列表側(cè)邊結(jié)束端的距離。
2.1.3、List列表滾動事件監(jiān)聽
List組件提供了一系列事件方法用來監(jiān)聽列表的滾動,您可以根據(jù)需要,監(jiān)聽這些事件來做一些操作:
- onScroll:列表滑動時觸發(fā),返回值scrollOffset為滑動偏移量,scrollState為當(dāng)前滑動狀態(tài)。
- onScrollIndex:列表滑動時觸發(fā),返回值分別為滑動起始位置索引值與滑動結(jié)束位置索引值。
- onReachStart:列表到達(dá)起始位置時觸發(fā)。
- onReachEnd:列表到底末尾位置時觸發(fā)。
- onScrollStop:列表滑動停止時觸發(fā)。
2.1.4、設(shè)置List排列方向
List組件里面的列表項(xiàng)默認(rèn)是按垂直方向排列的,如果您想讓列表沿水平方向排列,您可以將List組件的listDirection屬性設(shè)置為Axis.Horizontal。
①Vertical(默認(rèn)值):子組件ListItem在List容器組件中呈縱向排列。
②Horizontal:子組件ListItem在List容器組件中呈橫向排列。
2.2、Grid組件
Grid組件為網(wǎng)格容器,是一種網(wǎng)格列表,由“行”和“列”分割的單元格所組成,通過指定“項(xiàng)目”所在的單元格做出各種各樣的布局。Grid組件一般和子組件GridItem一起使用,Grid列表中的每一個條目對應(yīng)一個GridItem組件。
2.2.1、使用ForEach渲染網(wǎng)格布局
和List組件一樣,Grid組件也可以使用ForEach來渲染多個列表項(xiàng)GridItem,我們通過下面的這段示例代碼來介紹Grid組件的使用。
@Entry
@Component
struct GridExample {// 定義一個長度為16的數(shù)組private arr: string[] = new Array(16).fill('').map((_, index) => `item ${index}`);build() {Column() {Grid() {ForEach(this.arr, (item: string) => {GridItem() {Text(item).fontSize(16).fontColor(Color.White).backgroundColor(0x007DFF).width('100%').height('100%').textAlign(TextAlign.Center)}}, item => item)}.columnsTemplate('1fr 1fr 1fr 1fr').rowsTemplate('1fr 1fr 1fr 1fr').columnsGap(10).rowsGap(10).height(300)}.width('100%').padding(12).backgroundColor(0xF1F3F5)}
}
示例代碼中創(chuàng)建了16個GridItem列表項(xiàng)。同時設(shè)置columnsTemplate的值為'1fr 1fr 1fr 1fr',表示這個網(wǎng)格為4列,將Grid允許的寬分為4等分,每列占1份;rowsTemplate的值為'1fr 1fr 1fr 1fr',表示這個網(wǎng)格為4行,將Grid允許的高分為4等分,每行占1份。這樣就構(gòu)成了一個4行4列的網(wǎng)格列表,然后使用columnsGap設(shè)置列間距為10vp,使用rowsGap設(shè)置行間距也為10vp。示例代碼效果圖如下:
上面構(gòu)建的網(wǎng)格布局使用了固定的行數(shù)和列數(shù),所以構(gòu)建出的網(wǎng)格是不可滾動的。然而有時候因?yàn)閮?nèi)容較多,我們通過滾動的方式來顯示更多的內(nèi)容,就需要一個可以滾動的網(wǎng)格布局。我們只需要設(shè)置rowsTemplate和columnsTemplate中的一個即可。
將示例代碼中GridItem的高度設(shè)置為固定值,例如100;僅設(shè)置columnsTemplate屬性,不設(shè)置rowsTemplate屬性,就可以實(shí)現(xiàn)Grid列表的滾動:
Grid() {ForEach(this.arr, (item: string) => {GridItem() {Text(item).height(100)...}}, item => item)
}
.columnsTemplate('1fr 1fr 1fr 1fr')
.columnsGap(10)
.rowsGap(10)
.height(300)
三、頁簽組件
3.1、Tabs組件
在我們常用的應(yīng)用中,經(jīng)常會有視圖內(nèi)容切換的場景,來展示更加豐富的內(nèi)容。比如下面這個頁面,點(diǎn)擊底部的頁簽的選項(xiàng),可以實(shí)現(xiàn)“首頁”和“我的”
兩個內(nèi)容視圖的切換。
ArkUI開發(fā)框架提供了一種頁簽容器組件Tabs,開發(fā)者通過Tabs組件可以很容易的實(shí)現(xiàn)內(nèi)容視圖的切換。頁簽容器Tabs的形式多種多樣,不同的頁面設(shè)計頁簽不一樣,可以把頁簽設(shè)置在底部、頂部或者側(cè)邊。
3.1.1、Tabs組件的簡單使用
Tabs組件僅可包含子組件TabContent,每一個頁簽對應(yīng)一個內(nèi)容視圖即TabContent組件。下面的示例代碼構(gòu)建了一個簡單的頁簽頁面:
@Entry
@Component
struct TabsExample {private controller: TabsController = new TabsController()build() {Column() {Tabs({ barPosition: BarPosition.Start, controller: this.controller }) {TabContent() {Column().width('100%').height('100%').backgroundColor(Color.Green)}.tabBar('green')TabContent() {Column().width('100%').height('100%').backgroundColor(Color.Blue)}.tabBar('blue')TabContent() {Column().width('100%').height('100%').backgroundColor(Color.Yellow)}.tabBar('yellow')TabContent() {Column().width('100%').height('100%').backgroundColor(Color.Pink)}.tabBar('pink')}.barWidth('100%') // 設(shè)置TabBar寬度.barHeight(60) // 設(shè)置TabBar高度.width('100%') // 設(shè)置Tabs組件寬度.height('100%') // 設(shè)置Tabs組件高度.backgroundColor(0xF5F5F5) // 設(shè)置Tabs組件背景顏色}.width('100%').height('100%')}
}
效果圖如下:
上面示例代碼中,Tabs組件中包含4個子組件TabContent,通過TabContent的tabBar屬性設(shè)置TabBar的顯示內(nèi)容。使用通用屬性width和height設(shè)置了Tabs組件的寬高,使用barWidth和barHeight設(shè)置了TabBar的寬度和高度。
3.1.2、設(shè)置TabBar布局模式
因?yàn)門abs的布局模式默認(rèn)是Fixed的,所以Tabs的頁簽是不可滑動的。當(dāng)頁簽比較多的時候,可能會導(dǎo)致頁簽顯示不全,將布局模式設(shè)置為Scrollable的話,可以實(shí)現(xiàn)頁簽的滾動。
Tabs的布局模式有Fixed(默認(rèn))和Scrollable兩種:
- BarMode.Fixed:所有TabBar平均分配barWidth寬度(縱向時平均分配barHeight高度),頁簽不可滾動,效果圖如下:
- BarMode.Scrollable:每一個TabBar均使用實(shí)際布局寬度,超過總長度(橫向Tabs的barWidth,縱向Tabs的barHeight)后可滑動。
- 當(dāng)頁簽比較多的時候,可以滑動頁簽,下面的示例代碼將barMode設(shè)置為BarMode.Scrollable,實(shí)現(xiàn)了可滾動的頁簽:
@Entry
@Component
struct TabsExample {private controller: TabsController = new TabsController()build() {Column() {Tabs({ barPosition: BarPosition.Start, controller: this.controller }) {TabContent() {Column().width('100%').height('100%').backgroundColor(Color.Green)}.tabBar('green')TabContent() {Column().width('100%').height('100%').backgroundColor(Color.Blue)}.tabBar('blue')...}.barMode(BarMode.Scrollable).barWidth('100%').barHeight(60).width('100%').height('100%')}}
}
3.1.3、設(shè)置TabBar位置和排列方向
Tabs組件頁簽?zāi)J(rèn)顯示在頂部,某些場景下您可能希望Tabs頁簽出現(xiàn)在底部或者側(cè)邊,您可以使用Tabs組件接口中的參數(shù)barPosition設(shè)置頁簽位置。此外頁簽顯示位置還與vertical屬性相關(guān)聯(lián),vertical屬性用于設(shè)置頁簽的排列方向,當(dāng)vertical的屬性值為false(默認(rèn)值)時頁簽橫向排列,為true時頁簽縱向排列。
barPosition的值可以設(shè)置為BarPosition.Start(默認(rèn)值)和BarPosition.End:
3.1.4、自定義TabBar樣式?
TabBar的默認(rèn)顯示效果如下所示:
往往開發(fā)過程中,UX給我們的設(shè)計效果可能并不是這樣的,比如下面的這種底部頁簽效果:
TabContent的tabBar屬性除了支持string類型,還支持使用@Builder裝飾器修飾的函數(shù)。您可以使用@Builder裝飾器,構(gòu)造一個生成自定義TabBar樣式的函數(shù),實(shí)現(xiàn)上面的底部頁簽效果,示例代碼如下:
@Entry
@Component
struct TabsExample {@State currentIndex: number = 0;private tabsController: TabsController = new TabsController();@Builder TabBuilder(title: string, targetIndex: number, selectedImg: Resource, normalImg: Resource) {Column() {Image(this.currentIndex === targetIndex ? selectedImg : normalImg).size({ width: 25, height: 25 })Text(title).fontColor(this.currentIndex === targetIndex ? '#1698CE' : '#6B6B6B')}.width('100%').height(50).justifyContent(FlexAlign.Center).onClick(() => {this.currentIndex = targetIndex;this.tabsController.changeIndex(this.currentIndex);})}build() {Tabs({ barPosition: BarPosition.End, controller: this.tabsController }) {TabContent() {Column().width('100%').height('100%').backgroundColor('#00CB87')}.tabBar(this.TabBuilder('首頁', 0, $r('app.media.home_selected'), $r('app.media.home_normal')))TabContent() {Column().width('100%').height('100%').backgroundColor('#007DFF')}.tabBar(this.TabBuilder('我的', 1, $r('app.media.mine_selected'), $r('app.media.mine_normal')))}.barWidth('100%').barHeight(50).onChange((index: number) => {this.currentIndex = index;})}
}
說明:
示例代碼中將barPosition的值設(shè)置為BarPosition.End,使頁簽顯示在底部。使用@Builder修飾TabBuilder函數(shù),生成由Image和Text組成的頁簽。同時也給Tabs組件設(shè)置了TabsController控制器,當(dāng)點(diǎn)擊某個頁簽時,調(diào)用changeIndex方法進(jìn)行頁簽內(nèi)容切換。
最后還需要給Tabs添加onChange事件,Tab頁簽切換后觸發(fā)該事件,這樣當(dāng)我們左右滑動內(nèi)容視圖的時候,頁簽樣式也會跟著改變。