Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/229.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
无法调整android react本机模块中线性布局子项的大小_Android_Android Layout_Scroll_React Native_Android Layoutparams - Fatal编程技术网

无法调整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());
    }
};