#星光计划2.0# HarmonyOS从Text的宝藏属性想到的TabList新玩法 原创 精华

物联风景
发布于 2021-12-30 00:46
浏览
4收藏

本文正在参与51CTO HarmonyOS技术社区创作者激励计划-星光计划2.0

一.前言

前几天,运营小姐姐跟我说再发几篇文章有望冲击星光计划创作先锋奖,我一看有这等好事,哈,说笑呢,我是为了那些奖品吗,这不是小瞧我么,对于这个请求,依我的性格那当然
直接答应啊,能拿大奖造福大家不香么.
于是乎我只好拿出昨天发现的压箱底的宝藏内容,冲击一波大奖,谁都不许拦哈.
哈哈,开个小玩笑.

二.Text隐藏的王炸,全网暂时还未发掘

那既然要拿奖,总得拿出点真东西出来,于是打开了尘封的文档,这一看可不得了,看起来简单的text一点不简单啊,直把我惊了一身冷汗.
事情是这样的,我们知道所有的控件几乎都是拿Text做Base继承出来的,那Text里面有些什么呢?
#星光计划2.0# HarmonyOS从Text的宝藏属性想到的TabList新玩法-鸿蒙开发者社区
就是他了,你说,你说说,没想到浓眉大眼的Text也叛变啦.你这不是把Image的饭碗给抢了吗.
跟据文档,轻松就做出一个控件效果:
#星光计划2.0# HarmonyOS从Text的宝藏属性想到的TabList新玩法-鸿蒙开发者社区
但是这就完了吗.
我现在想实现在程序运行的时候动态改变这个图该怎么办.

三.动态修改上方图标

既然是动态修改,那自然就要在代码上下功夫了
Text类里面查看一下,果然有Element相关的接口:
#星光计划2.0# HarmonyOS从Text的宝藏属性想到的TabList新玩法-鸿蒙开发者社区
哈哈,天意,这里面的参数写得明明白白,我们可以设置上下左右四个方向的图标
话不多说,赶紧试一下
可是这个Element是什么呢.点进去一看,心凉一半:
#星光计划2.0# HarmonyOS从Text的宝藏属性想到的TabList新玩法-鸿蒙开发者社区
原来是个超类啊,这让我怎么用,官方文档貌似没有讲这个的.
经过在论坛的搜索,发现这么一篇宝藏文:
https://harmonyos.51cto.com/posts/8592
一句漫不经心的说话,将我疑惑解开:
#星光计划2.0# HarmonyOS从Text的宝藏属性想到的TabList新玩法-鸿蒙开发者社区
原来你有儿子啊,话不多说,拿来就用
#星光计划2.0# HarmonyOS从Text的宝藏属性想到的TabList新玩法-鸿蒙开发者社区
造出一个Element需要这三个东西,其中下面两个我不认识,去看Resource感觉挺复杂,那就只有PixelMap能用了
那怎么生成一个PixelMap呢:
#星光计划2.0# HarmonyOS从Text的宝藏属性想到的TabList新玩法-鸿蒙开发者社区
这里面提供了几个静态方法,对我而言,都没有用
突然我想到在哪用过PixelMap,记得我的朋友应该还记得那篇文章:
#星光计划2.0#应用开发-独家发布-摄像头扫描二维码(Java版)
这里面有过把Image转换成PixelMap的方法:
#星光计划2.0# HarmonyOS从Text的宝藏属性想到的TabList新玩法-鸿蒙开发者社区
于是乎立马想到,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);

后面效果就是这样:
#星光计划2.0# HarmonyOS从Text的宝藏属性想到的TabList新玩法-鸿蒙开发者社区
其实这篇文章也解答了一位老兄今年1月份的帖子:
https://harmonyos.51cto.com/answer/386

四.就这?

到这里,很多朋友以为结束了,nonono
为什么我会冒出一身冷汗,因为我看到了官方文档:
https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ui-java-component-tablist-tab-0000001062229749
#星光计划2.0# HarmonyOS从Text的宝藏属性想到的TabList新玩法-鸿蒙开发者社区
这里展示了一个顶部标签页,一般新闻,资讯,论坛类会用这种,我想要一个什么样的效果呢?
#星光计划2.0# HarmonyOS从Text的宝藏属性想到的TabList新玩法-鸿蒙开发者社区
我想在底部做出一个类似的切换效果,这种界面其实还是很常见的,比如微信
有了官方文档的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>

#星光计划2.0# HarmonyOS从Text的宝藏属性想到的TabList新玩法-鸿蒙开发者社区
但是仔细观察一下,会发现,微信上面选中的页面不仅文字会变色,图标也会变色:
#星光计划2.0# HarmonyOS从Text的宝藏属性想到的TabList新玩法-鸿蒙开发者社区
接下来就是见证奇怪的时刻

五.制作按下图片换色效果

为了实现这一步,最简单的做法是找两张图片,比如一张彩色,一张黑色,那这种图片哪里找呢?
在这个网站几乎常见不常见的图标都能找到:
https://www.iconfont.cn/search/index?spm=a313x.7781069.1998910419.28&searchType=icon&q= home&page=1&fromCollection=-1&fills=&tag=
选中一个喜欢的图标,点击下载按钮:
#星光计划2.0# HarmonyOS从Text的宝藏属性想到的TabList新玩法-鸿蒙开发者社区
#星光计划2.0# HarmonyOS从Text的宝藏属性想到的TabList新玩法-鸿蒙开发者社区
左边选颜色,右边选尺寸,下载完放到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);
            }
        });

大功告成,在模拟器里面运行一下:

#星光计划2.0# HarmonyOS从Text的宝藏属性想到的TabList新玩法-鸿蒙开发者社区
里面有几下图片变蓝然后又变白其实是出发了上面的onReselected(TabList.Tab tab)方法,我这里做法是直接变成未选中,大家也可以选择忽略这个方法,根据自己的应用场景灵活使用.

六.尚未解决的问题

1.本次使用了远程的tabList实现了底部文字及图标的切换效果,但是是利用切图片的方式实现了,有没有办法能够直接修改图片的颜色,望有大神告知
2.使用原生的TabList方式做出这样一个效果就是貌似PixelMapElement无法设置图片的大小,这就是为什么大家会看到我的meida资源的图片会有large字样,有没有办法设置图片的大小希望有大神能告知
3.点击Tab切换页面的效果时间关系没有做,而且本文重点也不在这,如果有想知道如何切换真正的页面搜索论坛里面TabList有其他大牛写的例子

七.总结

这篇文章属于抛砖引玉,主要是想说明一个不经意的发现也能发散出精彩的创意,可能在别人看来我这没什么,但是技术这东西,都是自己才能懂.
之前鸿蒙系统很多功能总有网友说这有什么用,我想说的是:到底有什么用,不要问别人,问自己,有没有那双真正能发现精彩的眼睛.
用一张楚团长的表情包与大家共勉:
#星光计划2.0# HarmonyOS从Text的宝藏属性想到的TabList新玩法-鸿蒙开发者社区

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2021-12-30 00:46:20修改
7
收藏 4
回复
举报
2条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋

楼主这行文风格有点意思

回复
2021-12-30 10:21:29
物联风景
物联风景 回复了 红叶亦知秋
楼主这行文风格有点意思

换换风格不容易腻歪呀

回复
2021-12-30 19:35:07
回复
    相关推荐