HarmonyOS從Text的寶藏屬性想到的TabList新玩法
想了解更多內(nèi)容,請(qǐng)?jiān)L問(wèn):
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)
一.前言
前幾天,運(yùn)營(yíng)小姐姐跟我說(shuō)再發(fā)幾篇文章有望沖擊星光計(jì)劃創(chuàng)作先鋒獎(jiǎng),我一看有這等好事,哈,說(shuō)笑呢,我是為了那些獎(jiǎng)品嗎,這不是小瞧我么,對(duì)于這個(gè)請(qǐng)求,依我的性格那當(dāng)然
直接答應(yīng)啊,能拿大獎(jiǎng)造福大家不香么.
于是乎我只好拿出昨天發(fā)現(xiàn)的壓箱底的寶藏內(nèi)容,沖擊一波大獎(jiǎng),誰(shuí)都不許攔哈.
哈哈,開(kāi)個(gè)小玩笑.
二.Text隱藏的王炸,全網(wǎng)暫時(shí)還未發(fā)掘
那既然要拿獎(jiǎng),總得拿出點(diǎn)真東西出來(lái),于是打開(kāi)了塵封的文檔,這一看可不得了,看起來(lái)簡(jiǎn)單的text一點(diǎn)不簡(jiǎn)單啊,直把我驚了一身冷汗.
事情是這樣的,我們知道所有的控件幾乎都是拿Text做Base繼承出來(lái)的,那Text里面有些什么呢?

就是他了,你說(shuō),你說(shuō)說(shuō),沒(méi)想到濃眉大眼的Text也叛變啦.你這不是把Image的飯碗給搶了嗎.
跟據(jù)文檔,輕松就做出一個(gè)控件效果:

但是這就完了嗎.
我現(xiàn)在想實(shí)現(xiàn)在程序運(yùn)行的時(shí)候動(dòng)態(tài)改變這個(gè)圖該怎么辦.
三.動(dòng)態(tài)修改上方圖標(biāo)
既然是動(dòng)態(tài)修改,那自然就要在代碼上下功夫了
Text類(lèi)里面查看一下,果然有Element相關(guān)的接口:

哈哈,天意,這里面的參數(shù)寫(xiě)得明明白白,我們可以設(shè)置上下左右四個(gè)方向的圖標(biāo)
話(huà)不多說(shuō),趕緊試一下
可是這個(gè)Element是什么呢.點(diǎn)進(jìn)去一看,心涼一半:

原來(lái)是個(gè)超類(lèi)啊,這讓我怎么用,官方文檔貌似沒(méi)有講這個(gè)的.
經(jīng)過(guò)在論壇的搜索,發(fā)現(xiàn)這么一篇寶藏文:
https://harmonyos.51cto.com/posts/8592
一句漫不經(jīng)心的說(shuō)話(huà),將我疑惑解開(kāi):

原來(lái)你有兒子啊,話(huà)不多說(shuō),拿來(lái)就用

造出一個(gè)Element需要這三個(gè)東西,其中下面兩個(gè)我不認(rèn)識(shí),去看Resource感覺(jué)挺復(fù)雜,那就只有PixelMap能用了
那怎么生成一個(gè)PixelMap呢:

這里面提供了幾個(gè)靜態(tài)方法,對(duì)我而言,都沒(méi)有用
突然我想到在哪用過(guò)PixelMap,記得我的朋友應(yīng)該還記得那篇文章:
#星光計(jì)劃2.0#應(yīng)用開(kāi)發(fā)-獨(dú)家發(fā)布-攝像頭掃描二維碼(Java版)
這里面有過(guò)把Image轉(zhuǎn)換成PixelMap的方法:

于是乎立馬想到,Image里面應(yīng)該有取PixelMap的方法,結(jié)果天助我也:
- //先創(chuàng)建一個(gè)img
- Image img =new Image(getContext());
- //把media資源設(shè)置進(jìn)去
- img.setPixelMap(ResourceTable.Media_setting_large);
- //直接取出生成PixelMapElement
- PixelMapElement pixelMapElement= new PixelMapElement(img.getPixelMap());
接下來(lái)的事情就簡(jiǎn)單了:
- Text account_text = (Text) findComponentById(ResourceTable.Id_text_helloworld);
- account_text.setAroundElements(null, pixelMapElement, null, null);
后面效果就是這樣:

其實(shí)這篇文章也解答了一位老兄今年1月份的帖子:
https://harmonyos.51cto.com/answer/386
四.就這?
到這里,很多朋友以為結(jié)束了,nonono
為什么我會(huì)冒出一身冷汗,因?yàn)槲铱吹搅斯俜轿臋n:
https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ui-java-component-tablist-tab-0000001062229749

這里展示了一個(gè)頂部標(biāo)簽頁(yè),一般新聞,資訊,論壇類(lèi)會(huì)用這種,我想要一個(gè)什么樣的效果呢?

我想在底部做出一個(gè)類(lèi)似的切換效果,這種界面其實(shí)還是很常見(jiàn)的,比如微信
有了官方文檔的buff,很快我們就能做出一個(gè)類(lèi)似的效果:
- <?xml version="1.0" encoding="utf-8"?>
- <DirectionalLayout
- xmlns:ohos="http://schemas.huawei.com/res/ohos"
- ohos:height="match_parent"
- ohos:width="match_parent"
- ohos:alignment="top"
- ohos:orientation="vertical"
- >
- <Text
- ohos:id="$+id:text_helloworld"
- ohos:height="match_content"
- ohos:width="match_content"
- ohos:top_margin="200vp"
- ohos:layout_alignment="horizontal_center"
- ohos:text="歡迎登錄系統(tǒng)"
- ohos:text_size="30fp"
- ohos:text_color="#58d421"
- ohos:element_top="$media:home_large"
- />
- <DirectionalLayout
- ohos:height="match_content"
- ohos:width="match_parent"
- ohos:top_margin="60vp"
- ohos:left_margin="30vp"
- ohos:orientation="horizontal"
- >
- <Text
- ohos:height="30vp"
- ohos:width="50vp"
- ohos:text_size="20fp"
- ohos:text="賬號(hào):"
- ohos:text_color="#58d421"
- />
- <TextField
- ohos:id="$+id:account_input"
- ohos:height="30vp"
- ohos:width="230vp"
- ohos:left_margin="10vp"
- ohos:text_size="20fp"
- ohos:background_element="$graphic:text_filed_style"
- />
- </DirectionalLayout>
- <DirectionalLayout
- ohos:height="match_content"
- ohos:width="match_parent"
- ohos:top_margin="10vp"
- ohos:left_margin="30vp"
- ohos:orientation="horizontal"
- >
- <Text
- ohos:height="30vp"
- ohos:width="50vp"
- ohos:text_size="20fp"
- ohos:text="密碼:"
- ohos:text_color="#58d421"
- />
- <TextField
- ohos:id="$+id:pwd_input"
- ohos:height="30vp"
- ohos:width="230vp"
- ohos:text_input_type="pattern_password"
- ohos:left_margin="10vp"
- ohos:text_size="20fp"
- ohos:padding="0vp"
- ohos:background_element="$graphic:text_filed_style"
- />
- </DirectionalLayout>
- <Button
- ohos:top_margin="50vp"
- ohos:id="$+id:main_btn"
- ohos:height="50vp"
- ohos:width="100vp"
- ohos:clickable="true"
- ohos:text="登陸"
- ohos:layout_alignment="center"
- ohos:text_size="20vp"
- ohos:text_color="#58d421"
- ohos:scrollbar_background_color="#3FC390EF"
- ohos:background_element="$graphic:capsule_button_element"
- />
- <TabList
- ohos:id="$+id:main_tabList"
- ohos:height="150vp"
- ohos:width="match_parent"
- ohos:text_size="20fp"
- ohos:layout_alignment="bottom"
- ohos:orientation="horizontal"
- ohos:normal_text_color="black"
- />
- </DirectionalLayout>

但是仔細(xì)觀(guān)察一下,會(huì)發(fā)現(xiàn),微信上面選中的頁(yè)面不僅文字會(huì)變色,圖標(biāo)也會(huì)變色:

接下來(lái)就是見(jiàn)證奇怪的時(shí)刻
五.制作按下圖片換色效果
為了實(shí)現(xiàn)這一步,最簡(jiǎn)單的做法是找兩張圖片,比如一張彩色,一張黑色,那這種圖片哪里找呢?
在這個(gè)網(wǎng)站幾乎常見(jiàn)不常見(jiàn)的圖標(biāo)都能找到:
https://www.iconfont.cn/search/index?spm=a313x.7781069.1998910419.28&searchType=icon&q= home&page=1&fromCollection=-1&fills=&tag=
選中一個(gè)喜歡的圖標(biāo),點(diǎn)擊下載按鈕:


左邊選顏色,右邊選尺寸,下載完放到media目錄就行
把圖標(biāo)都準(zhǔn)備好之后,就要想辦法了
官方的TabList和Tab都已經(jīng)實(shí)現(xiàn)好了,肯定不能動(dòng)
那我們就用繼承吧:
- class myTab extends TabList.Tab {
- PixelMapElement normal;
- PixelMapElement pressed;
- Color defaultColor = Color.BLACK;
- public myTab(TabList list,Context context) {
- list.super(context);
- this.setTextColor(defaultColor);
- }
- public void setImage(int normal_img,int pressed_img){
- Image img = new Image(getContext());
- img.setPixelMap(normal_img);
- normal = new PixelMapElement(img.getPixelMap());
- img.setPixelMap(pressed_img);
- pressed = new PixelMapElement(img.getPixelMap());
- super.setAroundElements(null,normal,null,null);
- }
- public void isSelected(boolean select){
- this.setTextColor(select?Color.BLUE:defaultColor);
- super.setAroundElements(null,select ? pressed : normal,null,null);
- }
- }
這里我們用myTab繼承了TabList里面的Tab類(lèi),就不去講語(yǔ)法了,總之這樣就行
注意這里面的兩個(gè)方法:
setImage(int normal_img,int pressed_img)方法用來(lái)設(shè)置兩個(gè)圖片,一個(gè)是普通未選中的狀態(tài),另一個(gè)就是選中的狀態(tài)
isSelected(boolean select)來(lái)指示當(dāng)Tab被選中的時(shí)候如何進(jìn)行切換圖片
在主程序的tabList里面添加事件監(jiān)聽(tīng):
- TabList tabList = (TabList) findComponentById(ResourceTable.Id_main_tabList);
- myTab tab = new myTab(tabList,getContext());
- tab.setText("home");
- tab.setImage(ResourceTable.Media_home_large,ResourceTable.Media_home_large_pushed);
- tabList.addTab(tab);
- myTab tab2 = new myTab(tabList,getContext());
- tab2.setText("my");
- tab2.setImage(ResourceTable.Media_my_large,ResourceTable.Media_my_large_pushed);
- tabList.addTab(tab2);
- myTab tab3 = new myTab(tabList,getContext());
- tab3.setText("setting");
- tab3.setImage(ResourceTable.Media_setting_large,ResourceTable.Media_setting_large_pushed);
- tabList.addTab(tab3);
- tabList.setFixedMode(true);
- tabList.addTabSelectedListener(new TabList.TabSelectedListener() {
- @Override
- public void onSelected(TabList.Tab tab) {
- // 當(dāng)某個(gè)Tab從未選中狀態(tài)變?yōu)檫x中狀態(tài)時(shí)的回調(diào)
- myTab mytab = (myTab)tab;
- mytab.isSelected(true);
- }
- @Override
- public void onUnselected(TabList.Tab tab) {
- // 當(dāng)某個(gè)Tab從選中狀態(tài)變?yōu)槲催x中狀態(tài)時(shí)的回調(diào)
- myTab mytab = (myTab)tab;
- mytab.isSelected(false);
- }
- @Override
- public void onReselected(TabList.Tab tab) {
- // 當(dāng)某個(gè)Tab已處于選中狀態(tài),再次被點(diǎn)擊時(shí)的狀態(tài)回調(diào)
- this.onUnselected(tab);
- }
- });
大功告成,在模擬器里面運(yùn)行一下:

里面有幾下圖片變藍(lán)然后又變白其實(shí)是出發(fā)了上面的onReselected(TabList.Tab tab)方法,我這里做法是直接變成未選中,大家也可以選擇忽略這個(gè)方法,根據(jù)自己的應(yīng)用場(chǎng)景靈活使用.
六.尚未解決的問(wèn)題
1.本次使用了遠(yuǎn)程的tabList實(shí)現(xiàn)了底部文字及圖標(biāo)的切換效果,但是是利用切圖片的方式實(shí)現(xiàn)了,有沒(méi)有辦法能夠直接修改圖片的顏色,望有大神告知
2.使用原生的TabList方式做出這樣一個(gè)效果就是貌似PixelMapElement無(wú)法設(shè)置圖片的大小,這就是為什么大家會(huì)看到我的meida資源的圖片會(huì)有l(wèi)arge字樣,有沒(méi)有辦法設(shè)置圖片的大小希望有大神能告知
3.點(diǎn)擊Tab切換頁(yè)面的效果時(shí)間關(guān)系沒(méi)有做,而且本文重點(diǎn)也不在這,如果有想知道如何切換真正的頁(yè)面搜索論壇里面TabList有其他大牛寫(xiě)的例子
七.總結(jié)
這篇文章屬于拋磚引玉,主要是想說(shuō)明一個(gè)不經(jīng)意的發(fā)現(xiàn)也能發(fā)散出精彩的創(chuàng)意,可能在別人看來(lái)我這沒(méi)什么,但是技術(shù)這東西,都是自己才能懂.
之前鴻蒙系統(tǒng)很多功能總有網(wǎng)友說(shuō)這有什么用,我想說(shuō)的是:到底有什么用,不要問(wèn)別人,問(wèn)自己,有沒(méi)有那雙真正能發(fā)現(xiàn)精彩的眼睛.
用一張楚團(tuán)長(zhǎng)的表情包與大家共勉:
想了解更多內(nèi)容,請(qǐng)?jiān)L問(wèn):
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)