Reputation: 6240
PlaceActivity hosts Two Fragments
When i try to change the orientation the app crashes with the following Error Log.
01-12 15:24:57.950: E/AndroidRuntime(30412): FATAL EXCEPTION: main
01-12 15:24:57.950: E/AndroidRuntime(30412): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.m7.nomad/com.m7.nomad.PlaceActivity}: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment com.m7.nomad.fragments.PlaceSlideFragment: make sure class name exists, is public, and has an empty constructor that is public
01-12 15:24:57.950: E/AndroidRuntime(30412): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1968)
01-12 15:24:57.950: E/AndroidRuntime(30412): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1993)
01-12 15:24:57.950: E/AndroidRuntime(30412): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3363)
01-12 15:24:57.950: E/AndroidRuntime(30412): at android.app.ActivityThread.access$700(ActivityThread.java:127)
01-12 15:24:57.950: E/AndroidRuntime(30412): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1163)
01-12 15:24:57.950: E/AndroidRuntime(30412): at android.os.Handler.dispatchMessage(Handler.java:99)
01-12 15:24:57.950: E/AndroidRuntime(30412): at android.os.Looper.loop(Looper.java:137)
01-12 15:24:57.950: E/AndroidRuntime(30412): at android.app.ActivityThread.main(ActivityThread.java:4507)
01-12 15:24:57.950: E/AndroidRuntime(30412): at java.lang.reflect.Method.invokeNative(Native Method)
01-12 15:24:57.950: E/AndroidRuntime(30412): at java.lang.reflect.Method.invoke(Method.java:511)
01-12 15:24:57.950: E/AndroidRuntime(30412): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
01-12 15:24:57.950: E/AndroidRuntime(30412): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
01-12 15:24:57.950: E/AndroidRuntime(30412): at dalvik.system.NativeStart.main(Native Method)
01-12 15:24:57.950: E/AndroidRuntime(30412): Caused by: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment com.m7.nomad.fragments.PlaceSlideFragment: make sure class name exists, is public, and has an empty constructor that is public
01-12 15:24:57.950: E/AndroidRuntime(30412): at android.support.v4.app.Fragment.instantiate(Fragment.java:405)
01-12 15:24:57.950: E/AndroidRuntime(30412): at android.support.v4.app.FragmentState.instantiate(Fragment.java:97)
01-12 15:24:57.950: E/AndroidRuntime(30412): at android.support.v4.app.FragmentManagerImpl.restoreAllState(FragmentManager.java:1767)
01-12 15:24:57.950: E/AndroidRuntime(30412): at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:208)
01-12 15:24:57.950: E/AndroidRuntime(30412): at com.m7.nomad.PlaceActivity.onCreate(PlaceActivity.java:34)
01-12 15:24:57.950: E/AndroidRuntime(30412): at android.app.Activity.performCreate(Activity.java:4465)
01-12 15:24:57.950: E/AndroidRuntime(30412): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1052)
01-12 15:24:57.950: E/AndroidRuntime(30412): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1932)
01-12 15:24:57.950: E/AndroidRuntime(30412): ... 12 more
01-12 15:24:57.950: E/AndroidRuntime(30412): Caused by: java.lang.InstantiationException: can't instantiate class com.m7.nomad.fragments.PlaceSlideFragment; no empty constructor
01-12 15:24:57.950: E/AndroidRuntime(30412): at java.lang.Class.newInstanceImpl(Native Method)
01-12 15:24:57.950: E/AndroidRuntime(30412): at java.lang.Class.newInstance(Class.java:1319)
01-12 15:24:57.950: E/AndroidRuntime(30412): at android.support.v4.app.Fragment.instantiate(Fragment.java:394)
01-12 15:24:57.950: E/AndroidRuntime(30412): ... 19 more
PlaceSlidesFragemntsAdapter.java
public class PlaceSlidesFragmentAdapter extends FragmentPagerAdapter {
DBAdapter db = new DBAdapter(SplashActivity.context);
List<String> photoList = new ArrayList<String>();
private int mCount;
public PlaceSlidesFragmentAdapter(FragmentManager fm) {
super(fm);
db.open();
Cursor photosCursor = db.getPhotos(PlaceActivity.placeId);
// Iterate Through the Place Cursor
if (photosCursor.moveToFirst()) {
do {
photoList.add(photosCursor.getString(1));
} while (photosCursor.moveToNext());
}
db.close();
mCount = photoList.size();
}
@Override
public Fragment getItem(int position) {
return new PlaceSlideFragment(photoList.get(position));
}
@Override
public int getCount() {
return mCount;
}
public void setCount(int count) {
if (count > 0 && count <= 10) {
mCount = count;
notifyDataSetChanged();
}
}
}
PlaceSlideFragment.java
public final class PlaceSlideFragment extends Fragment {
String imageResourceId;
public PlaceSlideFragment(String i) {
imageResourceId = i;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ImageView image = new ImageView(getActivity());
ImageLoader imgLoader = new ImageLoader(MainActivity.context);
imgLoader.DisplayImage(imageResourceId, new Activity(), image);
LinearLayout layout = new LinearLayout(getActivity());
layout.setLayoutParams(new LayoutParams());
layout.setGravity(Gravity.CENTER);
layout.addView(image);
return layout;
}
}
Upvotes: 3
Views: 3846
Reputation: 18391
The stacktrace contains the following line
Unable to instantiate fragment com.m7.nomad.fragments.PlaceSlideFragment: make sure class name exists, is public, and has an empty constructor that is public
There is a problem with the constructor, a good practice with fragments is using a getInstance method that will call the empty constructor.
Why the need of empty constructor?
Android framework will call these when fragments are recreated e.g. configuration change
If you have any other problems with fragments comment below
EDIT:
FRAGMENT EXAMPLE
public final class PlaceSlideFragment extends Fragment {
public static Fragment newInstance() {
return new PlaceSlideFragment();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ImageView image = new ImageView(getActivity());
ImageLoader imgLoader = new ImageLoader(MainActivity.context);
imgLoader.DisplayImage(getArguments().getInt("key"), new Activity(), image);
LinearLayout layout = new LinearLayout(getActivity());
layout.setLayoutParams(new LayoutParams());
layout.setGravity(Gravity.CENTER);
layout.addView(image);
return layout;
}
}
IN PAGER
@Override
public Fragment getItem(int position) {
PlaceSlideFragment frag = PlaceSlideFragment.newInstance();
Bundle args = new Bundle()
args.putInt("key",ID_RESOURCE_HERE);
frag.setArguments(args);
return frag;
}
I hope this helps, you can also take a look a retaining fragments and handling configuration changes since you will probably run into other exceptions later on
Upvotes: 3
Reputation: 23972
Your Fragment
must have an empty constructor.
Use setArguments(Bundle)
instead of passing parameters to constructor directly.
In your example in PlaceSlideFragment.java
remove constructor. Instead, inside onCreateView
use:
imageResourceId = getArguments().getString("param");
Then, to instantinate PlaceSlideFragment
use this code:
Fragment f = new PlaceSlideFragment();
Bundle args = new Bundle();
args.putString("param", yourParam);
f.setArguments(args);
or it will be even better if you'll move this code into some static method of PlaceSlideFragment
Upvotes: 8
Reputation: 3417
Caused by: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment com.m7.nomad.fragments.PlaceSlideFragment: make sure class name exists, is public, and has an empty constructor that is public
This line shows that you doesn't have support library. Add support library as below:
Right Click Project -> Android Tools -> Add Support Library
and then clean and build your Project.
Upvotes: 1