鴻蒙開源第三方件組件-輪播組件Banner
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)
前言
基于安卓平臺的輪播組件Banner(https://github.com/youth5201314/banner/tree/release-1.4.10),實(shí)現(xiàn)了鴻蒙化遷移和重構(gòu),代碼已經(jīng)開源到(https://gitee.com/isrc_ohos/banner_ohos),目前已經(jīng)獲得了很多人的Star和Fork,歡迎各位下載使用并提出寶貴意見!
背景
Banner一般位于APP的頂部或中部,通過循環(huán)播放和手動(dòng)滑動(dòng)的方式對一些圖片進(jìn)行展示,其底部通常放置一行圓圈狀的指示器,表示當(dāng)前正在展示的圖片的頁碼。Banner組件播放圖片美觀且節(jié)約頁面,目前已經(jīng)被廣泛應(yīng)用于各大APP。
功能展示
基于鴻蒙系統(tǒng),通過自定義控件屬性的方式實(shí)現(xiàn)了Banner組件,該組件支持圖片的循環(huán)播放、手動(dòng)滑動(dòng)兩種功能。
1、循環(huán)播放
當(dāng)頁面沒有任何操作時(shí),Banner內(nèi)部的圖片按照提前設(shè)定時(shí)間間隔和順序自動(dòng)輪播,這種方式稱為循環(huán)播放,效果如圖一所示。
圖一 循環(huán)播放功能展示
2、手動(dòng)滑動(dòng)
手指在組件處滑動(dòng)時(shí),也可以實(shí)現(xiàn)圖片的播放,此時(shí)圖片的播放順序由用戶的滑動(dòng)方向決定,播放時(shí)間間隔由用戶的滑動(dòng)速度決定。
圖二 手動(dòng)滑動(dòng)功能展示
Sample解析
圖三 Banner組件的標(biāo)題和指示器
Sample中選取了五張圖片進(jìn)行輪播展示,每一張圖片下方都添加了頁碼指示器和圖片標(biāo)題。頁碼指示器用于顯示當(dāng)前正在播放的圖片的頁碼,標(biāo)題用于顯示圖片的關(guān)鍵信息,效果如圖三所示。Sample中給圖片增加了點(diǎn)擊事件,當(dāng)用戶對頁面內(nèi)容感興趣時(shí),可通過手指進(jìn)行點(diǎn)擊,圖片會鏈接到另外的展示界面,效果如圖四所示。
圖四 圖片支持點(diǎn)擊事件的效果
下面對Sample部分的代碼進(jìn)行具體解釋:
1、導(dǎo)入Banner類、OnBannerListener類
- //用于實(shí)例化Banner對象
- import com.youth.banner.Banner;
- //用于圖片接收點(diǎn)擊事件
- import com.youth.banner.listener.OnBannerListener;
2、實(shí)例化對象
- Banner banner = new Banner(this);
3、設(shè)置Banner的Layout參數(shù)
- //組件寬度跟隨父控件,高度固定為800
- DirectionalLayout.LayoutConfig layoutConfig = new DirectionalLayout.LayoutConfig (ComponentContainer.LayoutConfig.MATCH_PARENT, 800);
4、設(shè)置組件的監(jiān)聽
- banner.setOnBannerListener(this); //用于圖片接收點(diǎn)擊事件
- @Override
- public void OnBannerClick(int position) {
- //此處為了展示圖片支持點(diǎn)擊事件的功能,為第0、2、3幅圖片設(shè)置了點(diǎn)擊事件
- if (position == 0){ // “標(biāo)題1” 所在圖片
- present(new forthAbilitySlice(),new Intent());
- }
- if (position == 2){ // “紅色法拉利大促銷” 所在圖片
- present(new five AbilitySlice(),new Intent());
- }
- if (position == 3){ // “拳擊” 所在圖片
- present(new SecondAbilitySlice(),new Intent());
- }
- }
5、準(zhǔn)備組件需播放的圖片
- List<Integer> list=new ArrayList<>(); //將5張圖片提前放入List
- list.add(ResourceTable.Media_1);
- list.add(ResourceTable.Media_2);
- list.add(ResourceTable.Media_3);
- list.add(ResourceTable.Media_4);
- list.add(ResourceTable.Media_5);
6、準(zhǔn)備圖片的標(biāo)題
- List<String> title=new ArrayList<>(); //將5個(gè)標(biāo)題提前放入List
- title.add("藍(lán)色夾克");
- title.add("圓您星夢");
- title.add("拳擊");
- title.add("紅色法拉利大促銷");
- title.add("邊看邊買");
7、設(shè)置組件參數(shù)
在此步驟中,圖片模式、圖片輪播的時(shí)間間隔、組件風(fēng)格、標(biāo)題大小四個(gè)屬性可以不設(shè)置,當(dāng)用戶不設(shè)置時(shí),屬性采用默認(rèn)值。
- banner.setImages(list) //組件載入圖片list
- .setBannerTitles(title) //組件載入圖片標(biāo)題list
- .setScaleType(3) //圖片模式設(shè)置
- .setDelayTime(3000) //圖片輪播的時(shí)間間隔設(shè)置
- .setBannerStyle(5) //組件風(fēng)格設(shè)置
- .setTitleTextSize(60) //標(biāo)題大小設(shè)置
- .start();
8、將Banner添加到Layout中
- myLayout.addComponent(banner);
Library解析
1、功能實(shí)現(xiàn)
(1)循環(huán)播放
圖五 循環(huán)播放原理圖
如圖五所示,圖片(1)到(5)是我們載入組件的5張?jiān)瓐D,復(fù)制圖片(1)放在(6)的位置,第(1)張和第(6)張圖片相同。當(dāng)組件循環(huán)播放時(shí),會依次播放圖片(1)到(5),并為每張圖片設(shè)置停留時(shí)間,當(dāng)播放到圖片(6)時(shí),不設(shè)停留時(shí)間,直接跳轉(zhuǎn)到圖片(1)進(jìn)行播放,由于圖片(1)和(6)相同,此時(shí)用戶肉眼看不出圖片的轉(zhuǎn)換。同樣,我們需要復(fù)制圖片(5)放在(0)的位置,適用于手動(dòng)滑動(dòng)模式下,用戶向左滑動(dòng)圖片的情況。
采用上述循環(huán)播放原理,圖片(5)和(1)的切換效果如圖六(b)所示,為滑動(dòng)播放效果。若不采用上述原理,播放完圖片(5)后直接跳轉(zhuǎn)到圖片(1)進(jìn)行播放,會導(dǎo)致兩張圖片出現(xiàn)如圖六(a)所示的閃現(xiàn)播放的效果,與前四張圖片的切換效果不一致,所以此處需要使用圖五所示的循環(huán)播放原理。
(a)圖片閃現(xiàn)播放效果
b)圖片滑動(dòng)播放效果
圖六 圖片閃現(xiàn)播放和滑動(dòng)播放效果對比
循環(huán)播放原理代碼分析如下:
- switch (state) {
- case 0: // 無任何操作時(shí)
- if (currentItem == 0) { //播放第0張時(shí)
- viewPager.setCurrentPage(count, true); //跳轉(zhuǎn)到第5張播放
- } else if (currentItem == count + 1) { //播放第6張時(shí)
- viewPager.setCurrentPage(1, true); //跳轉(zhuǎn)到第1張播放
- }
- break;
- case 1: //開始滑動(dòng)時(shí)
- if (currentItem == count + 1) {
- viewPager.setCurrentPage(1, true);
- } else if (currentItem == 0) {
- viewPager.setCurrentPage(count, true);
- }
- break;
- case 2: //結(jié)束滑動(dòng)
- break; //不再執(zhí)行任何操作
- }
2、 指示器的構(gòu)建
鴻蒙系統(tǒng)Banner組件的指示器可以5個(gè)種類,分別是:圓形指示器、數(shù)字指示器、數(shù)字指示器和標(biāo)題、圓形指示器和標(biāo)題(垂直顯示)、圓形指示器和標(biāo)題(水平顯示)。此處以圓形指示器為例,講解指示器的構(gòu)建方法。
(1)指示器初始化
當(dāng)組件開始運(yùn)行時(shí),第一張圖片所在的圓點(diǎn)為黑色選中狀態(tài),其余的圓點(diǎn)為紅色未選中狀態(tài)。
- if (i == 0) { //初始狀態(tài)播放第一張圖片
- params = new DirectionalLayout.LayoutConfig(mIndicatorSelectedWidth, mIndicatorSelectedHeight);
- component1.setBackground( ElementScatter.getInstance(getContext()).parse(mIndicatorSelectedResId)); //圓點(diǎn)的背景設(shè)置為黑色選中狀態(tài)
- } else { //除第一張以外的其他圖片
- params = new DirectionalLayout.LayoutConfig(mIndicatorWidth, mIndicatorHeight); component1.setBackground(ElementScatter.getInstance(getContext()).parse(mIndicatorUnselectedResId));
- } //圓點(diǎn)的背景設(shè)置為紅色未選中狀態(tài)
(2) 指示器更新
當(dāng)圖片輪播到下一張時(shí),指示器狀態(tài)更新,新播放的圖片所在的圓點(diǎn)被置為黑色選中狀態(tài),其余的圓點(diǎn)為紅色未選中狀態(tài)。
- //將上一張圖片所在的圓點(diǎn)置為紅色未選中狀態(tài)
- indicatorImages.get((lastPosition - 1 + count) % count).setBackground( ElementScatter.getInstance(getContext()).parse(mIndicatorUnselectedResId));
- indicatorImages.get((lastPosition - 1 + count) % count).setLayoutConfig(Unselectedparams);
- //將正在播放的圖片所在的圓點(diǎn)置為黑色選中狀態(tài)
- indicatorImages.get((position - 1 + count) % count).setBackground( ElementScatter.getInstance(getContext()).parse(mIndicatorSelectedResId));
- indicatorImages.get((position - 1 + count) % count).setLayoutConfig(Selectedparams);
3、 移植方法
鴻蒙Banner組件在移植的時(shí)候,大部分采用API替換的方式,將原來安卓的API替換為鴻蒙的API,例如使用鴻蒙的PageSlider類替換安卓的ViewPage類。
項(xiàng)目貢獻(xiàn)人
陳叢笑 鄭森文 朱偉 陳美汝
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)