簡體   English   中英

Android 應用程序 - 谷歌地圖位置標記從 Map 片段消失

[英]Android app - Google maps location markers disappearing from Map fragment

我對 Android 開發非常陌生。 這是我第一次嘗試創建應用程序。 我創建了一個選項卡式導航應用程序,有 4 個片段可以在它們之間導航:主頁、搜索、Map 和來自MainActivity的 Account 片段。 我在MapsFragment中使用了SupportMapFragment來顯示 map。 在訪問MapsFragment時,map 顯示並放大我的當前位置並突出顯示某些重要位置,這些位置是從 Firebase 實例檢索到的,帶有標記。

當我第一次啟動應用程序並訪問 Map 片段時,一切都按預期工作。 我放大了當前位置,並看到了所有必需的標記。 當我從那一點切換到不同的片段時,就會出現問題。 當我導航到主頁、搜索或帳戶片段,然后返回 Map 片段時,不再顯示任何位置標記。 我仍然可以看到我當前的位置並在打開 Map 片段時放大它,但其他標記消失了。

我最初認為這與每次導航到另一個片段時重新創建的片段有關,因為我使用.replace(container, fragment)根據從底部導航欄中單擊的按鈕來更改片段。 但我觀察到 Map 片段會加載我當前的位置並正確放大,因此loadMap() function 被執行,但不知何故標記沒有出現。 如果我重新啟動應用程序,標記會在我第一次打開 Map 片段時正常運行。

當我在導航到其他片段后返回 Map 時,如何保持標記顯示在 Map 上的任何幫助將不勝感激。 謝謝!

這是我的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()
        }
    }
}

發生這種情況是因為您的 map 片段在更換新片段后“死亡”。 試試這個解決方案:

首先,您需要在主要活動中添加所有可以調用的所需片段:

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 但我認為沒有問題

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM