16722


AndroidStudioでAndroidアプリを作っています。  
今回、`fragment_main.xml`にタブを実装しようと思い、以下のコードを書きました。  
（１つ目のタブ、タブ１をタップすると下にカレンダー＋テキストビューが出てきて、２つ目のタブ、タブ２をタップするとテキストビューのみ出てくる）  
[![画像の説明をここに入力](https://i.stack.imgur.com/9d5Wx.png)](https://i.stack.imgur.com/9d5Wx.png)

しかし、xmlのプレビューではちゃんと表示されているものの、エミュレーターを実行すると落ちてしまい、  
`Caused by: java.lang.NullPointerException: Attempt to invoke virtual method
'void android.widget.TabHost.setup()' on a null object
referencef`というエラーがでてきました。

`fragment_main.xml`の中身を`activity_main.xml`に書くときちんとタブがでてくるのですが、なぜ`fragment_main.xml`に書くとエラーになってしまうのか分かりません。  
ちなみに`fragment_main.xml`は、アプリを起動したときに最初に表示される場面です。

`fragment_main.xml`

[code]

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    
    <TabHost
        android:id="@android:id/tabhost"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true" >
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical" >
    
            <TabWidget
                android:id="@android:id/tabs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" >
            </TabWidget>
    
            <FrameLayout
                android:id="@android:id/tabcontent"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical">
    
                <LinearLayout
                    android:id="@+id/tab1"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:orientation="vertical">
    
                    <CalendarView
                        android:layout_width="match_parent"
                        android:layout_height="0px"
                        android:layout_weight="3"
                        android:clickable="true">
    
                    </CalendarView>
    
                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="1dp"
                        android:background="#ccc"/>
    
                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="0px"
                        android:layout_weight="1"
                        android:padding="10dp"
                        android:textSize="20dp"
                        android:text="MEMO"/>
    
                </LinearLayout>
    
                <LinearLayout
                    android:id="@+id/tab2"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:orientation="vertical">
    
                    <TextView
                        android:id="@+id/textView2"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="TextView-タブ2" />
                </LinearLayout>
    
            </FrameLayout>
        </LinearLayout>
    </TabHost>
    
[/code]

`MainActivity.java`のタブに関係する部分

[code]

     @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        mNavigationDrawerFragment = (NavigationDrawerFragment)
                getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
        mTitle = getTitle();
    
        // Set up the drawer.
        mNavigationDrawerFragment.setUp(
                R.id.navigation_drawer,
                (DrawerLayout) findViewById(R.id.drawer_layout));
    
        TabHost tabhost = (TabHost)findViewById(android.R.id.tabhost);
        tabhost.setup();
    
    //ここからタブに関する部分
        TabHost.TabSpec tab1 = tabhost.newTabSpec("tab1");
        tab1.setIndicator("タブ１");
        tab1.setContent(R.id.tab1);
        tabhost.addTab(tab1);
    
        TabHost.TabSpec tab2 = tabhost.newTabSpec("tab2");
        tab2.setIndicator("タブ2");
        tab2.setContent(R.id.tab2);
        tabhost.addTab(tab2);
    
        tabhost.setCurrentTab(0);
    }
    
[/code]

`activity_main.xml`

[code]

    <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    
    
    <FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    
    
    <fragment
        android:id="@+id/navigation_drawer"
        android:name="com.example.yuriyuri.toolbar.NavigationDrawerFragment"
        android:layout_width="@dimen/navigation_drawer_width"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        tools:layout="@layout/fragment_navigation_drawer" />
    
    </android.support.v4.widget.DrawerLayout>
    
[/code]

* * *

`変更後のonCreate内`

[code]

       protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        mNavigationDrawerFragment = (NavigationDrawerFragment)
                getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
        mTitle = getTitle();
    
        // Set up the drawer.
        mNavigationDrawerFragment.setUp(
                R.id.navigation_drawer,
                (DrawerLayout) findViewById(R.id.drawer_layout));
    
        PlaceholderFragment placeholderFragment = PlaceholderFragment.newInstance(1);
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.container,placeholderFragment).commit();
    
    
        TabHost tabhost = (TabHost)findViewById(android.R.id.tabhost);
        tabhost.setup();
    
    
        TabHost.TabSpec tab1 = tabhost.newTabSpec("tab1");
        tab1.setIndicator("タブ１");
        tab1.setContent(R.id.tab1);
        tabhost.addTab(tab1);
    
        TabHost.TabSpec tab2 = tabhost.newTabSpec("tab2");
        tab2.setIndicator("タブ2");
        tab2.setContent(R.id.tab2);
        tabhost.addTab(tab2);
    
        tabhost.setCurrentTab(0);
    
    }
    
[/code]

`PlaceholderFragment のクラス`

[code]

        public static class PlaceholderFragment extends Fragment {
        /**
         * The fragment argument representing the section number for this
         * fragment.
         */
        private static final String ARG_SECTION_NUMBER = "section_number";
    
        /**
         * Returns a new instance of this fragment for the given section
         * number.
         */
        public static PlaceholderFragment newInstance(int sectionNumber) {
            PlaceholderFragment fragment = new PlaceholderFragment();
            Bundle args = new Bundle();
            args.putInt(ARG_SECTION_NUMBER, sectionNumber);
            fragment.setArguments(args);
            return fragment;
        }
    
        public PlaceholderFragment() {
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_main, container, false);
            return rootView;
        }
    
        @Override
        public void onAttach(Activity activity) {
            super.onAttach(activity);
            ((MainActivity) activity).onSectionAttached(
                    getArguments().getInt(ARG_SECTION_NUMBER));
        }
    }
    
[/code]


CC BY-SA 3.0
2015-09-17T13:28:51.670
16716
2015-09-18T16:05:35.123
2015-09-18T01:54:33.787
12330
12330
question
android fragment
Androidアプリで、activity_main.xml以外の場所でタブを表示させたい。


fragment_main.xml を使う Fragment が、Activity の onCreate の処理の段階では、まだ Attach
されていないので、その fragment_main.xml の中にある、tabhost を findViewById しても、見つけられず、null
になっていると思います。

tabhost を findViewById して見つける前に、当該 Fragment を用意して Activity に Attach
する処理を書けば、解消されるのではないでしょうか？（または、activity_main.xml に当該 Fragment を含めておくか）

[code]

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_main, container, false);
    
        TabHost tabhost = (TabHost) rootView.findViewById(android.R.id.tabhost);
        tabhost.setup();
    
        // ここからタブに関する部分
        TabHost.TabSpec tab1 = tabhost.newTabSpec("tab1");
        tab1.setIndicator("タブ１");
        tab1.setContent(R.id.tab1);
        tabhost.addTab(tab1);
    
        TabHost.TabSpec tab2 = tabhost.newTabSpec("tab2");
        tab2.setIndicator("タブ2");
        tab2.setContent(R.id.tab2);
        tabhost.addTab(tab2);
    
        tabhost.setCurrentTab(0);
    
        return rootView;
    }
    
[/code]

注記：MainActivity の onCreate で Fragment をアタッチする処理を書くなりする、と先に述べましたが、Activity 側が
onCreate の段階では、Fragment 側も未だ、onCreateView が終っていませんで、これではまだ駄目でした。

本筋としては、Fragment 側の onCreateView で処理するのが一番です。どうしても、Activity
側で処理を書きたいのであれば、Fragment 側の onCreateView
が確実に終ったタイミングのところで行わねばなりません（onPostCreate とか？）。


CC BY-SA 3.0
2015-09-17T15:24:16.270
16722
2015-09-18T16:05:35.123
2015-09-18T16:05:35.123
7290
7290
16716
answer