SwipeableContainer跳转返回后滑动其他容器触发首个容器左滑异常
我在页面中添加了多个SwipeableContainer可滑动容器,每个容器左右两侧均配有按钮,容器顶部组件为MultiButton,点击可跳转至其他页面。当用户从跳转页返回SwipeableContainer所在页面后,对其他任意SwipeableContainer执行左滑操作时,首个SwipeableContainer也会同步向左展开。相关演示截图及示例代码如下:
//Swipeable containers bugs public void SwipeableContainerPage(Form mainForm){ Form formSC = new Form("Swipeable Container", new BorderLayout()); formSC.getToolbar().setBackCommand("", e -> mainForm.showBack()); Container northcnt = new Container(new BoxLayout(BoxLayout.Y_AXIS)); Container centercnt = new Container(new BoxLayout(BoxLayout.Y_AXIS)); Container southcnt = new Container(new BoxLayout(BoxLayout.Y_AXIS)); MultiButton mb_1 = new MultiButton("MB1"); Button b_l1 = new Button("LB1"); Button b_r1 = new Button("RB1"); MultiButton mb_2 = new MultiButton("MB2"); Button b_l2 = new Button("LB2"); Button b_r2 = new Button("RB2"); MultiButton mb_3 = new MultiButton("MB3"); Button b_l3 = new Button("LB3"); Button b_r3 = new Button("RB3"); SwipeableContainer sc_1 = new SwipeableContainer(b_l1, b_r1, mb_1); SwipeableContainer sc_2 = new SwipeableContainer(b_l2, b_r2, mb_2); SwipeableContainer sc_3 = new SwipeableContainer(b_l3, b_r3, mb_3); mb_1.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { GoToAndBackPage(formSC); } }); mb_2.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { GoToAndBackPage(formSC); } }); mb_3.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { GoToAndBackPage(formSC); } }); centercnt.add(sc_1); centercnt.add(sc_2); centercnt.add(sc_3); formSC.add(BorderLayout.NORTH, northcnt).add(BorderLayout.CENTER, centercnt).add(BorderLayout.SOUTH, southcnt); formSC.show(); } //page for SC to go to public void GoToAndBackPage(Form mainForm){ Form formGoTo = new Form("Go To Page", new BorderLayout()); formGoTo.getToolbar().setBackCommand("", e -> mainForm.showBack()); Container northcnt = new Container(new BoxLayout(BoxLayout.Y_AXIS)); Container centercnt = new Container(new BoxLayout(BoxLayout.Y_AXIS)); Container southcnt = new Container(new BoxLayout(BoxLayout.Y_AXIS)); Label l_welcome = new Label("Welcome to the Go To Page"); centercnt.add(l_welcome); formGoTo.add(BorderLayout.NORTH, northcnt).add(BorderLayout.CENTER, centercnt).add(BorderLayout.SOUTH, southcnt); formGoTo.show(); }
演示截图:


这是Codename One中SwipeableContainer的已知手势绑定异常问题,触发条件是包含多个SwipeableContainer的页面退到后台(跳转其他页面)再重新唤起时,内部的滑动手势识别器会错误将所有滑动事件同步分发到首个初始化的SwipeableContainer实例。
修复方案
可根据业务场景选择以下任意一种方式解决:
方案1:页面显示时重置所有SwipeableContainer状态
在SwipeableContainer所在Form的show方法执行前,添加显示监听器,每次页面被唤起时,统一关闭所有SwipeableContainer的展开状态,同时重置手势绑定,该方案兼容性最高,不会影响原有滑动交互灵敏度:
// 放在formSC.show()之前执行 formSC.addShowListener(e -> { // 遍历所有子组件找到SwipeableContainer执行重置 for(Component cmp : centercnt) { if(cmp instanceof SwipeableContainer) { ((SwipeableContainer) cmp).close(); cmp.revalidate(); } } });
方案2:禁用SwipeableContainer的全局手势复用
初始化每个SwipeableContainer时,手动关闭手势复用机制,每个实例单独绑定自身手势:
// 每个SwipeableContainer初始化后添加该配置 sc_1.setRestoreDragPosition(false); sc_2.setRestoreDragPosition(false); sc_3.setRestoreDragPosition(false);
内容的提问来源于stack exchange,提问作者James N
相关产品推荐
相关产品推荐

