2015-10-15 84 views
4

夥計們,在按鈕單擊片段訪問方法從MainActivity

我試圖向用戶發送當前的經緯度從點擊一個按鈕在MainActivity到MapFragment(片段)。我使用的界面,從片段中實現inMainActivity但是當我嘗試接取從片段onButtonClick的方法,我收到了

在android.app.ActivityThread.main(ActivityThread.java:5221) 在java.lang.reflect中.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:899) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694) 引起:java.lang.NullPointerException:嘗試調用虛擬方法void com.xtechkid.blah.threadingapplication.M apDemoActivity.setupCurrlocation(com.google.android.gms.maps.model.LatLng)」上的空對象引用 在com.xtechkid.sudheej.threadingapplication.MainActivity.findLocation(MainActivity.java:67)

我的代碼如下

這裏是地圖片段

public class MapDemoActivity extends Fragment { 
final LatLng MU = new LatLng(40.8874245, 67.0200729); 
private GoogleMap mMap; // Might be null if Google Play services APK is not available. 
CommInter mCallback; 
public interface CommInter { 
    public void communicatesWithActivity(double lati,double longi); 
} 


@Override 
public void onAttach(Context context) { 
    super.onAttach(context); 

    Activity a; 

    // if (context instanceof Activity){ 
     a=(Activity) context; 
    //} 

    try{ 
     mCallback = (CommInter) a; 
    }catch (ClassCastException e){ 
     throw new ClassCastException(a.toString()); 
    } 
} 
@Override 
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 
    View view = inflater.inflate(R.layout.activity_main, container, false); 

    //setUpMapIfNeeded(); 

    if (mMap != null) { 
     mMap.setMyLocationEnabled(true); 
    } 

    return view; 
} 
//This method when called from Main is throwing Exception 
public void setupCurrlocation(LatLng MUSEUM) { 
    makeText(getContext(), "I am inside the function ", Toast.LENGTH_LONG).show(); 
    System.out.println("I am inside the function"); 
    /*CameraPosition cameraPosition = new CameraPosition.Builder() 
      .target(MUSEUM) 
      .zoom(10) 
      .bearing(70) 
      .tilt(25) 
      .build(); 
mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition)); 
*/ 
    } 

} 

代碼從主要活動

import android.app.FragmentManager; 
import android.support.v7.app.AppCompatActivity; 
import android.content.Intent; 
import android.location.LocationManager; 
import android.os.Bundle; 
import android.provider.Settings; 
import android.view.View; 
import android.widget.TextView; 
import android.widget.Toast; 
import com.google.android.gms.maps.model.LatLng; 

public class MainActivity extends AppCompatActivity implements  MapDemoActivity.CommInter { 

private TextView txtLocation; 
private String provider; 

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

@Override 
public void communicatesWithActivity(double lati, double longi) { 
    MapDemoActivity mapFrag = (MapDemoActivity)getSupportFragmentManager().findFragmentById(R.id.map); 
    final LatLng MUSEU = new LatLng(38.8874245, 77.0200729); 
    //final LatLng MUSEU = new LatLng(lati, longi); 
    mapFrag.setupCurrlocation(MUSEU); 
} 

public void findLocation(View v) { 
    //final LatLng setLoc = new LatLng(38.8874245, -77.0200729); 
    //// MapDemoActivity fragment; 
    // Fragment t = (Fragment)getSupportFragmentManager()findViewById(R.id.map); 
    // fragment.setupCurrlocation(v,setLoc); 
    txtLocation = (TextView) findViewById(R.id.textViewLocation); 
    LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE); 
    boolean isLocEnabled = service.isProviderEnabled(LocationManager.GPS_PROVIDER); 
    if (!isLocEnabled) { 
     Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); 
     startActivity(intent); 
    } 

    GPSTracker gps = new GPSTracker(MainActivity.this); 

    // check if GPS enabled 
    if(gps.canGetLocation()){ 

     double latitude = gps.getLatitude(); 
     double longitude = gps.getLongitude(); 

     // \n is for new line 

     Toast.makeText(getApplicationContext(), "Your Location is - \nLat: " + latitude + "\nLong: " + longitude, Toast.LENGTH_LONG).show(); 
     txtLocation.setText("Lat: " + latitude + "Long: " + longitude); 

     //System.out.println(MUS); 
     //The PROBLEM IS HERE I DONT KNOW THE FIX 
     communicatesWithActivity(latitude,long); 


    }else{ 
     // can't get location 
     // GPS or Network is not enabled 
     // Ask user to enable GPS/network in settings 
     gps.showSettingsAlert(); 
    } 


    } 

} 
+0

findFragmentById(R.id.map)返回null。在activity_main.xml中是否真的有一個ID爲「map」的片段? –

回答

2

你沒有使用谷歌地圖。您需要在調用setupcurrlocation的地方擁有所有這些導入。

import com.google.android.gms.maps.CameraUpdateFactory; 
import com.google.android.gms.maps.GoogleMap; 
import com.google.android.gms.maps.MapFragment; 
import com.google.android.gms.maps.model.CameraPosition; 
import com.google.android.gms.maps.model.LatLng; 
import com.google.android.gms.maps.model.Marker; 
import com.google.android.gms.maps.model.MarkerOptions; 
// et al... 

public void setupCurrlocation(LatLng MUSEUM) { 
    GoogleMap googleMap = ((MapFragment) fragmentManager. 
        findFragmentById(R.id.map)).getMap(); 
    googleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID); 
    Marker marker = googleMap.addMarker(new MarkerOptions().position(latLng).title(null)); 
    CameraPosition cameraPosition = new CameraPosition.Builder().target(MUSEUM).zoom(10).bearing(70).tilt(25) 
          .build(); 
    googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition)); 

} 

基本上我會在片段附加到活動內部有此方法。您需要管理谷歌地圖的可見性。因爲它將保持在其他片段之上。
通過控制框架佈局的可見性,您可以控制地圖在其框架佈局中的可見性。

實施例:

// your activity layout here: 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    //TO DO/> 

    <RelativeLayout 
     android:layout_height="wrap_content" 
     android:layout_width="match_parent" 
     android:id="@+id/myrellayout"> 

     // ALL THE THINGS IN YOUR ACTIVTY 

    </RelativeLayout> 

    // THE FRAMELAYOUTS MANAGE YOUR MAP FRAGMENT AND OTHER FRAGMENTS VISIBILITY 

    <FrameLayout 
     android:id="@+id/firstfrag" 
     android:layout_below="@+id/myrellayout" 
     android:layout_height="fill_parent" 
     android:layout_width="match_parent" 
     android:visibility="gone"/> 

    <FrameLayout 
     android:id="@+id/secondfrag" 
     android:layout_below="@+id/myrellayout" 
     android:layout_height="fill_parent" 
     android:layout_width="match_parent" 
     android:visibility="gone"/> 

     <fragment 
      android:id="@+id/map" 
      android:layout_height="match_parent" 
      android:layout_width="match_parent" 
      android:name="com.google.android.gms.maps.MapFragment"/> 
    </FrameLayout> 
</RelativeLayout> 

https://developers.google.com/maps/documentation/android-api/ https://developers.google.com/maps/documentation/javascript/examples/

2

唯一的例外是在活動發生時,由於的findFragmentById返回null。根據您發佈的代碼,您已在您的xml中聲明您的Fragment。由於您使用的是getSupportFragmentManager,請確保您使用com.google.android.gms.maps.SupportMapFragment而不是com.google.android.gms.maps.MapFragment來聲明它。這可能是你變得空的原因之一。另一方面,你可以使用一個transactin

私人MapDemoActivity mFragment;

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    if (savedInstanceState == null) { 
     mFragment = new MapDemoActivity(); 
     getSupportFragmentManager().beginTransaction().replace(R.id.container, mFragment, "TAG").commit(); 
    } 
} 

然後你可以使用mFragment。在你的xml中,你必須用正常的ViewGroup替換<fragment,例如FrameLayout。與編號container

2

嗨,你可以嘗試另一種方式喜歡在你的片段類和你的活動類中創建一個公共靜態方法在按鈕點擊調用此方法與所需的經度和緯度。

/* 
* Get User Desired Location in fragment class */ 
public static void getLocation(double lati, double longi) 
{ 
    try { 
     CameraUpdate center = CameraUpdateFactory.newLatLng(new LatLng(lati, longi)); 
     CameraUpdate zoom = CameraUpdateFactory.zoomTo(15); 
     googleMap.moveCamera(center); 
     googleMap.animateCamera(zoom); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

/* Get Desired Location in your activity class*/ 
btnCurrentLocation.setOnClickListener(new OnClickListener() 
{ 
    @Override 
    public void onClick(View v) 
    { 
     ClassName.getLocation(lati, longi); 
    } 
});