[英]Cannot resize linear layout children in android react native module
我修改了一个线性布局,通过调整左边的孩子的大小来响应触摸,而右边的孩子占据了剩余的空间,模拟了一个可以使用以下代码“打开”或“关闭”的水平滚动
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) leftView.getLayoutParams();
//Log.d("ll","width " + newWidth);
lp.width=newWidth;
leftView.setLayoutParams(lp);
在本机反应中,touch仍然调用此方法并记录预期值,但不更新子项的大小。 它更新的唯一时间是我将可见性切换为已消失然后再次可见。 从java调用invalidate / requestLayout或从js调用forceUpdate没有任何效果。
我需要调用一些其他代码来使视图无效并重绘吗? 我需要提供一些提示,以便该组件滚动或响应触摸吗?
我有同样的问题,我在这个旧的报道问题上找到了答案本地回购。
在自定义布局中添加以下代码,之后甚至无需调用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无效,然后调用此代码,主要恢复正常行为。 还有一些情况下,测量不会像正常情况那样发生,我必须发布延迟的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();
上面的代码将解决您的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.