0

배경 :
사용자의 위치를 ​​중심으로 텍스트에 위치 정보를 제공 할 수있는 앱을 만듭니다. 이렇게하려면 기본 설정에서 테스트하기 위해 간단한 자격 증명 검사와 서버 주소가 필요합니다.Google지도 현재 조각을 단편으로 대체하는 부분

문제 :
사용자가 다른 단편 등 마커 적절한지도 형태 (하이브리드), 자신의 위치를 ​​보여주는지도 원본 단편에서 탐색하고지도 단편 복귀하려 할 때마다, LatLng 0,0 및 일반지도 (예 : 사용자 위치 표시 없음)가 기본값입니다.

초기 생각은 다른 조각으로 전환 할 때지도 조각의 상태를 저장하고 스택에서 다른 조각을 팝 때 다시로드하려고 시도했습니다. 그러나 나는 전환해야 할 때마다 MainActivity의 현재 조각을 바꾸는 것이 더 간단 할 것이라고 생각했습니다. 따라서 앱을 열면 MainActivity는 새로운 MapFragment를 만들고 PreferencesFragment로 대체하고 'saving'이 현재 MapFragment를 만들어 현재 단편을 바꿉니다. 생각이지도 내 기능을 처음로드로 내 문제를 해결할 수 있습니다.

지도 조각 포함 MFragment의 코드 :

public class MFragment extends Fragment implements android.location.LocationListener, 
        GooglePlayServicesClient.ConnectionCallbacks, 
        GooglePlayServicesClient.OnConnectionFailedListener{ 

private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000; 
private static GoogleMap map; 
private static LocationClient lClient; 
private final static String TAG = "MFragment"; 
private String provider; 
private Location loc; 
private LocationManager lManager; 
private LatLng currentLatLng; 
private final long MIN_TIME = 1000; 
private final float MIN_DIST = 10; 
private Update updateMarkers = new Update(); 
private View view; 
private MapFragment mFrag; 

public void onCreate(Bundle savedInstanceState){ 
    super.onCreate(savedInstanceState); 
    mFrag = MapFragment.newInstance(); 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) { 
    super.onCreateView(inflater, container, savedInstanceState); 
    //sets the layout for this fragment 
    view = inflater.inflate(R.layout.fragment_map, container, false); 
    //insert MapFragment into this Fragment 
    getActivity().getFragmentManager().beginTransaction() 
      .replace(R.id.mapview, mFrag) 
      .commit(); 
    //get a handle on the map from the MapFragment 
//  map = mFrag.getMap(); 
    //instantiates the location manager 
    lManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE); 
    //instantiate the location client 
    lClient = new LocationClient(getActivity(), this, this); 
    lClient.connect(); 
    //run through initialization of all objects 
    setUpMapIfNeeded(); 
    Log.d(TAG, "Successfully created MFragment"); 
    return view; 
} 

/** 
* instantiates map from the MapFragment if map is null. 
*/ 
private void setUpMapIfNeeded() { 
    if (getActivity() != null && getActivity().getFragmentManager() != null && 
      map == null) { 
     map = mFrag.getMap(); 
     Log.d(TAG, "Map generated."); 
     setUpMap(); 
    } else if (lClient.isConnected()) { 
     updateMap(); 
    } else { 
     setUpMap(); 
    } 
} 

/** 
* sets up the location data for the map. conditional clause so that the GPS doesn't crash 
* if the app can't get a location straight away. 
*/ 
private void setUpMap() { 
    if (map != null) { 
     map.setMyLocationEnabled(true); 
     map.setMapType(GoogleMap.MAP_TYPE_HYBRID); 
     Criteria crit = new Criteria(); 
     provider = lManager.getBestProvider(crit, false); 
     if (lManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { 
      loc = lManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); 
     } else { 
      loc = lManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 
     } 
     lManager.requestLocationUpdates(provider, MIN_TIME, MIN_DIST, this); 

    } 
} 


protected void updateMap() { 
    if (servicesConnected()) { 
     map.clear(); 
     currentLatLng = new LatLng(this.loc.getLatitude(), this.loc.getLongitude()); 
     map.animateCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng, 14)); 
     map.addMarker(new MarkerOptions() 
        .position(currentLatLng) 
        .title("You")); 
     map.setOnMarkerClickListener(new OnMarkerClickListener() { 

      @Override 
      public boolean onMarkerClick(Marker m) { 
       SMSFragment sFrag = new SMSFragment(); 
       sFrag.setMarker(m); 
       getActivity().getFragmentManager().beginTransaction() 
        .replace(android.R.id.content, sFrag) 
        .commit(); 
       return false; 
      } 
     }); 

    } 
} 

/** 
* checks for connection to google play services 
* @return 
*/ 
private boolean servicesConnected() { 
    int resultCode = GooglePlayServicesUtil 
      .isGooglePlayServicesAvailable(getActivity().getApplicationContext()); 
    if (ConnectionResult.SUCCESS == resultCode) { 
     Log.d(TAG, getString(R.string.play_available)); 
     return true; 
    } else { 
     if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) { 
      GooglePlayServicesUtil 
       .getErrorDialog(resultCode, getActivity(), 
        CONNECTION_FAILURE_RESOLUTION_REQUEST).show(); 
     } else { 
      Log.i(TAG, "This device is not supported"); 
     } 
     return false; 
    } 
} 

@Override 
public void onConnectionFailed(ConnectionResult connectionResult) { 
    if (connectionResult.hasResolution()) { 
     try { 
      connectionResult 
       .startResolutionForResult(getActivity(), CONNECTION_FAILURE_RESOLUTION_REQUEST); 
     } catch (IntentSender.SendIntentException e) { 
      e.printStackTrace(); 
     } 
    } else { 
     Toast.makeText(getActivity(), R.string.connect_failed, Toast.LENGTH_SHORT).show(); 
    } 
} 

/** 
* Called after location client connects 
*/ 
@Override 
public void onConnected(Bundle arg0) { 
    updateMap(); 
} 

/** 
* simple display message after disconnecting. 
*/ 
@Override 
public void onDisconnected() { 
    Toast.makeText(getActivity(), R.string.disconnected, Toast.LENGTH_SHORT).show(); 
} 


public void onStart() { 
    super.onStart(); 
    lClient.connect(); 
    setUpMapIfNeeded(); 
} 

public void onResume() { 
    super.onResume(); 
    lClient.connect(); 
    setUpMapIfNeeded(); 
} 

public void onPause() { 
    lClient.disconnect(); 
    super.onPause(); 
} 

public void onStop() { 
    lClient.disconnect(); 
    super.onStop(); 
} 

public void onDestroy() { 
    lClient.disconnect(); 
    super.onDestroy(); 
} 

@Override 
public void onLocationChanged(Location location) { 
    this.loc = location; 
    updateMap(); 
} 

@Override 
public void onProviderDisabled(String provider) { 
    // TODO Auto-generated method stub 

} 

@Override 
public void onProviderEnabled(String provider) { 
    // TODO Auto-generated method stub 

} 

@Override 
public void onStatusChanged(String provider, int status, Bundle extras) { 
    // TODO Auto-generated method stub 

} 


public void updateMarkers(List<Record> records){ 
    //update map with markers corresponding to each latitude, longitude passed back from records 
    for (Record r : records){ 
     map.addMarker(new MarkerOptions() 
       .position(new LatLng(r.getValueOfLatitude(), r.getValueOfLongitude()))); 
    } 
} 

private class Update extends AsyncTask<Void, Void, Boolean> { 

    private List<Record> records; 

    protected Update() { 
     super(); 
     records = new ArrayList<Record>(); 
    } 

    @Override 
    protected Boolean doInBackground(Void... params) { 
     Connect conn = new Connect(getActivity()); 
     try { 
      records = conn.getAll(); 
      return true; 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return false; 
    } 

    protected void onPostExecute(Boolean result) { 
     if (result) { 
      updateMarkers(records); 
     } else { 
      Toast.makeText(getActivity(), R.string.rec_fail, Toast.LENGTH_SHORT).show(); 
     } 
    } 
} 
} 

그리고 (PrefsFragment에서 MFragment에) 다른 조각에서 조각을 교체하는 예 :

register = (Button) v.findViewById(R.id.register); 

    save.setOnClickListener(new View.OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      saveToPreferences(v); 
      ((MainActivity)getActivity()).replaceFragment(); 
     } 
    }); 

    register.setOnClickListener(new View.OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      getActivity().getFragmentManager().beginTransaction() 
       .replace(android.R.id.content, new RegFragment()) 
       .commit(); 
     } 
    }); 

    return v; 
} 

를 버튼은 호출 저장을 메소드를 MainActivity에서 MapFragment로 대체하려고 시도했지만, FragmentManager를 사용하여 등록 버튼과 유사한 메소드를 사용하여 맵 문제를 해결하지는 않습니다.

도움을 주시면 감사하겠습니다.

답변

0

정말 필요하지 않으면 다른 조각 안에 조각을 넣지 마십시오. 그렇게하기로 한 경우처럼 ActivityFragmentManager을 사용할 수 없습니다. 대신에 컨테이너 조각의 자식 조각 관리자를 사용하여 getChildFragmentManager()을 호출하여 자식 조각을 삽입 할 조각 트랜잭션을 만들어야합니다.

API 수준 17 (Android 4.2) 이후 또는 가장 최신 Android 지원 라이브러리를 사용하여 지원됩니다. 기본적으로 지원 라이브러리를 항상 사용하는 것이 좋습니다.

+0

내가 액티비티 내에서 Map을 처리하는 가장 좋은 방법은 무엇일까? 액티비티가 setUpMapIfNeeded(), setUpMap(), updateMap(), 등등과지도는 여전히 일부 사용자 정의를 사용할 수 있습니까? 앱에서지도를 사용하는 것은 이번이 처음입니다. 경험 부족에 사과드립니다. – fakataha

+0

MapFragment 또는 SupportMapFragment를 확장하는 클래스를 만들고 그 안에지도 논리 인 setUpMapIfNeeded() 메서드와 나머지를 추가하는 것이 좋습니다. – BladeCoder