Cannot resize linear layout children in android react native module

前端 未结 4 858
清酒与你
清酒与你 2021-02-13 21:31

Full code here

Video of correct behavior in java and incorrect in react native here

I have modified a linear layout to respond to touch by resizing the left chil

4条回答
  •  一生所求
    2021-02-13 21:48

    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 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);
                }
            });
    
    
        }
    

提交回复
热议问题