只修列表滚动:每次渲染换一套新的 Table+ScrollPane 塞回同一单元格(复用时 ScrollPane 不重新测量 widget 高度,maxY=0 导致滚轮失效)
This commit is contained in:
1 parent
94c467a40d
commit
ee1f2a2ced
1 file changed
+36
-6
@@ -49,6 +49,11 @@ public final class ObjectPanel {
|
||||
java.util.List<Object[]> inspectFields = new ArrayList<Object[]>();
|
||||
List<Object> objects = new ArrayList<Object>();
|
||||
Object target;
|
||||
Class<?> tableClass;
|
||||
Class<?> scrollClass;
|
||||
Class<?> actorClass;
|
||||
Class<?> cellClass;
|
||||
Object listCell; // 承载列表 ScrollPane 的单元格
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,6 +71,10 @@ public final class ObjectPanel {
|
||||
Class<?> skinClass = Class.forName("com.badlogic.gdx.scenes.scene2d.ui.Skin", true, loader);
|
||||
Class<?> fieldClass = Class.forName("com.badlogic.gdx.scenes.scene2d.ui.TextField", true, loader);
|
||||
|
||||
state.tableClass = tableClass;
|
||||
state.scrollClass = scrollClass;
|
||||
state.actorClass = actorClass;
|
||||
state.cellClass = cellClass;
|
||||
Object root = tableClass.getConstructor().newInstance();
|
||||
Object rows = tableClass.getConstructor().newInstance();
|
||||
call(rows, Obf.TABLE_TOP, new Class<?>[0], tableClass);
|
||||
@@ -116,6 +125,7 @@ public final class ObjectPanel {
|
||||
// 唯一 expand+fill 的单元格:内容区(上面是列表/Inspector,最下面是日志块,同一个滚动区)
|
||||
cell = call(root, Obf.TABLE_ADD, new Class<?>[] {actorClass}, cellClass, scroll);
|
||||
layoutCell(cell, Obf.CELL_TOP, Obf.CELL_EXPAND, Obf.CELL_FILL);
|
||||
state.listCell = cell;
|
||||
|
||||
wire(loader, refresh, new Runnable() {
|
||||
@Override
|
||||
@@ -272,8 +282,7 @@ public final class ObjectPanel {
|
||||
state.objects = objects;
|
||||
try {
|
||||
// Table.clearChildren()(载荷名 `SourceFile()V`):把列表里的行全清掉重建。
|
||||
call(state.listTable, Obf.TABLE_CLEAR_CHILDREN, new Class<?>[0], void.class);
|
||||
state.logBlockStarted = false;
|
||||
beginRender(state);
|
||||
Class<?> cellClass = Class.forName(Obf.CELL, true, state.loader);
|
||||
Class<?> actorClass = Class.forName(Obf.ACTOR, true, state.loader);
|
||||
for (int i = 0; i < objects.size() && i < 300; i++) {
|
||||
@@ -508,6 +517,29 @@ public final class ObjectPanel {
|
||||
* 否则 ScrollPane 里缓存的高度还是旧的,表现为"内容多了却不能滚"。
|
||||
* `b_()V` = `invalidate()`(来源:MapMethods 对 gdx-1.11.0 的指纹比对)。
|
||||
*/
|
||||
/**
|
||||
* 每次渲染都换一套**全新的 Table + ScrollPane**,塞回同一个单元格。
|
||||
*
|
||||
* 为什么必须换:ScrollPane 只在 layout 时量一次里面 widget 的高度,我们之后往 widget 里
|
||||
* 加/删行,它记的高度还是旧的 —— maxY 一直是 0,滚轮就滚不动(你看到的现象)。
|
||||
* 换一个新的 ScrollPane 最省事也最稳(只做这一件事,不改任何别的行为)。
|
||||
*/
|
||||
private static void beginRender(State state) throws Exception {
|
||||
Object table = state.tableClass.getConstructor().newInstance();
|
||||
call(table, Obf.TABLE_TOP, new Class<?>[0], state.tableClass);
|
||||
call(table, Obf.TABLE_LEFT, new Class<?>[0], state.tableClass);
|
||||
Class<?> skinClass = Class.forName("com.badlogic.gdx.scenes.scene2d.ui.Skin", true, state.loader);
|
||||
Object scroll = state.scrollClass.getConstructor(state.actorClass, skinClass)
|
||||
.newInstance(table, state.skin);
|
||||
state.listTable = table;
|
||||
state.listScroll = scroll;
|
||||
if (state.listCell != null) {
|
||||
// Cell.setActor(Actor):把旧 ScrollPane 换成新的
|
||||
call(state.listCell, "D", new Class<?>[] {state.actorClass}, state.cellClass, scroll);
|
||||
}
|
||||
state.logBlockStarted = false;
|
||||
}
|
||||
|
||||
private static void invalidateList(final State state) {
|
||||
try {
|
||||
call(state.listTable, "b_", new Class<?>[0], void.class);
|
||||
@@ -528,8 +560,7 @@ public final class ObjectPanel {
|
||||
private static void fillRows(final State state, List<String> lines,
|
||||
java.util.Map<Integer, Object[]> clickable) {
|
||||
try {
|
||||
call(state.listTable, Obf.TABLE_CLEAR_CHILDREN, new Class<?>[0], void.class);
|
||||
state.logBlockStarted = false;
|
||||
beginRender(state);
|
||||
Class<?> cellClass = Class.forName(Obf.CELL, true, state.loader);
|
||||
Class<?> actorClass = Class.forName(Obf.ACTOR, true, state.loader);
|
||||
for (int i = 0; i < lines.size(); i++) {
|
||||
@@ -586,8 +617,7 @@ public final class ObjectPanel {
|
||||
/** 用纯文本行填列表区(行不可点)。 */
|
||||
private static void fillTextRows(final State state, List<String> lines) {
|
||||
try {
|
||||
call(state.listTable, Obf.TABLE_CLEAR_CHILDREN, new Class<?>[0], void.class);
|
||||
state.logBlockStarted = false;
|
||||
beginRender(state);
|
||||
Class<?> cellClass = Class.forName(Obf.CELL, true, state.loader);
|
||||
Class<?> actorClass = Class.forName(Obf.ACTOR, true, state.loader);
|
||||
for (String line : lines) {
|
||||
|
||||
Reference in new issue
Block a user