【问题标题】:Android app - Google maps location markers disappearing from Map fragmentAndroid 应用程序 - 谷歌地图位置标记从地图片段中消失
【发布时间】:2022-01-26 04:49:45
【问题描述】:

我对 Android 开发非常陌生。这是我第一次尝试创建应用程序。我创建了一个选项卡式导航应用程序,有 4 个片段可以在它们之间导航:来自MainActivity 的主页、搜索、地图和帐户片段。我在MapsFragment 中使用了SupportMapFragment 来显示地图。访问MapsFragment 时,地图会显示并放大我的当前位置,并突出显示从 Firebase 实例检索到的某些重要位置,并带有标记。

当我第一次启动应用程序并访问地图片段时,一切都按预期工作。我放大了当前位置,并看到了所有必需的标记。当我从那一点切换到不同的片段时,就会出现问题。当我导航到 Home、Search 或 Account 片段,然后返回到 Map 片段时,任何位置标记都不再可见。我仍然可以看到我当前的位置,并在打开地图片段时放大它,但其他标记消失了。

我最初认为这与每次导航到另一个片段时重新创建片段有关,因为我使用.replace(container, fragment) 根据从底部导航栏中单击的按钮来更改片段。但我观察到地图片段会加载我当前的位置并正确放大,因此loadMap() 函数被执行但不知何故标记没有出现。如果我重新启动应用程序,标记会在我第一次打开地图片段时正常运行。

如果我在导航到其他片段后返回地图时如何保持标记显示在地图上,我们将不胜感激。谢谢!

这是我的MapsFragment.java的预览:

public class MapsFragment extends Fragment {
    private SupportMapFragment supportMapFragment;
    private AutocompleteSupportFragment autocompleteSupportFragment;
    private FusedLocationProviderClient client;
    private Geocoder geocoder;
    private ArrayList<String> mPostCodes;
    private ArrayList<Marker> searchMarker;
    private DatabaseReference locationRef;
    private DatabaseReference businessRef;
    private String apiKey;


    public MapsFragment() {
        // Required empty public constructor
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        // Initialize Map fragment
        supportMapFragment = (SupportMapFragment)
                getChildFragmentManager().findFragmentById(R.id.google_map);

        // initialize Places client
        apiKey = getString(R.string.map_key);
        if(!Places.isInitialized()){
            Places.initialize(requireActivity(), apiKey);
        }
        PlacesClient placesClient = Places.createClient(requireActivity());

        // Initialize AutoComplete search bar and set autocomplete parameters
        autocompleteSupportFragment = (AutocompleteSupportFragment)
                getChildFragmentManager().findFragmentById(R.id.autocomplete_fragment);
        autocompleteSupportFragment.setTypeFilter(TypeFilter.ADDRESS);
        autocompleteSupportFragment.setLocationBias(RectangularBounds.newInstance(
                new LatLng(55.836229, -4.252612),
                new LatLng(55.897463, -4.325364)));
        autocompleteSupportFragment.setCountries("UK");
        autocompleteSupportFragment.setPlaceFields(Arrays.asList(Place.Field.ID, Place.Field.NAME, Place.Field.LAT_LNG));

        // initialize search marker list
        searchMarker = new ArrayList<Marker>();

        // Initialize client to get user's last location on device
        client = LocationServices.getFusedLocationProviderClient(requireActivity());

        // Initialize geocoder to convert business postcodes to latlng coordinates
        mPostCodes = new ArrayList<>();
        geocoder = new Geocoder(requireActivity());

        // Get business locations
        locationRef = FirebaseDatabase.getInstance().getReference("Business Locations");
        locationRef.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                if(snapshot.exists()){
                    for(DataSnapshot locationSnapshot : snapshot.getChildren()){
                        BusinessLocation location = locationSnapshot.getValue(BusinessLocation.class);
                        mPostCodes.add(location.getPostCode());
                    }
                }
            }
            @Override
            public void onCancelled(@NonNull DatabaseError error) {
                Log.i("Location error", "Error retrieving location: ", error.toException().getCause());
            }
        });

        // initialize reference to business table
        businessRef = FirebaseDatabase.getInstance().getReference("Businesses");

        // render the map
        loadMap();
    }

    private void loadMap() {
        if (ActivityCompat.checkSelfPermission(requireActivity(),
                Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            Task<Location> task = client.getLastLocation();

            task.addOnSuccessListener(new OnSuccessListener<Location>() {
                @Override
                public void onSuccess(Location location) {
                    if(location != null){
                        supportMapFragment.getMapAsync(new OnMapReadyCallback() {
                            @Override
                            public void onMapReady(@NonNull GoogleMap googleMap) {

                                // autocomplete place search
                                autocompleteSupportFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
                                    @Override
                                    public void onError(@NonNull Status status) {
                                        Log.i("AutoComplete error", "error status: " + status);
                                    }

                                    @Override
                                    public void onPlaceSelected(@NonNull Place place) {
                                        LatLng placeLatLng = place.getLatLng();

                                        MarkerOptions placeOptions = new MarkerOptions().position(placeLatLng)
                                                .title("search")
                                                .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE));

                                        if(!searchMarker.isEmpty()){
                                            Marker searchedMarker = searchMarker.get(0);
                                            searchMarker.remove(searchedMarker);
                                            searchedMarker.remove();
                                        }

                                        final Marker marker  = googleMap.addMarker(placeOptions);
                                        searchMarker.add(marker);
                                        googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(placeLatLng, 10));
                                    }
                                });

                                LatLng myLatLng = new LatLng(location.getLatitude(),
                                        location.getLongitude());

                                // show current location
                                if (ActivityCompat.checkSelfPermission(requireActivity(),
                                        Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                                    googleMap.setMyLocationEnabled(true);
                                    googleMap.getUiSettings().setZoomControlsEnabled(true);
                                    googleMap.getUiSettings().setCompassEnabled(true);
                                }

                                // show markers for all businesses on database
                                for(String code : mPostCodes){
                                    try{
                                        Address address = geocoder.getFromLocationName(code, 1).get(0);
                                        LatLng latLng = new LatLng(address.getLatitude(), address.getLongitude());

                                        MarkerOptions options = new MarkerOptions().position(latLng);
                                        googleMap.addMarker(options);
                                    }catch (IOException e){
                                       Toast.makeText(requireActivity(), e.getMessage(), Toast.LENGTH_LONG).show();
                                    }
                                }
                                googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(myLatLng, 10));
                            }
                        });
                    }
                }
            });
        }else {
            ActivityCompat.requestPermissions(requireActivity(),
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 44);
        }
    }

    private ActivityResultLauncher<String> mPermissionResult = registerForActivityResult(
            new ActivityResultContracts.RequestPermission(),
            result -> {
                if(result){
                    loadMap();
                }
            }
    );
}

这是我的fragment_maps.xml 文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".fragments.MapsFragment">

    <fragment
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/google_map"
        android:name="com.google.android.gms.maps.SupportMapFragment"/>

    <fragment
        android:id="@+id/autocomplete_fragment"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:name="com.google.android.libraries.places.widget.AutocompleteSupportFragment"/>

</RelativeLayout>

这是我的MainActivity.kt 文件:

class MainActivity : AppCompatActivity() {

    private val homeFragment = HomeFragment()
    private val searchFragment = SearchFragment()
    private val mapFragment = MapsFragment()
    private val accountFragment = AccountFragment()
    private val guestAccountFragment = GuestAccountFragment()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        replaceFragment(homeFragment)

        bottom_navigation.setOnItemSelectedListener {
            when (it.itemId) {
                R.id.id_home -> replaceFragment(homeFragment)
                R.id.id_search -> replaceFragment(searchFragment)
                R.id.id_map -> replaceFragment(mapFragment)
                R.id.id_account -> {
                    if(FirebaseAuth.getInstance().currentUser == null){
                        replaceFragment(guestAccountFragment)
                    }else {
                        replaceFragment(accountFragment)
                    }
                }
            }
            true
        }

    }

    private fun replaceFragment(fragment : Fragment){
        if(fragment != null){
            val transaction = supportFragmentManager.beginTransaction()
            transaction.replace(R.id.fragment_container, fragment)
            transaction.commit()
        }
    }
}

【问题讨论】:

    标签: java android kotlin google-maps android-fragments


    【解决方案1】:

    发生这种情况是因为您的地图片段在替换新片段后“死亡”。试试这个解决方案:

    首先你需要在你的主要活动中添加所有可以调用的片段:

    getSupportFragmentManager().beginTransaction()
                    .add(R.id.fragment_container_view, fragment1)
                    .add(R.id.fragment_container_view, fragment2)
                    .add(R.id.fragment_container_view, fragment3)
                    .commit();
    

    添加后,您可以通过调用此代码来更改它们:

    getSupportFragmentManager().beginTransaction()
                        .show(fragment2)
                        .hide(fragment1)
                        .commit();
    

    代码是用Java写的,但我认为没有问题

    【讨论】:

      猜你喜欢
      • 2012-12-19
      • 1970-01-01
      • 2016-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多