专栏名称: 51CTO技术栈
有趣 | 有料 | 有内涵,为您提供最优质的内容,愿我们一起悦享技术,成就人生。
目录
相关文章推荐
码农翻身  ·  11w*14薪,进DeepSeek了! ·  昨天  
程序员的那些事  ·  65 ... ·  3 天前  
51好读  ›  专栏  ›  51CTO技术栈

立个Flag:在鸿蒙上做一款独一无二的遥控器!

51CTO技术栈  · 公众号  · 程序员  · 2021-02-01 18:05

正文

首先立 flag:用 3516 做一款独一无二的遥控器,然后用这款遥控器去尽情的操纵 3861 这款智能小车。


第一呢,肯定不能做的太粗糙了,打工人也要有点儿追求的。


第二呢,围绕着源码,发现一些更多的好东西,比如这次 C++ 界面开发中大多数 API,官方是暂未给出的,这就需要是我去摸索源码。


其中最重要的一点,我想看看能否在 3516 和 3861 组成局域网之后,能否利用分布式软总线能力去调用(当然,这个可能会吹牛,毕竟钊哥说他目前还没调通)。

flag 立完了,这个能不能实现.....我尽力吧!


老规矩先上该应用的演示视频:

https://harmonyos.51cto.com/show/3006

首先呢,大家得搭好 3516 的环境,我最近之所以鸽了这么长时间没有发文章,也有一部分这个原因。


因为我本身用的系统是 ubuntu20.04,然后在其上搭 windows 虚拟机来烧系统以及刷应用。


我在这个过程中是“编代码 3 分钟,刷系统 3 天”,这里我也分享一下我遇到的坑,如果大家也有我这种环境配置的话,希望可以帮助到大家。


最开始的时候,我是用的 virtualBox 虚拟机来搭的 windows,这个 windows 来玩 3861 的时候别提多顺畅了。


当我以为 3516 也会一样顺畅的时候,我发现我错了,装上 3516 的驱动后,我的 windows 开始了无限自动重启模式,我在尝试着修复无果后,一度想着放弃....


是作为一名合格的码农,怎么能随便放弃呢!然后抱着试试看的态度,我装了一个 vmware,没想到啊,真是“山重水复疑无路,柳暗花明又一村”。3516 的环境就这样被搭好了!


好了,说了这么长时间的废话:总结来说就是如果你的本体是 linux,那么你在装 window 的时候虚拟机要选用 vmware,不要用 virtualBox。


PS:我这里本体用了 linux,不是装叉,因为工作的原因导致我毕业之后没就用过 windows,慢慢也就习惯了 linux 了。


然后呢,具体搭建环境的过程,社区置顶处有文章介绍,在 windows 为本体,linux 做虚拟机的情况下,难度还是要小很多的,所以各位大佬也不用太担心这个过程。


好的,作为这个系列的第一篇,也就是实现这个目标的第一步:我先在 3516 上做一个遥控器的应用。


当然这个应用不追求什么完美,但至少也得能看得过去,所以我自认为我做的还是很认真的,演示视频链接见开头,好不好看,大家可以留言评论一拨儿。


下面进入正题,我们来看 C++ 的应用界面开发:


①HarmonyOS 的设备开发的图形图像子系统


首先发出来官网该方面资料介绍的链接:
https://device.harmonyos.com/cn/docs/develop/subsystems/oem_subsys_graphic_des-0000001051677150#ZH-CN_TOPIC_0000001051770388__section73736284117

HarmonyOS 图形系统,提供基础 UI 组件和容器类组件,包括 button、image、label、list、animator、scroll view、swipe view、font、clock、chart、canvas、slider、layout 等。


不过呢,目前官网给出的示例还是十分有限的,如果想要按自己的想法去构思应用的话,很明显这些官方的介绍还是远远不够的。


下面我给出这部分源码的代码位置:其中绝大多数的头文件在:foundation/graphic/lite/interfaces/kits/ui/。


其实 foundation/graphic/ 就存放了源码中的图形模块,各位大佬可以尽情去相关模块源码中遨游,然后能给我点儿指导也是极好的。


在这里我们先整理一下,目前已经开放的,包括源码中已经有的图形模块可以分为两部分一部分是容器类组件,一部分是普通组件,其中容器类组件有如下图。


普通类组件如下图:


容器类组件:

另外据我目前已有的探索结论是: 一个主界面有一个 RootView,使用 GetWindowRootView 来获得。


大家可以把它看成一个界面中最大的容器类组件,然后大家就是把界面相关的容器类组件,普通类组件往上堆就可以。当然别的多界面的实现方式应该不同。


②开始正式该应用的实现过程


如上图,大家可以看到这个整个界面的布局,其中左上角的小箭头是退出应用的,然后它的右边是一行文字动画,接着往下是两个 label 来显示当前遥控器的模式和小车的状态,紧接着是两个按钮。


接下来是整个 SWIPE 容器组件,可以滑动来实现界面的切换。下面就按照这个顺序来介绍:其中重点是小箭头的功能的实现和 SWIPE 容器组件的实现,别的么,其实不值一提。


退出应用功能的实现: PS:这个功能的实现,完全没有介绍,完全是自己看着源码琢磨出来的,并且我还发现了源码中这块儿写的有 Bug,源码中会有点击不中的情况。


先拿代码把这个图标画出来:
static const charconst BACK_ICON_PATH = "/controlCar/assets/entry/resources/base/media/ic_back.png";
static char g_backIconAbsolutePath[MAX_PATH_LENGTH] = {0};
const char* pathHeader = GetSrcPath();
if(sprintf_s(g_backIconAbsolutePath,MAX_PATH_LENGTH,"%s%s",pathHeader,BACK_ICON_PATH) 0){
    printf("GalleryAbilitySlice::OnStart | g_backIconAbsolutePath error");
    return;
}
    backIcon = new UIImageView();
    backIcon->SetPosition(00);
    backIcon->SetSrc(g_backIconAbsolutePath);
    backIcon->SetTouchable(true);
    backIcon->Resize(40,40);

实现退出功能:
    auto onClick = [this] (UIView& view, const Event& event) -> bool {
        TerminateAbility();
        return true;
    };
    backIconListener = new EventListener(onClick, nullptr);
    backIcon->SetOnClickListener(backIconListener);

字幕滚动: 是不是觉得很难,刚开始我也觉得是,然并卵,太 TM 简单了,只需要调用 SetLineBreakMode 这个 API 就可以了。


下面是这个组件的实现代码:
    label_title = new UILabel();
    label_title->SetPosition(280,0);
    label_title->Resize(500,40);
    label_title->SetTextColor(Color::Red());
    label_title->SetText("欢迎各位大佬使用本智能小车遥控器,希望各位大佬能玩的开心!");
    label_title->SetFont("SourceHanSansSC-Regular.otf",30);
    label_title->SetLineBreakMode(UILabel::LINE_BREAK_MARQUEE);

显示的两个 label 和两个 button 按钮: 这个嘛,太简单了,就不解释了,直接来最简单的设置就可以了。


见下面代码:
    //设置显示遥控器模式状态label
    label_remote_state = new UILabel();
    label_remote_state->SetPosition(10,40);
    label_remote_state->Resize(300,40);
    label_remote_state->SetTextColor(Color::Green());
    label_remote_state->SetText("当前模式:基础模式");
    label_remote_state->SetFont("SourceHanSansSC-Regular.otf",20);

    //设置label
    label = new UILabel();
    label->SetPosition(300,40);
    label->SetStyle(STYLE_BACKGROUND_COLOR,Color::Gray().full);
    label->Resize(350,40);
    label->SetText("当前小车连接状态:正在检测中...");
    label->SetTextColor(Color::Green());
    label->SetFont("SourceHanSansSC-Regular.otf"20);

    //设置连接小车按钮
    bt_connect = new UILabelButton();
    bt_connect->SetPosition(700,40,100,40);
    bt_connect->SetTextColor(Color::Green());
    bt_connect->SetText("连接小车");

    //设置断开连接按钮
    bt_disconnect = new UILabelButton();
    bt_disconnect->SetPosition(850,40,100,40);
    bt_disconnect->SetTextColor(Color::Green());
    bt_disconnect->SetText("断开连接");

整个 SWIPE 容器组件的实现: 没错,这部分是整个应用实现的最困难处,文档中介绍基本等于没有。


整个 SWIPE 容器实现的技术难点应该是两点:

  • 设置滑动回调类。

  • 在 SWIPE 使用了 GridLayout 来实现整个遥控器按钮的设计。







请到「今天看啥」查看全文