谷歌地图未显示在 ViewPager 的选项卡片段上 [英] Google Map not showing on tab fragment in ViewPager

查看:15
本文介绍了谷歌地图未显示在 ViewPager 的选项卡片段上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个新的 Android 项目.

第一个活动是使用滑块菜单和片段.在第一个片段上有一个列表视图 (PrimaryFragmentDormir.java).选择其中一行后,将启动一个新活动.最后一个活动使用三个选项卡来显示有关所选行对象的不同信息.列表视图是从远程 JSON 文件加载的.第一个选项卡显示有关所选对象的详细信息,第二个选项卡应显示地图.

我已按照官方文档设置了在我的应用中包含 Google 地图所需的所有内容,至少我是这么认为的.当用户选择第二个选项卡时,会显示一个空白屏幕,并在左下角显示 Google 徽标.

这是 Android 清单:

<?xml version="1.0" encoding="utf-8"?><清单 xmlns:android="http://schemas.android.com/apk/res/android"package="com.solinpromex.elpasojuarezexperience" ><使用权限 android:name="android.permission.INTERNET"/><使用权限 android:name="android.permission.ACCESS_NETWORK_STATE"/><使用权限 android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><使用权限android:name="android.permission.ACCESS_COARSE_LOCATION"/><使用权限android:name="android.permission.ACCESS_FINE_LOCATION"/><使用权限 android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/><使用功能 android:glEsVersion="0x00020000" android:required="true"/><使用库 android:name="com.google.android.maps"/><应用android:name=".app.AppController"机器人:allowBackup="真"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:theme="@style/AppTheme" ><元数据android:name="com.google.android.gms.version"android:value="@integer/google_play_services_version"/><元数据android:name="com.google.android.maps.v2.API_KEY"android:value="..隐藏在这里..."/><活动android:name=".Inicio"android:label="@string/app_name" ><意图过滤器><action android:name="android.intent.action.MAIN"/><类别 android:name="android.intent.category.LAUNCHER"/></意图过滤器></活动><活动android:name=".MainActivity"android:label="@string/app_name" ></活动><活动android:name=".Detelle_Hotel"android:label="@string/title_activity_detalle__hotel" ></活动></应用程序></清单>

这里是承载标签的主要活动:

导入android.support.v4.view.ViewPager;导入android.support.v7.app.AppCompatActivity;导入android.os.Bundle;导入android.support.v7.widget.Toolbar;导入 android.view.Menu;导入android.view.MenuItem;公共类 Detelle_Hotel 扩展 AppCompatActivity {//声明你的视图和变量公共字符串 nombre_hotel_recibido, foto_hotel_recibido, descripcion_hotel_recibido,direccion_hotel_recibido,web_hotel,tel_hotel,tel_reservas,zona_hotel,facebook_hotel,twitter_hotel;私人 int hotel_num_estrellas,id_hotel;私人双 calificacion_hotel,latitud_hotel,longitud_hotel;工具栏工具栏;ViewPager 寻呼机;ViewPagerAdapter 适配器;SlidingTabLayout 选项卡;CharSequence Titles[]={"Info","Mapa","Opinión"};int Numboftabs = 3;@覆盖protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_detalle__hotel);nombre_hotel_recibido = getIntent().getStringExtra("nombre_hotel");direccion_hotel_recibido = getIntent().getStringExtra("direccion_hotel");descripcion_hotel_recibido = getIntent().getStringExtra("descripcion_hotel");foto_hotel_recibido = getIntent().getStringExtra("foto_hotel");hotel_num_estrellas = getIntent().getIntExtra("num_estrellas",0);setTitle(nombre_hotel_recibido);//创建工具栏并将其设置为活动的工具栏工具栏=(工具栏)findViewById(R.id.tool_bar);setSupportActionBar(工具栏);//创建 ViewPagerAdapter 并传递 Fragment Manager、选项卡的标题和选项卡数.适配器 = 新 ViewPagerAdapter(getSupportFragmentManager(),Titles,Numboftabs);//分配 ViewPager 视图并设置适配器pager = (ViewPager) findViewById(R.id.pager);pager.setAdapter(适配器);//分配滑动选项卡布局视图tabs = (SlidingTabLayout) findViewById(R.id.tabs);tabs.setDistributeEvenly(true);//要使 Tabs Fixed 设置为 true,这会使选项卡在可用宽度中均匀分布//为 Tab View 的滚动条指示器设置自定义颜色tabs.setCustomTabColorizer(new SlidingTabLayout.TabColorizer() {@覆盖公共 int getIndicatorColor(int position) {返回 getResources().getColor(R.color.rojomodesto);}});//为 SlidingTabsLayout 设置 ViewPagertabs.setViewPager(pager);}}

这里是第二个标签的代码:

导入android.os.Bundle;导入 android.support.annotation.Nullable;导入android.support.v4.app.Fragment;导入 android.view.LayoutInflater;导入android.view.View;导入android.view.ViewGroup;导入 com.google.android.gms.maps.GoogleMap;导入 com.google.android.gms.maps.model.LatLng;导入 com.google.android.gms.maps.model.MarkerOptions;导入 com.google.android.gms.maps.GoogleMap;导入 com.google.android.gms.maps.MapFragment;导入 com.google.android.gms.maps.model.BitmapDescriptorFactory;导入 com.google.android.gms.maps.model.LatLng;导入 com.google.android.gms.maps.model.Marker;导入 com.google.android.gms.maps.model.MarkerOptions;公共类 Tab2 扩展片段 {私人谷歌地图;静态最终 LatLng HAMBURG = new LatLng(53.558, 9.927);静态最终 LatLng KIEL = new LatLng(53.551, 9.993);@覆盖public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup 容器, @Nullable Bundle savedInstanceState) {查看 v = inflater.inflate(R.layout.tab_2, container, false);返回 v;}@覆盖公共无效 onActivityCreated(捆绑状态){super.onActivityCreated(state);map = ((MapFragment) getActivity().getFragmentManager().findFragmentById(R.id.map)).getMap();如果(地图!=空){汉堡标记 = map.addMarker(new MarkerOptions().position(HAMBURG).title("汉堡"));标记基尔 = map.addMarker(new MarkerOptions().位置(基尔).title("基尔").snippet("基尔很酷").icon(位图描述符工厂.fromResource(R.drawable.res)));}}}

我已经检查了 API 密钥并且没问题.感谢您的支持.

解决方案

问题是当你调用 getActivity().getFragmentManager() 时,你得到的是 Activity 的 Fragment Manager.p>

由于您在 Fragment 中使用嵌套 MapFragment,因此您需要使用

I am working in a new Android project.

The first activity is using a slider menu and fragments. On the first fragment there is a list view (PrimaryFragmentDormir.java). After selecting one of the rows, a new activity is launched. This last activity uses three tabs, to show different information about the selected row object. The listview is loaded from remote JSON files. The first tab shows details about the selected object, the second tab should show a map.

I have followed the official documentation to setup all the needed to include Google Maps on my app, at least I think so. When the user selects the second tab, a blank screen is shown with the Google logo at the left bottom side.

Here is the Android Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.solinpromex.elpasojuarezexperience" >

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />


    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
    <uses-feature android:glEsVersion="0x00020000" android:required="true"/>

    <uses-library android:name="com.google.android.maps"/>


    <application
        android:name=".app.AppController"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
        <meta-data
            android:name="com.google.android.maps.v2.API_KEY"
            android:value="..hidden here..." />
        <activity
            android:name=".Inicio"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
        </activity>
        <activity
            android:name=".Detalle_Hotel"
            android:label="@string/title_activity_detalle__hotel" >
        </activity>



    </application>

</manifest>

Here the main activity that hosts the tabs:

import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;

public class Detalle_Hotel extends AppCompatActivity {
    // Declaring Your View and Variables

    public String nombre_hotel_recibido, foto_hotel_recibido, descripcion_hotel_recibido,direccion_hotel_recibido,web_hotel,tel_hotel,tel_reservas,zona_hotel,facebook_hotel,twitter_hotel;
    private int hotel_num_estrellas, id_hotel;
    private double calificacion_hotel,latitud_hotel,longitud_hotel;

    Toolbar toolbar;
    ViewPager pager;
    ViewPagerAdapter adapter;
    SlidingTabLayout tabs;
    CharSequence Titles[]={"Info","Mapa","Opinión"};
    int Numboftabs =3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_detalle__hotel);

        nombre_hotel_recibido = getIntent().getStringExtra("nombre_hotel");
        direccion_hotel_recibido = getIntent().getStringExtra("direccion_hotel");
        descripcion_hotel_recibido = getIntent().getStringExtra("descripcion_hotel");
        foto_hotel_recibido = getIntent().getStringExtra("foto_hotel");
        hotel_num_estrellas = getIntent().getIntExtra("num_estrellas",0);
        setTitle(nombre_hotel_recibido);

        // Creating The Toolbar and setting it as the Toolbar for the activity

        toolbar = (Toolbar) findViewById(R.id.tool_bar);
        setSupportActionBar(toolbar);


        // Creating The ViewPagerAdapter and Passing Fragment Manager, Titles fot the Tabs and Number Of Tabs.
        adapter =  new ViewPagerAdapter(getSupportFragmentManager(),Titles,Numboftabs);

        // Assigning ViewPager View and setting the adapter
        pager = (ViewPager) findViewById(R.id.pager);
        pager.setAdapter(adapter);

        // Assiging the Sliding Tab Layout View
        tabs = (SlidingTabLayout) findViewById(R.id.tabs);
        tabs.setDistributeEvenly(true); // To make the Tabs Fixed set this true, This makes the tabs Space Evenly in Available width

        // Setting Custom Color for the Scroll bar indicator of the Tab View
        tabs.setCustomTabColorizer(new SlidingTabLayout.TabColorizer() {
            @Override
            public int getIndicatorColor(int position) {
                return getResources().getColor(R.color.rojomodesto);
            }
        });

        // Setting the ViewPager For the SlidingTabsLayout
        tabs.setViewPager(pager);



    }



}

Here the code for the second tab:

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.google.android.gms.maps.GoogleMap;

import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

import com.google.android.gms.maps.GoogleMap;

import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;



public class Tab2 extends Fragment {

    private GoogleMap map;
    static final LatLng HAMBURG = new LatLng(53.558, 9.927);
    static final LatLng KIEL = new LatLng(53.551, 9.993);

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.tab_2, container, false);

        return v;


    }


    @Override
    public void onActivityCreated(Bundle state) {
        super.onActivityCreated(state);


        map = ((MapFragment) getActivity().getFragmentManager().findFragmentById(R.id.map))
                .getMap();

        if (map!=null){
            Marker hamburg = map.addMarker(new MarkerOptions().position(HAMBURG)
                    .title("Hamburg"));
            Marker kiel = map.addMarker(new MarkerOptions()
                    .position(KIEL)
                    .title("Kiel")
                    .snippet("Kiel is cool")
                    .icon(BitmapDescriptorFactory
                            .fromResource(R.drawable.res)));
        }

    }

}

I have checked out the API key and it is OK. Thank you for your support.

解决方案

The problem is that when you call getActivity().getFragmentManager(), you're getting the Activity's Fragment Manager.

Since you're using a nested MapFragment inside of a Fragment, you need to use getChildFragmentManager(): For example:

GoogleMap mapFragment = ((MapFragment) getChildFragmentManager()
            .findFragmentById(R.id.map)).getMap();

So, replace this:

map = ((MapFragment) getActivity().getFragmentManager().findFragmentById(R.id.map))
                .getMap();

With this:

map = ((MapFragment) getChildFragmentManager().findFragmentById(R.id.map))
                .getMap();

However, while that would work, you would be better off having your Fragment extend MapFragment or SupportMapFragment, that way you wouldn't need to have nested Fragments, and you would avoid the potential of running into this problem.

Solution using TabLayout from the support library:

As ActionBar Tabs are deprecated, this is now the best way to implement tabs with a ViewPager. Notice this is done without use of a nested SupportMapFragment, and instead has the map Fragment extent SupportMapFragment:

MainActivity imports:

import android.content.Context;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.support.v4.app.FragmentManager;
import android.view.View;
import android.widget.TextView;

MainActivity class:

public class MainActivity extends AppCompatActivity {

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

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        // Get the ViewPager and set it's PagerAdapter so that it can display items
        ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
        PagerAdapter pagerAdapter =
                new PagerAdapter(getSupportFragmentManager(), MainActivity.this);
        viewPager.setAdapter(pagerAdapter);

        // Give the TabLayout the ViewPager
        TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
        tabLayout.setupWithViewPager(viewPager);

        // Iterate over all tabs and set the custom view
        for (int i = 0; i < tabLayout.getTabCount(); i++) {
            TabLayout.Tab tab = tabLayout.getTabAt(i);
            tab.setCustomView(pagerAdapter.getTabView(i));
        }
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    class PagerAdapter extends FragmentPagerAdapter {

        String tabTitles[] = new String[] { "Tab One", "Tab Two", "Tab Three", };
        Context context;

        public PagerAdapter(FragmentManager fm, Context context) {
            super(fm);
            this.context = context;
        }

        @Override
        public int getCount() {
            return tabTitles.length;
        }

        @Override
        public Fragment getItem(int position) {

            switch (position) {
                case 0:
                    return new BlankFragment();
                case 1:
                    return new BlankFragment();
                case 2:
                    return new MapFragment();
            }

            return null;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            // Generate title based on item position
            return tabTitles[position];
        }

        public View getTabView(int position) {
            View tab = LayoutInflater.from(MainActivity.this).inflate(R.layout.custom_tab, null);
            TextView tv = (TextView) tab.findViewById(R.id.custom_text);
            tv.setText(tabTitles[position]);
            return tab;
        }

    }
}

The MapFragment, notice that it directly extends SupportMapFragment instead of having a nested SupportMapFragment inside it:

import android.util.Log;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

public class MapFragment extends SupportMapFragment implements
        OnMapReadyCallback {

    private final LatLng HAMBURG = new LatLng(53.558, 9.927);
    private final LatLng KIEL = new LatLng(53.551, 9.993);

    private static final String ARG_SECTION_NUMBER = "section_number";

    private GoogleMap mMap;
    private Marker marker;

    public MapFragment() {
    }

    @Override
    public void onResume() {
        super.onResume();

        Log.d("MyMap", "onResume");
        setUpMapIfNeeded();
    }

    private void setUpMapIfNeeded() {

        if (mMap == null) {

            Log.d("MyMap", "setUpMapIfNeeded");

            getMapAsync(this);
        }
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        Log.d("MyMap", "onMapReady");
        mMap = googleMap;
        setUpMap();
    }

    private void setUpMap() {

        mMap.setMyLocationEnabled(true);
        mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
        mMap.getUiSettings().setMapToolbarEnabled(false);


        mMap.setMyLocationEnabled(true);
        mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
        mMap.getUiSettings().setMapToolbarEnabled(false);

        Marker hamburg = mMap.addMarker(new MarkerOptions().position(HAMBURG)
                .title("Hamburg"));
        Marker kiel = mMap.addMarker(new MarkerOptions()
                .position(KIEL)
                .title("Kiel")
                .snippet("Kiel is cool")
                .icon(BitmapDescriptorFactory
                        .fromResource(R.mipmap.ic_launcher)));

        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(HAMBURG, 15));

        mMap.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);
    }
}

layout xml for the Activity:

<RelativeLayout
    android:id="@+id/main_layout"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:background="?attr/colorPrimary"
        android:elevation="6dp"
        android:minHeight="?attr/actionBarSize"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

    <android.support.design.widget.TabLayout
        android:id="@+id/tab_layout"
        app:tabMode="fixed"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/toolbar"
        android:background="?attr/colorPrimary"
        android:elevation="6dp"
        app:tabTextColor="#d3d3d3"
        app:tabSelectedTextColor="#ffffff"
        app:tabIndicatorColor="#ff00ff"
        android:minHeight="?attr/actionBarSize"
        />

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="fill_parent"
        android:layout_below="@id/tab_layout"/>

</RelativeLayout>

custom_tab.xml, which is the layout for each tab:

<?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">
    <TextView
        android:id="@+id/custom_text"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:background="?attr/selectableItemBackground"
        android:gravity="center"
        android:textSize="16dip"
        android:textColor="#ffffff"
        android:singleLine="true"
        />
</LinearLayout>

Gradle:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:23.0.1'
    compile 'com.android.support:design:23.0.1'
    compile 'com.google.android.gms:play-services:7.0.0'
}

Result:

这篇关于谷歌地图未显示在 ViewPager 的选项卡片段上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆