cesardeazevedo / react-native-bottom-sheet-behavior

react-native wrapper for android BottomSheetBehavior
MIT License
1.15k stars 114 forks source link

Bottom action sheet following material style #34

Closed Noitidart closed 6 years ago

Noitidart commented 6 years ago

Following the material guidelines here - https://material.io/guidelines/components/bottom-sheets.html#bottom-sheets-modal-bottom-sheets

I am trying to create an action sheet like this:

We see it has a overlay in the back that slightly dims as it expands. And hitting that overlay hides it. May you please help me accomplish this, excuse this, I wasn't able to figure it out.

So far I got this code below, the issues:

    render() {
             <CoordinatorLayout>
                <View>
                      {/* my stuff here */}
                      <Button onPress={this.showActions} title="Show" />
                 </View>
                <BottomSheetBehavior hideable={false} ref={this.refSheet} elevation={5} style={{ position:'absolute', width:'100%' }}>
                    <View style={{backgroundColor: '#4389f2'}}>
                        <View>
                            <Icon name="invite" />
                            <Text>Invite Members</Text>
                        </View>
                        <View>
                            <Icon name="uninvite" />
                            <Text>Remove Members</Text>
                        </View>
                    </View>
                </BottomSheetBehavior>
            </CoordinatorLayout>
    }

    refSheet = el => this.sheet = el

    showActions = () => {
        this.sheet.setBottomSheetState(BottomSheetBehavior.STATE_EXPANDED);
    }
cesardeazevedo commented 6 years ago

Hi,

I'm not sure on what's going on yet, but did you tried the overlay from this approach https://github.com/cesardeazevedo/react-native-bottom-sheet-behavior/issues/27#issuecomment-314218108 ?

Noitidart commented 6 years ago

Oh wow thank you for such fast reply. I will check that out right now.

Noitidart commented 6 years ago

Oh darn, so that requires me to put an overlay background <View>, but I put the BottomSheetBehavior inside a child component on a screen, so the overlay only covers inside that child. If i move the overlay outside into screen component, it covers that. I'll have to move overlay out into immediate child of <App>.

Is this the only way? I'll for sure do it, but i was just hoping like when we show an alert() it handles the modal overlay thingy. Is this a possibility for future?

Noitidart commented 6 years ago

Exactly as this guy is offering here - https://github.com/soarcn/BottomSheet - but I prefer your module much more. And this guys isn't react-native package its raw java.

Noitidart commented 6 years ago

Here's another nice example form here - https://github.com/EstebanFuentealba/react-native-share

cesardeazevedo commented 6 years ago

I got it, and sorry to tell this, but maybe my component doesn't provide what exactly you are looking for, what are you looking for is a BottomSheetDialogFragment and not a BottomSheetBehavior

The BottomSheetDialogFragment implements exactly the behavior of Modal bottom sheets, you can a look at the differences between them at this video https://www.youtube.com/watch?v=WeaylHAwIIk

And you might be wondering the difference between them, and indeed, they are actually very similar, but the BottomSheetBehavior doesn't provide any overlay for you, and allows you interact together with the background, peaking and some others features, and the BottomSheetDialogFragment inherits a DialogFragment, and it will behave more like an alert(), which is what you are looking for.

And you also might be wondering if you can achieve a model bottom sheet with this component (which you already found it anyway), and i would say maybe...

As you can see, you are going to implement a few things from scratch, such as the overlay stuff, and Animating Views on react-native side, and i can't say how perfect it could be compared to the native implementation of BottomSheetDialogFragment.

Even though the BottomSheetBehavior is more complex than the BottomSheetDialogFragment and has a different purpose, i've no plans to support or write a module for BottomSheetDialogFragment at the moment, i am only maintaining those packages to work properly with future versions of react-native.

The best way would be to wrap soarcn/BottomSheet or even BottomSheetDialogFragment directely into react-native, which is a little bit of more work than implementing an overlay view, but it would be certely possible tough.

Maybe react-native-share could work better for this purposed, but i haven't tried it yet, even though they use a very simple js implementation which is indeed a very simple effect to achieve with the Animation API, i personally wouldn't use my package for this purposed, there's a few use cases that would makes more sense (such as interation with the background), maybe my package can bloat your project for just a simple effect that you can achieve with a few lines.

I hope it helps, even though it doesn't help you at all.

Noitidart commented 6 years ago

Oh wow thank you sir very much for such an in-depth reply. I really really appreciate it. I wish I could have used your module, yours is done so nicely, so nicely thought out. I'll close this topic then. Thanks again very very much for everything! Thanks for leaving this open for me to close even.

Noitidart commented 6 years ago

Oh by any chance do you have any references a newbie to java and native react modules can look at? I was thinking of trying to create BottomSheetDialogFragment with a custom <View> in it from react-native. That way people can create the grid like view, or the row views in there. So it's a mix of an overlay and non-overlay module.

cesardeazevedo commented 6 years ago

Thanks for your interest in creating a BottomSheetDialogFragment, maybe you can get something working with a few native code, and believe, most of them are boilerplate.

Creating the BottomSheetBehavior was one of the most hardest and chalenge things that i ever made, and i didn't had much experience with react-native native code, it took me a whole week hacking around and understanding how the things work, and stackoverflow didn't help (see), there's isn't much interest of react-native comunity in general about native components, and most of the js based components are prefered, just because they are cross plataform, but the result are just "fake components" that doesn't a give a native fell, but there are some good components out there, so i can't judge.

So here is some guide.

  1. Don't be afraid if you don't have expirience with the native side of the force, it will only empower you to develop better apps.

  2. Try to find some native open source project that implements BottomSheetDialogFragment, and try to understand how it works before expose those things on the react-native (i played and hacked a lot when wrapping the anchor point implementation)

Here is very simple get started. MainActivity.java MyBottomSheetDialogFragment.java

  1. Try to think how you would like the API on the react-native side, BottomSheetDialogFragment is managed from java code directly, and not from xml, we just inflate the BottomSheet content from a xml layout, so, this leaves us with a NativeModule API, but we will need to connect a custom renders by somehow, NativeComponent, could work as well, if we want a more declarative approach, which would be more convinient to work with custom renders.

Which maybe give us two possibilites that came on my mind.

NativeModule

componentDidMount() {
  RNBottomSheetDialogFragment.open(this.customRender);
}

renderCustomRender() {
  return (
    <View ref={ref => this.customRender}>
      <Text>Content</Text>
    </View>
  )
}

NativeComponent

render() {
  return (
    <RNBottomSheetDialogFragment open={true}>
       <View><Text>Content</Text></View>
    </RNBottomSheetDialogFragment>
  )
}

I can't say yet which of them would be apropriate, but i would move forward with NativeComponet since we don't need to pass a node reference manually over the bridge, but it can't work with NativeComponent directly since BottomSheetDialogFragment doesn't inherits any ViewGroup and react-native wouldn't allow us to extend a ViewGroupManager<BottomSheetDialogFragment>, but maybe inherits a dummy ViewGroup and manage the BottomSheetDialogFragment aside could work, so we could make the things more declarative, i think both of them could be implemented though.

  1. Implement the Manager (BottomSheetDialogFragmentManager.java), and make the use of @ReactMethod or @ReactProp, it really going to depent if you are using NativeModules or NativeComponent, and implement the open functionality.

  2. Inflate the BottomSheetDialogFragment content by somehow, maybe overriding the addView method to inflate the child (i just can't think in something else now :joy:)

  3. Expose whatever you need on the javascript side, just take a look at these js files https://github.com/cesardeazevedo/react-native-bottom-sheet-behavior/tree/master/lib, most of them are very simple.

This is a very superficial overview, lots of things may be missing or wrong.

About references, the NativeModules and Native UI Components is very good get started, but it will only help you on the react-native api and how to connect the native side with react, and won't help you at all with the BottomSheetDialogFragment itself, the best way to handle that is looking for android tutorials and open source android projects, that i mentioned, once you are familiar with the android side, you are good to go to expose it to react-native.

If you are really want to try this, i would recomend started with react-native-create-library to reduce the boilerplate, if you create a repository with it, i can might help you on my spare time.

Noitidart commented 6 years ago

Wow wow thank you very much sir! I strongly agree with you:

but the result are just "fake components" that doesn't a give a native fell,

I strongly agree that the pure js components are "fake". I really feel an immense difference, especially on the older devices.

I will read carefully through your generous reply here and your stackoverflow topic and try to make a PR for BottomSheetDialogFragment to this module! :) Or we can keep it seperate whatever you prefer. :)

Thank you sir!

cesardeazevedo commented 6 years ago

I think a separate repo would be more appropriate, this repo is already too much specifically to BottomSheetBehavior (and starting with the name), and after implementing anchor point, it became too big, so, i can't handle more functionality right now.

Noitidart commented 6 years ago

Roger that, for sure I'll keep it seperate then. :) Thanks for your support brother!