我尝试使用本教程解决项目中的Portrait / Landscape段: http://www.cs.dartmouth.edu/~campbell/cs65/lecture09/lecture09.html
一切似乎都很好(包括风景和肖像),但是如果我从纵向旋转到横向或签证,应用程序会崩溃:错误
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)
在从纵向视图更改为横向视图时,有何建议如何阻止应用崩溃?
我的应用程序的那部分:
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(布局)
<?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>
答案 0 :(得分:2)
您可以通过在应用程序的清单文件中添加以下内容来避免活动重新创建。 如
android:configChanges="keyboardHidden|orientation|screenSize"
和
<activity
android:name=".your activity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/app_name" >
</activity>