旋转平板电脑时应用程序崩溃(单面到双面显示)

时间:2014-11-26 12:55:04

标签: android android-listview landscape-portrait

我尝试使用本教程解决项目中的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>

1 个答案:

答案 0 :(得分:2)

您可以通过在应用程序的清单文件中添加以下内容来避免活动重新创建。 如

android:configChanges="keyboardHidden|orientation|screenSize" 

   <activity
            android:name=".your activity"
            android:configChanges="orientation|keyboardHidden|screenSize"
            android:label="@string/app_name" >
        </activity>