#星光计划2.0# HarmonyOS从Text的宝藏属性想到的TabList新玩法 原创 精华
本文正在参与51CTO HarmonyOS技术社区创作者激励计划-星光计划2.0
一.前言
前几天,运营小姐姐跟我说再发几篇文章有望冲击星光计划创作先锋奖,我一看有这等好事,哈,说笑呢,我是为了那些奖品吗,这不是小瞧我么,对于这个请求,依我的性格那当然
直接答应啊,能拿大奖造福大家不香么.
于是乎我只好拿出昨天发现的压箱底的宝藏内容,冲击一波大奖,谁都不许拦哈.
哈哈,开个小玩笑.
二.Text隐藏的王炸,全网暂时还未发掘
那既然要拿奖,总得拿出点真东西出来,于是打开了尘封的文档,这一看可不得了,看起来简单的text一点不简单啊,直把我惊了一身冷汗.
事情是这样的,我们知道所有的控件几乎都是拿Text做Base继承出来的,那Text里面有些什么呢?
就是他了,你说,你说说,没想到浓眉大眼的Text也叛变啦.你这不是把Image的饭碗给抢了吗.
跟据文档,轻松就做出一个控件效果:
但是这就完了吗.
我现在想实现在程序运行的时候动态改变这个图该怎么办.
三.动态修改上方图标
既然是动态修改,那自然就要在代码上下功夫了
Text类里面查看一下,果然有Element相关的接口:
哈哈,天意,这里面的参数写得明明白白,我们可以设置上下左右四个方向的图标
话不多说,赶紧试一下
可是这个Element是什么呢.点进去一看,心凉一半:
原来是个超类啊,这让我怎么用,官方文档貌似没有讲这个的.
经过在论坛的搜索,发现这么一篇宝藏文:
https://harmonyos.51cto.com/posts/8592
一句漫不经心的说话,将我疑惑解开:
原来你有儿子啊,话不多说,拿来就用
造出一个Element需要这三个东西,其中下面两个我不认识,去看Resource感觉挺复杂,那就只有PixelMap能用了
那怎么生成一个PixelMap呢:
这里面提供了几个静态方法,对我而言,都没有用
突然我想到在哪用过PixelMap,记得我的朋友应该还记得那篇文章:
#星光计划2.0#应用开发-独家发布-摄像头扫描二维码(Java版)
这里面有过把Image转换成PixelMap的方法:
于是乎立马想到,Image里面应该有取PixelMap的方法,结果天助我也:
//先创建一个img
Image img =new Image(getContext());
//把media资源设置进去
img.setPixelMap(ResourceTable.Media_setting_large);
//直接取出生成PixelMapElement
PixelMapElement pixelMapElement= new PixelMapElement(img.getPixelMap());
接下来的事情就简单了:
Text account_text = (Text) findComponentById(ResourceTable.Id_text_helloworld);
account_text.setAroundElements(null, pixelMapElement, null, null);
后面效果就是这样:
其实这篇文章也解答了一位老兄今年1月份的帖子:
https://harmonyos.51cto.com/answer/386
四.就这?
到这里,很多朋友以为结束了,nonono
为什么我会冒出一身冷汗,因为我看到了官方文档:
https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ui-java-component-tablist-tab-0000001062229749
这里展示了一个顶部标签页,一般新闻,资讯,论坛类会用这种,我想要一个什么样的效果呢?
我想在底部做出一个类似的切换效果,这种界面其实还是很常见的,比如微信
有了官方文档的buff,很快我们就能做出一个类似的效果:
<?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="欢迎登录系统"
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="账号:"
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>
但是仔细观察一下,会发现,微信上面选中的页面不仅文字会变色,图标也会变色:
接下来就是见证奇怪的时刻
五.制作按下图片换色效果
为了实现这一步,最简单的做法是找两张图片,比如一张彩色,一张黑色,那这种图片哪里找呢?
在这个网站几乎常见不常见的图标都能找到:
https://www.iconfont.cn/search/index?spm=a313x.7781069.1998910419.28&searchType=icon&q= home&page=1&fromCollection=-1&fills=&tag=
选中一个喜欢的图标,点击下载按钮:
左边选颜色,右边选尺寸,下载完放到media目录就行
把图标都准备好之后,就要想办法了
官方的TabList和Tab都已经实现好了,肯定不能动
那我们就用继承吧:
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类,就不去讲语法了,总之这样就行
注意这里面的两个方法:
setImage(int normal_img,int pressed_img)
方法用来设置两个图片,一个是普通未选中的状态,另一个就是选中的状态
isSelected(boolean select)
来指示当Tab被选中的时候如何进行切换图片
在主程序的tabList里面添加事件监听:
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) {
// 当某个Tab从未选中状态变为选中状态时的回调
myTab mytab = (myTab)tab;
mytab.isSelected(true);
}
@Override
public void onUnselected(TabList.Tab tab) {
// 当某个Tab从选中状态变为未选中状态时的回调
myTab mytab = (myTab)tab;
mytab.isSelected(false);
}
@Override
public void onReselected(TabList.Tab tab) {
// 当某个Tab已处于选中状态,再次被点击时的状态回调
this.onUnselected(tab);
}
});
大功告成,在模拟器里面运行一下:
里面有几下图片变蓝然后又变白其实是出发了上面的onReselected(TabList.Tab tab)
方法,我这里做法是直接变成未选中,大家也可以选择忽略这个方法,根据自己的应用场景灵活使用.
六.尚未解决的问题
1.本次使用了远程的tabList实现了底部文字及图标的切换效果,但是是利用切图片的方式实现了,有没有办法能够直接修改图片的颜色,望有大神告知
2.使用原生的TabList方式做出这样一个效果就是貌似PixelMapElement无法设置图片的大小,这就是为什么大家会看到我的meida资源的图片会有large字样,有没有办法设置图片的大小希望有大神能告知
3.点击Tab切换页面的效果时间关系没有做,而且本文重点也不在这,如果有想知道如何切换真正的页面搜索论坛里面TabList有其他大牛写的例子
七.总结
这篇文章属于抛砖引玉,主要是想说明一个不经意的发现也能发散出精彩的创意,可能在别人看来我这没什么,但是技术这东西,都是自己才能懂.
之前鸿蒙系统很多功能总有网友说这有什么用,我想说的是:到底有什么用,不要问别人,问自己,有没有那双真正能发现精彩的眼睛.
用一张楚团长的表情包与大家共勉:
楼主这行文风格有点意思
换换风格不容易腻歪呀