touchGFX手环滚动菜单的实现(三)

it2023-11-13  71

touchGFX手环滚动菜单的实现(三)

文章目录

touchGFX手环滚动菜单的实现(三)前言1.实现原理分析2.代码实现3.实现过程遇到的坑1. 两个滑动控件的选择回调函数逻辑不同2. 在实际开发板中点击难以触发3. 界面切换效果无法实现4. 选择回调函数的BUG 后记

前言

本系列文章由萧萧宵小(wurendikunn@outlook.com)编写,转载请注明出处。

文章链接:https://blog.csdn.net/qq_33350808/article/details/109191831

本文涉及到的软件为touchGFX Designer 4.13.0。本文学习如何实现手环中滚动菜单,希望在具体实例中学习各种控件的使用,在学习过程中会涉及到图片控件、文字控件、自定义容器、滚动控件、动作事件等等。内容过多,分几次发布。

在上一章我们已经完成了不同图标的滚动显示及其标题显示。在这一章学习如何给图标加上点击切换界面的逻辑。

1.实现原理分析

点击屏幕切换界面的逻辑可以分为两个步骤:

点击图标触发事件根据事件触发返回的索引切换对应的界面

理解这两点之后需要在写代码之前做一点准备工作,为主界面添加要切换的界面及其切换逻辑。

为5个图标添加对应的5个界面(加中文标题时记得使用中文字体,不然无法显示)

其中逻辑切换的参数如图所示

其中切换效果有滑动(slide)和覆盖(cover)。

添加结束之后点击生成代码

2.代码实现

先找到gui/screen_start_screen/Screen_startView.hpp,打开在其中添加如图所示的代码。

红框内添加的是:

//声明点击事件回调函数 Callback<Screen_startView, int16_t> scrollListClickedCallback; //声明点击事件处理函数 void scrollListClickHandler(int16_t itemSelected); 找到gui/screen_start_screen/Screen_startView.cpp,添加如图所示的代码 红框内添加的是: Screen_startView::Screen_startView(): //初始化将处理函数与回调函数绑定 scrollListClickedCallback(this,&Screen_startView::scrollListClickHandler) { scrollList_start.setItemSelectedCallback(scrollListClickedCallback); } //... void Screen_startView::scrollListClickHandler(int16_t itemSelected) { switch (itemSelected % 5) { case 0: application().gotoScreen_viewScreenNoTransition(); break; case 1: application().gotoScreen_clockScreenNoTransition(); break; case 2: application().gotoScreen_dialScreenNoTransition(); break; case 3: application().gotoScreen_optionsScreenNoTransition(); break; case 4: application().gotoScreen_settingScreenNoTransition(); break; } }

添加完之后根据自己的图标顺序修改对应索引切换的界面。完成编辑运行,滑动图片点击就能切换到对应界面。

3.实现过程遇到的坑

虽然到这里已经完成效果,但是在实际实现过程中遇到过很多的坑,有必要一一说明一下:

1. 两个滑动控件的选择回调函数逻辑不同

在GFX中有两个滑动控件:scrollList和scrollWheel。两者都有选择回调函数,而且两者的描述在官方文档中是一致的,我一开始用的是scrollWheel控件,但是实际用的时候并不是点击触发,而是选中对应的目标就触发,体现在实际的开发板就是我才滑动到对应目标,还没有释放触摸就已经切换到对应界面了,这种效果肯定不是我想要的。

而对于scrollList控件来说就是正常的点击目标才触发切换界面(点击的过程是点击再释放)。

造成这两者的差异其实可以再源码中找到,是因为回调触发的位置不同,有兴趣的可以去研究一下。

总之结论就是想要实现点击切换界面的效果就请用scrollList界面

2. 在实际开发板中点击难以触发

在电脑上软件仿真逻辑正常之后我将其烧录到实际板子上,但是遇到了一个问题,我不管怎么点都是触发的滑动图标效果,点击一个图片非常的艰难,得丝毫不差才行。

既然还是可以触发切换界面的效果,说明触发动作还在,但是点击本身很难触发,结合实际应该是因为将点击动作中的一点点偏移也算成滑动动作。

既然这样GFX中应该有一个管理滑动触发阈值的函数,然后我在官方文档中的确找到了类似的函数:setDragThreshold(),在说明中了解到GFX中的触摸阈值默认为0,意思就是只要我点击的时候偏移了一个像素,就无法触发。但是文档完全没有说明在哪里使用它。仔细查看整个工程代码后发现整个GFX也被作为一个HAL的实例对象,其用的是私有的静态指针,贼像单例模式。所以我在主界面的构造函数中写下下面的代码。

touchgfx::HAL::getInstance()->setDragThreshold(5);//设置了偏移小于5个不算作拖动

OK,完成实现,开发板上已经能顺滑的点击进去。

3. 界面切换效果无法实现

我在写切换逻辑的时候也试过滑动的界面切换,在电脑的软仿真中运行OK,但是在板子跑的时候就歇菜了。在我请教ST官网论坛的开发人员之后,知道了如何实现它。原来在GFX中涉及界面切换的滑动效果属于高级的动画效果,需要给GFX预留足够的显示缓存才能够实现。具体修改的地方在TouchGFXGeneratedHAL.cpp中的void TouchGFXGeneratedHAL::initialize()。

void TouchGFXGeneratedHAL::initialize() { HAL::initialize(); registerEventListener(*(touchgfx::Application::getInstance())); setFrameBufferStartAddresses((void*)frameBuf, (void*)0, (void*)0);//在这里添加新缓存 /* * Set whether the DMA transfers are locked to the TFT update cycle. If * locked, DMA transfer will not begin until the TFT controller has finished * updating the display. If not locked, DMA transfers will begin as soon as * possible. Default is true (DMA is locked with TFT). */ lockDMAToFrontPorch(true); }

添加结束之后就能在板子上也观察到界面切换的高级效果了。

4. 选择回调函数的BUG

我用的GFX的版本是4.13,在我将滑动控件的循环模式改为不循环之后,点击回调返回的索引就不能对应到每个目标。在询问开发人员之后只给出了等待新版本GFX的答复。所以无能为力,想要使用选择回调函数的话就不能用无循环的滑动控件。不信邪的小伙伴可以试一试。

后记

这一章完成了滚动菜单的点击切换界面的功能,至此已经基本实现了手环中点击滚动图标的效果。下一章就在每一个界面中实现不同的常用控件。

本系列文章总目录:touchGFX学习记录

最新回复(0)