findFragmentById always returns a null

2019-02-25 05:56发布

I'm using an actionbar in navigation mode in the mainActivity. Different tabs has different layouts, and on one of these tabs, I embed a layout which has a MapFragment inside. With the following code, the app works well, the mapFragments works fine, the tabs works fine. However, once I want to get access the mapFragment embeded in myFragment use getFragmentManager().findFragmentById(R.id.map_add), I always get null.

I've tried using FragmentManager and FragmentTransaction to add myfragment and the MapFragment, but still get null from findFragmentById(R.id.map_add). Please help...

The MainActivity initialized like this:

protected void onCreate(Bundle bundle) {
    super.onCreate(bundle);
    setContentView(R.layout.main);

    // ActionBar gets initiated
    ActionBar actionbar = getActionBar();
    // Tell the ActionBar we want to use Tabs.
    actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
    // initiating the tabs and set text to it.
    ActionBar.Tab myTab = actionbar.newTab().setText("hey");

    // create the fragments we want to use for display content
    Fragment myFragment = new myFragment();

    // set the Tab listener. Now we can listen for clicks.
    myTab.setTabListener(new MyTabsListener(myFragment));


    // add the tabs to the actionbar
    actionbar.addTab(myTab);
    map=((MapFragment)getFragmentManager().findFragmentById(R.id.map_add)).getMap();//line 103

}

the layout of the MainActivity, main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
</RelativeLayout>

the code of the tablistener:

    class MyTabsListener implements ActionBar.TabListener {
    public Fragment fragment;

    public MyTabsListener(Fragment fragment) {
        this.fragment = fragment;
    }

    @Override
    public void onTabReselected(Tab tab, FragmentTransaction ft) {

    }

    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        ft.replace(R.id.fragment_container, fragment);           
    }

    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        ft.remove(fragment);
    }

}

the code of myFragment:

public static class AddAliasFragment extends Fragment {

    private static View view;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        if (view != null) {
            ViewGroup parent = (ViewGroup) view.getParent();
            if (parent != null)
                parent.removeView(view);
        }
        try {
            view = inflater.inflate(R.layout.myfragment_layout, container, false);
        } catch (InflateException e) {
            /* map is already there, just return view as it is */
        }
        return view;
    }

    public MapFragment getMapFragment(){
        return (MapFragment)getFragmentManager().findFragmentById(R.id.map_add);
    } 

}

the layout of myFragment: myfragment_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/map_add_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<EditText
    android:id="@+id/search"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:hint="@string/searchhint"
    />

<Button
    android:id="@+id/searchbtn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignBottom="@+id/search"
    android:layout_toRightOf="@id/search"
    android:text="@string/go" />

<fragment 
      android:id="@+id/map_add"
      android:tag="add"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:layout_below="@id/search"
      android:name="com.google.android.gms.maps.MapFragment"/>

the Logcat output: the nullpointer exception refers to line 103, which is the getMap() line, I have comment after it in the aforementioned code

04-02 21:23:12.122: E/AndroidRuntime(3672): FATAL EXCEPTION: main
04-02 21:23:12.122: E/AndroidRuntime(3672): java.lang.RuntimeException: Unable to start     activity ComponentInfo{com.test.test/com.test.test.MainActivity}:     java.lang.NullPointerException
04-02 21:23:12.122: E/AndroidRuntime(3672):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2307)
04-02 21:23:12.122: E/AndroidRuntime(3672):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2357)
04-02 21:23:12.122: E/AndroidRuntime(3672):     at android.app.ActivityThread.access$600(ActivityThread.java:153)
04-02 21:23:12.122: E/AndroidRuntime(3672):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1247)
04-02 21:23:12.122: E/AndroidRuntime(3672):     at android.os.Handler.dispatchMessage(Handler.java:99)
04-02 21:23:12.122: E/AndroidRuntime(3672):     at android.os.Looper.loop(Looper.java:137)
04-02 21:23:12.122: E/AndroidRuntime(3672):     at android.app.ActivityThread.main(ActivityThread.java:5226)
04-02 21:23:12.122: E/AndroidRuntime(3672):     at java.lang.reflect.Method.invokeNative(Native Method)
04-02 21:23:12.122: E/AndroidRuntime(3672):     at java.lang.reflect.Method.invoke(Method.java:511)
04-02 21:23:12.122: E/AndroidRuntime(3672):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
04-02 21:23:12.122: E/AndroidRuntime(3672):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562)
04-02 21:23:12.122: E/AndroidRuntime(3672):     at dalvik.system.NativeStart.main(Native Method)
04-02 21:23:12.122: E/AndroidRuntime(3672): Caused by: java.lang.NullPointerException
04-02 21:23:12.122: E/AndroidRuntime(3672):     at     com.test.test.MainActivity.onCreate(MainActivity.java:103)
04-02 21:23:12.122: E/AndroidRuntime(3672):     at android.app.Activity.performCreate(Activity.java:5104)
04-02 21:23:12.122: E/AndroidRuntime(3672):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
04-02 21:23:12.122: E/AndroidRuntime(3672):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2261)
04-02 21:23:12.122: E/AndroidRuntime(3672):     ... 11 more

2条回答
Fickle 薄情
2楼-- · 2019-02-25 06:52

This happens because the MapFragment has not finished loading the google map object. To fix this try overriding onActivityCreated when you create the map fragment. From your implementation of onActivityCreated then do all of your map accesses and modifications.

myMapFragment=new SupportMapFragment(){
    @Override
    public void onActivityCreated(Bundle savedInstanceState){
        //modify your map here
    }
}
查看更多
成全新的幸福
3楼-- · 2019-02-25 06:59

In mi case the problem was not specify SupportMapFragment. I have uses like this:

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/map"
    android:name="com.google.android.gms.maps.MapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    class="com.google.android.gms.maps.SupportMapFragment" />

As explained here https://stackoverflow.com/a/16663713/2411379 for Google Map V2 use.

查看更多
登录 后发表回答