Ive tried to solve my Portrait/Landscape segment in my project using this tutorial: http://www.cs.dartmouth.edu/~campbell/cs65/lecture09/lecture09.html
Everything seems to work fine (both landscape and portrait), but if i rotate from portrait to landscape or visa verse the app crashes with this: error
11-26 13:42:38.822 22594-22594/picturedtalk.com.picturedtalk E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: picturedtalk.com.picturedtalk, PID: 22594
java.lang.RuntimeException: Unable to start activity ComponentInfo{picturedtalk.com.picturedtalk/picturedtalk.com.picturedtalk.Signs.SignActivity}: android.app.Fragment$InstantiationException: Unable to instantiate fragment picturedtalk.com.picturedtalk.Signs.DetailsFragment: make sure class name exists, is public, and has an empty constructor that is public
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2338)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2390)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3930)
at android.app.ActivityThread.access$900(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1327)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5292)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.app.Fragment$InstantiationException: Unable to instantiate fragment picturedtalk.com.picturedtalk.Signs.DetailsFragment: make sure class name exists, is public, and has an empty constructor that is public
at android.app.Fragment.instantiate(Fragment.java:601)
at android.app.FragmentState.instantiate(Fragment.java:98)
at android.app.FragmentManagerImpl.restoreAllState(FragmentManager.java:1759)
at android.app.Activity.onCreate(Activity.java:899)
at picturedtalk.com.picturedtalk.Signs.SignActivity.onCreate(SignActivity.java:16)
Any suggestion how i can stop the app from crashing when changing from portrait to landscape view?
That part of my app:
SignActivity.java
public class SignActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.signs_layout);
}
}
ListFragment.java
public class ListFragment extends android.app.ListFragment {
private ArrayList<Signs> storage;
boolean mDualPane;
int mCurrentCheckPosition = 0;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
SignAdapter adapter = new
SignAdapter(Storage.get(getActivity()).getStorageOfSigns());
setListAdapter(adapter);
//Check if the we are using layout-land version of the XML to figure out if
portrait/landscape
View detailsFrame = getActivity().findViewById(R.id.details);
mDualPane = detailsFrame != null && detailsFrame.getVisibility() == View.VISIBLE;
//restore last state
if (savedInstanceState != null) {
mCurrentCheckPosition = savedInstanceState.getInt("curChoice", 0);
}
if (mDualPane) {
//only select one item at the time
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
showDetails(mCurrentCheckPosition);
} else {
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
getListView().setItemChecked(mCurrentCheckPosition, true);
}
}
//Handle flipping during fragment use
//DOES NOT WORK
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putInt("curChoice", mCurrentCheckPosition);
}
private void showDetails(int index) {
mCurrentCheckPosition = index;
if (mDualPane) {
getListView().setItemChecked(index, true);
DetailsFragment details = (DetailsFragment) getFragmentManager().findFragmentById(R.id.details);
if (details == null || details.getShownIndex() != index) {
UUID startId = ((SignAdapter) getListAdapter()).getItem(0).getId();
details = new DetailsFragment(startId);
// Execute a transaction, replacing any existing fragment
// with this one inside the frame.
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.details, details);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
}
} else {
Intent intent = new Intent();
intent.setClass(getActivity(), DetailsActivity.class);
intent.putExtra("index", index);
startActivity(intent);
}
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
if(!mDualPane){
Signs signs = ((SignAdapter) getListAdapter()).getItem(position);
Intent intent = new Intent(getActivity(),
picturedtalk.com.picturedtalk.Signs.DetailsActivity.class);
intent.putExtra(DetailsFragment.EXTRA_SIGN_ID, signs.getId());
startActivity(intent);
}
else{
UUID signId = ((SignAdapter) getListAdapter()).getItem(position).getId();
DetailsFragment fragment = new DetailsFragment(signId);
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.details, fragment);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
}
}
private class SignAdapter extends ArrayAdapter<Signs> {
public SignAdapter(ArrayList<Signs> sSigns) {
super(getActivity(), 0, sSigns);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//If we were given a view, inflate one
if (convertView == null) {
convertView = getActivity().getLayoutInflater().inflate(R.layout.signs_row,
null);
}
//Configure the view for this Crime
Signs signs = getItem(position);
TextView titleTextView = (TextView) convertView.findViewById(R.id.label);
titleTextView.setText(signs.getName());
return convertView;
}
}}
DetailsActivity.java
public class DetailsActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
UUID mSignId;
mSignId = (UUID)getIntent().getSerializableExtra(DetailsFragment.EXTRA_SIGN_ID);
DetailsFragment details = new DetailsFragment(mSignId);
getFragmentManager().beginTransaction().replace(android.R.id.content, details).commit();
UUID STOPTHIs = mSignId;
}
else {
UUID mSignId;
mSignId = (UUID)getIntent().getSerializableExtra(DetailsFragment.EXTRA_SIGN_ID);
DetailsFragment details = new DetailsFragment(mSignId);
getFragmentManager().beginTransaction().add(android.R.id.content, details).commit();
}
}}
DetailsFragment.java
public class DetailsFragment extends Fragment {
public int getShownIndex() {
return getArguments().getInt("index", 0);
}
public static final String EXTRA_SIGN_ID = "sign_id";
private UUID extraSignId;
// private static DetailsFragment detailsFragment;
private View view;
private TextView title;
private ImageView illustrativeView;
private ImageView pictureView;
private VideoView videoView;
private Signs mSign;
private String TAG = "DETAILFRAGMENT";
public DetailsFragment(UUID signId) {
this.extraSignId = signId;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSign = Storage.get(getActivity()).getSigns(extraSignId);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.signs_details, container, false);
title = (TextView) view.findViewById(R.id.title);
illustrativeView = (ImageView) view.findViewById(R.id.illustrateImage);
pictureView = (ImageView) view.findViewById(R.id.pictureImage);
videoView = (VideoView) view.findViewById(R.id.videoView);
title.setText(mSign.getName());
try {
Bitmap illuBitmap = BitmapFactory.decodeFile(mSign.getIllustrativeURL());
illustrativeView.setImageBitmap(illuBitmap);
} catch (Exception e) {
Log.d(TAG, "failed loading illustrative image");
}
try {
Bitmap picBitmap = BitmapFactory.decodeFile(mSign.getImageURL());
pictureView.setImageBitmap(picBitmap);
} catch(Exception e){
Log.d(TAG, "failed loading picture image");
}
try {
Uri uri = Uri.parse(mSign.getVideoURL());
videoView.setVideoURI(uri);
videoView.requestFocus();
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.setLooping(true);
}
});
videoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
videoView.setBackgroundResource(R.drawable.simp);
return true;
}
});
videoView.start();
} catch (Exception e) {
Log.d(TAG, "failed loading video");
}
return view;
}}
Signs.java
public class Signs {
UUID id;
String name;
String videoURL;
String imageURL;
String illustrativeURL;
public Signs(String name, String imageURL,String videoURL, String illustrativeURL){
this.id = UUID.randomUUID();
this.name = name;
this.videoURL = videoURL;
this.imageURL = imageURL;
this.illustrativeURL = illustrativeURL;
}
public UUID getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getVideoURL() {
return videoURL;
}
public void setVideoURL(String videoURL) {
this.videoURL = videoURL;
}
public String getImageURL() {
return imageURL;
}
public void setImageURL(String imageURL) {
this.imageURL = imageURL;
}
public String getIllustrativeURL() {
return illustrativeURL;
}
public void setIllustrativeURL(String illustrativeURL) {
this.illustrativeURL = illustrativeURL;
}}
signs_layout.xml (layout)
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<fragment
android:id="@+id/titles"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="picturedtalk.com.picturedtalk.Signs.ListFragment" />
signs_layout.xml (/layout-land)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false"
android:orientation="horizontal" >
<fragment
android:id="@+id/titles"
android:layout_width="0px"
android:layout_height="match_parent"
android:layout_weight="1"
class="picturedtalk.com.picturedtalk.Signs.ListFragment" />
<FrameLayout
android:id="@+id/details"
android:layout_width="0px"
android:layout_height="match_parent"
android:layout_weight="3"
android:background="?android:attr/detailsElementBackground" />
</LinearLayout>
signs_details.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="50dp"
android:text="TitleHere"
android:id="@+id/title"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="98dp" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/illustrateImage"
android:layout_below="@id/title"
android:layout_toRightOf="@+id/pictureImage"
android:background="@drawable/signs_logo"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/pictureImage"
android:layout_centerVertical="true"
android:layout_below="@+id/title"
android:layout_centerHorizontal="true"
android:background="@drawable/simp"/>
<VideoView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/videoView"
android:layout_below="@id/title"
android:layout_toLeftOf="@+id/pictureImage"/>
</RelativeLayout>
signs_listview.xml
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/listview"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
signs_row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@+id/label"
android:textSize="20px" >
</TextView>
</LinearLayout>
You can avoid activity recreation by adding following to your application's manifest file. as
and