Codename One:tabs监听切换结合removeTabAt触发栈溢出问题求助
解决Tab切换时删除标签页导致的StackOverflowError问题
哈哈,这个栈溢出的坑我踩过!咱们先把问题根源捋清楚,再给你修复方案~
为什么会出现StackOverflowError?
你在addSelectionListener里触发删除最后一个标签页的操作时,删除标签页本身会再次触发SelectionListener的回调——因为Tab组件在删除标签后,会自动更新选中状态并通知监听器。这样就形成了无限递归:监听器触发删除→删除触发监听器→监听器再触发删除……直到栈被撑爆。
修复方案:加标记打破递归循环
我们只需要给删除操作加一个临时标记,让监听器在"正在删除标签"的状态下直接跳过逻辑,就能避免无限递归。同时还要完善触发条件,确保只有从最后一个标签切换到倒数第二个时才执行删除:
// 新增一个标记,用来标记是否正在执行删除标签的操作 private boolean isRemovingTab = false; // 初始化Tab选择监听器 tabs.addSelectionListener((oldSelected, newSelected) -> { Log.p("There are " + tabs.getTabCount() + " tabs in total"); Log.p("Index of oldSelected tab: " + oldSelected); Log.p("Index of newSelected tab: " + newSelected); // 如果正在删除标签,直接返回,避免递归触发 if (isRemovingTab) { return; } int tabCount = tabs.getTabCount(); // 严格判断触发条件: // 1. 标签数量至少为2(避免越界) // 2. 之前选中的是最后一个标签 // 3. 现在切换到了倒数第二个标签 if (tabCount >= 2 && oldSelected == tabCount - 1 && newSelected == oldSelected - 1) { Log.p("The user selected the previous tab from the last one, removing the last tab..."); // 标记进入删除状态 isRemovingTab = true; // 删除最后一个标签 tabs.removeTabAt(tabCount - 1); // 取消删除标记 isRemovingTab = false; } });
额外注意点
- 避免索引越界:一定要先判断
tabCount >= 2,不然当只剩1个标签时,oldSelected - 1会变成负数,引发索引错误。 - 确认选中状态:大部分Tab组件在删除最后一个标签后,会自动选中前一个标签(也就是你切换到的倒数第二个),但如果你的组件有特殊行为,可以在删除后手动调用
tabs.setSelectedIndex(newSelected)确保选中状态正确。
内容的提问来源于stack exchange,提问作者Francesco Galgani
相关产品推荐
相关产品推荐

