0

我正在开发一个带有片段的 Android 3.1 平板电脑应用程序。

我已经看到只有两个片段同时在内存中。当我显示第三个时,第一个调用onDestroyView.

EditText以编程方式添加到片段的视图中。EditText在片段的视图重新创建onResume方法后,那些不再显示。

我使用它们EditText让用户将数据添加到表单中,并将引用存储在firstTable HashMap. 我将使用它HashMap来检索用户的值。

EditText在这里,我以编程方式创建这些:

private LinearLayout createNewFirstTableRow(long articleId)
{
    LinearLayout layout = new LinearLayout(mActivity);
    LayoutParams parentParams = new LayoutParams(LayoutParams.MATCH_PARENT, 40);
    parentParams.weight = 1;
    layout.setLayoutParams(parentParams);

    if (firstTable == null)
        firstTable = new HashMap<Long, ArrayList<EditText>>();

    ArrayList<EditText> fields = new ArrayList<EditText>(7);

    LayoutParams params = new LayoutParams(0, 40);
    params.weight = 0.125f;

    TextView textView = new TextView(mActivity);
    textView.setLayoutParams(params);
    textView.setText(new Long(articleId).toString());
    layout.addView(textView);

    for (int i = 0; i < 7; i++)
    {
        EditText edit = new EditText(mActivity);
        edit.setLayoutParams(params);
        edit.setInputType(InputType.TYPE_CLASS_NUMBER);
        fields.add(i, edit);
        layout.addView(edit);
    }

    firstTable.put(new Long(articleId), fields);

    return layout;
}

firstTable变量是一个全局变量:private HashMap<Long, ArrayList<EditText>> firstTable;.

要添加我的EditText我,请执行以下操作onResume

@Override
public void onResume()
{
    Log.v("QuantityFragment", "onResume: " + firstTableRowIndex);

    if ((firstTable != null) && (secondTable != null))
    {
        firstTableRowIndex = FIRST_TABLE_ROW_INDEX;
        secondTableRowIndex = SECOND_TABLE_ROW_INDEX;

        LinearLayout table = (LinearLayout)view.findViewById(R.id.quantityTable);

        for (int index = 0; index < firstTable.size(); index++)
        {
            Long articleId = articleIds.get(index);

            table.addView(resumeTable(articleId, secondTable.get(articleId)), secondTableRowIndex);
            table.addView(resumeTable(articleId, firstTable.get(articleId)), firstTableRowIndex);

            firstTableRowIndex++;
            secondTableRowIndex++;
        }
    }

    super.onResume();
}

private LinearLayout resumeTable(Long articleId, ArrayList<EditText> fields)
{
    LinearLayout layout = new LinearLayout(mActivity);
    LayoutParams parentParams = new LayoutParams(LayoutParams.MATCH_PARENT, 40);
    parentParams.weight = 1;
    layout.setLayoutParams(parentParams);


    LayoutParams params = new LayoutParams(0, 40);
    params.weight = 0.125f;

    TextView textView = new TextView(mActivity);
    textView.setLayoutParams(params);
    textView.setText(new Long(articleId).toString());
    layout.addView(textView);

    for (int index = 0; index < fields.size(); index++)
    {
        layout.addView(fields.get(index));
    }

    return layout;
}

但是,在这里layout.addView(textView);我得到一个例外:

IllegalStateException:指定的孩子已经有一个父母。您必须首先在孩子的父母上调用 removeView()。

有没有另一种方法来重新添加这些EditText

更新:

我已经解决了我的问题改变resumeTable

private LinearLayout resumeTable(Long articleId, ArrayList<EditText> fields)
{
    LinearLayout layout = new LinearLayout(mActivity);
    LayoutParams parentParams = new LayoutParams(LayoutParams.MATCH_PARENT, 40);
    parentParams.weight = 1;
    layout.setLayoutParams(parentParams);


    LayoutParams params = new LayoutParams(0, 40);
    params.weight = 0.125f;

    TextView textView = new TextView(mActivity);
    textView.setLayoutParams(params);
    textView.setText(new Long(articleId).toString());
    layout.addView(textView);

    for (int index = 0; index < fields.size(); index++)
    {
        LinearLayout parent = (LinearLayout)fields.get(index).getParent();
        parent.removeView(fields.get(index));
        layout.addView(fields.get(index));
    }

    return layout;
}

这是重要的部分:

    for (int index = 0; index < fields.size(); index++)
    {
        LinearLayout parent = (LinearLayout)fields.get(index).getParent();
        parent.removeView(fields.get(index));
        layout.addView(fields.get(index));
    }

这个问题是开放的,如果您有更好的解决方案,请告诉我。

4

2 回答 2

2

抛出该异常是因为您存储了对添加到布局中的Views(the EditText) 的引用,然后您再次将这些引用重新添加Views到新构造的父级中。

关于解决方案,我不知道您为什么决定存储对那些EditTexts. 我认为值得存储的唯一数据EditTexts是用户输入的文本,在这种情况下,您应该存储该文本而不是那个特定的EditText.Your 方法是:

//...
if (firstTable == null) {
    // your HashMap now stores text instead of an EditText
    firstTable = new HashMap<Long, ArrayList<String>>();// store only the text from the EditText
}

    ArrayList<String> fields = new ArrayList<String>(7);
    LayoutParams params = new LayoutParams(0, 40);
    params.weight = 0.125f;

    TextView textView = new TextView(mActivity);
    textView.setLayoutParams(params);
    textView.setText(new Long(articleId).toString());
    layout.addView(textView);

    for (int i = 0; i < 7; i++) {
        EditText edit = new EditText(mActivity);
        edit.setLayoutParams(params);
        edit.setInputType(InputType.TYPE_CLASS_NUMBER);
        fields.add(i, ""); // the EditText are empty at first
        layout.addView(edit);
    }
    firstTable.put(new Long(articleId), fields);

那么什么时候可以恢复EditTexts

private LinearLayout resumeTable(Long articleId, ArrayList<String> fields) {
    LinearLayout layout = new LinearLayout(mActivity);
    LayoutParams parentParams = new LayoutParams(LayoutParams.MATCH_PARENT, 40);
    parentParams.weight = 1;
    layout.setLayoutParams(parentParams);
    LayoutParams params = new LayoutParams(0, 40);
    params.weight = 0.125f;
    TextView textView = new TextView(mActivity);
    textView.setLayoutParams(params);
    textView.setText(new Long(articleId).toString());
    layout.addView(textView);
    for (int index = 0; index < fields.size(); index++) {
        // create new EditTexts
        EditText edit = new EditText(mActivity);
        edit.setLayoutParams(params);
        edit.setInputType(InputType.TYPE_CLASS_NUMBER);
        edit.setText(fields.get(index)); // get the text coresponding to this particular EditText
        layout.addView(edit);
    }
    return layout;
}

当然,当用户在其中输入内容时,EditTexts您应该将其存储在firstTable变量中正确位置的位置。

于 2012-06-26T10:19:28.003 回答
0

我认为问题是由于两次添加字段元素

 ArrayList<EditText> fields = new ArrayList<EditText>(7);

1 - 在 createNewFirstTableRow

for (int i = 0; i < 7; i++)
    {
        EditText edit = new EditText(mActivity);
        edit.setLayoutParams(params);
        edit.setInputType(InputType.TYPE_CLASS_NUMBER);
        fields.add(i, edit);//<-----------
        layout.addView(edit);//<----------- added in layout 
    }

2- onResume()->resumeTable

for (int index = 0; index < fields.size(); index++)
    {
        layout.addView(fields.get(index));//<----------------
    }

当字段元素已经添加到屏幕上时,您不能添加两次.......

于 2012-06-26T10:01:30.860 回答