新建个空工程,在此命名为z20_winMoveV2
添加滑动所需控件并命名
添加控件并命名
编辑控件提示文本(从上到下为ctrl1、ctrl2、ctrl3)便于区分
编写代码
添加滑动窗口类的头文件
在页面对应代码添加:#include “ScreenMoveProMaxPlusUltraTurbo.h”,如下:
#include "ScreenMoveProMaxPlusUltraTurbo.h"
添加用户代码
namespace
{
//定义窗口滑动对象
static SCREEN_MOVE* ScreenMovePtr = NULL;
#define TIMER_MOVE 1
static const int timerMove = 5;
static void startMove(void)
{
mActivityPtr->unregisterUserTimer(TIMER_MOVE);
mActivityPtr->registerUserTimer(TIMER_MOVE, timerMove);
}
static void changeMoveDir(const SCREEN_MOVE::MOVE_DIR dir, const int curPage)
{
LOGD("--%d-- --%s-- 滑动方向改变:%d curPage:%d nextPage:%d\n", __LINE__, __FILE__, dir, curPage, ScreenMovePtr->getNextPage());
}
static void moveDone(const SCREEN_MOVE::MOVE_DIR dir, const int curPage)
{
LOGD("--%d-- --%s-- 滑动完成:%d curPage:%d\n", __LINE__, __FILE__, dir, curPage);
}
static void addConfigCtrls(void)
{
ScreenMovePtr->deleteAllCtrlPtr();
//添加需要滑动的控件
ScreenMovePtr->addCtrlPtr((ZKBase*&)mctrl1Ptr);
ScreenMovePtr->addCtrlPtr((ZKBase*&)mctrl2Ptr);
ScreenMovePtr->addCtrlPtr((ZKBase*&)mctrl3Ptr);
//设置当前窗口为窗口0
ScreenMovePtr->setCurPage(0);
}
static void addCantMoveCtrlId(void)
{
ScreenMovePtr->deleteAllDisbleMoveCtrlId();
ScreenMovePtr->addDisbleMoveCtrlId(ID_MAIN_ctrl2);
}
static void ScreenMoveInit(void)
{
delete ScreenMovePtr;
ScreenMovePtr = new SCREEN_MOVE();
//设置纵向滑动
// ScreenMovePtr->setValidMoveDir((SCREEN_MOVE::MOVE_DIR)(SCREEN_MOVE::DIR_UP|SCREEN_MOVE::DIR_DOWN));
//添加滑动窗口
addConfigCtrls();
//添加点击到就不能滑动的控件ID
addCantMoveCtrlId();
//定时器回调
ScreenMovePtr->addScreenMoveTimer(startMove);
//滑动完成回调
ScreenMovePtr->addMoveDoneCallback(moveDone);
//滑动方向改变
ScreenMovePtr->addMoveDirChangeCallback(changeMoveDir);
//窗口复位
ScreenMovePtr->screenMoveDone();
}
}
添加初始化、滑动界面以及跟手滑动代码
初始化
在界面的初始化函数static void onUI_init()添加ScreenMoveInit()初始化函数。
/**
* 当界面构造时触发
*/
static void onUI_init(){
//初始化窗口滑动
ScreenMoveInit();
}
滑动界面
在界面的static bool onUI_Timer(int id)函数添加滑动界面函数ScreenMovePtr->screenMove()调用。
static bool onUI_Timer(int id){
switch (id) {
//滑动窗口
case TIMER_MOVE:
{
return ScreenMovePtr->screenMove();
}
break;
default:
break;
}
return true;
}
跟手滑动
在界面static bool onmainActivityTouchEvent(const MotionEvent &ev)函数添加跟手滑动ScreenMovePtr->onTouchEvent(ev)函数。
static bool onmainActivityTouchEvent(const MotionEvent &ev) {
switch (ev.mActionStatus) {
case MotionEvent::E_ACTION_DOWN://触摸按下
//LOGD("时刻 = %ld 坐标 x = %d, y = %d", ev.mEventTime, ev.mX, ev.mY);
break;
case MotionEvent::E_ACTION_MOVE://触摸滑动
break;
case MotionEvent::E_ACTION_UP: //触摸抬起
break;
default:
break;
}
//滑动页面
return ScreenMovePtr->onTouchEvent(ev);
}
添加滑动窗口类代码
新建滑动窗口类命名为ScreenMoveProMaxPlusUltraTurbo,并将源文件和头文件放到工程jni目录下,如下图:
ScreenMoveProMaxPlusUltraTurbo.h文件内容
/*
* ScreenMoveProMaxPlusUltraTurbo.h
*
* Created on: 2023年2月14日
* Author: Z20、Z21 86面板FAE
*/
#ifndef JNI_USER_SCREENMOVEPROMAXPLUSULTRATURBO_H_
#define JNI_USER_SCREENMOVEPROMAXPLUSULTRATURBO_H_
#include "include/control/common.h"
#include <system/Thread.h>
#include "control/ZKBase.h"
#include "utils/ScreenHelper.h"
#include <map>
#include <vector>
#include <set>
//滑动阈值(滑动超过此值,视为滑动)
#define MOVE_THRESHOLD 30
//最低滑动速度,滑动大于此速度则触发滑屏
#define TURN_PAGE_MIN_SPEED 0.0001
//单步滑动距离
#define SPEED ScreenHelper::getScreenWidth()
class ScreenMoveProMaxPlusUltraTurbo {
public:
//滑动方向
enum MOVE_DIR{DIR_NULL = 0X00, DIR_MOVE_LEFT = 0X01, DIR_MOVE_RIGHT = 0X02, DIR_UP = 0X04, DIR_DOWN = 0X08};
private:
//滑动方向
MOVE_DIR mMoveDir;
Mutex mMoveDirMutex;
//当前页
int mCurPage;
Mutex mCurPageMutex;
//下一页
int mNextPage;
Mutex mNextPageMutex;
//允许滑动的方向
MOVE_DIR mValidMoveDir;
Mutex mValidMoveDirMutex;
//控件坐标
std::map<int, LayoutPosition> mCtrlPos;
Mutex mCtrlPosMutex;
//放置控件
std::vector<ZKBase*> mCtrl;
Mutex mCtrlMutex;
//触摸到就不能触发滑动的控件ID
std::set<int> mDisbleMoveCtrlId;
Mutex mDisbleMoveCtrlIdMutex;
//屏幕宽度
int mScreenWidth;
Mutex mScreenWidthMutex;
//屏幕高度
int mScreenHeight;
Mutex mScreenHeightMutex;
//横向滑动距离
int mHorizontalMoveDis;
//纵向滑动距离
int mVerticalMoveDis;
/*
* @brife 事件回调
* @param dir 滑动方向
* @param curPage 当前页
* */
typedef void (*MOVE_EVENT_CALLBACK)(const MOVE_DIR dir, const int curPage);
//滑动方向切换回调
std::set<MOVE_EVENT_CALLBACK> mMoveDirChange;
Mutex mMoveDirChangeMutex;
//滑动完成回调
std::set<MOVE_EVENT_CALLBACK> mMoveDone;
Mutex mMoveDoneMutex;
//是否点击到不可滑动界面的控件
bool mIsTouchDisbleMoveCtrl;
//滑动速度是否达到滑动阈值
bool mIsSlideSpeedUpToThreshold;
//滑动距离是否达到滑动阈值
bool mIsSlideDistanceUpToThreshold;
/*
* @brife 定时器滑动回调
* */
typedef void (*SCREEN_MOVE_TIMER)(void);
std::set<SCREEN_MOVE_TIMER> mScreenMoveTimer;
Mutex mScreenMoveTimerMutex;
//自动滑屏时的滑动距离
int mMoveLen;
Mutex mMoveLenMutex;
/*
* @brife 页面滑动回调
* @param dir 滑动方向
* @param xMoveLen x轴滑动距离
* @param yMoveLen y轴滑动距离
* */
typedef void (*PAGE_MOVE_CALLBACK)(const MOVE_DIR& dir, const int& xMoveLen, const int& yMoveLen);
//当前页滑动回调
std::set<PAGE_MOVE_CALLBACK> mCurPageMoveVec;
//下一页滑动回调
std::set<PAGE_MOVE_CALLBACK> mNextPageMoveVec;
/*
* @brife 窗口位置复位回调
* @param curPage 当前页面
* */
typedef void(*PAGE_RESET_POS_CALLBACK)(const int& curPage);
//当前窗口位置复位回调
std::set<PAGE_RESET_POS_CALLBACK> mPageResetPosVec;
private:
/*
* @brife 判断是否点击到不可滑动界面的控件
* @param ev 触摸点(此坐标参考原点是屏幕左上角)
* @param ctrlPtr 控件指针
* */
void judgeIsTouchDisbleMoveCtrl(MotionEvent ev, ZKBase*& ctrlPtr);
public:
/*
* @brife 获取是否点击到不可滑动界面的控件标志
* @return true 当前不可滑动界面;false 当前可以滑动界面
* */
const bool getIsTouchDisbleMoveCtrlFlag(void);
/*
* @brife 设置点击到不可滑动界面的控件标志
* @param flag true不可滑动;false 可滑动
* */
void setIsTouchDisbleMoveCtrlFlag(const bool& flag);
private:
/*
* @brife 判断滑动速度是否达到滑动阈值
* @param ev 触摸点(此坐标参考原点是屏幕左上角)
* */
void judgeIsSlideSpeedUpToThreshold(const MotionEvent &ev);
/*
* @brife 获取判断滑动速度是否达到滑动阈值标志
* @param flag true 当前可滑动界面;false 当前不可滑动界面
* */
void setIsSlideSpeedUpToThresholdFlag(const bool& flag);
/*
* @brife 获取判断滑动速度是否达到滑动阈值标志
* @param true 当前可滑动界面;false 当前不可滑动界面
* */
const bool getIsSlideSpeedUpToThresholdFlag(void);
/*
* @brife 判断滑动距离是否达到滑动阈值
* @param ev 触摸点(此坐标参考原点是屏幕左上角)
* */
void judgeIsSlideDistanceUpToThreshold(const MotionEvent &ev);
/*
* @brife 获取判断滑动距离是否达到滑动阈值标志
* @return true 滑动距离达到滑动阈值;false 滑动距离未达到滑动阈值
* */
const bool getIsSlideDistanceUpToThresholdFlag(void);
/*
* @brife 控件失能/使能
* @param isInvalid true 失能;false 使能
* */
void setCtrlInvalid(const bool isInvalid);
/*
* @brife 窗口控件复位
* */
void screenCtrlPosReset(void);
/*
* @brife 同步下一页为当前页
* */
void setNextPageBecomeCurPage(void);
/*
* @brife 显示当前页面,隐藏其他页面
* */
void disCurPage(void);
/*
* @brife 设置所有控件为抬起状态
* */
void setCtrlNotPress(void);
public:
/*
* @brife 滑动完成函数
* */
void screenMoveDone(void);
private:
/*
* @brife 滑动当前页
* @param len 偏移的滑动距离(自动滑动时使用)
* */
void moveCurPage(const int len=0);
/*
* @brife 滑动下一页
* @param len 偏移的滑动距离(自动滑动时使用)
* */
void moveNextPage(const int len=0);
/*
* @brife 抬起判断是否能启动滑屏
* @ref 当满足(没触摸到不能滑动界面的控件&&(滑动距离超过界面1/3||滑动速度大于滑动速度阈值))时可以开启滑屏
* */
void judgeWetherMoveScreen(void);
/*
* @brife 设置自动滑屏时的距离
* @param len 滑动距离
* */
void setMoveLen(const int len);
/*
* @brife 获取滑屏时的距离
* @return 返回滑屏距离
* */
const int getMoveLen(void);
public:
ScreenMoveProMaxPlusUltraTurbo();
virtual ~ScreenMoveProMaxPlusUltraTurbo();
/*
* @brife 设置当前页
* @param page 页面编号
* */
void setCurPage(const int page);
/*
* @brife 获取当前页
* @return 返回当前页
* */
const int getCurPage(void);
/*
* @brife 设置下一页页码
* */
void setNextPage(void);
/*
* @brife 获取协议页页码
* @return 返回页码
* */
const int getNextPage(void);
/*
* @brife 设置可以滑动的方向
* @param dir 滑动方向
* */
void setValidMoveDir(const MOVE_DIR& dir);
/*
* @brife 获取可以滑动的方向
* @param 返回可以滑动方向
* */
const MOVE_DIR getValidMoveDir(void);
/*
* @brife ev 触摸坐标点
* @return 表示该触摸事件在此被拦截,系统不再将此触摸事件传递到控件上; false 触摸事件将继续传递到控件上
* */
const bool onTouchEvent(MotionEvent ev);
private:
/*
* @brife 限定滑动方向,当左右滑动或者上下滑动超过阈值后则只能进行该方向的滑动
* @param ev 触摸事件数据
* */
void determineSlideDirection(MotionEvent &ev);
public:
/*
* @brife 设置滑动方向
* @param ev 坐标值
* */
void setMoveDir(const MotionEvent &ev);
/*
* @brife 设置滑动方向
* @param dir 滑动方向
* */
void setMoveDir(const MOVE_DIR& dir);
/*
* @brife 获取滑动方向
* @return DIR_HORIZONTAL 横向滑动;DIR_VERTICAL 纵向滑动;DIR_NULL 没有滑动方向
* */
const MOVE_DIR getMoveDir(void);
/*
* @brife 添加控件坐标
* @param id 控件ID
* @param pos 控件坐标位置
* */
void addCtrlPos(const int id, const LayoutPosition& pos);
/*
* @brife 获取控件坐标
* @param id 控件坐标ID
* @param pos 控件坐标
* @return true 获取成功;false 获取失败
* */
const bool getCtrlPos(const int id, LayoutPosition& pos);
/*
* @brife 清除所有控件坐标位置
* */
void clearAllCtrlPos(void);
/*
* @brife 添加一个控件
* @param ptr 控件指针
* */
void addCtrlPtr(ZKBase*& ptr);
/*
* @brife 替换索引控件指针
* @param index 索引
* @param ptr 控件指针
* */
void replaceCtrlPtr(const uint32_t index, ZKBase*& ptr);
/*
* @brife 获取索引控件id
* @param index 索引
* @return -1 代表获取失败;其他代表获取成功
* */
const int getCtrlPtrId(const uint32_t index);
/*
* @brife 获取索引控件指针
* @param index 索引
* @param ctrlPtr 控件指针
* @return true 获取成功;false 获取失败
* */
const bool getCtrlPtr(const uint32_t index, ZKBase*& ctrlPtr);
/*
* @brife 删除所有已添加的控件
* */
void deleteAllCtrlPtr(void);
/*
* @brife 获取控件数量
* @return 返回控件数量
* */
const uint32_t getCtrlCount(void);
/*
* @brife 触摸到就不能触发滑动的控件ID
* @param id 控件ID
* */
void addDisbleMoveCtrlId(const int id);
/**
* @brife 判断id是否为触摸到就不能触发滑动的控件ID
* @param 当前触摸到的控件id
* @return true id是触摸到就不能触发滑动的控件ID;false id不是触摸到就不能触发滑动的控件ID
* */
const bool isDisbleMoveCtrlId(const int id);
/*
* @brife 删除所有触摸到就不能触发滑动的控件ID
* */
void deleteAllDisbleMoveCtrlId(void);
/*
* @brife 设置屏幕宽度
* @param width 宽度
* */
void setScreenWidth(const int width);
/*
* @brife 获取屏幕宽度
* @return 返回屏幕宽度
* */
const int getScreenWidth(void);
/*
* @brife 设置高度
* @param height 高度
* */
void setScreenHeight(const int height);
/*
* @brife 获取高度
* @return 返回屏幕高度
* */
const int getScreenHeight(void);
/*
* @brife 设置横向滑动距离
* @param ev 触摸坐标点
* */
void setHorizontalMoveDis(const MotionEvent &ev);
/*
* @brife 获取横向滑动距离
* @return 返回横向滑动距离
* */
const int getHorizontalMoveDis(void);
/*
* @brife 设置纵向滑动距离
* @param ev 触摸坐标点
* */
void setVerticalMoveDis(const MotionEvent &ev);
/*
* @brife 获取纵向滑动距离
* @return 返回滑动距离
* */
const int getVerticalMoveDis(void);
/*
* @brife 注册滑动方向切换回调函数
* @param fun 被回调函数
* */
void addMoveDirChangeCallback(const MOVE_EVENT_CALLBACK& fun);
/*
* @brife 移除滑动方向切换回调函数
* @param fun 被回调函数
* */
void deleteMoveDirChangeCallback(const MOVE_EVENT_CALLBACK& fun);
/*
* @brife 执行滑动方向切换回调函数
* */
void exeMoveDirChangeCallback(void);
/*
* @brife 注册滑动完成回调
* @param fun 被回调函数
* */
void addMoveDoneCallback(const MOVE_EVENT_CALLBACK& fun);
/*
* @brife 注销滑动完成回调
* @param fun 被回调函数
* */
void deleteMoveDoneCallback(const MOVE_EVENT_CALLBACK& fun);
/*
* @brife 执行滑动完成回调函数
* */
void exeMoveDoneCallback(void);
/*
* @brife 注册滑动定时器
* @param fun 回调函数
* */
void addScreenMoveTimer(const SCREEN_MOVE_TIMER& fun);
/*
* @brife 移除定时器滑动回调函数
* @param fun 回调函数
* */
void deleteScreenMoveTimer(const SCREEN_MOVE_TIMER& fun);
/*
* @brife 启动定时器回调函数
* */
void exeScreenMoveTimer(void);
/*
* @brife 滑动屏幕
* @retrun true 为滑动到位;false 已滑动到位
* */
const bool screenMove(void);
/*
* @brife 注册当前页滑动回调
* @param fun 回调函数
* */
void addCurPageMoveCallback(const PAGE_MOVE_CALLBACK& fun);
/*
* @brife 移除当前页回调
* @param fun 回调函数
* */
void delCurPageMoveCallback(const PAGE_MOVE_CALLBACK& fun);
/*
* @brife 执行当前页回调
* @param dir 滑动方向
* @param xMoveLen x轴滑动距离
* @param yMoveLen y轴滑动距离
* */
void exeCurPageMoveCallback(const MOVE_DIR& dir, const int& xMoveLen, const int& yMoveLen);
/*
* @brife 注册下一页滑动回调
* @param fun 回调函数
* */
void addNextPageMoveCallback(const PAGE_MOVE_CALLBACK& fun);
/*
* @brife 移除下一页回调
* @param fun 回调函数
* */
void delNextPageMoveCallback(const PAGE_MOVE_CALLBACK& fun);
/*
* @brife 执行下一页回调
* @param dir 滑动方向
* @param xMoveLen x轴滑动距离
* @param yMoveLen y轴滑动距离
* */
void exeNextPageMoveCallback(const MOVE_DIR& dir, const int& xMoveLen, const int& yMoveLen);
/*
* @brife 注册页面复位回调
* @param fun 回调函数
* */
void addScreenCtrlPosResetCallback(const PAGE_RESET_POS_CALLBACK& fun);
/*
* @brife 移除页面复位回调
* @param fun 回调函数
* */
void delScreenCtrlPosResetCallback(const PAGE_RESET_POS_CALLBACK& fun);
/*
* @brife 执行页面复位回调
* */
void exeScreenCtrlPosResetCallback(const int& curPage);
/*
* @brife 上一页滑动
* */
void moveToPrePage(void);
/*
* @brife 下一页滑动
* */
void moveToNextPage(void);
};
#define SCREEN_MOVE ScreenMoveProMaxPlusUltraTurbo
#endif /* JNI_USER_SCREENMOVEPROMAXPLUSULTRATURBO_H_ */
ScreenMoveProMaxPlusUltraTurbo.cpp文件内容
/*
* ScreenMoveProMaxPlusUltraTurbo.cpp
*
* Created on: 2023年2月14日
* Author: Z20、Z21 86面板FAE
*/
#include <math.h>
#include "ScreenMoveProMaxPlusUltraTurbo.h"
#include "utils/ScreenHelper.h"
#include "utils/log.h"
#include "window/ZKWindow.h"
//用于获取滑动速度
#include "utils/VelocityTracker.h"
#ifndef DEBUG
#define DEBUG LOGD("--%d-- --%s-- Debug!!\n", __LINE__, __FILE__);
#endif
ScreenMoveProMaxPlusUltraTurbo::ScreenMoveProMaxPlusUltraTurbo() {
// TODO 自动生成的构造函数存根
mMoveDir = DIR_NULL;
mCurPage = 0;
mNextPage = 0;
mValidMoveDir = (MOVE_DIR)(DIR_MOVE_LEFT|DIR_MOVE_RIGHT); //默认可以横向滑屏
mIsTouchDisbleMoveCtrl = false;
mIsSlideSpeedUpToThreshold = false;
mIsSlideDistanceUpToThreshold = false;
mScreenWidth = ScreenHelper::getScreenWidth();
mScreenHeight = ScreenHelper::getScreenHeight();
mHorizontalMoveDis = 0;
mVerticalMoveDis = 0;
mMoveLen = 0;
}
ScreenMoveProMaxPlusUltraTurbo::~ScreenMoveProMaxPlusUltraTurbo() {
// TODO 自动生成的析构函数存根
}
void ScreenMoveProMaxPlusUltraTurbo::judgeIsTouchDisbleMoveCtrl(MotionEvent ev, ZKBase*& ctrlPtr)
{
//非按下事件,函数返回
if(MotionEvent::E_ACTION_DOWN != ev.mActionStatus){return;}
//标记可以滑动
mIsTouchDisbleMoveCtrl = false;
if(NULL == ctrlPtr){ LOGD("--%d-- --%s-- 控件指针为NULL!!\n", __LINE__, __FILE__); return;}
//判断是否点击到控件
if(false == ctrlPtr->getPosition().isHit(ev.mX, ev.mY)){return;}
//获取控件ID
const int ctrlId = ctrlPtr->getID();
// LOGD("--%d-- --%s-- clicked ctrl id:%d\n", __LINE__, __FILE__, ctrlId);
//判断是否点击到可见的禁止滑屏控件
if(true == isDisbleMoveCtrlId(ctrlId) && true == ctrlPtr->isVisible())
{
//标记不能滑动屏幕
mIsTouchDisbleMoveCtrl = true;
return;
}
//判断控件是否是窗口,如果是窗口需要拿出窗口里的控件来进行判断
if(110000 <= ctrlId && ctrlId < 119000 && true == ctrlPtr->isVisible())
{
//相对位置偏移
ev.mX = ev.mX - ctrlPtr->getPosition().mLeft;
ev.mY = ev.mY - ctrlPtr->getPosition().mTop;
//定义获取窗口控件数组
vector<ZKBase*> controlsList;
//获取窗口下的所有控件
((ZKWindow*)ctrlPtr)->getAllControls(controlsList);
//遍历判断是否点击到窗口内的控件
for(uint32_t level1 = 0; level1 < controlsList.size(); ++level1)
{
judgeIsTouchDisbleMoveCtrl(ev, controlsList[level1]);
//触摸到禁止滑动屏幕控件,函数返回
if(true == mIsTouchDisbleMoveCtrl){return;}
}
}
}
const bool ScreenMoveProMaxPlusUltraTurbo::getIsTouchDisbleMoveCtrlFlag(void)
{
return mIsTouchDisbleMoveCtrl;
}
void ScreenMoveProMaxPlusUltraTurbo::setIsTouchDisbleMoveCtrlFlag(const bool& flag)
{
mIsTouchDisbleMoveCtrl = flag;
}
void ScreenMoveProMaxPlusUltraTurbo::judgeIsSlideSpeedUpToThreshold(const MotionEvent &ev)
{
//滑动速度追踪
static VelocityTracker mVelocityTracker;
switch (ev.mActionStatus) {
case MotionEvent::E_ACTION_DOWN://触摸按下
//标志位设置为不可滑动
mIsSlideSpeedUpToThreshold = false;
//初始化滑动计算参数
mVelocityTracker.reset();
break;
case MotionEvent::E_ACTION_MOVE://触摸滑动
{
//传入触摸坐标点
mVelocityTracker.addMovement(ev);
}
break;
case MotionEvent::E_ACTION_UP: //触摸抬起
{
const MOVE_DIR dir = getMoveDir();
//标志位设置为不可滑动
mIsSlideSpeedUpToThreshold = false;
if(DIR_MOVE_LEFT == dir || DIR_MOVE_RIGHT == dir || dir == (DIR_MOVE_LEFT|DIR_MOVE_RIGHT))
{//DEBUG
//获取横向坐标来进行判断
mIsSlideSpeedUpToThreshold = (fabs(mVelocityTracker.getXVelocity()) > TURN_PAGE_MIN_SPEED)? true : false;
}
else if(DIR_UP == dir || DIR_DOWN == dir || dir == (DIR_UP|DIR_DOWN))
{//DEBUG
//获取纵向坐标来进行判断
mIsSlideSpeedUpToThreshold = (fabs(mVelocityTracker.getYVelocity()) > TURN_PAGE_MIN_SPEED)? true : false;
}
// LOGD("--%d-- --%s-- xSpeed:%.4f ySpeed:%.4f mIsSlideSpeedUpToThreshold:%d\n", __LINE__, __FILE__,
// mVelocityTracker.getXVelocity(), mVelocityTracker.getYVelocity(), mIsSlideSpeedUpToThreshold);
//复位获取速度参数
mVelocityTracker.reset();
}
break;
default:
break;
}
}
void ScreenMoveProMaxPlusUltraTurbo::setIsSlideSpeedUpToThresholdFlag(const bool& flag)
{
mIsSlideSpeedUpToThreshold = flag;
}
const bool ScreenMoveProMaxPlusUltraTurbo::getIsSlideSpeedUpToThresholdFlag(void)
{
return mIsSlideSpeedUpToThreshold;
}
void ScreenMoveProMaxPlusUltraTurbo::judgeIsSlideDistanceUpToThreshold(const MotionEvent &ev)
{
static MotionEvent moveDis;
switch (ev.mActionStatus) {
case MotionEvent::E_ACTION_DOWN://触摸按下
moveDis = ev;
break;
case MotionEvent::E_ACTION_MOVE://触摸滑动
break;
case MotionEvent::E_ACTION_UP: //触摸抬起
{
MOVE_DIR dir = getMoveDir();
//标志位设置为不可滑动
mIsSlideDistanceUpToThreshold = false;
if(DIR_MOVE_LEFT == dir || DIR_MOVE_RIGHT == dir)
{
//获取横向坐标滑动距离来进行判断
mIsSlideDistanceUpToThreshold = (abs(ev.mX- moveDis.mX) > ScreenHelper::getScreenWidth()/3)? true : false;
}
else if(DIR_UP == dir || DIR_DOWN == dir)
{
//获取纵向坐标滑动距离来进行判断
mIsSlideDistanceUpToThreshold = (abs(ev.mY- moveDis.mY) > ScreenHelper::getScreenHeight()/3)? true : false;
}
}
break;
default:
break;
}
}
const bool ScreenMoveProMaxPlusUltraTurbo::getIsSlideDistanceUpToThresholdFlag(void)
{
return mIsSlideDistanceUpToThreshold;
}
void ScreenMoveProMaxPlusUltraTurbo::setCtrlInvalid(const bool isInvalid)
{
Mutex::Autolock _l(mCtrlMutex);
for(uint32_t level1 = 0; level1 < mCtrl.size(); ++level1)
{
mCtrl[level1]->setTouchPass(isInvalid);
// mCtrl[level1]->setInvalid(isInvalid);
}
}
void ScreenMoveProMaxPlusUltraTurbo::screenCtrlPosReset(void)
{
Mutex::Autolock _l(mCtrlMutex);
int ctrlId = -1;
LayoutPosition pos;
for(uint32_t level1 = 0; level1 < mCtrl.size(); ++level1)
{
ctrlId = mCtrl[level1]->getID();
if(false == getCtrlPos(ctrlId, pos))
{
LOGD("--%d-- --%s-- 查找:%d 位置失败!!\n", __LINE__, __FILE__, ctrlId);
continue;
}
//位置复原
mCtrl[level1]->setPosition(pos);
// LOGD("--%d-- --%s-- index:%d Id:%d left:%d top:%d\n", __LINE__, __FILE__, level1, mCtrl[level1]->getID(), pos.mLeft, pos.mTop);
}
//执行页面复位回调
exeScreenCtrlPosResetCallback(getCurPage());
}
void ScreenMoveProMaxPlusUltraTurbo::setNextPageBecomeCurPage(void)
{
const int nextPage = getNextPage();
setCurPage(nextPage);
}
void ScreenMoveProMaxPlusUltraTurbo::disCurPage(void)
{
const uint32_t curPage = getCurPage();
Mutex::Autolock _l(mCtrlMutex);
for(uint32_t level1 = 0; level1 < mCtrl.size(); ++level1)
{
mCtrl[level1]->setVisible(curPage == level1);
// LOGD("--%d-- --%s-- curPage:%d index:%d dis:%d\n", __LINE__, __FILE__, curPage, level1, curPage == level1);
}
if(0 < mCtrl.size())
//显示当前页
mCtrl[curPage]->setVisible(true);
}
void ScreenMoveProMaxPlusUltraTurbo::setCtrlNotPress(void)
{
Mutex::Autolock _l(mCtrlMutex);
for(uint32_t level1 = 0; level1 < mCtrl.size(); ++level1)
{
mCtrl[level1]->setPressed(false);
}
}
void ScreenMoveProMaxPlusUltraTurbo::screenMoveDone(void)
{DEBUG
//所有控件复位
screenCtrlPosReset();DEBUG
//隐藏其他页面,显示当前页
disCurPage();DEBUG
//使能控件
setCtrlInvalid(false);DEBUG
//回调滑动完毕函数
exeMoveDoneCallback();DEBUG
//设置初始滑动距离为0,表示滑动结束
setMoveLen(0);DEBUG
//清除滑动方向
setMoveDir(DIR_NULL);DEBUG
}
void ScreenMoveProMaxPlusUltraTurbo::moveCurPage(const int len)
{
ZKBase* ctrlPtr = NULL;
if(true == getIsTouchDisbleMoveCtrlFlag() || false == getCtrlPtr(getCurPage(), ctrlPtr))
{
LOGD("--%d-- --%s-- 禁止滑动:%d 控件地址:%d !!\n", __LINE__, __FILE__, getIsTouchDisbleMoveCtrlFlag(), (int)ctrlPtr);
return;
}
LayoutPosition ctrlPos;
if(false == getCtrlPos(ctrlPtr->getID(), ctrlPos))
{
LOGD("--%d-- --%s-- id:%d 获取坐标失败!!\n", __LINE__, __FILE__, ctrlPtr->getID());
return;
}
//横向滑动
if(DIR_MOVE_LEFT == getMoveDir() || DIR_MOVE_RIGHT == getMoveDir())
{
ctrlPos.mLeft += getHorizontalMoveDis()+len;
// LOGD("--%d-- --%s-- left:%d dis:%d\n", __LINE__, __FILE__, ctrlPos.mLeft, getHorizontalMoveDis());
}
//纵向滑动
else if(DIR_UP == getMoveDir() || DIR_DOWN == getMoveDir())
{
ctrlPos.mTop += getVerticalMoveDis()+len;
}
//设置控件位置
ctrlPtr->setPosition(ctrlPos);
//显示控件
ctrlPtr->setVisible(true);
// LOGD("--%d-- --%s-- cur ctrl id:%d left:%d top:%d\n", __LINE__, __FILE__, ctrlPtr->getID(), ctrlPos.mLeft, ctrlPos.mTop);
//执行当前页滑动回调
exeCurPageMoveCallback(getMoveDir(), getHorizontalMoveDis()+len, getVerticalMoveDis()+len);
}
void ScreenMoveProMaxPlusUltraTurbo::moveNextPage(const int len)
{
ZKBase* ctrlPtr = NULL;
if(true == getIsTouchDisbleMoveCtrlFlag() || false == getCtrlPtr(getNextPage(), ctrlPtr))
{
LOGD("--%d-- --%s-- 禁止滑动:%d 控件地址:%d !!\n", __LINE__, __FILE__, getIsTouchDisbleMoveCtrlFlag(), (int)ctrlPtr);
return;
}
LayoutPosition ctrlPos;
if(false == getCtrlPos(ctrlPtr->getID(), ctrlPos))
{
LOGD("--%d-- --%s-- id:%d 获取坐标失败!!\n", __LINE__, __FILE__, ctrlPtr->getID());
return;
}
//横向滑动
if(DIR_MOVE_LEFT == getMoveDir() || DIR_MOVE_RIGHT == getMoveDir())
{
ctrlPos.mLeft += getHorizontalMoveDis()+len;
//偏移到当前页后面
ctrlPos.mLeft += (DIR_MOVE_LEFT == getMoveDir())? getScreenWidth() : -getScreenWidth();
}
//纵向滑动
else if(DIR_UP == getMoveDir() || DIR_DOWN == getMoveDir())
{
ctrlPos.mTop += getVerticalMoveDis()+len;
//偏移到当前页后面
ctrlPos.mTop += (DIR_UP == getMoveDir())? getScreenHeight() : -getScreenHeight();
}
//设置控件位置
ctrlPtr->setPosition(ctrlPos);
//显示控件
ctrlPtr->setVisible(true);
// LOGD("--%d-- --%s-- next ctrl id:%d left:%d\n", __LINE__, __FILE__, ctrlPtr->getID(), ctrlPos.mLeft);
//执行下一页滑动回调
exeNextPageMoveCallback(getMoveDir(), getHorizontalMoveDis()+len, getVerticalMoveDis()+len);
}
void ScreenMoveProMaxPlusUltraTurbo::judgeWetherMoveScreen(void)
{
//启动滑屏
if(false == getIsTouchDisbleMoveCtrlFlag() && (getIsSlideSpeedUpToThresholdFlag() || getIsSlideDistanceUpToThresholdFlag())&&
(DIR_NULL != (getMoveDir()&getValidMoveDir())))
{DEBUG
//失能控件
setCtrlInvalid(true);DEBUG
//设置初始滑动距离为1,表示滑动开始
setMoveLen(1);DEBUG
//启动滑屏
exeScreenMoveTimer();DEBUG
}
//不满足滑屏条件,位置复位
else
{DEBUG
//使能控件
setCtrlInvalid(false);DEBUG
//显示当前页面,隐藏其他页面
disCurPage();DEBUG
//控件复位
screenCtrlPosReset();DEBUG
//设置初始滑动距离为0,表示滑动动作结束
setMoveLen(0);
LOGD("--%d-- --%s-- dir:%d enable:%d speed:%d distance:%d 控件复位!!\n", __LINE__, __FILE__, getMoveDir(),
getIsTouchDisbleMoveCtrlFlag(), getIsSlideSpeedUpToThresholdFlag(), getIsSlideDistanceUpToThresholdFlag());
}
}
void ScreenMoveProMaxPlusUltraTurbo::setMoveLen(const int len)
{
Mutex::Autolock _l(mMoveLenMutex);
mMoveLen = len;
}
const int ScreenMoveProMaxPlusUltraTurbo::getMoveLen(void)
{
Mutex::Autolock _l(mMoveLenMutex);
return mMoveLen;
}
void ScreenMoveProMaxPlusUltraTurbo::setCurPage(const int page)
{
Mutex::Autolock _l(mCurPageMutex);
mCurPage = page;
}
const int ScreenMoveProMaxPlusUltraTurbo::getCurPage(void)
{
Mutex::Autolock _l(mCurPageMutex);
return mCurPage;
}
void ScreenMoveProMaxPlusUltraTurbo::setNextPage(void)
{
int page = getCurPage();
//向上滑向左滑
if(DIR_MOVE_LEFT == getMoveDir() || DIR_UP == getMoveDir())
{
page = (page+1)%getCtrlCount();
}
//向下滑向右滑
else if(DIR_MOVE_RIGHT == getMoveDir() || DIR_DOWN == getMoveDir())
{
page = (0 > page-1)? getCtrlCount()-1 : page-1;
}
{
Mutex::Autolock _l(mNextPageMutex);
mNextPage = page;
}
}
const int ScreenMoveProMaxPlusUltraTurbo::getNextPage(void)
{
Mutex::Autolock _l(mNextPageMutex);
return mNextPage;
}
void ScreenMoveProMaxPlusUltraTurbo::setValidMoveDir(const MOVE_DIR& dir)
{
Mutex::Autolock _l(mValidMoveDirMutex);
mValidMoveDir = dir;
}
const ScreenMoveProMaxPlusUltraTurbo::MOVE_DIR ScreenMoveProMaxPlusUltraTurbo::getValidMoveDir(void)
{
Mutex::Autolock _l(mValidMoveDirMutex);
return mValidMoveDir;
}
const bool ScreenMoveProMaxPlusUltraTurbo::onTouchEvent(MotionEvent ev)
{
//当页面只有一项时,不能滑动
if(getCtrlCount() <= 1){ LOGD("--%d-- --%s-- 当前页面仅有%d页,不能滑屏!!\n", __LINE__, __FILE__, getCtrlCount()); return false;}
//初始滑动距离不为0,代表滑动开始,此时不能进入滑屏函数
if(0 != getMoveLen()){LOGD("--%d-- --%s-- len:%d 当前正在滑屏!!!", __LINE__, __FILE__, getMoveLen()); return true;}
//确定滑动方向
determineSlideDirection(ev);
//获取滑动方向
setMoveDir(ev);
//计算滑动速度是否达到滑动阈值
judgeIsSlideSpeedUpToThreshold(ev);
//计算滑动距离是否达到滑动阈值
judgeIsSlideDistanceUpToThreshold(ev);
//计算横向滑动距离
setHorizontalMoveDis(ev);
//计算纵向滑动距离
setVerticalMoveDis(ev);
switch (ev.mActionStatus) {
case MotionEvent::E_ACTION_DOWN://触摸按下
{
//判断是否点击到不可滑动的控件指针
ZKBase* ctrlPtr = NULL;
if(true == getCtrlPtr(getCurPage(), ctrlPtr))
{
judgeIsTouchDisbleMoveCtrl(ev, ctrlPtr);
}
else
{
LOGD("--%d-- --%s-- index:%d 查找控件失败!!\n", __LINE__, __FILE__, getCurPage());
}
}
break;
case MotionEvent::E_ACTION_MOVE://触摸滑动
//滑动距离超过 MOVE_THRESHOLD且已知滑动方向,开始跟手滑屏
if((MOVE_THRESHOLD < abs(getHorizontalMoveDis()) || MOVE_THRESHOLD < abs(getVerticalMoveDis())) &&
(DIR_NULL != (getMoveDir()&getValidMoveDir())))
{
//所有控件设置为抬起状态
setCtrlNotPress();
//失能控件
setCtrlInvalid(true);
//滑动当前页
moveCurPage();
//滑动下一页
moveNextPage();
}
break;
case MotionEvent::E_ACTION_UP: //触摸抬起
//所有控件设置为抬起状态
setCtrlNotPress();
//判断是否启动滑屏
judgeWetherMoveScreen();
break;
default:DEBUG
//所有控件设置为抬起状态
setCtrlNotPress();
//控件位置复位
screenCtrlPosReset();
//设置初始滑动距离为0,表示滑动结束
setMoveLen(0);DEBUG
break;
}
// LOGD("--%d-- --%s-- getIsTouchDisbleMoveCtrlFlag:%d getIsSlideSpeedUpToThresholdFlag:%d\n", __LINE__, __FILE__,
// getIsTouchDisbleMoveCtrlFlag(), getIsSlideSpeedUpToThresholdFlag());
// LOGD("--%d-- --%s-- getHorizontalMoveDis:%d getVerticalMoveDis:%d\n", __LINE__, __FILE__,
// getHorizontalMoveDis(), getVerticalMoveDis());
//开始滑动则拦截触摸事件
return (true == getIsTouchDisbleMoveCtrlFlag())? false :
(getIsSlideSpeedUpToThresholdFlag() || (MOVE_THRESHOLD < abs(getHorizontalMoveDis()) || MOVE_THRESHOLD < abs(getVerticalMoveDis())));
}
void ScreenMoveProMaxPlusUltraTurbo::determineSlideDirection(MotionEvent &ev)
{
//触发上下滑动就不能再左右滑动
static ScreenMoveProMaxPlusUltraTurbo::MOVE_DIR moveDir;
static MotionEvent moveDis;
switch (ev.mActionStatus) {
case MotionEvent::E_ACTION_DOWN://触摸按下
//清空滑动方向
moveDir = ScreenMoveProMaxPlusUltraTurbo::DIR_NULL;
//保存点击坐标点
moveDis = ev;
break;
case MotionEvent::E_ACTION_MOVE://触摸滑动
case MotionEvent::E_ACTION_UP: //触摸抬起
{
const int disX = ev.mX - moveDis.mX;
const int disY = ev.mY - moveDis.mY;
//左右滑动
if(MOVE_THRESHOLD <= abs(disX) && ScreenMoveProMaxPlusUltraTurbo::DIR_NULL ==
(moveDir & (ScreenMoveProMaxPlusUltraTurbo::DIR_DOWN | ScreenMoveProMaxPlusUltraTurbo::DIR_UP)))
{
//Y轴清零
ev.mY = moveDis.mY;
moveDir = ScreenMoveProMaxPlusUltraTurbo::MOVE_DIR(ScreenMoveProMaxPlusUltraTurbo::DIR_MOVE_LEFT |
ScreenMoveProMaxPlusUltraTurbo::DIR_MOVE_RIGHT);
// LOGD("--%d-- --%s-- 左右滑动:%d\n", __LINE__, __FILE__, (int)moveDir);
}
//上下滑动
else if(MOVE_THRESHOLD <= abs(disY) && ScreenMoveProMaxPlusUltraTurbo::DIR_NULL ==
(moveDir & (ScreenMoveProMaxPlusUltraTurbo::DIR_MOVE_LEFT | ScreenMoveProMaxPlusUltraTurbo::DIR_MOVE_RIGHT)))
{
//X轴清零
ev.mX = moveDis.mX;
moveDir = ScreenMoveProMaxPlusUltraTurbo::MOVE_DIR(ScreenMoveProMaxPlusUltraTurbo::DIR_DOWN |
ScreenMoveProMaxPlusUltraTurbo::DIR_UP);
// LOGD("--%d-- --%s-- 上下滑动:%d\n", __LINE__, __FILE__, (int)moveDir);
}
}
break;
default:
break;
}
}
void ScreenMoveProMaxPlusUltraTurbo::setMoveDir(const MotionEvent &ev)
{
static MotionEvent moveDis;
switch (ev.mActionStatus) {
case MotionEvent::E_ACTION_DOWN://触摸按下
{
moveDis = ev;
{
Mutex::Autolock _l(mMoveDirMutex);
mMoveDir = DIR_NULL;
LOGD("--%d-- --%s-- mMoveDir init:%d\n", __LINE__, __FILE__, mMoveDir);
}
}
break;
case MotionEvent::E_ACTION_MOVE://触摸滑动
{
const int disX = ev.mX - moveDis.mX;
const int disY = ev.mY - moveDis.mY;
{
//判断方向不重复
if(getMoveDir() != ((0 < disX)? DIR_MOVE_RIGHT : DIR_MOVE_LEFT) &&
//判断是否使能该方向滑动
(0 == (getValidMoveDir() & (DIR_DOWN | DIR_UP)))&&
//判断滑动阈值是否达到
MOVE_THRESHOLD <= abs(disX))
{
{
Mutex::Autolock _l(mMoveDirMutex);
mMoveDir = (0 < disX)? DIR_MOVE_RIGHT : DIR_MOVE_LEFT;
}
//当触发上下滑动后不能触发左右滑动
if(0 != (getValidMoveDir() & (DIR_DOWN | DIR_UP)))
{
LOGD("--%d-- --%s-- mMoveDir:%d 当触发上下滑动后不能触发左右滑动\n", __LINE__, __FILE__, mMoveDir);
break;
}
//控件复位
screenCtrlPosReset();
//设置下一页页码
setNextPage();
//滑动方向改变回调
exeMoveDirChangeCallback();
//显示当前页
disCurPage();
}
//判断方向不重复
else if(getMoveDir() != ((0 < disY)? DIR_DOWN : DIR_UP) &&
//判断是否使能该方向滑动
(0 == (getValidMoveDir() & (DIR_MOVE_RIGHT | DIR_MOVE_LEFT)))&&
//判断滑动阈值是否达到
MOVE_THRESHOLD <= abs(disY))
{
{
Mutex::Autolock _l(mMoveDirMutex);
mMoveDir = (0 < disY)? DIR_DOWN : DIR_UP;
}
//当触发左右滑动后不能触发上下滑动
if(0 != (getValidMoveDir() & (DIR_MOVE_RIGHT | DIR_MOVE_LEFT)))
{
LOGD("--%d-- --%s-- mMoveDir:%d 当触发左右滑动后不能触发上下滑动\n", __LINE__, __FILE__, mMoveDir);
break;
}
//控件复位
screenCtrlPosReset();
//设置下一页页码
setNextPage();
//滑动方向改变回调
exeMoveDirChangeCallback();
//显示当前页
disCurPage();
}
else
{
// LOGD("--%d-- --%s-- disX:%d disY:%d mMoveDir:%d validMoveDir:%d diable slide:%d\n",
// __LINE__, __FILE__, disX, disY, mMoveDir, getValidMoveDir(), getIsTouchDisbleMoveCtrlFlag());
}
}
//回调滑动方向改变函数
}
break;
case MotionEvent::E_ACTION_UP: //触摸抬起
break;
default:
{//DEBUG
{
Mutex::Autolock _l(mMoveDirMutex);
mMoveDir = DIR_NULL;
}
}
break;
}
}
void ScreenMoveProMaxPlusUltraTurbo::setMoveDir(const MOVE_DIR& dir)
{
Mutex::Autolock _l(mMoveDirMutex);
mMoveDir = dir;
}
const ScreenMoveProMaxPlusUltraTurbo::MOVE_DIR ScreenMoveProMaxPlusUltraTurbo::getMoveDir(void)
{
Mutex::Autolock _l(mMoveDirMutex);
return mMoveDir;
}
void ScreenMoveProMaxPlusUltraTurbo::addCtrlPos(const int id, const LayoutPosition& pos)
{
Mutex::Autolock _l(mCtrlPosMutex);
mCtrlPos[id] = pos;
}
const bool ScreenMoveProMaxPlusUltraTurbo::getCtrlPos(const int id, LayoutPosition& pos)
{
Mutex::Autolock _l(mCtrlPosMutex);
std::map<int, LayoutPosition>::iterator it = mCtrlPos.find(id);
if(mCtrlPos.end() != it)
{
pos = it->second;
return true;
}
return false;
}
void ScreenMoveProMaxPlusUltraTurbo::clearAllCtrlPos(void)
{
Mutex::Autolock _l(mCtrlPosMutex);
mCtrlPos.clear();
}
void ScreenMoveProMaxPlusUltraTurbo::addCtrlPtr(ZKBase*& ptr)
{
//添加控件
{
Mutex::Autolock _l(mCtrlMutex);
mCtrl.push_back(ptr);
}
//保存位置
if(NULL != ptr)
{
addCtrlPos(ptr->getID(), ptr->getPosition());
}
}
void ScreenMoveProMaxPlusUltraTurbo::replaceCtrlPtr(const uint32_t index, ZKBase*& ptr)
{
Mutex::Autolock _l(mCtrlMutex);
if(mCtrl.size() <= index)
{
LOGD("--%d-- --%s-- 索引:%u 大于数据长度:%u\n", __LINE__, __FILE__, index, mCtrl.size());
return;
}
//恢复被控控件位置
LayoutPosition orgCtrlPos;
const int id = mCtrl[index]->getID();
if(true == getCtrlPos(id, orgCtrlPos))
{
mCtrl[index]->setPosition(orgCtrlPos);
}
else
{
LOGD("--%d-- --%s-- 查找不到:%d 控件位置!!!\n", __LINE__, __FILE__, id);
}
//替换控件
mCtrl[index] = ptr;
LOGD("--%d-- --%s-- index:%d befor id:%d after id:%d\n", __LINE__, __FILE__, index, id, mCtrl[index]->getID());
//保存控件位置
addCtrlPos(ptr->getID(), ptr->getPosition());
}
const int ScreenMoveProMaxPlusUltraTurbo::getCtrlPtrId(const uint32_t index)
{
Mutex::Autolock _l(mCtrlMutex);
if(mCtrl.size() <= index)
{
LOGD("--%d-- --%s-- 索引:%u 大于数据长度:%u\n", __LINE__, __FILE__, index, mCtrl.size());
return -1;
}
return mCtrl[index]->getID();
}
const bool ScreenMoveProMaxPlusUltraTurbo::getCtrlPtr(const uint32_t index, ZKBase*& ctrlPtr)
{
Mutex::Autolock _l(mCtrlMutex);
if(mCtrl.size() <= index)
{
LOGD("--%d-- --%s-- 索引:%u 大于数据长度:%u\n", __LINE__, __FILE__, index, mCtrl.size());
return false;
}
ctrlPtr = mCtrl[index];
return true;
}
void ScreenMoveProMaxPlusUltraTurbo::deleteAllCtrlPtr(void)
{
//清空控件
{
Mutex::Autolock _l(mCtrlMutex);
mCtrl.clear();
}
//清除控件位置
clearAllCtrlPos();
}
const uint32_t ScreenMoveProMaxPlusUltraTurbo::getCtrlCount(void)
{
Mutex::Autolock _l(mCtrlMutex);
return mCtrl.size();
}
void ScreenMoveProMaxPlusUltraTurbo::addDisbleMoveCtrlId(const int id)
{
Mutex::Autolock _l(mDisbleMoveCtrlIdMutex);
mDisbleMoveCtrlId.insert(id);
}
const bool ScreenMoveProMaxPlusUltraTurbo::isDisbleMoveCtrlId(const int id)
{
Mutex::Autolock _l(mDisbleMoveCtrlIdMutex);
return (mDisbleMoveCtrlId.end() != mDisbleMoveCtrlId.find(id));
}
void ScreenMoveProMaxPlusUltraTurbo::deleteAllDisbleMoveCtrlId(void)
{
Mutex::Autolock _l(mDisbleMoveCtrlIdMutex);
mDisbleMoveCtrlId.clear();
}
void ScreenMoveProMaxPlusUltraTurbo::setScreenWidth(const int width)
{
Mutex::Autolock _l(mScreenWidthMutex);
mScreenWidth = width;
}
const int ScreenMoveProMaxPlusUltraTurbo::getScreenWidth(void)
{
Mutex::Autolock _l(mScreenWidthMutex);
return mScreenWidth;
}
void ScreenMoveProMaxPlusUltraTurbo::setScreenHeight(const int height)
{
Mutex::Autolock _l(mScreenHeightMutex);
mScreenHeight = height;
}
const int ScreenMoveProMaxPlusUltraTurbo::getScreenHeight(void)
{
Mutex::Autolock _l(mScreenHeightMutex);
return mScreenHeight;
}
void ScreenMoveProMaxPlusUltraTurbo::setHorizontalMoveDis(const MotionEvent &ev)
{
//为使能左右滑动,直接返回
if(DIR_NULL == (DIR_MOVE_LEFT&getValidMoveDir()) && DIR_NULL == (DIR_MOVE_RIGHT&getValidMoveDir()))
{
mHorizontalMoveDis = 0;
return;
}
static MotionEvent orgTouchPoint;
switch (ev.mActionStatus) {
case MotionEvent::E_ACTION_DOWN://触摸按下
orgTouchPoint = ev;
mHorizontalMoveDis = 0;
break;
case MotionEvent::E_ACTION_MOVE://触摸滑动
mHorizontalMoveDis = ev.mX - orgTouchPoint.mX;
mHorizontalMoveDis += ((mHorizontalMoveDis < 0)? MOVE_THRESHOLD : -1*MOVE_THRESHOLD);
break;
case MotionEvent::E_ACTION_UP: //触摸抬起
// LOGD("--%d-- --%s-- mHorizontalMoveDis:%d\n", __LINE__, __FILE__, mHorizontalMoveDis);
break;
default:
mHorizontalMoveDis = 0;
break;
}
}
const int ScreenMoveProMaxPlusUltraTurbo::getHorizontalMoveDis(void)
{
return mHorizontalMoveDis;
}
void ScreenMoveProMaxPlusUltraTurbo::setVerticalMoveDis(const MotionEvent &ev)
{ //为使能上下滑动,直接返回
if(DIR_NULL == (DIR_UP&getValidMoveDir()) && DIR_NULL == (DIR_DOWN&getValidMoveDir()))
{
mVerticalMoveDis = 0;
return;
}
static MotionEvent orgTouchPoint;
switch (ev.mActionStatus) {
case MotionEvent::E_ACTION_DOWN://触摸按下
orgTouchPoint = ev;
mVerticalMoveDis = 0;
break;
case MotionEvent::E_ACTION_MOVE://触摸滑动
mVerticalMoveDis = ev.mY - orgTouchPoint.mY - MOVE_THRESHOLD;
mVerticalMoveDis += ((mVerticalMoveDis < 0)? MOVE_THRESHOLD : -1*MOVE_THRESHOLD);
break;
case MotionEvent::E_ACTION_UP: //触摸抬起
break;
default:
mVerticalMoveDis = 0;
break;
}
}
const int ScreenMoveProMaxPlusUltraTurbo::getVerticalMoveDis(void)
{
return mVerticalMoveDis;
}
void ScreenMoveProMaxPlusUltraTurbo::addMoveDirChangeCallback(const MOVE_EVENT_CALLBACK& fun)
{
Mutex::Autolock _l(mMoveDirChangeMutex);
mMoveDirChange.insert(fun);
}
void ScreenMoveProMaxPlusUltraTurbo::deleteMoveDirChangeCallback(const MOVE_EVENT_CALLBACK& fun)
{
Mutex::Autolock _l(mMoveDirChangeMutex);
std::set<MOVE_EVENT_CALLBACK>::iterator it = mMoveDirChange.find(fun);
if(mMoveDirChange.end() != it)
{
mMoveDirChange.erase(it);
}
}
/*
* @brife 执行滑动方向切换回调函数
* */
void ScreenMoveProMaxPlusUltraTurbo::exeMoveDirChangeCallback(void)
{
Mutex::Autolock _l(mMoveDirChangeMutex);
for (std::set<MOVE_EVENT_CALLBACK>::iterator it=mMoveDirChange.begin(); it!=mMoveDirChange.end(); ++it)
{
//传参滑动方向以及当前页页码
(*it)(getMoveDir(), getCurPage());
}
}
void ScreenMoveProMaxPlusUltraTurbo::addMoveDoneCallback(const MOVE_EVENT_CALLBACK& fun)
{
Mutex::Autolock _l(mMoveDoneMutex);
mMoveDone.insert(fun);
}
void ScreenMoveProMaxPlusUltraTurbo::deleteMoveDoneCallback(const MOVE_EVENT_CALLBACK& fun)
{
Mutex::Autolock _l(mMoveDoneMutex);
std::set<MOVE_EVENT_CALLBACK>::iterator it = mMoveDone.find(fun);
if(mMoveDone.end() != it)
{
mMoveDone.erase(it);
}
}
void ScreenMoveProMaxPlusUltraTurbo::exeMoveDoneCallback(void)
{
Mutex::Autolock _l(mMoveDoneMutex);
for (std::set<MOVE_EVENT_CALLBACK>::iterator it=mMoveDone.begin(); it!=mMoveDone.end(); ++it)
{
//传参滑动方向以及当前页页码
(*it)(getMoveDir(), getCurPage());
}
}
void ScreenMoveProMaxPlusUltraTurbo::addScreenMoveTimer(const SCREEN_MOVE_TIMER& fun)
{
Mutex::Autolock _l(mScreenMoveTimerMutex);
mScreenMoveTimer.insert(fun);
}
void ScreenMoveProMaxPlusUltraTurbo::deleteScreenMoveTimer(const SCREEN_MOVE_TIMER& fun)
{
Mutex::Autolock _l(mScreenMoveTimerMutex);
mScreenMoveTimer.erase(fun);
}
void ScreenMoveProMaxPlusUltraTurbo::exeScreenMoveTimer(void)
{
Mutex::Autolock _l(mScreenMoveTimerMutex);
for (std::set<SCREEN_MOVE_TIMER>::iterator it=mScreenMoveTimer.begin(); it!=mScreenMoveTimer.end(); ++it)
{
(*it)();
}
}
const bool ScreenMoveProMaxPlusUltraTurbo::screenMove(void)
{
//获取上一滑动距离(初始设置的滑动距离为1)
//moveLen 最大值为抬手时,还剩余的滑动距离
int moveLen = getMoveLen();
//横向滑动
if(DIR_MOVE_LEFT == getMoveDir() || DIR_MOVE_RIGHT == getMoveDir())
{
//增加滑动步进
moveLen += SPEED;
//限定单步滑动距离(不可超过高度)
moveLen = (getScreenWidth()-abs(getHorizontalMoveDis()) <= moveLen)? getScreenWidth()-abs(getHorizontalMoveDis()) : moveLen;
//转换滑动方向(正为向右,负为向左)
moveLen = (DIR_MOVE_LEFT == getMoveDir())? -1*moveLen : moveLen;
//滑动当前页
moveCurPage(moveLen);
//滑动下一页
moveNextPage(moveLen);
}
//纵向滑动
else if(DIR_UP == getMoveDir() || DIR_DOWN == getMoveDir())
{
//增加滑动步进
moveLen += SPEED;
//限定单步滑动距离(不可超过高度)
moveLen = (getScreenHeight()-abs(getVerticalMoveDis()) <= moveLen)? getScreenHeight()-abs(getVerticalMoveDis()) : moveLen;
//转换滑动方向(正为向下,负为向上)
moveLen = (DIR_UP == getMoveDir())? -1*moveLen : moveLen;
//滑动当前页
moveCurPage(moveLen);
//滑动下一页
moveNextPage(moveLen);
}
//将值弄成正值
moveLen = abs(moveLen);
//满足条件代表滑动到位
if(getScreenWidth()-abs(getHorizontalMoveDis()) <= moveLen || getScreenHeight()-abs(getVerticalMoveDis()) <= moveLen)
{
//同步下一页页码为当前页码
setNextPageBecomeCurPage();
LOGD("--%d-- --%s-- 滑动完成!!!\n", __LINE__, __FILE__);
//滑动结束
screenMoveDone();
//返回false,代表滑动结束
return false;
}
//标记当前滑动距离
setMoveLen(moveLen);
//返回true代表为滑动结束
return true;
}
void ScreenMoveProMaxPlusUltraTurbo::addCurPageMoveCallback(const PAGE_MOVE_CALLBACK& fun)
{
mCurPageMoveVec.insert(fun);
}
void ScreenMoveProMaxPlusUltraTurbo::delCurPageMoveCallback(const PAGE_MOVE_CALLBACK& fun)
{
mCurPageMoveVec.erase(fun);
}
void ScreenMoveProMaxPlusUltraTurbo::exeCurPageMoveCallback(const MOVE_DIR& dir, const int& xMoveLen, const int& yMoveLen)
{
for(auto it : mCurPageMoveVec)
{
it(dir, xMoveLen, yMoveLen);
}
}
void ScreenMoveProMaxPlusUltraTurbo::addNextPageMoveCallback(const PAGE_MOVE_CALLBACK& fun)
{
mNextPageMoveVec.insert(fun);
}
void ScreenMoveProMaxPlusUltraTurbo::delNextPageMoveCallback(const PAGE_MOVE_CALLBACK& fun)
{
mNextPageMoveVec.erase(fun);
}
void ScreenMoveProMaxPlusUltraTurbo::exeNextPageMoveCallback(const MOVE_DIR& dir, const int& xMoveLen, const int& yMoveLen)
{
for(auto it : mNextPageMoveVec)
{
it(dir, xMoveLen, yMoveLen);
}
}
void ScreenMoveProMaxPlusUltraTurbo::addScreenCtrlPosResetCallback(const PAGE_RESET_POS_CALLBACK& fun)
{
mPageResetPosVec.insert(fun);
}
void ScreenMoveProMaxPlusUltraTurbo::delScreenCtrlPosResetCallback(const PAGE_RESET_POS_CALLBACK& fun)
{
mPageResetPosVec.erase(fun);
}
void ScreenMoveProMaxPlusUltraTurbo::exeScreenCtrlPosResetCallback(const int& curPage)
{
for(auto it : mPageResetPosVec)
{
it(curPage);
}
}
void ScreenMoveProMaxPlusUltraTurbo::moveToPrePage(void)
{
//向下滑动
if(DIR_NULL != (getValidMoveDir()&DIR_DOWN))
{
//点击
onTouchEvent(MotionEvent(MotionEvent::E_ACTION_DOWN,
ScreenHelper::getScreenWidth()/2, ScreenHelper::getScreenHeight()/2, 0));
//滑动
onTouchEvent(MotionEvent(MotionEvent::E_ACTION_MOVE,
ScreenHelper::getScreenWidth()/2, ScreenHelper::getScreenHeight()/2+2*MOVE_THRESHOLD, 1));
//抬起
onTouchEvent(MotionEvent(MotionEvent::E_ACTION_UP,
ScreenHelper::getScreenWidth()/2, ScreenHelper::getScreenHeight()/2+3*MOVE_THRESHOLD, 2));
//设置滑动速度大上限
setIsSlideSpeedUpToThresholdFlag(true);
//启动滑屏
judgeWetherMoveScreen();
}
//向右滑动
else if(DIR_NULL != (getValidMoveDir()&DIR_MOVE_RIGHT))
{
//点击
onTouchEvent(MotionEvent(MotionEvent::E_ACTION_DOWN,
ScreenHelper::getScreenWidth()/2, ScreenHelper::getScreenHeight()/2, 0));
//滑动
onTouchEvent(MotionEvent(MotionEvent::E_ACTION_MOVE,
ScreenHelper::getScreenWidth()/2+2*MOVE_THRESHOLD, ScreenHelper::getScreenHeight()/2, 1));
//抬起
onTouchEvent(MotionEvent(MotionEvent::E_ACTION_UP,
ScreenHelper::getScreenWidth()/2+3*MOVE_THRESHOLD, ScreenHelper::getScreenHeight()/2, 2));
//设置滑动速度大上限
setIsSlideSpeedUpToThresholdFlag(true);
//启动滑屏
judgeWetherMoveScreen();
}
else
{
LOGD("--%d-- --%s-- dir:%d 未使能滑动方向!!\n", __LINE__, __FILE__, getValidMoveDir());
}
}
void ScreenMoveProMaxPlusUltraTurbo::moveToNextPage(void)
{
//向上滑动
if(DIR_NULL != (getValidMoveDir()&DIR_UP))
{
//点击
onTouchEvent(MotionEvent(MotionEvent::E_ACTION_DOWN,
ScreenHelper::getScreenWidth()/2, ScreenHelper::getScreenHeight()/2, 0));
//滑动
onTouchEvent(MotionEvent(MotionEvent::E_ACTION_MOVE,
ScreenHelper::getScreenWidth()/2, ScreenHelper::getScreenHeight()/2-2*MOVE_THRESHOLD, 1));
//抬起
onTouchEvent(MotionEvent(MotionEvent::E_ACTION_UP,
ScreenHelper::getScreenWidth()/2, ScreenHelper::getScreenHeight()/2-3*MOVE_THRESHOLD, 2));
//设置滑动速度大上限
setIsSlideSpeedUpToThresholdFlag(true);
//启动滑屏
judgeWetherMoveScreen();
}
//向左滑动
else if(DIR_NULL != (getValidMoveDir()&DIR_MOVE_LEFT))
{
//点击
onTouchEvent(MotionEvent(MotionEvent::E_ACTION_DOWN,
ScreenHelper::getScreenWidth()/2, ScreenHelper::getScreenHeight()/2, 0));
//滑动
onTouchEvent(MotionEvent(MotionEvent::E_ACTION_MOVE,
ScreenHelper::getScreenWidth()/2-2*MOVE_THRESHOLD, ScreenHelper::getScreenHeight()/2, 1));
//抬起
onTouchEvent(MotionEvent(MotionEvent::E_ACTION_UP,
ScreenHelper::getScreenWidth()/2-3*MOVE_THRESHOLD, ScreenHelper::getScreenHeight()/2, 2));
//设置滑动速度大上限
setIsSlideSpeedUpToThresholdFlag(true);
//启动滑屏
judgeWetherMoveScreen();
}
else
{
LOGD("--%d-- --%s-- dir:%d 未使能滑动方向!!\n", __LINE__, __FILE__, getValidMoveDir());
}
}
具体操作说明
实际使用只需要修改控件(下图红框)、添加点击到就不能滑动窗口控件ID(下图黄框)以及设置滑动方向(下图蓝框,默认横向滑动取消注释变为纵向滑动)。
添加底部导航标识
有时需要在可滑动页面底部标识当前滑动到哪一页,如下图底部中间所示:
添加绘制导航标识点画布
在页面添加绘制标识点所用画布,命名为navigationBar,如下图所示:
ui布局位置参数如下所示:
添加绘制导航标识点代码
当滑动完成重新绘制一次标识点即可,因此我们只需在滑动完成回调函数moveDone添加如下代码即可实现功能:
/*
* @brife 绘画导航标识
* */
static void drawNavigationBar(void)
{
//画笔大小
const int brushSize = 4;
//导航栏点距
const int pointerDis = 5;
/*计算各个点X轴位置*/
//第一个点的X坐标
const int firstPointX =
(ScreenHelper::getScreenWidth()-(ScreenMovePtr->getCtrlCount()-1)*(brushSize*2+pointerDis))/2;
//每一个点的坐标
std::vector<int> mPointX;
//获取各点X轴坐标
for(uint32_t level1 = 0; level1 < ScreenMovePtr->getCtrlCount(); ++level1)
{
mPointX.push_back(firstPointX+level1*(brushSize*2+pointerDis));
}
//清空画布
mnavigationBarPtr->erase(0, 0, 480, mnavigationBarPtr->getPosition().mHeight);
//设置画笔大小
mnavigationBarPtr->setLineWidth(3);
for(uint32_t level1 = 0; level1 < mPointX.size(); ++level1)
{
//设置颜色
mnavigationBarPtr->setSourceColor((ScreenMovePtr->getCurPage() == level1)? 0XFF48DE5E:0XFF424040);
//画点
mnavigationBarPtr->fillArc(mPointX[level1]+brushSize, 9, brushSize);
}
}
static void moveDone(const SCREEN_MOVE::MOVE_DIR dir, const int curPage)
{
LOGD("--%d-- --%s-- 滑动完成:%d curPage:%d\n", __LINE__, __FILE__, dir, curPage);
drawNavigationBar();
}