腾讯新闻的横向和纵向拖动
素材清单
无
涉及的技能
- 动态面板的叠加嵌套
- 交互事件:OnDragStart,OnDrag,OnDragDrop,This.x,This.y,DragX,DragY。
案例效果
本例模拟腾讯新闻的手势滑动效果,横向滑动屏幕切换新闻频道,纵向滑动屏幕查看频道内的新闻列表。
效果.gif移动链接如下:
横向和纵向拖拽
横向滑动屏幕,在要闻、视频等频道进行切换,纵向滑动时,向下滑动到顶端和向上滑动到底端都有尽头,切换频道时横向滑动超过一半就自动滑过去,不足一半恢复当前频道。
简明步骤
- 主界面布局。
- 添加第二层负责拖拽功能的动态面板及其频道内容。
- 判断和确定拖拽方向。
- 横向纵向拖拽频道列表。
- 拖拽结束的交互优化。
具体步骤及说明
1. 主界面布局。
1.新建一个项目,命名为“横向和纵向滑动综合
”。
2.向默认的home页添加一个动态面板,参数如下:
| 名称 | 类型 | 坐标 | 尺寸 |
| ------------ | ------------- | ------------ |
| dpMain
| Dynamic Panel | 0,0
| 414,736
|
将其锁定方便操作其他控件。
3.添加5个 Label 到主屏上方作为频道名,分别命名为要闻
,视频
,科技
等。使用上对齐
和水平分布
功能进行对齐操作。
水平分布.png
4.在这几个 label 下面动态面板上面放置一个白色矩形作为导航栏背景,坐标和尺寸为(0,0,414,70)
。通过widget manager 调整控件之间的层次结构如图, 图中的 navi 就是导航栏背景矩形。
5.同样的方法在主屏下方制作 Tab 栏新闻
和关心
,Tab 栏坐标是(0,736-70,414,70)
。
将字体调整到18的大小,所有控件锁定,主界面制作完毕。
2. 添加第二层负责拖拽功能的动态面板。
1.添加动态面板到dpMain
的state1中,作为拖拽内容的容器,它的高是主屏幕的高度减去导航栏和 tab 栏的高度70,参数如下:
| 名称 | 类型 | 坐标 | 尺寸 |
| ------------ | ------------- | ------------ |
| dpDrag
| Dynamic Panel | 0,70
| 414,736-70-70
|
2.双击dpDrag
的 state1,添加2个动态面板,参数如下:
| 名称 | 类型 | 坐标 | 尺寸 |
| ------------ | ------------- | ------------ |
| dpNews
| Dynamic Panel | 0,0
| 414,1000
|
| 名称 | 类型 | 坐标 | 尺寸 |
| ------------ | ------------- | ------------ |
| dpVideo
| Dynamic Panel | 414,0
| 414,1000
|
dpNews的高度需要超过主屏高度来实现纵向拖动显示新闻列表,这里暂时设置成1000。
dpVideo的 x 坐标设置成主屏宽度414,这样正好和dpNews连接并列横置,高度同dpNews。
3.分别制作新闻和视频板块的内容。
分别双击dpNews
和dpVideo
,进入他们的 state1,上方放置图片作为新闻图片,下方放置新闻列表,参数自定,添加一个 label 新闻图片
提示一下现在是在哪个频道,效果大致如图即可。
4.widget manager 的结构如下图:
widget manager.png至此,界面设计完毕,接下来添加交互。
3. 判断和确定拖拽方向。
1.判断用户是横向还是纵向拖动。
参数 DragX 用于记录横向的拖拽距离,DragY 用于记录纵向的拖拽距离,如果DragX > DragY,就是说用户横向的拖拽距离大于纵向拖拽的距离,即用户是在横向拖拽。
向左拖拽,DragX是负值,向右拖拽,DragX是正值。向上拖拽,DragY 是负值,向下拖拽,DragY 是正值。所以,比较是时候是绝对值进行比较。
2.通过 OnDragStart 事件来判断拖拽方向。
OnDragStart事件是在用户的拖拽行为已经开始进行了,但物体还没有跟随手指开始移动时发生的动作。
双击dpDrag
的 state1,单击选中dpNews
的 state1,双击OnDragStart
事件,在打开的窗口中点击add condition
添加条件判断。
第一个下拉菜单选择value
,点击fx
,在出现的新窗口中,点击insert variable or function
,寻找并选择 abs 函数,计算绝对值。将括号中的x
替换成DragX
,点击OK
。结果如下图:
在中间条件选择中选择is greater than
,在下一个fx
中,参考前一个fx
,设置成[[math.abs(dragy)]]
,也可以自行打字输入。最后结果如下图:
3.创建一个自定义变量dragDirection
,用来作为拖拽方向的标志,如果是横向拖动,就设置为horizontal
,如果是纵向的,就设置为vertical
。
在用例编辑器中,选中set variable value
,在右侧找到add variable
,在弹出的窗口中找到加号添加自定义变量,命名为dragDirection
,确定后,在用例编辑器中右侧窗口选中它打钩。在下方的set variable to
中的文本框中手动输入horizontal
,确定。
OnDragStart 事件中的用例显示如下图:
条件3.png4.双击OnDragStart
,添加case2。
case 2会自动设置条件为else if true
,也就是说 case 1不成立就会执行 case 2的情况。
本例中,case 1不成立,就是说用户在做纵向的拖拽,导致了 DragX 小于 DragX
这时应将dragDirection
变量设置成vertical
。方法参考上面。最后结果如下图:
4. 横向纵向拖拽频道列表。
1.当 DragY 大于0,向下拖拽时,如果dpNews
的 y 坐标大于0了,代表我们已经拖拽到动态面板的最顶部,就不能继续向下拖拽了。
在dpNews
的 state1中,继续编辑用例,添加条件。这里用到了2个条件同时满足,需要在编辑第一个关于 DragY 的条件后,点击加号添加第二个关于 This.y 的条件,结果如下图:
2.当 DragY 小于0,向上拖拽时,如果dpNews
的 y 坐标小于736(主屏高度)-70(导航栏高度)-70(tab 栏高度)-1000(新闻内容的动态面板高度)了,结果是-404,即我们还可以向上拖拽的距离只有404,这时我们已经拖拽到动态面板的最底部,就不能继续向上拖拽了。
在dpNews
的 state1中,继续编辑用例,添加此条件case 2
,方法同上,结果如图:
3.当 DragX 大于0,向右拖拽时,如果dpNews
的 x 坐标大于0了,代表我们已经拖拽到动态面板的最左边,就不能继续向右拖拽了。
在dpNews
的 state1中,继续编辑用例,添加此条件case 3
,方法同上,结果如图:
4.只要dragDirection
等于horizontal
,我们就让新闻频道和视频频道一起横向移动。
在dpNews
的 state1中,继续编辑用例,添加此条件case 4
。
在左侧窗口中添加 actions,单击选择move
,在右侧的configure actions
窗口中,在两个新闻的动态面板前打钩选中,在下面的参数 move 中选择with drag x
进行横向拖拽。结果如图:
5.最后一个 case 5
直接添加纵向移动,结果如图:
6.预览效果。这时候要闻频道可以上下拖拽,不能向右,可以向左拖拽出视频频道,但不流畅。且在视频频道无法拖回到要闻频道。我们应该加上视频的向右拖拽交互。
参考上面的操作,我们给dpVideo
也添加类似的交互用例。这个操作可以使用用例的复制功能。我们选中dpNews
,在它的交互用例中选中OnDragStart
,右边有个小三角,选择里面的copy
命令。
再回来选中dpVideo
,在右侧的小三角中选择paste
,即可复制交互。可以同样的方案复制OnDrag
事件中的交互用例,稍作修改,只有case 5
不同,结果如下图:
5. 拖拽结束的交互优化。
1.在拖拽结束的时候要判断一下是哪个频道在当前屏幕上,如果各有半个屏幕,我们要自动完成拖拽,呈现整个频道页面。
我们来添加OnDragStop
事件。如果频道移动超过半个屏幕即414/2的空间,拖拽动作就算停止了,我们也要讲下一个频道移动到屏幕上,同时将移动出去的频道 y 坐标设置为0作为复位,下一次再看到它时还是初始的第一条新闻纪录。
添加dpNews
的用例过程如下图:
OnDragStop2.png
OnDragStop3.png
第一个
move
使用了500ms 的线性过度来平移两个频道,第二个
move是第一个
move`动作后,不用过度动画直接将新闻频道定位在坐标(-414,0),作为复位的动作
2.如果没有移动到屏幕一半的情况下,我们应该对屏幕位置进行复位,弹回到刚才的频道。用例设置的最终结果如图:
dpNews.png3.同法设置 dpVideo 的用例设置最终结果如图:
dpVideo1.png
网友评论