1

私のアプリには次の特徴があります。

  • ランドスケープ モードの場合、画面を半分に分割し、いくつかのフラグメント ("LocFragment" と "MapFragment") を表示します。
  • 縦向きモードの場合、ActionBar に 2 つのタブを表示します。フラグメントは画面全体をカバーし、タブ選択でフラグメントを切り替えます。
  • 4.x+ をターゲットにしているので、サポート ライブラリや ActionBarSherlock は気にしません。

アプリの起動時に電話が横向きモードの場合、すべて正常に動作します。ただし、1) 電話が縦向きモードの場合、2) アプリが起動するとき、3) 電話が横向きモードになると、アプリがクラッシュします。

layour/activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:id="@+id/FragmentContainer"
        android:layout_width="match_parent" 
        android:layout_height="match_parent">
    </FrameLayout>

 layout-land/activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment
        android:name="org.solamour.eq.LocFragment"
        android:id="@+id/EarthquakeListFragment"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="match_parent" />
    <fragment
        android:name="org.solamour.eq.MapFragment"
        android:id="@+id/EarthquakeMapFragment"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="match_parent" />

public class MainActivity extends Activity {
    TabListener<LocFragment> locTabListener;
    TabListener<MapFragment> mapTabListener;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ActionBar actionBar = getActionBar();
        View fragmentContainer = findViewById(R.id.FragmentContainer);
        boolean bLandscape = fragmentContainer == null;

        if (!bLandscape) {
            actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
            actionBar.setDisplayShowTitleEnabled(false);

            Tab listTab = actionBar.newTab();
            locTabListener = new TabListener<LocFragment>
                (this, R.id.FragmentContainer,
                        LocFragment.class);
            listTab.setText("List")
                .setContentDescription("List of locations")
                .setTabListener(locTabListener);
            actionBar.addTab(listTab);

            Tab mapTab = actionBar.newTab();
            mapTabListener = new TabListener<MapFragment>
                (this, R.id.FragmentContainer,
                        MapFragment.class);
            mapTab.setText("Map")
                .setContentDescription("Map of interests")
                .setTabListener(mapTabListener);
            actionBar.addTab(mapTab);
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        View fragmentContainer = findViewById(R.id.FragmentContainer);
        boolean bLandscape = fragmentContainer == null;

        if (!bLandscape) {
            FragmentTransaction ft =
                    getFragmentManager().beginTransaction();
            if (mapTabListener.fragment != null) {
                ft.detach(mapTabListener.fragment);
            }
            if (locTabListener.fragment != null) {
                ft.detach(locTabListener.fragment);
            }
            ft.commit();
        }

        super.onSaveInstanceState(outState);
    }

    @Override
    public void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);

        View fragmentContainer = findViewById(R.id.FragmentContainer);
        boolean bLandscape = fragmentContainer == null;

        if (!bLandscape) {
            locTabListener.fragment =getFragmentManager().
                    findFragmentByTag(LocFragment.class.getName());
            mapTabListener.fragment = getFragmentManager().
                    findFragmentByTag(MapFragment.class.getName());
        }
    }

    public static class TabListener<T extends Fragment>
            implements ActionBar.TabListener {
        private Fragment fragment;
        private Activity activity;
        private Class<T> fragmentClass;
        private int fragmentContainer;

        public TabListener(Activity activity,
                int fragmentContainer, Class<T> fragmentClass) {
            this.activity = activity;
            this.fragmentContainer = fragmentContainer;
            this.fragmentClass = fragmentClass;
        }

        public void onTabSelected(Tab tab, FragmentTransaction ft) {
            if (fragment == null) {
                String fragmentName = fragmentClass.getName();
                fragment = Fragment.instantiate(activity, fragmentName);
                ft.add(fragmentContainer, fragment, fragmentName);
            } else {
                ft.attach(fragment);
            }
        }

        public void onTabUnselected(Tab tab, FragmentTransaction ft) {
            if (fragment != null) {
                ft.detach(fragment);
            }
        }

        public void onTabReselected(Tab tab, FragmentTransaction ft) {
            if (fragment != null)
                ft.attach(fragment);
        }
    }
}

クラッシュといえば、Eclipse は単に「アクティビティ ComponentInfo を開始できません{...}: android.view.InflateException: Binary XML file line #7: Error inflating class fragment」と言っています。「setContentView(R.layout.activity_main)」のどこかにあるはずですが、ソースをコード内でフォローするように設定する方法がわかりません。提案をいただければ幸いです。ありがとうございました。

__

ソル

4

1 に答える 1

0

エラーは、ランドスケープ レイアウトの 7 行目にあります。

fragment android:name="org.solamour.eq.LocFragment"

クラスへのパスが間違っているか、LocFragment にエラーがあり、それを表示するとクラッシュする可能性があります。

于 2012-08-27T13:33:02.607 に答える