I am trying to create an app that uses Jack Wharton's ViewPager library (here) using only images for every page (something like Prixing (here) main screen). Everything works ok, except for the saveInstance in the Fragment.
In Jack Wharton's example, he stores the text in a String variable, named mContent, and restores it in onCreate, but in my case, what should I do? Save/Restore a bitmap?! Any objective answer would be much appreciated!
I'm quite new to this Fragment using applications, cause every example I look at, presents only the basics, and it's getting difficult upon more complex ones.
PS. If is it usefull to know, I'm using CirclePageIndicator.
Current Fragment Code here:
public final class SpecialOfferFragment extends Fragment {
private int imageResourceId;
public static SpecialOfferFragment newInstance(int i) {
//probably I'll use a bitmap(downloaded) as parameter instead of using static images
SpecialOfferFragment fragment = new SpecialOfferFragment();
fragment.imageResourceId = i;
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// if ((savedInstanceState != null) { }
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ImageView image = new ImageView(getActivity());
image.setImageResource(imageResourceId);
image.setScaleType(ScaleType.FIT_XY);
LinearLayout layout = new LinearLayout(getActivity());
layout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT));
layout.setGravity(Gravity.CENTER);
layout.addView(image);
return layout;
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//smth to save here..
}
}
In this current state of the app, I get the following Exception:
04-12 07:28:17.760: E/AndroidRuntime(31903): FATAL EXCEPTION: main
04-12 07:28:17.760: E/AndroidRuntime(31903): java.lang.NullPointerException
04-12 07:28:17.760: E/AndroidRuntime(31903): at android.support.v4.app.FragmentManagerImpl.saveFragmentBasicState(FragmentManager.java:1576)
04-12 07:28:17.760: E/AndroidRuntime(31903): at android.support.v4.app.FragmentManagerImpl.saveAllState(FragmentManager.java:1617)
04-12 07:28:17.760: E/AndroidRuntime(31903): at android.support.v4.app.FragmentActivity.onSaveInstanceState(FragmentActivity.java:481)
04-12 07:28:17.760: E/AndroidRuntime(31903): at android.app.Activity.performSaveInstanceState(Activity.java:1113)
04-12 07:28:17.760: E/AndroidRuntime(31903): at android.app.Instrumentation.callActivityOnSaveInstanceState(Instrumentation.java:1188)
04-12 07:28:17.760: E/AndroidRuntime(31903): at android.app.ActivityThread.performStopActivityInner(ActivityThread.java:2804)
04-12 07:28:17.760: E/AndroidRuntime(31903): at android.app.ActivityThread.handleStopActivity(ActivityThread.java:2862)
04-12 07:28:17.760: E/AndroidRuntime(31903): at android.app.ActivityThread.access$900(ActivityThread.java:127)
04-12 07:28:17.760: E/AndroidRuntime(31903): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1175)
04-12 07:28:17.760: E/AndroidRuntime(31903): at android.os.Handler.dispatchMessage(Handler.java:99)
04-12 07:28:17.760: E/AndroidRuntime(31903): at android.os.Looper.loop(Looper.java:137)
04-12 07:28:17.760: E/AndroidRuntime(31903): at android.app.ActivityThread.main(ActivityThread.java:4511)
04-12 07:28:17.760: E/AndroidRuntime(31903): at java.lang.reflect.Method.invokeNative(Native Method)
04-12 07:28:17.760: E/AndroidRuntime(31903): at java.lang.reflect.Method.invoke(Method.java:511)
04-12 07:28:17.760: E/AndroidRuntime(31903): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:980)
04-12 07:28:17.760: E/AndroidRuntime(31903): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:747)
04-12 07:28:17.760: E/AndroidRuntime(31903): at dalvik.system.NativeStart.main(Native Method)
This happens whenever I pause/stop the activity containing this fragment, like pushing the Home button.
**
**
public class MainMenu extends FragmentActivity {
//private List<CategoriesHolder> categoriesList = new ArrayList<CategoriesHolder>();
//private CategoriesAdapter categoriesAdapter = null;
//private GridView gv_mainmenu_categories;
SpecialOfferFragmentAdapter mAdapter;
ViewPager mPager;
PageIndicator mIndicator;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mainmenu);
linkUI();
setAction();
// just for testing
String[] imagesUrls = null;
mAdapter = new SpecialOfferFragmentAdapter(getSupportFragmentManager(),
this, imagesUrls);
//categoriesAdapter = new CategoriesAdapter(this, categoriesList);
// used for Categories GridView
//gv_mainmenu_categories.setAdapter(categoriesAdapter);
// used for ViewPager
mPager.setAdapter(mAdapter);
mIndicator.setViewPager(mPager);
}
private void linkUI() {
mPager = (ViewPager) findViewById(R.id.vp_mainmenu_special_offers);
mIndicator = (CirclePageIndicator) findViewById(R.id.indicator);
//gv_mainmenu_categories = (GridView) findViewById(R.id.gv_mainmenu_categories);
}
private void setAction() {
}
}
public class SpecialOfferFragmentAdapter extends FragmentPagerAdapter implements
IconPagerAdapter {
private int[] mCarouselImages = new int[] { R.drawable.pic1,
R.drawable.pic2, R.drawable.pic3, R.drawable.pic4, R.drawable.pic5
};
private String[] imagesUrls;
private Context context;
public static final int[] ICONS = new int[] {
R.drawable.perm_group_calendar, R.drawable.perm_group_camera,
R.drawable.perm_group_device_alarms, R.drawable.perm_group_location };
private int mCount = mCarouselImages.length;
public SpecialOfferFragmentAdapter(FragmentManager fm, Context context,
String[] imagesUrls) {
super(fm);
this.context = context;
this.imagesUrls = imagesUrls;
}
@Override
public Fragment getItem(int position) {
return SpecialOfferFragment.newInstance(mCarouselImages[position]);
}
@Override
public int getCount() {
return mCount;
}
@Override
public int getIconResId(int index) {
return ICONS[index % ICONS.length];
}
public void setCount(int count) {
if (count > 0 && count <= 10) {
mCount = count;
notifyDataSetChanged();
}
}
}
When the activity goes into the background, the system calls onSaveInstanceState() . You should save the search query in the onSaveInstanceState() bundle. This small amount of data is easy to save. It's also all the information you need to get the activity back into its current state.
State can be restored in either the onCreate() or the onRestoreInstanceState() methods of the activity by extracting values from the Bundle object and updating the activity based on the stored values.
A Fragment represents a reusable portion of your app's User Interface. Retained Fragment consists of the configuration change that causes the underlying Activity to be destroyed. The term "retained" refers to the fragment that will not be destroyed on configuration changes.
Saving the State The first step in extending the StateChange application is to make sure that the text entered by the user is extracted from the EditText component within the onSaveInstanceState() method of the StateChangeActivity activity, and then saved as a key-value pair into the Bundle object.
To achieve the thing which you want, you should use integer value to store the current position in your ViewPager
, and after that use this value to set the right position to your ViewPager
.
For example do something like this in your FragmentActivity
:
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putInt("mMyCurrentPosition", mPager.getPosition());
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mMyCurrentPosition = savedInstanceState.getInt("mMyCurrentPosition");
// where mMyCurrentPosition should be a public value in your activity.
}
which will saved your ViewPager's last position. And after that in your onResume()
for example you can check
if(mMyCurrentPosition != 0){
mPager.setCurrentItem(mMyCurrentPosition);
}
I think this should work , it's not a good practice to save images / bitmaps in bundle (and I don't think you are able to do it).
Ok first id like to clear something up that might solve your confusion about savedinstancestate. Savedinstancestate can only handle primitives ( int, double, float, byte..) and the String object. This should be all you need but in some cases you want to save instances of other objects as well. For this you would need some other pattern to accomplish the job, for example a factory pattern wich holds an array of all your bitmaps. Like for instance create a class ImageFactory that holds a static ArrayList of bitmaps. Whenever you rotate your device the oncreateview and onactivitycreated methods are called again and this is the moment to check if you want to retrieve information from your factory or not. for example
if(savedInstanceState != null) { //we have a savedinstancestate so there probably are saved images ImageFactory.getBMPs(); }
hope you can do something with this info. good luck
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With