Je souhaite afficher une barre dès que l'utilisateur ouvre l'activité Google Maps, mais le fait est qu'il n'y a pas de vues dans l'activité à utiliser comme premier paramètre de l'activité (dans la fonction findViewById()
of Snackbar.make()
). Qu'est-ce que je mets là? Voici le code de classe 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();
}
}
Aussi, voici l'activité code 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" />
Et enfin, voici l'erreur stacktrace:
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)
Merci pour l'aide! :)
Je vois quelques options ... Vous ne savez pas lequel peut résoudre votre problème.
Plus simple
SupportMapFragment
étend la classe Android.support.v4.app.Fragment
. De cette façon, il a une méthode getView()
Snackbar.make(mapFragment.getView(), "Click the pin for more options", Snackbar.LENGTH_LONG).show();
Trouver la vue racine
À partir de cette réponse , il existe un moyen d'obtenir la vue racine via:
getWindow().getDecorView().getRootView()
Alors peut-être que vous pouvez faire:
Snackbar.make(getWindow().getDecorView().getRootView(), "Click the pin for more options", Snackbar.LENGTH_LONG).show();
Ajouter un LinearLayout factice pour obtenir la vue
Honnêtement, je ne suis pas sûr que cette solution soit possible. Je ne sais pas si vous pouvez ajouter un LinearLayout au-dessus du fragment Maps ... Je pense que c'est OK, mais comme je n'ai jamais travaillé avec Maps API auparavant, je n'en suis pas sûr.
<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>
et alors:
Snackbar.make(findViewById(R.id.dummy_layout_for_snackbar), "Click the pin for more options", Snackbar.LENGTH_LONG).show();
Comme le souligne Shahab Rauf, obtenir la vue via getDecorView () peut placer la barre de contrôle derrière la barre de navigation en bas. J'utilise le code suivant: (Utilisez et étendez votre plaisir)
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();
}
}
Je dirais que findViewById
est la meilleure approche. Si vous utilisez getWindow().getDecorView().getRootView()
, le message sera affiché derrière la barre de navigation inférieure.
Dans mon cas, je n'avais pas besoin de créer un élément factice en XML. J'ai utilisé le code suivant
Snackbar.make(findViewById(R.id.container),"This will start payment process.", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
et mon fichier XML est comme suit
<Android.support.design.widget.CoordinatorLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:fitsSystemWindows="true"
tools:context=".HomePatientActivity">
<Android.support.design.widget.AppBarLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:paddingTop="@dimen/appbar_padding_top"
Android:theme="@style/AppTheme.AppBarOverlay">
<Android.support.v7.widget.Toolbar
Android:id="@+id/toolbar"
Android:layout_width="match_parent"
Android:layout_height="?attr/actionBarSize"
Android:layout_weight="1"
Android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/AppTheme.PopupOverlay">
</Android.support.v7.widget.Toolbar>
<Android.support.design.widget.TabLayout
Android:id="@+id/sliding_tabs"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_weight="1"
app:layout_anchorGravity="top"
app:tabMode="fixed" />
</Android.support.design.widget.AppBarLayout>
<Android.support.v4.view.ViewPager
Android:id="@+id/container"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
</Android.support.v4.view.ViewPager>
<Android.support.design.widget.FloatingActionButton
Android:id="@+id/fab"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_gravity="end|bottom"
Android:layout_margin="@dimen/fab_margin"
app:srcCompat="@Android:drawable/ic_dialog_email" />
</Android.support.design.widget.CoordinatorLayout>
Essayez ceci dans n'importe quelle activité:
snackbar(findViewById(Android.R.id.content),"your text")