amorenew / FlutterBlocFragment

5 stars 0 forks source link

passing parameteres for fragments #5

Closed pishguy closed 5 years ago

pishguy commented 5 years ago

i want to pass some parameters for fragments. with this implementation we can't and i want to know whats best solution about this issue

amreniouinnovent commented 5 years ago

@MahdiPishguy check how I pass the title and make instead of String a Map<String, dynamic>

pishguy commented 5 years ago

@amreniouinnovent my mean is passing parameter between fragments

amreniouinnovent commented 5 years ago

@MahdiPishguy same like the title it could be added to the event in FragmentManager().addFragment(event.routeName); could update data too

    if (event is FragmentNavigateEvent) {
      if (!FragmentManager().isExist(event.routeName)) {
        FragmentManager().addFragment(event.routeName);
      }
      final int currentIndex =
          FragmentManager().navigateToName(event.routeName);
      print('bloc currentIndex:$currentIndex');
      yield FragmentCurrentState(currentIndex);
pishguy commented 5 years ago

@amreniouinnovent i'm not sure for this implementation, because i have more parameter, not only single parameter, whats your idea?

amreniouinnovent commented 5 years ago

@MahdiPishguy here you will add a parameter like a title in the fragment interface and fragment 1 https://github.com/amorenew/FlutterBlocFragment/blob/master/lib/fragments/fragment1.dart and same like int navigateToName(String fragmentName) { } you can make updateData(String fragmentName,dynamic data)

amreniouinnovent commented 5 years ago

more than value could be Map<String,dynamic>

pishguy commented 5 years ago

@amreniouinnovent thanks, i check that

pishguy commented 5 years ago

@MahdiPishguy same like the title it could be added to the event in FragmentManager().addFragment(event.routeName); could update data too

    if (event is FragmentNavigateEvent) {
      if (!FragmentManager().isExist(event.routeName)) {
        FragmentManager().addFragment(event.routeName);
      }
      final int currentIndex =
          FragmentManager().navigateToName(event.routeName);
      print('bloc currentIndex:$currentIndex');
      yield FragmentCurrentState(currentIndex);

i don't understood how can i pass value

amreniouinnovent commented 5 years ago

@MahdiPishguy in navigateToName there is a for loop once you catch the matched fragment pass the value to it

(value.child as Fragment).setData(value );

 _fragments.asMap().forEach((int index, Widget value) {
      if (value is Fragment && value.getRouteName() == fragmentName) {
        fragmentIndex = index;
      } else if (value is BlocProvider &&
          value.child is Fragment &&
          (value.child as Fragment).getRouteName() == fragmentName) {
        fragmentIndex = index;
      } else if (value is MultiBlocProvider &&
          value.child is Fragment &&
          (value.child as Fragment).getRouteName() == fragmentName) {
        fragmentIndex = index;
      }
    });
pishguy commented 5 years ago

@amreniouinnovent your mean is i should use switch() statement?

amreniouinnovent commented 5 years ago

@MahdiPishguy No. just in navigateToName pass your data as a new parameter then inside the existing for loop use (value.child as Fragment).setData(value );

amreniouinnovent commented 5 years ago

so Navigation Event have new data parameter then navigateToName passing the data to the Fragment

don't forget to add a data field to Fragment interface.

pishguy commented 5 years ago

@amreniouinnovent i'm sorry i don't know how can i implementing that

amreniouinnovent commented 5 years ago

@MahdiPishguy I am so busy currently try to use singleton class if it is urgent

pishguy commented 5 years ago

@amreniouinnovent i get null i'm not sure my code is correct:

https://github.com/MahdiPishguy/FlutterBlocFragmentTest

  int navigateToName(String fragmentName) {
    int fragmentIndex = -1;
    print('manager navigateToName:$fragmentIndex');

    _fragments.asMap().forEach((int index, Widget value) {
      if (value is Fragment && value.getRouteName() == fragmentName) {
        fragmentIndex = index;
      } else if (value is BlocProvider && value.child is Fragment && (value.child as Fragment).getRouteName() == fragmentName) {
        fragmentIndex = index;
        (value.child as Fragment).setData((value.child as Fragment).getParameter());
      } else if (value is MultiBlocProvider && value.child is Fragment && (value.child as Fragment).getRouteName() == fragmentName) {
        fragmentIndex = index;
        (value.child as Fragment).setData((value.child as Fragment).getParameter());
      }
    });
    print('manager navigateToName:$fragmentIndex');
    _backstack.add(fragmentIndex);
    _currentIndex = fragmentIndex;
    return fragmentIndex;
  }

Fragment1

class Fragment1 extends StatefulWidget implements Fragment {
  String myname;
  @override
  State<Fragment1> createState() => _Fragment1();

  ...

  @override
  String getParameter() {
    return 'aaaaaaaa';
  }

  @override
  void setData(String value) {
    myname = value;
  }
}

Fragment

abstract class Fragment extends Widget{
  String getRouteName();
  String getTitle();
  String getParameter();

  void setData(String value) {}
}
amreniouinnovent commented 5 years ago

@MahdiPishguy could you pass a fixe value variable if it works then add parameter to navigateToName(String fragmentName)

pishguy commented 5 years ago

@amreniouinnovent

i get null again if i understand whats your mean

(value.child as Fragment).setData('11111');
amreniouinnovent commented 5 years ago

@MahdiPishguy if I got time I will add this implementation

pishguy commented 5 years ago

@amreniouinnovent can you got free time to help me today?

amreniouinnovent commented 5 years ago

@MahdiPishguy I have to deliver this week a new release so it too hard to support this week

amreniouinnovent commented 5 years ago

@MahdiPishguy you can use a singleton class for now

class GlobalData {
  factory GlobalData() => _instance ??= new GlobalData._();
  GlobalData._();
  //One instance, needs factory
  static GlobalData _instance;

  bool isDriverTablet = false;
}

Usage: GlobalData().isDriverTablet

pishguy commented 5 years ago

@amreniouinnovent

@MahdiPishguy you can use a singleton class for now

class GlobalData {
  factory GlobalData() => _instance ??= new GlobalData._();
  GlobalData._();
  //One instance, needs factory
  static GlobalData _instance;

  bool isDriverTablet = false;
}

Usage: GlobalData().isDriverTablet

I get stackoverflow error

amreniouinnovent commented 5 years ago

@MahdiPishguy StackOverflow is related to your logic you call nested calls over and over

pishguy commented 5 years ago

@amreniouinnovent maybe, because i use that whenever i need to pass data :(

pishguy commented 5 years ago

@amreniouinnovent hi,

can you got free time to help me how can i implementing this feature?

thanks in advance

amreniouinnovent commented 5 years ago

@MahdiPishguy check the latest commit I added an example for passing the parameter confirm if it works

pishguy commented 5 years ago

@amreniouinnovent thank you very much

amreniouinnovent commented 5 years ago

@MahdiPishguy You are welcome