无法调整android中的线性布局subprocess反应原生模块

完整代码在这里

在java中正确行为的video和不正确的反应原生在这里

我修改了一个线性布局,通过调整左边的孩子的大小来响应触摸,而右边的孩子占据了剩余的空间,模拟了一个可以使用以下代码“打开”或“关闭”的水平滚动

LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) leftView.getLayoutParams(); //Log.d("ll","width " + newWidth); lp.width=newWidth; leftView.setLayoutParams(lp); 

在本机反应中,touch仍然调用此方法并记录预期值,但不更新子项的大小。 它更新的唯一时间是我将可见性切换为已消失然后再次可见。 从java调用invalidate / requestLayout或从js调用forceUpdate没有任何效果。

我需要调用一些其他代码来使视图无效并重绘吗? 我需要提供一些提示,以便该组件滚动或响应触摸吗?

我遇到了同样的问题,我在这个旧的报道问题上find了关于本地回购的答案。

在自定义布局中添加以下代码,之后甚至无需调用requestLayout()或invalidate()。 更新布局的LayoutParams后,会立即传播更改。 此解决方案与ReactPicker.java和ReactToolbar.java中使用的解决方案相同。

 @Override public void requestLayout() { super.requestLayout(); // The spinner relies on a measure + layout pass happening after it calls requestLayout(). // Without this, the widget never actually changes the selection and doesn't call the // appropriate listeners. Since we override onLayout in our ViewGroups, a layout pass never // happens after a call to requestLayout, so we simulate one here. post(measureAndLayout); } private final Runnable measureAndLayout = new Runnable() { @Override public void run() { measure( MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.EXACTLY)); layout(getLeft(), getTop(), getRight(), getBottom()); } }; 

在大多数情况下,RN android确实没有更新子布局或可见性或适配器更改。 通过在需要更新时将挂钩插入自定义视图将使/ requestLayout无效,然后调用此代码,主要恢复正常行为。 仍有一些情况下,测量不会像正常情况那样发生,我必须postDelayed Runnables然后导致这种失效。 在所有情况下处理节点的父母可能不是绝对必要的,但对某些人而言则是如此。

在View Manager中

 Method markNewLayout, getShadowNode; public ViewManager(){ super(); if (markNewLayout == null) { try { markNewLayout = CSSNode.class.getDeclaredMethod("markHasNewLayout"); markNewLayout.setAccessible(true); } catch (Exception e) { e.printStackTrace(); } } try{ if (getShadowNode==null){ getShadowNode = UIImplementation.class.getDeclaredMethod("resolveShadowNode",int.class); getShadowNode.setAccessible(true); } } catch (Exception e) { e.printStackTrace(); } public class MyShadowNode extends LayoutShadowNode { @Override public void markUpdated(){ super.markUpdated(); if (hasNewLayout()) markLayoutSeen(); dirty(); } @Override public boolean isDirty(){ return true; } @Override protected CustomView createViewInstance(final ThemedReactContext reactContext) { view.setRnUpdateListener(new CustomView.RNUpdateListener() { MyShadowNode node; @Override public void needsUpdate() { view.requestLayout(); Runnable r = new Runnable() { @Override public void run() { if (node ==null){ try { node = (MyShadowNode) getShadowNode.invoke(uiImplementation, view.getId()); } catch (Exception e){ e.printStackTrace(); } } if (node != null) { if (node.hasNewLayout()) node.markLayoutSeen(); ReactShadowNode parent = node.getParent(); while (parent != null) { if (parent.hasNewLayout()) { try { markNewLayout.invoke(parent,view.getId()); } catch (Exception e) { e.printStackTrace(); } parent.markLayoutSeen(); } parent = parent.getParent(); } node.markUpdated(); } Log.d(getName(), "markUpdated"); } }; reactContext.runOnNativeModulesQueueThread(r); } }); } 

尝试逐个删除布局的内容。 可能是其中一个孩子有包装内容。 您可以使用hierarchyViewer和uiautomatorviewer来考虑权重。 如果可能,发布hierarchyViewer数据。

 LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) leftView.getLayoutParams(); lp.width=newWidth; leftView.setLayoutParams(lp); leftView.requestLayout(); 

上面的代码将解决您的问题。