Fragment Activity中的IllegalStateException

时间:2013-05-03 09:46:14

标签: android android-fragments android-fragmentactivity illegalstateexception

我有一个代表客户信息的FragmentActivity类;在这个类中,我有两个用于Fragment和Fragment Adapter的内部类。以下是我的代码:

public class CustomerInfoFragmentActivity extends FragmentActivity implements     OnClickListener, OnItemSelectedListener, OnCheckedChangeListener, OnSeekBarChangeListener,     OnPageChangeListener
{
public static final String  FORM_NAME       = "Customer Information";
private static final String TAG             = "CustomerInfoFragmentActivity";
private static final int    TIME_DIALOG_ID  = 0;
private static final int    DATE_DIALOG_ID  = 1;
// No. of pages to be loaded in pager; make sure this is accurate
private static int          PAGE_COUNT      = 4;
private ServerService       serverService;
// Form entry date
Calendar                    formDate;
// Layout view containing navigation bar and buttons
LinearLayout                navigatorLayout;
Button                      firstButton;
Button                      lastButton;
Button                      formDateButton;
Button                      saveButton;
Button                      clearButton;
SeekBar                     navigationSeekbar;
// View pager that holds all the pages generated dynamically
ViewPager                   pager;
// Views displayed in pages, sorted w.r.t. appearance on pager
TextView                    phone1TextView;
EditText                    phone1;
TextView                    phone1OwnerTextView;
CheckBox                    phone1Owner;
EditText                    phone1OwnerName;
TextView                    phone2TextView;
EditText                    phone2;
TextView                    phone2OwnerTextView;
CheckBox                    phone2Owner;
EditText                    phone2OwnerName;
TextView                    address;
EditText                    address1;
EditText                    address2;
EditText                    landmark;
EditText                    town;
EditText                    patientId;
Button                      scanBarcode;
// ArrayList to hold all the linear layouts - 1 for each page
ArrayList<ViewGroup>        groups;
View[]                      views;

class CustomerInfoFragment extends Fragment
{
    int currentPage;

    @Override
    public void onCreate (Bundle savedInstanceState)
    {
        super.onCreate (savedInstanceState);
        Bundle data = getArguments ();
        currentPage = data.getInt ("current_page", 0);
    }

    @Override
    public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        // Return a layout of views from pre-filled ArrayList of groups
        if (currentPage != 0 && groups.size () != 0)
            return groups.get (currentPage - 1);
        else
            return null;
    }
}

class CustomerInfoFragmentPagerAdapter extends FragmentPagerAdapter
{
    /** Constructor of the class */
    public CustomerInfoFragmentPagerAdapter (FragmentManager fragmentManager)
    {
        super (fragmentManager);
    }

    /** This method will be invoked when a page is requested to create */
    @Override
    public Fragment getItem (int arg0)
    {
        CustomerInfoFragment fragment = new CustomerInfoFragment ();
        Bundle data = new Bundle ();
        data.putInt ("current_page", arg0 + 1);
        fragment.setArguments (data);
        return fragment;
    }

    /** Returns the number of pages */
    @Override
    public int getCount ()
    {
        return PAGE_COUNT;
    }
}

@Override
protected void onCreate (Bundle savedInstanceState)
{
    super.onCreate (savedInstanceState);
    setContentView (R.layout.template);
    serverService = new ServerService (getApplicationContext ());
    formDate = Calendar.getInstance ();
    createViews (this);
    initView (views);
    updateDisplay ();
}

public void createViews (Context context)
{
    // Create fixed views
    formDateButton = (Button) findViewById (R.template_id.formDate);
    firstButton = (Button) findViewById (R.template_id.firstButton);
    lastButton = (Button) findViewById (R.template_id.lastButton);
    clearButton = (Button) findViewById (R.template_id.clearButton);
    saveButton = (Button) findViewById (R.template_id.saveButton);
    navigationSeekbar = (SeekBar) findViewById (R.template_id.navigationSeekbar);
    pager = (ViewPager) findViewById (R.template_id.pager);
    navigationSeekbar.setMax (PAGE_COUNT - 1);
    navigatorLayout = (LinearLayout) findViewById (R.template_id.navigatorLayout);
    // If the form consists only of single page, then hide the
    // navigatorLayout
    if (PAGE_COUNT < 2)
    {
        navigatorLayout.setVisibility (LinearLayout.GONE);
    }
    FragmentManager fragmentManager = getSupportFragmentManager ();
    CustomerInfoFragmentPagerAdapter pagerAdapter = new CustomerInfoFragmentPagerAdapter (fragmentManager);
    pager.setAdapter (pagerAdapter);
    // Create views for pages
    phone1TextView = new TextView (context);
    phone1 = new EditText (context);
    phone1OwnerTextView = new TextView (context);
    phone1Owner = new CheckBox (context);
    phone1OwnerName = new EditText (context);
    phone2TextView = new TextView (context);
    phone2 = new EditText (context);
    phone2OwnerTextView = new TextView (context);
    phone2Owner = new CheckBox (context);
    phone2OwnerName = new EditText (context);
    address = new TextView (context);
    address1 = new EditText (context);
    address2 = new EditText (context);
    landmark = new EditText (context);
    town = new EditText (context);
    patientId = new EditText (context);
    scanBarcode = new Button (context);
    phone1TextView.setText (R.string.primary_phone);
    phone1TextView.setTextAppearance (context, R.style.text);
    phone1.setTag (R.string.primary_phone);
    phone1.setHint (R.string.primary_phone_hint);
    phone1.setInputType (InputType.TYPE_CLASS_PHONE);
    phone1.setTextAppearance (context, R.style.text);
    phone1Owner.setText (R.string.self_owned);
    phone1Owner.setChecked (true);
    phone1OwnerName.setTag (R.string.owner_name);
    phone1OwnerName.setHint (R.string.owner_name_hint);
    phone1OwnerName.setVisibility (EditText.GONE);
    phone2TextView.setText (R.string.secondary_phone);
    phone2TextView.setTextAppearance (context, R.style.text);
    phone2.setTag (R.string.secondary_phone);
    phone2.setHint (R.string.secondary_phone_hint);
    phone2.setInputType (InputType.TYPE_CLASS_PHONE);
    phone2.setTextAppearance (context, R.style.text);
    phone2Owner.setText (R.string.self_owned);
    phone2Owner.setChecked (true);
    phone2OwnerName.setTag (R.string.secondary_phone);
    phone2OwnerName.setHint (R.string.owner_name_hint);
    phone2OwnerName.setVisibility (EditText.GONE);
    address.setText (R.string.address);
    address.setTextAppearance (context, R.style.text);
    address1.setTag (R.string.address1);
    address1.setTextAppearance (context, R.style.text);
    address1.setHint (R.string.address1_hint);
    address2.setTag (R.string.address2);
    address2.setTextAppearance (context, R.style.text);
    address2.setHint (R.string.address2_hint);
    landmark.setTag (R.string.landmark);
    landmark.setTextAppearance (context, R.style.text);
    landmark.setHint (R.string.landmark_hint);
    town.setTag (R.string.town);
    town.setTextAppearance (context, R.style.text);
    town.setHint (R.string.town_hint);
    town.setText (App.getCity ());
    patientId.setTag (R.string.patient_id);
    patientId.setHint (R.string.patient_id_hint);
    patientId.setTextAppearance (context, R.style.text);
    patientId.setInputType (InputType.TYPE_CLASS_NUMBER);
    scanBarcode.setText (R.string.scan_barcode);
    scanBarcode.setTextAppearance (context, R.style.text);
    scanBarcode.setCompoundDrawables (getResources ().getDrawable (R.drawable.barcode), null, null, null);
    // Create layouts and store in ArrayList
    groups = new ArrayList<ViewGroup> ();
    LinearLayout layout = new LinearLayout (context);
    layout.setOrientation (LinearLayout.VERTICAL);
    layout.addView (phone1TextView);
    layout.addView (phone1);
    layout.addView (phone1Owner);
    layout.addView (phone1OwnerName);
    groups.add (layout);

    LinearLayout layout2 = new LinearLayout (context);
    layout2.setOrientation (LinearLayout.VERTICAL);
    layout2.addView (phone2TextView);
    layout2.addView (phone2);
    layout2.addView (phone2Owner);
    layout2.addView (phone2OwnerName);
    groups.add (layout2);

    LinearLayout layout3 = new LinearLayout (context);
    layout3.setOrientation (LinearLayout.VERTICAL);
    layout3.addView (address);
    layout3.addView (address1);
    layout3.addView (address2);
    layout3.addView (landmark);
    layout3.addView (town);
    groups.add (layout3);

    LinearLayout layout4 = new LinearLayout (context);
    layout4.setOrientation (LinearLayout.VERTICAL);
    layout4.addView (patientId);
    layout4.addView (scanBarcode);
    groups.add (layout4);

    // Set event listeners
    formDateButton.setOnClickListener (this);
    firstButton.setOnClickListener (this);
    lastButton.setOnClickListener (this);
    clearButton.setOnClickListener (this);
    saveButton.setOnClickListener (this);
    scanBarcode.setOnClickListener (this);
    navigationSeekbar.setOnSeekBarChangeListener (this);
    views = new View[] {phone1Owner, phone2Owner};
    for (View v : views)
    {
        if (v instanceof Spinner)
        {
            ((Spinner) v).setOnItemSelectedListener (this);
        }
        else if (v instanceof CheckBox)
        {
            ((CheckBox) v).setOnCheckedChangeListener (this);
        }
    }
    pager.setOnPageChangeListener (this);
}

public void initView (View[] views)
{
    for (View v : views)
    {
        if (v instanceof Spinner)
        {
            ((Spinner) v).setSelection (0);
        }
        else if (v instanceof EditText)
        {
            ((EditText) v).setText ("");
        }
    }
    gotoPage (0);
}

public void updateDisplay ()
{
    formDateButton.setText (DateFormat.format ("dd-MMM-yyyy", formDate));
}

public void gotoFirstPage ()
{
    gotoPage (0);
}

public void gotoLastPage ()
{
    gotoPage (PAGE_COUNT - 1);
}

private void gotoPage (int pageNo)
{
    pager.setCurrentItem (pageNo);
    navigationSeekbar.setProgress (pageNo);
}

@Override
public void onProgressChanged (SeekBar seekbar, int progress, boolean isByUser)
{
    // Move to page at the index of progress
    if (isByUser)
        pager.setCurrentItem (progress);
}

@Override
public void onPageSelected (int pageNo)
{
    gotoPage (pageNo);
}
}

当我刷页面时出现问题,当从第一页到最后一页时,我没有任何问题,但后退一步会抛出IllegalStateException,表明该孩子已经有父母。这是一个例外:

05-03 14:21:36.713: E/AndroidRuntime(944): FATAL EXCEPTION: main
05-03 14:21:36.713: E/AndroidRuntime(944): java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
05-03 14:21:36.713: E/AndroidRuntime(944):  at android.view.ViewGroup.addViewInner(ViewGroup.java:1976)
05-03 14:21:36.713: E/AndroidRuntime(944):  at android.view.ViewGroup.addView(ViewGroup.java:1871)
05-03 14:21:36.713: E/AndroidRuntime(944):  at android.view.ViewGroup.addView(ViewGroup.java:1828)
05-03 14:21:36.713: E/AndroidRuntime(944):  at android.view.ViewGroup.addView(ViewGroup.java:1808)
05-03 14:21:36.713: E/AndroidRuntime(944):  at android.support.v4.app.NoSaveStateFrameLayout.wrap(NoSaveStateFrameLayout.java:40)

在调试时,我发现当我滑到最后一页时,CustomerFragment的onCreateView(...)方法最初被调用两次而根本不被调用。 我在Android开发方面还不太成熟,所以请原谅我,如果我做的事情非常愚蠢......

1 个答案:

答案 0 :(得分:0)

在深入了解Fragments和ViewPages如何工作之后,我的问题终于得到了解决。我在代码中添加了以下行,问题得到了解决:

pager.setOffscreenPageLimit(PAGE_COUNT);