Android mapview с фрагментами не может быть добавлен дважды? - PullRequest
11 голосов
/ 19 октября 2011

Я использую класс совместимости Android с хаком для использования представлений карты во фрагменте, найденном здесь: https://github.com/petedoyle/android-support-v4-googlemaps

К сожалению, я обнаружил, что если фрагмент карты удаляется из действия, а затемпосле прочтения я получаю сообщение об ошибке «Вам разрешено иметь только один MapView в MapActivity».

Я понимаю принцип, лежащий в основе этой ошибки, и попытался уничтожить представление карты в методе фрагментов onPause. К сожалению, я могукажется, полностью не разрушает вид карты, так как я все еще его получаю. Мой код выглядит так:

private RelativeLayout layout; 
private MapView mp;

public void onResume(){
    super.onResume();
    Bundle args = getArguments();
    if(mp == null)
    {
        mp = new MapView(getActivity(), this.getString(R.string.map_api_key)); 
        mp.setClickable(true);
    }

    String request = args.getString("requestId");
    layout = (RelativeLayout) getView().findViewById(R.id.mapholder);
    layout.addView(mp);
    //TextView txt = (TextView) getView().findViewById(R.id.arguments);
    //txt.setText(request);
}

public void onPause(){
    super.onPause();
    layout.removeView(mp);
    mp = null;
}

Есть ли у кого-нибудь мысли о том, какую ссылку я здесь пренебрегаю уничтожать?

Ответы [ 5 ]

15 голосов
/ 30 ноября 2011

Я столкнулся с той же проблемой.Вот как я это решил:

  • Так как в упражнении должен быть только один экземпляр mapView, я инициализирую его в методе onCreate в Activity:

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // initialize MapView programmatically to be used in Fragment :
        this.mActivityMapView = new MapView(MainActivity.this, getString(R.string.debug_mapview_apikey));
    
        setContentView(R.layout.activity_main);
    }
    
  • Затем я восстанавливаю его во фрагменте метода onCreateView:

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        this.mMapView = ((MainActivity) getActivity()).getMapView();
        return this.mMapView;
    }
    
  • И уничтожаю его во фрагменте метода onDestroy:

    public void onDestroy() {
        NoSaveStateFrameLayout parentView = (NoSaveStateFrameLayout) this.mMapView.getParent();
        parentView.removeView(this.mMapView);
        super.onDestroy();
    }
    
6 голосов
/ 05 февраля 2012

Ответы Макса и Бликера работают хорошо, но вы должны проявить особую осторожность, если хотите поддерживать изменения ориентации экрана, как и я.Оказывается, когда вы поворачиваете экран, он снова вызывает OnCreateView, не вызывая метод onPause, таким образом добавляя представление карты дважды.Чтобы это исправить, внутри OnCreateView я сделал следующее:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
    this.mMapView = ((MyGameActivity) getActivity()).getMapView();
    if (this.mMapView.getParent()!=null)
    {
        NoSaveStateFrameLayout parentView = (NoSaveStateFrameLayout) this.mMapView.getParent();
        parentView.removeView(this.mMapView);
    }
    return this.mMapView;
}
6 голосов
/ 23 декабря 2011

Возможно, вы захотите удалить представление карты в методе onPause (вместо метода onDestroy)

public void onPause() {
    NoSaveStateFrameLayout parentView = (NoSaveStateFrameLayout) this.mMapView.getParent();
    parentView.removeView(this.mMapView);
    super.onPause();}

Таким образом, вы можете добавить MapFragment в backstack.(FragmentTransaction.addToBackStack предотвращает уничтожение фрагмента)

4 голосов
/ 27 сентября 2012

Я пытался получить простое решение этой проблемы.В классе, который обрабатывает мои данные View (расширение RelativeLayout), я объявил private static MapView myMapView;.

Затем переопределите метод onFinishInflate (), как в следующем фрагменте кода:

    @Override
protected void onFinishInflate() {  
    super.onFinishInflate();

    //myMapView = (MapView) findViewById(R.id.map_view);
    if (myMapView==null) 
        myMapView = new MapView(context, getResources().getString(R.string.map_view_api_key));  
    if (myMapView.getParent() != null)
        ((ViewGroup)myMapView.getParent()).removeView(myMapView);

    myMapView.setClickable(true);
    myMapView.setEnabled(true);
    RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
    myMapView.setLayoutParams(lp);          
    this.addView(myMapView);

}

Thisто есть у вас есть только один экземпляр MapView.

0 голосов
/ 02 января 2016

Вот как я решил эту проблему в случае фрагмента.

Создать макет

 <LinearLayout
        android:id="@+id/ll_mapcontainer"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" />

Вы можете разместить этот макет в любом месте вашего XML-файла, где вы хотите отобразить карту

Теперь код будет таким:

package com.yuviii.sample;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
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.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.yuviii.sample.R;

/**
 * Created by yubraj Poudel on 12/20/15.
 */
public class ContactUsFragment extends Fragment  {
    static final LatLng PRACTICAL_ANSWER_LOCATION = new LatLng(53.558, 9.927);
    private SupportMapFragment fragment;
    private GoogleMap map;

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



    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
                    initializeMap();
    }

    private void initializeMap() {

        FragmentManager fm = getChildFragmentManager();
        fragment = (SupportMapFragment) fm.findFragmentById(R.id.ll_mapcontainer);
        if (fragment == null) {
            fragment = SupportMapFragment.newInstance();
            fm.beginTransaction().replace(R.id.ll_mapcontainer, fragment).commit();
        }

    }
    @Override
    public void onResume() {
        super.onResume();
        if (map == null) {
            map = fragment.getMap();
            map.addMarker(new MarkerOptions().position(PRACTICAL_ANSWER_LOCATION));
        }
    }   
}

Это работает для меня. Наслаждайтесь !!!

...