我修改了线性布局,以通过调整左孩子的大小来响应触摸,而右孩子则占用其余空间,并使用以下代码模拟可以打开"或关闭"的水平滚动. LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) leftView.getLayoutParams(); //Log.d("ll","width " + newWidth); lp.width=newWidth; leftView.setLayoutParams(lp);在react native中,touch仍在调用此方法并记录期望值,但是子代的大小未更新.它唯一更新的时间是当我将可见性切换为消失"然后再次可见时.从Java调用视图上的invalidate/requestLayout或从js调用forceUpdate都没有任何效果.我还需要调用其他一些代码来使视图无效并重画视图吗?我需要给我一个提示,以提示该组件滚动或响应触摸吗?解决方案在大多数情况下,RN android确实不会更新子级布局,可见性或适配器更改.通过在需要更新时将挂钩插入自定义视图中,该更新将使/requestLayout无效/然后调用此代码,通常可以恢复正常行为.在某些情况下,无法正常进行测量,因此我不得不发布Delayed 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 {@Overridepublic void markUpdated(){ super.markUpdated(); if (hasNewLayout()) markLayoutSeen(); dirty();}@Overridepublic 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); } }); }Full code hereVideo of correct behavior in java and incorrect in react native hereI have modified a linear layout to respond to touch by resizing the left child while the right child takes up the rest of the space, simulating a horizontal scroll that can be 'opened' or 'closed' using the following code LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) leftView.getLayoutParams(); //Log.d("ll","width " + newWidth); lp.width=newWidth; leftView.setLayoutParams(lp);In react native, touch is still calling this method and logging the expected values, but the size of the children is not updated. The only time it updates is when I switch the visibility to gone then visible again. Calling invalidate/requestLayout on the view from java or forceUpdate from js does not have any effect.Is there some other code I need to call to invalidate and redraw the view? Is there a hint I need to give to react that this component scrolls or responds to touch? 解决方案 RN android is indeed not updating children layout or visibility or adapter changes under most conditions. By inserting hooks into the custom view when an update is needed that will invalidate/requestLayout then call this code normal behavior is restored, mostly. There are still some cases where measurement does not happen like it does normally and I have to postDelayed Runnables that then cause this invalidation. Dealing with a node's parents may not be strictly necessary in all cases, but it is for some.In View ManagerMethod 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 {@Overridepublic void markUpdated(){ super.markUpdated(); if (hasNewLayout()) markLayoutSeen(); dirty();}@Overridepublic 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); } }); } 这篇关于无法在android react native模块中调整线性布局子元素的大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
09-05 19:05