我有一个代表客户信息的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开发方面还不太成熟,所以请原谅我,如果我做的事情非常愚蠢......
答案 0 :(得分:0)
在深入了解Fragments和ViewPages如何工作之后,我的问题终于得到了解决。我在代码中添加了以下行,问题得到了解决:
pager.setOffscreenPageLimit(PAGE_COUNT);