2

Edit: Here I'm trying to use getParent() in conjuction with getChildFragmentManager().

setSchemes.java

// .getSpinnerValue() is red in the IDE, the tooltip says "cannot resolve method 'getSpinnerValue()'
FragmentTransaction fragmentTransaction = getChildFragmentManager().beginTransaction();
String parentSpinnerValue = fragmentTransaction.getParent().getSpinnerValue();

I'll have many instances of a fragment, the only thing different is the spinner value. Each of these fragments add many instances of a nested fragment on a button click. I need my nested fragments to "know" which parent fragment they belong to. So I'm wondering if there's a way for each instance of the nested fragment to call up to whatever fragment created it and get the spinner value from it.

I'm not sure if this is the kind of question that requires code, but I'll add some here for context. If any more is needed I'm happy to edit stuff in.

So, here in the parent fragment. I add the nested instances like this (this is in onCreateView):

addSet.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            ++fragIdCount2;
            FragmentManager fragmentManager = getFragmentManager();
            String fragString2 = Integer.toString(fragIdCount2);
            setSchemes frag1 = new setSchemes();
            FragmentTransaction fragmentTransaction = getChildFragmentManager().beginTransaction();
            fragmentTransaction.add(R.id.LinearLayoutChild1, frag1, fragString2);
            fragmentTransaction.commit();
            fragmentManager.executePendingTransactions();

        }
    });

In onPause I can get the spinner value like this:

Spinner exerciseSpinner = (Spinner) getView().findViewById(R.id.movementName);
    String spinnerText = exerciseSpinner.getSelectedItem().toString();

I need to be able to get that spinner value from the nested fragment instead, so once I pass all my nested instances' values into my controller object, they can carry with them what their parent fragment's spinner value is. I can then place the nested instances' in the right arrays based on what its parent's spinner value is.

Edit: So here's my code in the current state. I'll just use my real file names for ease

movementSetsRepsFrag.java (this is the parent fragment)

@Override
public void onPause() {
    super.onPause();



    Spinner exerciseSpinner = (Spinner) getView().findViewById(R.id.movementName);
    String spinnerText = exerciseSpinner.getSelectedItem().toString();



    ControllerData.getInstance().setExSpinnerValue1(spinnerText);

}

// Here's my method that I'll be calling in the nested fragment
public String getSpinnerValue(){
    Spinner exerciseSpinner = (Spinner) getView().findViewById(R.id.movementName);
    String spinnerText = exerciseSpinner.getSelectedItem().toString();

    return spinnerText;
}

setSchems.java (nested/child fragment)

@Override
public void onPause(){
    super.onPause();


    String parentSpinnerValue = ((movementSetsRepsFrag) getParentFragment()).getSpinnerValue();


    EditText setsEditText = (EditText) getView().findViewById(R.id.sets);
    EditText repsEditText = (EditText) getView().findViewById(R.id.reps);
    EditText weightEditText = (EditText) getView().findViewById(R.id.weight);


    String value = setsEditText.getText().toString() + " x " + repsEditText.getText().toString() + " @ " +
            weightEditText.getText().toString();


    ControllerData.getInstance().setEditTextValue1(value, parentSpinnerValue);

}

ControllerData.java (This is the singleton object that I'm using to store my values and perform logic on the arrays I put the values into)

String[] exArray1 = new String[15];
String[] exArray2 = new String[15];

// EXERCISE SPINNER SETTERS
// here I'm setting the spinner value to the first index of the arrays
public void setExSpinnerValue1(String text){
    if(exArray1[0] == null){
        exArray1[0] = text;
    }else if(exArray2[0] == null){
        exArray2[0] = text;
    }
}

int a1 = 1;
int b1 = 1;

// SCHEME SETTERS
// my goal here is to take in a value from setSchemes and add it to whatever array has the spinner value at exArray[0]
public void setEditTextValue1(String setSchemeValue, String parentSpinnerValue){

    if(exArray1[0].equals(parentSpinnerValue)){
        if(exArray1[a1] == null){
            exArray1[a1] = setSchemeValue;
            a1++;
        }
    }
    if(exArray2[0].equals(parentSpinnerValue)){
        if(exArray2[b1] == null){
            exArray2[b1] = setSchemeValue;
            b1++;
        }
    }
}

Results.java (here is where I display the arrays as TextViews)

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_results);

    //ControllerData getController = new ControllerData();

    LinearLayout resultsLayout = (LinearLayout) findViewById(R.id.resultsLayout);


    // array1﹕ Bench Press null
    // array2﹕ Squat 2 x 3 @ 5

    if(ControllerData.getInstance().exArray1 != null){
        for(int i = 0; i < 15; i++){
            if(ControllerData.getInstance().exArray1[i] != null){
                String exValue1 = ControllerData.getInstance().exArray1[i];
                TextView textView1 = new TextView(this);
                textView1.setText(exValue1);
                resultsLayout.addView(textView1);
            }
        }
    }if(ControllerData.getInstance().exArray2 != null){
        for(int i = 0; i < 15; i++){
            if(ControllerData.getInstance().exArray2[i] != null){
                String exValue2 = ControllerData.getInstance().exArray2[i];
                TextView textView2 = new TextView(this);
                textView2.setText(exValue2);
                resultsLayout.addView(textView2);
            }
        }

    }

    Log.d("array1", ControllerData.getInstance().exArray1[0] + " " + ControllerData.getInstance().exArray1[1]);
    Log.d("array2", ControllerData.getInstance().exArray2[0] + " " + ControllerData.getInstance().exArray2[1]);

}
therealone
  • 421
  • 10
  • 22

1 Answers1

1

Edit: Creating fragment within a fragment Here is an example of creating a fragment (grandchild) within another fragment (child) using getChildFragmentManager().

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                     Bundle savedInstanceState) {
    FragmentManager fragmentManager = getChildFragmentManager();
    GrandchildFragment grandchildFragment = new GrandchildFragment();
    fragmentManager.beginTransaction()
        .add(R.id.grandchildFragment, grandchildFragment, "GrandchildFrag")
        .commit();
    return inflater.inflate(R.layout.fragment_child, container, false);
}

End edit

I think that getParentFragment() is what you are looking for. See documentation here and here. If you have, let's say, a public routine call public String getSpinnerValue() in the parent fragment, then you can use something like the following:

String parentFragmentValue = ((ParentClass) getParentFragment()).getSpinnerValue();

The above can also be accomplished with an interface which may be cleaner.

You can also pass the value directly to the the child fragment at fragment creation time with something like this:

public ChildFragment() {
    // Required empty constructor
}

static ChildFragment newInstance(String valueInParent) {
    Bundle args;
    ChildFragment childFragment;

    childFragment= new ChildFragment();
    args = new Bundle();
    args.putString("valueInParent", valueInParent);
    childFragment.setArguments(args);
    return childFragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    String valueInParent;

    super.onCreate(savedInstanceState);
    if (getArguments() != null) {
        valueInParent= getArguments().getString("valueInParent");
    }

}

Parents can also call into the child routine which is just the reverse of the first solution above.

I hope this helps.

Cheticamp
  • 61,413
  • 10
  • 78
  • 131
  • Alright, so now I'm crashing every time I go to the results page. I'm outputting to logcat the contents of my arrays and they're returning null. Could you take a look at my edit in the main post? I'm going to post my current code using the first method you gave me – therealone May 07 '16 at 16:09
  • Tagging just to be sure you saw the comment! @Cheticamp – therealone May 08 '16 at 00:18
  • Fragments nested within fragments are permitted but there are some rules. It can be involved, but I have done it, so I know it works. See the accepted answer at http://stackoverflow.com/questions/6221763/android-can-you-nest-fragments for some good references. Make sure your code conforms to these documents. As for the null results, I suggest using the debugger to start at the top of your hierarchy and trace you calls to identify what is failing. If you find a specific intermediate issue, post it here for a look. – Cheticamp May 09 '16 at 13:34
  • Alright, so in that answer he says I can use getParent instead of getParentFragment if I have the support library. I added the v4 support library to my build.gradle file. If I replace getParentFragment in your first code suggestion with getParent, getParent is red in the IDE. In his answer he also seems to be implying that I need to use getChildFragmentManager in conjunction with getParent. So specifically, I'm confused trying to figure out " may be you need to use getChildFragmentManager() while doing fragment transaction." In my orignal post I'll add an edit showing my current attempt. – therealone May 09 '16 at 17:26
  • Not sure which "answer" you are referring to, but "getParentFragment()" is a member of "Fragment" and "getParent()" is part of "Activity." If you are calling from a fragment embedded in another fragment, you will need "getParentFragement()." You will also need "getChildFragmentManager()" for managing fragments created within another fragment. See this [link](http://developer.android.com/reference/android/app/Fragment.html#getChildFragmentManager%28%29). Other ways may be possible, but this is what is documented and works. – Cheticamp May 09 '16 at 18:52
  • "Answer" being the accepted answer of the question you linked to me. So now I think I understand that I need to use getParentFragment() because getParent() only works when targeting an Activity. I see the concept that I have to use getChildFragmentManager() for this problem, I just don't know how I'd actually implement that. It's slightly annoying that the Android docs don't come with examples – therealone May 09 '16 at 20:41