我在我的应用中使用ViewPager
,当我在与home button
的互动过程中按ViewPager
时,应用程序崩溃了,我得到了error
:
3780-3780/? E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.RuntimeException: Parcel: unable to marshal value OrdinaryFragment{42000b70 #0 id=0x7f090005 android:switcher:2131296261:0}
at android.os.Parcel.writeValue(Parcel.java:1235)
at android.os.Parcel.writeList(Parcel.java:622)
at android.os.Parcel.writeValue(Parcel.java:1195)
at android.os.Parcel.writeMapInternal(Parcel.java:591)
at android.os.Bundle.writeToParcel(Bundle.java:1619)
at android.os.Parcel.writeBundle(Parcel.java:605)
at android.app.ActivityManagerProxy.activityStopped(ActivityManagerNative.java:2245)
at android.app.ActivityThread$StopInfo.run(ActivityThread.java:2912)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4895)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:994)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:761)
at dalvik.system.NativeStart.main(Native Method)
我知道有一些序列化问题,但我不知道为什么会遇到这个问题。
这是我的代码:
ViewPager:
public class ViewPagerActivity extends FragmentActivity {
/**
* The {@link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {@link android.support.v4.app.FragmentPagerAdapter} derivative, which
* will keep every loaded fragment in memory. If this becomes too memory
* intensive, it may be best to switch to a
* {@link android.support.v4.app.FragmentStatePagerAdapter}.
*/
SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {@link android.support.v4.view.ViewPager} that will host the section contents.
*/
ViewPager mViewPager;
/**
* DBManager Class for comunicating with DataBase
*/
private DBManager dbManager;
/**
* Fragment ArrayList for ViewPager's adapter input
*/
private ArrayList<Fragment> adapterList;
private ArrayList<String> sectionTitleList;
private long recId;
private MasterDataWithRecIdI masterData;
private static final int NEW_RECORD = -1;
private static final String LAYOUT_ID = "LayoutId";
private static final int NUMBER_OF_PAGES = 5;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbManager = new DBManager();
masterData = (MasterDataWithRecIdI) getIntent().getSerializableExtra("MasterData");
if(savedInstanceState != null) {
ArrayList<Fragment> savedList = (ArrayList<Fragment>) savedInstanceState.getSerializable("Adapter");
initFragments(masterData, savedList);
}else{
initFragments(masterData, null);
}
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setOffscreenPageLimit(mSectionsPagerAdapter.getCount());
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putSerializable("Adapter", adapterList);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.viewpager_menu, menu);
return true;
}
/**
* Initializing Fragments and SectionsPagerAdapter
*/
private void initFragments(MasterDataWithRecIdI masterData, ArrayList<Fragment> savedAdapter) {
instantiateTitleArray();
if(savedAdapter == null){
adapterList = new ArrayList<Fragment>();
Fragment fm;
Bundle bundle;
int layoutId = 0;
for (int i = 0; i < 3; i++) {
switch(i) {
case 0:
layoutId = R.layout.client_information_page;
break;
case 1:
layoutId = R.layout.loan_information_page;
break;
case 2:
layoutId = R.layout.additional_information_1_page;
break;
}
bundle = new Bundle();
bundle.putInt(LAYOUT_ID, layoutId);
fm = new OrdinaryFragment();
fm.setArguments(bundle);
adapterList.add(fm);
}
fm = new LastFragment();
adapterList.add(fm);
recId = NEW_RECORD;
if (masterData != null) {
recId = masterData.getRecId();
}
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager(), adapterList, sectionTitleList, recId, dbManager);
((LastFragment) fm).setSectionsPagerAdapter(mSectionsPagerAdapter, dbManager);
} else {
recId = NEW_RECORD;
if (masterData != null) {
recId = masterData.getRecId();
}
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager(), savedAdapter, sectionTitleList, recId, dbManager);
}
}
OrdinaryFragment:
public class OrdinaryFragment extends Fragment {
private static final String LAYOUT_ID = "LayoutId";
private int layoutId;
/**
* The fragment argument representing the section number for this
* fragment.
*/
public static final String ARG_SECTION_NUMBER = "section_number";
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
this.setRetainInstance(true);
layoutId = getArguments().getInt(LAYOUT_ID);
View rootView = inflater.inflate(layoutId, container, false);
ArrayList<DetailsItemI> list = (ArrayList<DetailsItemI>)getArguments().getSerializable("ViewData");
ViewFillerController viewFiller = new ViewFillerController();
viewFiller.fillTheView(rootView, list);
return rootView;
}
}
SectionsPagerAdapter:
public class SectionsPagerAdapter extends FragmentPagerAdapter implements Serializable{
private static final int NEW_RECORD = -1;
private ArrayList<Fragment> fragmentList;
private ArrayList<String> sectionTitleList;
private long recId;
private DBManager dbManager;
public SectionsPagerAdapter(FragmentManager fm, ArrayList<Fragment> fragmentList, ArrayList<String> sectionTitleList, long recId, DBManager dbManager) {
super(fm);
this.fragmentList = fragmentList;
this.sectionTitleList = sectionTitleList;
this.recId = recId;
this.dbManager = dbManager;
}
@Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a OrdinaryFragment (defined as a static inner class
// below) with the page number as its lone argument.
Fragment fragment = this.fragmentList.get(position);
Bundle args;
if (fragment.getArguments() == null) {
args = new Bundle();
}else{
args = fragment.getArguments();
}
args.putInt(OrdinaryFragment.ARG_SECTION_NUMBER, position + 1);
args.putLong("RecordID", recId);
if(recId != NEW_RECORD){
args.putSerializable("ViewData", getTabViewValues(recId, position));
}
if(fragment.getArguments() == null) {
fragment.setArguments(args);
}
return fragment;
}
private ArrayList<DetailsItemI> getTabViewValues(long recId, int tabId){
return dbManager.selectDetailsWithRecIdAndTabId(recId, tabId);
}
@Override
public int getCount() {
return this.fragmentList.size();
}
@Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
if(sectionTitleList == null){
return "";
}
return this.sectionTitleList.get(position).toUpperCase(l);
}
}
Custom TextView
我使用Parcelable
:
public class XTextView extends TextView {
private String viewParameter;
public XTextView(Context context, AttributeSet attrs) {
super(context, attrs);
getViewAttributes(context, attrs);
}
public String getXViewParameter(){
return String.valueOf(this.viewParameter);
}
public String getXValue(){
return String.valueOf(this.getText());
}
public void setXValue(String xValue) {
this.setText(xValue);
}
/**
* Getting all attributes of view Id-s.
*
* @param context
* @param attrs
*/
private void getViewAttributes(Context context, AttributeSet attrs) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.XTextView);
final int N = a.getIndexCount();
for(int i = 0; i < N; i++){
int attr = a.getIndex(i);
switch(attr){
case R.styleable.XTextView_viewParameter:
viewParameter = a.getString(attr);
break;
}
}
a.recycle();
}
@Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SavedStateTextView ss = new SavedStateTextView(superState);
ss.stateToSave = String.valueOf(this.getText().toString());
return ss;
}
@Override
public void onRestoreInstanceState(Parcelable state) {
if(!(state instanceof SavedStateTextView)) {
super.onRestoreInstanceState(state);
return;
}
SavedStateTextView ss = (SavedStateTextView) state;
super.onRestoreInstanceState(ss.getSuperState());
this.setText(ss.stateToSave);
}
}
SavedStateTextView类:
public class SavedStateTextView extends View.BaseSavedState {
String stateToSave;
public SavedStateTextView(Parcelable superState) {
super(superState);
}
private SavedStateTextView(Parcel in) {
super(in);
this.stateToSave = in.readString();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeString(this.stateToSave);
}
public static final Parcelable.Creator<SavedStateTextView> CREATOR =
new Parcelable.Creator<SavedStateTextView>() {
@Override
public SavedStateTextView createFromParcel(Parcel source) {
return new SavedStateTextView(source);
}
@Override
public SavedStateTextView[] newArray(int size) {
return new SavedStateTextView[size];
}
};
}
我希望能有所帮助。
提前致谢。
已解决
见下面的答案。
答案 0 :(得分:0)
我解决了我的问题。
我在Fragments
中使用的ViewPager
不是Serializable
。我刚刚让它们实现Serializable
Interface
,现在它可以正常工作。