2016-08-03 67 views
11

我想在用户打开Goog​​le地图活动后立即显示快餐栏,但问题在于活动中没有视图用作活动的第一个参数(位于的的Snackbar.make())。我在那里放什么? 这里的java类代码:没有视图制作小吃店?

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback { 

private GoogleMap mMap; 

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

    // Obtain the SupportMapFragment and get notified when the map is ready to be used. 
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() 
      .findFragmentById(R.id.map); 
    mapFragment.getMapAsync(this); 
} 

@Override 
public void onMapReady(GoogleMap googleMap) { 
    mMap = googleMap; 
    mMap.setBuildingsEnabled(true); 
    mMap.getUiSettings().setZoomControlsEnabled(true); 
    float cameraZoom = 17; 
    LatLng location = new LatLng(43.404032, -80.478184); 
    mMap.addMarker(new MarkerOptions().position(location).title("49 McIntyre Place #18, Kitchener, ON N2R 1G3")); 
    CameraUpdateFactory.newLatLngZoom(location, cameraZoom); 
    Snackbar.make(findViewById(/*WHAT DO I PUT HERE?*/), "Click the pin for more options", Snackbar.LENGTH_LONG).show(); 
} 
} 

而且,这里是活动的XML代码:

<fragment xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:map="http://schemas.android.com/apk/res-auto" 
xmlns:tools="http://schemas.android.com/tools" 
android:id="@+id/map" 
android:name="com.google.android.gms.maps.SupportMapFragment" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
tools:context="ca.davesautoservice.davesautoservice.MapsActivity" /> 

最后,这里的堆栈跟踪错误:

08-03 11:42:21.333 3901-3901/? E/AndroidRuntime: FATAL EXCEPTION: main 
    Process: ca.davesautoservice.davesautoservice, PID: 3901 
    java.lang.NullPointerException 
     at android.support.design.widget.Snackbar.<init>(Snackbar.java:183) 
     at android.support.design.widget.Snackbar.make(Snackbar.java:215) 
     at ca.davesautoservice.davesautoservice.MapsActivity.onMapReady(MapsActivity.java:48) 
     at com.google.android.gms.maps.SupportMapFragment$zza$1.zza(Unknown Source) 
     at com.google.android.gms.maps.internal.zzo$zza.onTransact(Unknown Source) 
     at android.os.Binder.transact(Binder.java:361) 
     at xz.a(:com.google.android.gms.DynamiteModulesB:82) 
     at maps.ad.u$5.run(Unknown Source) 
     at android.os.Handler.handleCallback(Handler.java:808) 
     at android.os.Handler.dispatchMessage(Handler.java:103) 
     at android.os.Looper.loop(Looper.java:193) 
     at android.app.ActivityThread.main(ActivityThread.java:5333) 
     at java.lang.reflect.Method.invokeNative(Native Method) 
     at java.lang.reflect.Method.invoke(Method.java:515) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:828) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:644) 
     at dalvik.system.NativeStart.main(Native Method) 

感谢您的帮助! :)

+0

尝试更换 “findViewById()” 由 – W0rmH0le

回答

31

我看到一些选项...不知道哪一个可以解决您的问题。

Simpliest

SupportMapFragment扩展android.support.v4.app.Fragment类。通过这种方式,它有一个方法getView()

Snackbar.make(mapFragment.getView(), "Click the pin for more options", Snackbar.LENGTH_LONG).show(); 

查找根查看

From this answer,有一种方法可以通过根视图:

getWindow().getDecorView().getRootView() 

所以,也许,你可以做:

Snackbar.make(getWindow().getDecorView().getRootView(), "Click the pin for more options", Snackbar.LENGTH_LONG).show(); 

添加一个虚拟的LinearLayout来获取视图

老实说,我不确定这个解决方案是否可能。我不确定您是否可以在地图片段上方添加LinearLayout ...我认为这样可以,但由于之前我从未使用Maps API,因此我不确定。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/dummy_layout_for_snackbar" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical"> 

    <fragment 
     xmlns:map="http://schemas.android.com/apk/res-auto" 
     xmlns:tools="http://schemas.android.com/tools" 
     android:id="@+id/map" 
     android:name="com.google.android.gms.maps.SupportMapFragment" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     tools:context="ca.davesautoservice.davesautoservice.MapsActivity" /> 
</LinearLayout> 

然后:

Snackbar.make(findViewById(R.id.dummy_layout_for_snackbar), "Click the pin for more options", Snackbar.LENGTH_LONG).show(); 
+0

无论是前两种方法的工作 “getWindow()getDecorView()getRootView()。”精细;但为了使用第一个,我需要将整个'Snackbar.make()'动作移动到'onCreate()'中,因为'mapFragment'不是全局变量。发生的一件奇怪事情是,在这两种情况下,快餐栏文本默认显示为黑色而不是白色,但我可以在代码中手动更改它。 –

+10

如果使用以下方法获取视图'getWindow()。getDecorView()。getRootView()',则消息将显示在底部导航栏后面。 –

1

由于流星拉乌夫指出的,获得经由getDecorView视图()可以把小吃吧在底部的导航条的后面。我使用下面的代码:(使用和扩展让你高兴)

public class BaseActivity extends AppCompatActivity { 

    private View getRootView() { 
     final ViewGroup contentViewGroup = (ViewGroup) findViewById(android.R.id.content); 
     View rootView = null; 

     if(contentViewGroup != null) 
      rootView = contentViewGroup.getChildAt(0); 

     if(rootView == null) 
      rootView = getWindow().getDecorView().getRootView(); 

     return rootView; 
    } 

    protected void showSnackBarWithOK(@StringRes int res) { 
     final View rootView = getRootView(); 
     if(rootView != null) { 
      final Snackbar snackbar = Snackbar.make(getRootView(), res, Snackbar.LENGTH_INDEFINITE); 
      snackbar.setAction(R.string.ok, new View.OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        snackbar.dismiss(); 
       } 
      }); 

      snackbar.show(); 
     } 
    } 

    protected void showSnackBar(@StringRes int res) { 
     final View rootView = getRootView(); 
     if(rootView != null) 
      Snackbar.make(rootView, res, Snackbar.LENGTH_LONG).show(); 
    } 
}