The Busy Coder's Guide to Android Development 4.2 (ここStackOverflowのMark Murphy別名commonswareの提供)に示されているEU4Youサンプルプロジェクトを入手しました。このサンプルプロジェクトをフォローする方が簡単かもしれませんが、質問のコードの関連部分を投稿しようと思います。ActionBarSherlockプロジェクトもインポートする必要があります。また、Javaコンパイラを1.6に設定する必要があります(@Overrideアノテーションを許可するため)。
注:min-sdkを8(2.3、Froyo)に変更し、target-sdkを16(4.1、Ice Cream Sandwich)に変更しました。
注:framelayoutidをに変更しました。framelayoutidcountries
をに変更しました。left_pane
details
right_pane
メインレイアウトファイル(layout-large-land):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<FrameLayout
android:id="@+id/left_pane"
android:layout_weight="30"
android:layout_width="0px"
android:layout_height="fill_parent"
/>
<FrameLayout
android:id="@+id/right_pane"
android:layout_weight="70"
android:layout_width="0px"
android:layout_height="fill_parent"
/>
</LinearLayout>
メインレイアウトファイル:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/left_pane"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
サンプルアプリケーションの元のバージョンには、2つのアクティビティがあります(正確にはSherlockFragmentActivities)。
- EU4You-適切なレイアウト(デフォルトまたは横向き-大)をロードします。デフォルトの場合、SherlockListFragmentに国のリストをロードします。横長の場合は、リストと詳細フラグメントをロードして、選択した国を表示します。
- DetailsActivity-横向きの大きなレイアウトを使用していない場合、DetailsFragmentを介して選択した国をロードします。
リストフラグメント内の国をクリックすると、EU4You(メインのホスティングアクティビティ)がDetailsFragmentの存在と可視性をチェックします。存在する場合は、そのフラグメント内に国のWebサイトをロードします。そうでない場合は、DetailsActivityを起動し、DetailsFragmentの追加を処理します(指定した国のWebサイトをロードします)。
これは、タブレットや携帯電話で複数の画面レイアウトをサポートする一般的なアプリケーションのように、正常に機能します。
私の問題は、DetailsActivityを削除して、単一のアクティビティに固執したいということです。大きな横向きのレイアウトではない場合(つまり、タブレットまたは任意の向きの受話器で縦向きのレイアウトになっている場合)はいつでも、リストフラグメントを詳細フラグメントに交換(置換)したいと思います。したがって、私が行ったことは、EU4YouSherlockFragmentActivityで次のように変更されています。
オリジナル(さらに上のメモに記載されているフレームレイアウト名にわずかな名前の変更があります...国はleft_pane、詳細はright_paneです):
@Override
public void onCountrySelected(Country c) {
String url=getString(c.url);
if (details != null && details.isVisible()) {
details.loadUrl(url);
}
else {
Intent i=new Intent(this, DetailsActivity.class);
i.putExtra(DetailsActivity.EXTRA_URL, url);
startActivity(i);
}
}
私の変更したシングルアクティビティバージョン:
@Override
public void onCountrySelected(Country c) {
String url=getString(c.url);
if (details != null && details.isVisible()) {
details.loadUrl(url);
}
else {
details = new DetailsFragment();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.left_pane, details);
ft.addToBackStack(null);
ft.commit();
getSupportFragmentManager().executePendingTransactions();
details.loadUrl(url);
}
}
これは期待どおりに機能します。リスト上のWebサイトをクリックすると(タブレットのポートレートモード、または任意の向きの受話器で)、詳細が詳細フラグメントに表示されます。これは、Webサイトリストフラグメントを置き換えます。ただし、国の詳細が表示されているときにデバイスのホームボタンをクリックすると、次のlogcatの詳細で強制終了エラーが発生します(left_paneフレームレイアウトが1つしかないデフォルトのレイアウトのみ... left_paneとright_paneがある場合、タブレットの横向きでこの問題が発生します):
11-16 15:04:33.525: E/AndroidRuntime(688): FATAL EXCEPTION: main
11-16 15:04:33.525: E/AndroidRuntime(688): java.lang.RuntimeException: Unable to pause activity {com.commonsware.android.eu4you/com.commonsware.android.eu4you.EU4You}: java.lang.IllegalStateException: Content view not yet created
11-16 15:04:33.525: E/AndroidRuntime(688): at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3348)
11-16 15:04:33.525: E/AndroidRuntime(688): at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3305)
11-16 15:04:33.525: E/AndroidRuntime(688): at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:3288)
11-16 15:04:33.525: E/AndroidRuntime(688): at android.app.ActivityThread.access$2500(ActivityThread.java:125)
11-16 15:04:33.525: E/AndroidRuntime(688): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2040)
11-16 15:04:33.525: E/AndroidRuntime(688): at android.os.Handler.dispatchMessage(Handler.java:99)
11-16 15:04:33.525: E/AndroidRuntime(688): at android.os.Looper.loop(Looper.java:123)
11-16 15:04:33.525: E/AndroidRuntime(688): at android.app.ActivityThread.main(ActivityThread.java:4627)
11-16 15:04:33.525: E/AndroidRuntime(688): at java.lang.reflect.Method.invokeNative(Native Method)
11-16 15:04:33.525: E/AndroidRuntime(688): at java.lang.reflect.Method.invoke(Method.java:521)
11-16 15:04:33.525: E/AndroidRuntime(688): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
11-16 15:04:33.525: E/AndroidRuntime(688): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
11-16 15:04:33.525: E/AndroidRuntime(688): at dalvik.system.NativeStart.main(Native Method)
11-16 15:04:33.525: E/AndroidRuntime(688): Caused by: java.lang.IllegalStateException: Content view not yet created
11-16 15:04:33.525: E/AndroidRuntime(688): at android.support.v4.app.ListFragment.ensureList(ListFragment.java:328)
11-16 15:04:33.525: E/AndroidRuntime(688): at android.support.v4.app.ListFragment.getListView(ListFragment.java:222)
11-16 15:04:33.525: E/AndroidRuntime(688): at com.commonsware.android.eu4you.CountriesFragment.onSaveInstanceState(CountriesFragment.java:64)
11-16 15:04:33.525: E/AndroidRuntime(688): at android.support.v4.app.FragmentManagerImpl.saveFragmentBasicState(FragmentManager.java:1574)
11-16 15:04:33.525: E/AndroidRuntime(688): at android.support.v4.app.FragmentManagerImpl.saveAllState(FragmentManager.java:1644)
11-16 15:04:33.525: E/AndroidRuntime(688): at android.support.v4.app.FragmentActivity.onSaveInstanceState(FragmentActivity.java:499)
11-16 15:04:33.525: E/AndroidRuntime(688): at com.actionbarsherlock.app.SherlockFragmentActivity.onSaveInstanceState(SherlockFragmentActivity.java:127)
11-16 15:04:33.525: E/AndroidRuntime(688): at android.app.Activity.performSaveInstanceState(Activity.java:1036)
11-16 15:04:33.525: E/AndroidRuntime(688): at android.app.Instrumentation.callActivityOnSaveInstanceState(Instrumentation.java:1180)
11-16 15:04:33.525: E/AndroidRuntime(688): at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3330)
11-16 15:04:33.525: E/AndroidRuntime(688): ... 12 more
上記のコードから次の行を削除すると、このエラーの発生を防ぐことができます。
ft.addToBackStack(null);
置換トランザクションをバックスタックに追加できる必要があるため、この行を削除できません(このサンプルアプリケーションは、より多くのものがある実際のアプリケーションの基礎ですが、問題を単純化するために使用しました)。
したがって、2つの質問:
- なぜこうなった?
- どうすれば修正できますか(おそらく別のアプローチ)?
注意すべき点の1つは、実際のアプリケーションでは、このロジックはすべてアクションバーのタブ内にある必要があることです(バージョン2.3(Froyo)に戻る必要があるため、ActionBarSherlock)。
更新(2012年11月22日13:27 EST)
サンプルプロジェクトをGitHubに投稿しました。私はEclipseとAndroidの開発に慣れていないので、必要なものがすべて含まれていない可能性があります(ワークスペースは含まれておらず、ActionBarSherlockプロジェクトは含まれていないと思います...インポートする必要があります(ここにあります) )。