无法调整android react本机模块中线性布局子项的大小
我已经修改了一个线性布局,通过调整左侧子对象的大小来响应触摸,而右侧子对象占据了剩余的空间,模拟一个水平滚动,可以使用以下代码“打开”或“关闭”无法调整android react本机模块中线性布局子项的大小,android,android-layout,scroll,react-native,android-layoutparams,Android,Android Layout,Scroll,React Native,Android Layoutparams,我已经修改了一个线性布局,通过调整左侧子对象的大小来响应触摸,而右侧子对象占据了剩余的空间,模拟一个水平滚动,可以使用以下代码“打开”或“关闭” LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) leftView.getLayoutParams(); //Log.d("ll","width " + newWidth); lp.width=newWidth; leftView.setLayoutPa
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) leftView.getLayoutParams();
//Log.d("ll","width " + newWidth);
lp.width=newWidth;
leftView.setLayoutParams(lp);
在react native中,touch仍在调用此方法并记录预期值,但子对象的大小不会更新。它唯一更新的时间是我将可见性切换为“已消失”,然后再次显示。从java或js对视图调用invalidate/requestLayout没有任何效果
是否有其他代码需要调用以使视图无效并重新绘制?我是否需要给出一个提示来回应此组件滚动或响应触摸?尝试逐个删除版面内容。可能是其中一个孩子有包装内容。您可以使用hierarchyViewer和uiautomatorviewer 也要考虑重量。如果可能,发布hierarchyViewer数据
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) leftView.getLayoutParams();
lp.width=newWidth;
leftView.setLayoutParams(lp);
leftView.requestLayout();
以上代码将解决您的问题 在大多数情况下,RN android确实没有更新子布局、可见性或适配器更改。当需要更新时,通过在自定义视图中插入钩子,将使/requestLayout无效,然后调用此代码,通常恢复正常行为。仍然有一些情况下,测量不会像正常情况那样发生,我必须对延迟的可运行性进行后期处理,然后导致这种失效。并非在所有情况下都必须处理节点的父节点,但在某些情况下确实如此 视图管理器
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);
}
});
}
我也有同样的问题,我在react native的回购协议中找到了关于旧报告问题的答案 在自定义布局中添加以下代码,之后甚至不需要调用requestLayout()或invalidate()。更新布局的LayoutParams后,更改将立即传播。此解决方案与和中使用的解决方案相同
为了清楚起见,右侧子视图的宽度为0dp weight 1,左侧视图的宽度为显式宽度,从50dp开始,随着触摸的变化而变化。从rn 33升级到38,我必须添加此项才能使自定义视图组正常工作。但是,仍然有必要使用我的答案中的代码。对我的相关问题和我公认的黑客解决方案有任何评论吗?这不起作用。这是土生土长的。它会阻止/忽略所有requestLayout调用。
@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());
}
};