3

I want to pass some data from fragment parent to dialog fragment child. The trouble is I cannot pass the data through bundle since dagger instantiates fragment dialog, so the bundle is always null. I am using dagger 2.12..

I'm new to Dagger 2, so this might be something trivial. I am still trying to wrap my head around it.

I followed this tutorial, and adopted it to suit my application. To keep it simple here is my MainFragment:

public class MainFragment extends BaseFragment {

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        this.setHasOptionsMenu(true);
        return inflater.inflate(R.layout.my_fragment, container, false);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);
        inflater.inflate(R.menu.my_menu, menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch(item.getItemId()) {
            case R.id.action_delete:
                Bundle args = new Bundle();
                args.putString("BUNDLE_TITLE_KEY", getResources().getString(R.string.dialog_delete_name));
                args.putString("BUNDLE_MESSAGE_KEY", getResources().getString(R.string.delete_message));
                addDialogFragment(new ConformationFragmentDialog(), args);
                break;
            default:
                return super.onOptionsItemSelected(item);
        }
        return true;
    }
}

Here is BaseFragment (extended by MainFragment):

public class BaseFragment extends Fragment implements HasFragmentInjector {

    @Inject
    @Named(BaseFragmentModule.CHILD_FRAGMENT_MANAGER)
    FragmentManager childFragmentManager;

    @Inject
    DispatchingAndroidInjector<Fragment> childFragmentInjector;

    @Override
    public void onAttach(Context context) {
        AndroidInjection.inject(this);
        super.onAttach(context);
    }

    @Override
    public AndroidInjector<Fragment> fragmentInjector() {
        return childFragmentInjector;
    }

    protected final void addDialogFragment(DialogFragment dialogFragment, Bundle bundle) {
        dialogFragment.setArguments(bundle);
        childFragmentManager.beginTransaction().add(dialogFragment, "Hello").commit();
    }
}

And here is ConformationFragmentDialog:

public class ConformationFragmentDialog extends DialogFragment {

    @Override
    public void onAttach(Context context) {
        AndroidInjection.inject(this);
        super.onAttach(context);
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(getActivity());
        dialogBuilder.setNegativeButton(R.string.common_odustani, new DialogInterface.OnClickListener() {
            //TODO: set title and message dynamically, bundle is null
        }).setTitle("TITLE").setMessage("MESSAGE");
        return dialogBuilder.create();
    }
}

Here are BaseFragmentModule and MainFragmentModule:

@Module
public abstract class BaseFragmentModule {
    public static final String FRAGMENT = "BaseFragmentModule.fragment";
    public static final String CHILD_FRAGMENT_MANAGER = "BaseFragmentModule.ChildFragmentManager";


    @Provides
    @Named(CHILD_FRAGMENT_MANAGER)
    static FragmentManager childFragmentManager(@Named(FRAGMENT) Fragment fragment) {
        return fragment.getChildFragmentManager();
    }
}


@Module(includes = BaseFragmentModule.class, subcomponents = ConformationFragmentDialogSubcomponent.class)
public abstract class MainFragmentModule {

    @Binds
    @IntoMap
    @FragmentKey(ConformationFragmentDialog.class)
    abstract AndroidInjector.Factory<? extends Fragment> conformationFragmentDialog(ConformationFragmentDialogSubcomponent.Builder builder);


    @Binds
    @Named(BaseFragmentModule.FRAGMENT)
    abstract Fragment fragment(UvjetListFragment uvjetListFragment);

}

At this moment, ConformationFragmentDialogModule is empty and Subcomponents are basic subcomponents.

I want ConformationFragmentDialog to be reusable in different fragments. How can I set different title and message for every fragment from which I am calling ConformationFragmentDialog, while still doing things in dagger appropriate manner?

Maddy
  • 4,525
  • 4
  • 33
  • 53
Miljac
  • 135
  • 1
  • 12

1 Answers1

0

Create a fragment using static newInstance in your ConfirmationFragmentDialog class like this

public class ConformationFragmentDialog extends DialogFragment {
    public static ConformationFragmentDialog newInstance(String title,String msg) {
        ConformationFragmentDialog fragment = new ConformationFragmentDialog();

        // Supply string input as an argument.
        Bundle args = new Bundle();
        args.putString("BUNDLE_TITLE_KEY", title);
        args.putString("BUNDLE_MESSAGE_KEY", msg);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        String title = getArguments.getStrings("BUNDLE_TITLE_KEY");
        String message = getArguments.getStrings("");
        AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(getActivity());
        dialogBuilder.setNegativeButton(
            R.string.common_odustani, 
            new DialogInterface.OnClickListener() {
                //TODO: set title and message dynamically, bundle is null
            }
        ).setTitle("TITLE").setMessage("MESSAGE");
        return dialogBuilder.create();
    }
}

Also for your MainFragment return fragment by calling newInstance method.

n.arrow001
  • 1,090
  • 3
  • 10
  • 28
  • No, I am passing those keys into bundle, yes, but they cannot be retrieved because bundle is null, there is no bundle instance present at run-time. That part of code is useless, at this moment. I only left it to show what I was trying to do. If I would try to retrieve anything from bundle, I would get NullPointerException. – Miljac Nov 13 '17 at 13:10
  • You can do something like this to Get the data in Bundle. https://stackoverflow.com/questions/15459209/passing-argument-to-dialogfragment?noredirect=1&lq=1 – Piyush Kumar Nov 13 '17 at 14:59
  • Your comment led me to the right answer. The problem was me not getting the right bundle. I was trying to get arguments from bundle `savedInstanceState` instead of with `getArguments()` method. As stated [here](https://stackoverflow.com/questions/26637213/while-passing-android-dialogfragment-arguments-oncreatedialog-bundle-agument-is) `savedInstanceState` will be available when `onSaveInstanceState` is called. Edit your answer to reflect this, and I will accept it. – Miljac Nov 21 '17 at 07:59
  • Thanks @Miljac for your input. – Piyush Kumar Nov 21 '17 at 15:21