【问题标题】:If I'm in a nested fragment, how can I get a value from whatever fragment is the parent?如果我在嵌套片段中,我如何从父片段中获取值?
【发布时间】:2016-05-07 02:05:43
【问题描述】:

编辑:在这里,我尝试将 getParent() 与 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();

我会有很多片段实例,唯一不同的是微调器值。这些片段中的每一个都会在单击按钮时添加许多嵌套片段的实例。我需要我的嵌套片段来“知道”它们属于哪个父片段。所以我想知道嵌套片段的每个实例是否有办法调用创建它的任何片段并从中获取微调器值。

我不确定这是否是需要代码的问题,但我会在此处添加一些以作为上下文。如果需要更多内容,我很乐意在其中进行编辑。

所以,在父片段中。我像这样添加嵌套实例(这是在 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();

        }
    });

在 onPause 中,我可以像这样获得微调器值:

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

我需要能够从嵌套片段中获取该微调器值,因此一旦我将所有嵌套实例的值传递到我的控制器对象中,它们就可以随身携带其父片段的微调器值。然后,我可以根据其父级的微调器值将嵌套实例'放置在正确的数组中。

编辑:这是我当前状态下的代码。为了方便起见,我将使用我的真实文件名

movementSetsRepsFrag.java(这是父片段)

@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(嵌套/子片段)

@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(这是我用来存储我的值并在我将值放入的数组上执行逻辑的单例对象)

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(这里是我将数组显示为 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]);

}

【问题讨论】:

  • 你误用了片段......!!!
  • 我是如何“滥用片段”的?

标签: java android android-fragments


【解决方案1】:

编辑:在片段中创建片段 这是使用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);
}

结束编辑

我认为getParentFragment() 是您正在寻找的。请参阅文档 here 和 here。如果您在父片段中有一个公共例程调用public String getSpinnerValue(),那么您可以使用如下内容:

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

以上也可以通过一个可能更干净的界面来完成。

您还可以在片段创建时将值直接传递给子片段,如下所示:

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");
    }

}

父母也可以调用与上述第一个解决方案相反的子例程。

我希望这会有所帮助。

【讨论】:

  • 好吧,现在我每次进入结果页面都会崩溃。我正在向 logcat 输出我的数组的内容,它们返回 null。你能看看我在主帖中的编辑吗?我将使用您给我的第一种方法发布我当前的代码
  • 标记只是为了确保您看到了评论! @Cheticamp
  • 允许嵌套在片段中的片段,但有一些规则。它可以参与,但我已经做到了,所以我知道它有效。请参阅stackoverflow.com/questions/6221763/… 接受的答案以获得一些好的参考。确保您的代码符合这些文档。至于空结果,我建议使用调试器从层次结构的顶部开始并跟踪您的调用以识别失败的原因。如果您发现特定的中间问题,请在此处发布以查看。
  • 好吧,所以在那个答案中,他说如果我有支持库,我可以使用 getParent 而不是 getParentFragment。我将 v4 支持库添加到我的 build.gradle 文件中。如果我将您的第一个代码建议中的 getParentFragment 替换为 getParent,则 getParent 在 IDE 中为红色。在他的回答中,他似乎还暗示我需要将 getChildFragmentManager 与 getParent 结合使用。所以具体来说,我很困惑试图弄清楚“在进行片段事务时可能需要使用 getChildFragmentManager() 。”在我的原始帖子中,我将添加一个显示我当前尝试的编辑。
  • 不确定您指的是哪个“答案”,但“getParentFragment()”是“Fragment”的成员,“getParent()”是“Activity”的一部分。如果您从嵌入在另一个片段中的片段调用,则需要“getParentFragement()”。您还需要“getChildFragmentManager()”来管理在另一个片段中创建的片段。请参阅此link。其他方式可能是可能的,但这是记录在案并且有效的方式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-08
  • 2014-06-02
  • 1970-01-01
相关资源
最近更新 更多