繁体   English   中英

无法在android中调整原生模块中的线性布局子项

[英]Cannot resize linear layout children in android react native module

完整代码在这里

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

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

    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.javaReactToolbar.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM