2016-08-12 13 views
12

Pisałem natywny moduł Android, który owija BottomSheetBehavior.Owijarka klasy React-native dla CoordinatorLayout i BottomSheetBehavior

bardzo prosty BottomSheetBehavior mogą być realizowane jak to https://gist.github.com/cesardeazevedo/a4dc4ed12df33fe1877fc6cea42475ae

pierwszą rzeczą, że wychodził, cała strona musi być dzieckiem CoordinatorLayout i BottomSheetBehavior na koniec.

Musiałem więc napisać 2 rodzime moduły, <CoordinatorLayout /> i <BottomSheetBehavior />.

To jest opakowanie bottomSheetBehavior.

BottomSheetBehaviorManager.java

public class BottomSheetBehaviorManager extends ViewGroupManager<BottomSheetBehaviorView> { 

    @Override 
    public BottomSheetBehaviorView createViewInstance(ThemedReactContext context) { 
     return new BottomSheetBehaviorView(context); 
    } 
} 

BottomSheetBehaviorView.java

public class BottomSheetBehaviorView extends RelativeLayout { 

    public BottomSheetBehaviorView(Context context) { 
     super(context); 

     int width = ViewGroup.LayoutParams.WRAP_CONTENT; 
     int height = ViewGroup.LayoutParams.WRAP_CONTENT; 
     // int height = 1000; // fixed a height works, it only slide up half of the screen 

     CoordinatorLayout.LayoutParams params = new CoordinatorLayout.LayoutParams(width, height); 
     params.setBehavior(new BottomSheetBehavior()); 
     this.setLayoutParams(params); 

     BottomSheetBehavior<BottomSheetBehaviorView> bottomSheetBehavior = BottomSheetBehavior.from(this); 
     bottomSheetBehavior.setHideable(false); 
     bottomSheetBehavior.setPeekHeight(200); 
    } 
} 

A mój reaguje składnik stały się w ten sposób.

index.android.js

return() { 
    <CoordinatorLayout style={{flex: 1}}> 
     <View><!--app--></View> 
     <BottomSheetBehavior> 
     <View style={{height: 300}}> <!--height doesnt work--> 
      <Text>BottomSheetBehavior !</Text> 
     </View> 
     </BottomSheetBehavior> 
    </CoordinatorLayout> 
) 

i to działa!

react-native-bottomsheet-behavior

ale ja zmaga aby BottomSheet owinąć swoje Childs z wrap_content, to nie miało przesunąć cały ekran, należy go tylko ślizgać się przez zawiniętego treści (w tym przypadku ipsum lorem tekst), działa z komponentami systemu Android, ale nie działa z komponentami reagowania. A zatem, jak sprawić, by RelativeLayout zawijał komponent reagujący na siebie? Próbowałem również wdrożyć niektóre measure shadownode, ale nie działało zgodnie z oczekiwaniami, nie wiem, jak działają.

Dodałem ten przykład na moim githubie, aby wszyscy chcieli go wypróbować. https://github.com/cesardeazevedo/react-native-bottom-sheet-behavior

Odpowiedz

3

Po wielu debugowania, w końcu mam go, musiałem zrobić 2 rzeczy, najpierw było zastąpić funkcję onMeasure i zastosować wysokość dziecko do setMeasuredDimension i najwyraźniej stała się kwestią wysokości, ale po rozegraniu trochę, każda zmiana stanu łamie pozycję dolnego arkusza, więc musiałem wywołać requestLayout dla każdej zmiany stanu przez UIManager.dispatchViewManagerCommand i działa bardzo dobrze.

To jest implementacja, która naprawia.

commit

BottomSheetBehaviorView.js

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
    View child = this.getChildAt(0); 

    if (child != null) { 
     setMeasuredDimension(widthMeasureSpec, child.getHeight()); 
    } 
} 

BottomSheetBehaviorManager.js

@Override 
public Map<String, Integer> getCommandsMap() { 
    return MapBuilder.of("setRequestLayout", COMMAND_SET_REQUEST_LAYOUT); 
} 

@Override 
public void receiveCommand(BottomSheetBehaviorView view, int commandType, @Nullable ReadableArray args) { 
    if (commandType == COMMAND_SET_REQUEST_LAYOUT) { 
     setRequestLayout(view); 
    } 
} 

private void setRequestLayout(BottomSheetBehaviorView view) { 
    view.requestLayout(); 
} 

BottomSheetBehavior.js

componentDidUpdate() { 
    UIManager.dispatchViewManagerCommand(
     findNodeHandle(this), 
     UIManager.RCTBottomSheetBehaviorAndroid.Commands.setRequestLayout, 
     [], 
    ) 
    } 

Aktualizacja

zdałem sobie sprawę, że aktualizacja stanu, przesuwając miga cały układ, po spojrzeniu trochę kodu bibliotek, znalazłem funkcję needsCustomLayoutForChildren, który jest opisany na ViewGroupManager.java

/** 
    * Returns whether this View type needs to handle laying out its own children instead of 
    * deferring to the standard css-layout algorithm. 
    * Returns true for the layout to *not* be automatically invoked. Instead onLayout will be 
    * invoked as normal and it is the View instance's responsibility to properly call layout on its 
    * children. 
    * Returns false for the default behavior of automatically laying out children without going 
    * through the ViewGroup's onLayout method. In that case, onLayout for this View type must *not* 
    * call layout on its children. 
    */ 
    public boolean needsCustomLayoutForChildren() { 
    return false; 
    } 

Tak więc fixed zwraca true na CoordinatorLayoutManager.java

Oto jak to wygląda.

react-native-bottom-sheet-behavior

+0

Wow wow absolutnie niesamowite podziękować panu za podzielenie się postaram to i zrobić PR z 'BottomSheetFragment'! :) – Noitidart

Powiązane problemy