之前给大家介绍了TouchGFX整体的使用方法,这里我会通过事件界面及动态效果三个方向给大家演示并讲解一个例子。接下来会给大家做个iphone的下滑设置栏。
其中使用到的功能包括自定义窗口,下拉菜单,菜单页,滑动监控。
请先看演示。

由于录制软件的原因信号栏有点闪,效果还是可行的。
下拉菜单
首先需要看一下控件的组成。需要一个主窗口以及背景窗口。除此之外还需要一个自定义的容器控件,即下拉菜单页。在自定义章节会给大家介绍自定义控件的使用。
下拉菜单,主要的过程是滑动事件,还记的Container类吗,该类可以作为承载下拉菜单及主窗口显示的容器,通过重载该类,获取滑动事件,这样就可以获得想要的滑动了。
现在看一下代码。
#ifndef SLIDEMENU_CONTAINER_HPP
#define SLIDEMENU_CONTAINER_HPP
#include <touchgfx/containers/Container.hpp>
#include <touchgfx/widgets/Image.hpp>
#include <touchgfx/containers/ListLayout.hpp>
using namespace touchgfx;
class SlideMenuContainer : public touchgfx::Container 该类继承了Container
{
public:
SlideMenuContainer();
virtual ~SlideMenuContainer();
其中重载了以下事件,之前有说过每个事件的作用这里不过多介绍
virtual void handleTickEvent();
virtual void handleClickEvent(const touchgfx::ClickEvent& evt);
virtual void handleDragEvent(const touchgfx::DragEvent& evt);
virtual void handleGestureEvent(const touchgfx::GestureEvent& evt);
//获得当前状态
uint8_t getSelectedScreen()
{
return currentState;
}
设置一个回调函数用来对于上滑或者下滑进行处理
void setMenuChangeEndedCallback(touchgfx::GenericCallback<const SlideMenuContainer&>& callback)
{
menuChangeAction = &callback;
}
private:
enum States状态类型的定义
{
ANIMATE_COLLAPSE,
ANIMATE_SHOW,
NO_ANIMATION
} currentState;
GenericCallback<const SlideMenuContainer&>* menuChangeAction;
};
cpp文件
#include <gui/common/SlideMenuContainer.hpp>
#include <touchgfx/EasingEquations.hpp>
#include "BitmapDatabase.hpp"
#include <touchgfx/Color.hpp>
using namespace touchgfx;
SlideMenuContainer::SlideMenuContainer():
currentState(NO_ANIMATION),
menuChangeAction(0)
{
touchgfx::Application::getInstance()->registerTimerWidget(this);
setTouchable(true);
}
SlideMenuContainer::~SlideMenuContainer()
{
touchgfx::Application::getInstance()->unregisterTimerWidget(this);
}
void SlideMenuContainer::handleTickEvent()
{
}
void SlideMenuContainer::handleClickEvent(const ClickEvent& evt)
{
}
void SlideMenuContainer::handleDragEvent(const DragEvent& evt)
{
//touchgfx_printf("SlideMenuContainer->getDeltaX :%d \r\n", evt.getDeltaX()); //该拖拽事件,如果需要些特殊操作可以使用该事件
}
void SlideMenuContainer::handleGestureEvent(const GestureEvent& evt)
{
手势事件只检测上下滑动
if (evt.getType() == evt.SWIPE_VERTICAL)
{
//touchgfx_printf("SlideMenuContainer->handleGestureEvent \r\n");
区分上滑或者下滑
if (evt.getVelocity() < 0)
{
currentState = ANIMATE_COLLAPSE;
if (menuChangeAction && menuChangeAction->isValid())
{
menuChangeAction->execute(*this);
}
}
else if (evt.getVelocity() > 0)
{
currentState = ANIMATE_SHOW;
if (menuChangeAction && menuChangeAction->isValid())
{
menuChangeAction->execute(*this);
}
}
}
}
好了如此写就定义好了一个自定义的容器,再将放在窗口中的控件拿出放入该容器中就可以实现监听滑动事件了。
自定义窗口
在设计软件中选择自定义容器窗口,在这里创建一个自己的页面,之后编辑自己的菜单页,将需要的控件放入其中,当然这个给个建议,对于模块话的控件最好以功能性的需要将控件放入容器中,这样可以根据需要设置容器即可。
当开发完成后将子页面放在主窗口的上方,这样保证菜单页是隐藏在外面的下滑时逐渐移动下来。如图所示。
这里需要注意我勾选了MoveAnimator选项,这样移动时才有移动动画。
高仿IPhone
好了到这里将要开发主页面的逻辑了。
同样先看.h文件。
#ifndef MAINWINDOWVIEW_HPP
#define MAINWINDOWVIEW_HPP
#include <gui_generated/mainwindow_screen/MainWindowViewBase.hpp>
#include <gui/mainwindow_screen/MainWindowPresenter.hpp>
#include <gui/common/SlideMenuContainer.hpp>
class MainWindowView : public MainWindowViewBase
{
public:
MainWindowView();
这里我没有在设计时添加按钮逻辑
virtual ~MainWindowView() {}
virtual void setupScreen();
virtual void tearDownScreen();
protected:
SlideMenuContainer m_slideWindow; 定义一个我们之前写好的滑动窗口
Callback<MainWindowView, const SlideMenuContainer&> SliderCallback; 滑动窗口使用的回调
void SliderHandler(const SlideMenuContainer& sc);
};
#endif // MAINWINDOWVIEW_HPP
再看cpp文件
#include <gui/mainwindow_screen/MainWindowView.hpp>
MainWindowView::MainWindowView():
SliderCallback(this,&MainWindowView::SliderHandler)
{
}
void MainWindowView::setupScreen()
{
在窗口初始化时将窗口中的控件移除,再将移除的控件放到m_slideWindow中,再将m_slideWindow放入窗口
MainWindowViewBase::setupScreen();
remove(sliderWindow1);
remove(Background);
m_slideWindow.setPosition(0,0,
Background.getWidth(),
Background.getHeight());
m_slideWindow.setMenuChangeEndedCallback(SliderCallback);
m_slideWindow.add(Background);
m_slideWindow.add(sliderWindow1);
add(m_slideWindow);
}
void MainWindowView::tearDownScreen()
{
MainWindowViewBase::tearDownScreen();
}
void MainWindowView::SliderHandler(const SlideMenuContainer& sc)
{
//touchgfx_printf("RUN!!!\r\n");
这里判断当前设置栏的位置,是否是显示的。
const int endPosition=sliderWindow1.getY() >= 0 ? -800 : 0;
这里处理上滑或者下滑
if (m_slideWindow.getSelectedScreen() == 1)
{
滑动时调用startMoveAnimation,这里要和大家加一个点EasingEquations是一个缓动函数,可以根据需要去平滑动画的运动轨迹,具体的介绍我会在下方放入链接。
sliderWindow1.startMoveAnimation(sliderWindow1.getX(), endPosition,
20,
EasingEquations::cubicEaseInOut,
EasingEquations::cubicEaseInOut);
}
else if (m_slideWindow.getSelectedScreen() == 0)
{
sliderWindow1.startMoveAnimation(sliderWindow1.getX(), endPosition,
20,
EasingEquations::cubicEaseInOut,
EasingEquations::cubicEaseInOut);
}
}
菜单页
除此之外,官方还提供了自带的菜单页,但是提供的菜单页是点击事件才能实现的,当然也可以按照我们的方法将自定义容器与菜单控件结合使用。这里就看大家的发挥了。
如果需要的话可以看官方的demo。demo名字叫SlideMenu example,需要的话大家可以看看这个demo。
滑动窗口
好了,讲到这里主要的都讲到了,除了这种下滑外,我们可以发散下思维,制作多个窗口,也可以做到横滑的开发,这样是不是就能达到想要的效果了呢。