2016-10-03 7 views
4

아주 간단한 네이티브 Android UI 구성 요소를 구축했으며 반응하는 네이티브 프로젝트의 단추를 클릭 할 때 하위 뷰의 크기를 업데이트하려고합니다. 더 정확히 말하면,이 버튼을 클릭하면 내 SimpleViewManager에 명령을 보내고, 다시 내 사용자 정의보기의 resizeLayout()을 호출합니다.React Native : 사용자 지정 UI 구성 요소 크기 조정

resizeLayout()이 제대로 호출되었지만 전화를 돌릴 때까지 레이아웃이 으로 변경되지 않았는지 확인할 수 있습니다. 분명히 장치의 방향을 변경하면 draw()이 내 사용자 정의보기로 표시되지만 암시 적으로 호출하는 invalidate()도 마찬가지입니다.

크기 조정 대신 배경색을 변경하는 등 레이아웃을 변경하면 문제가 없습니다.

public class CustomComponent extends RelativeLayout { 
    public CustomComponent(Context context) { 
     super(context); 
     init(); 
    } 

    public CustomComponent(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     init(); 
    } 

    public CustomComponent(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 
     init(); 
    } 

    private void init() { 
     inflate(getContext(), R.layout.simple_layout, this); 
    } 

    public void resizeLayout(){ 
     LinearLayout childLayout = (LinearLayout) findViewById(R.id.child_layout); 
     RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) childLayout.getLayoutParams(); 
     layoutParams.height = 50; 
     layoutParams.width= 50; 
     childLayout.setLayoutParams(layoutParams); 

     invalidate(); 
    } 
} 

을하고 simple_layout.xml은 다음과 같습니다 :

내 사용자 지정 구성 요소는 다음과 같습니다

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/root_layout" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <LinearLayout 
     android:id="@+id/child_layout" 
     android:layout_width="100dp" 
     android:layout_height="50dp" 
     android:background="#ffee11"/> 
</RelativeLayout> 

어떤 도움을 주시면 감사하겠습니다.

답변

8

며칠 동안 검색 한 결과 드디어 this에 대한 응답이 반응 네이티브의 repo에 대한 이전보고 된 문제로 나타났습니다.

이 솔루션은 ReactPicker.javaReactToolbar.java에서 사용 된 것과 같습니다. 내 CustomComponent에 다음 코드를 넣어야하고 이후에는 requestLayout() 또는 invalidate()을 호출 할 필요가 없습니다. 변경 사항은 레이아웃의 LayoutParams를 업데이트하자마자 전파됩니다.

@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()); 
    } 
}; 
+0

감사합니다. 계층에서 업데이트되지 않는 custom-added-using-java 뷰의 문제를 해결할 수 있도록 도와주었습니다. (위의 메소드 오버라이드를 사용하여 컨테이너에 사용자 정의 뷰를 놓습니다.) – Venryx

+0

사실, 제 경우에는 분명히 한 가지 더 나아가 야합니다. 위의 컨테이너 뷰 (RelativeLayout에서 상속받은)를 추가 한 후''container.layout (0, 0, 너비, 높이);'''. – Venryx

+0

ReactNative 앱의 requestLayout이별로 유용하지 않기 때문에이 라이브러리가 폭넓게 도움이되었습니다. 라이브러리의 너비는 0, 높이 : 0입니다. 현상금 추가하기. –

0

대신 무효화의

requestLayout(); 

을 실행 해보십시오.

이 게시물에는보기 수명주기에 대한 유용한 정보도 있습니다. 그건 당신이 무엇인지 않는 한

Usage of forceLayout(), requestLayout() and invalidate()

는 또한,

<merge> 

당신의 CustomComponent 클래스가 바로 자식으로 RelativeLayout의를하지 않는 방법으로보기 XML의 루트 요소를 변경하는 것이 좋습니다 하기 위해 가다.

+0

안녕하십니까. 답변 해 주셔서 감사합니다. 실제로는 ''을 사용하는 것이 좋습니다. 그러나, 나는 이미 위의 모든 메소드를 내 CustomComponent와 childLayout 모두에서 호출 해 보았습니다. 코드는 Android 프로젝트에서 잘 작동합니다. React Native와 함께 사용하면 문제가 나타납니다. – George

관련 문제