Ich möchte eine Snackbar anzeigen, sobald der Benutzer die Google Maps-Aktivität öffnet, aber die Sache ist, dass es keine Ansichten in der Aktivität gibt, die als erster Parameter der Aktivität verwendet werden können (in der findViewById() von Snackbar.make()). Was stelle ich da ein? Hier ist der Java-Klassencode:
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();
}
}
Und zu guter Letzt, hier ist der Stacktrace-Fehler:
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)
Danke für die Hilfe! 🙂
Versuchen Sie “findViewById()” durch “getWindow().getDecorView().getRootView()” zu ersetzen
– W0rmH0le
3. August 2016 um 16:09 Uhr
W0rmH0le
Ich sehe einige Optionen… Ich bin mir nicht sicher, welche Ihr Problem beheben kann.
Am einfachsten
SupportMapFragment Klasse verlängert android.support.v4.app.Fragment. Auf diese Weise hat es eine Methode getView()
Snackbar.make(mapFragment.getView(), "Click the pin for more options", Snackbar.LENGTH_LONG).show();
Suchen Sie die Root-Ansicht
Aus dieser Antwort gibt es eine Möglichkeit, die Stammansicht zu erhalten über:
getWindow().getDecorView().getRootView()
Also, vielleicht können Sie tun:
Snackbar.make(getWindow().getDecorView().getRootView(), "Click the pin for more options", Snackbar.LENGTH_LONG).show();
HINWEIS: Dieser Ansatz hat die in den Kommentaren unten erwähnte Nebenwirkung:
Die Nachricht wird hinter der unteren Navigationsleiste angezeigt, wenn die folgende Methode verwendet wird, um die Ansicht getWindow().getDecorView().getRootView() abzurufen
Fügen Sie ein Dummy-LinearLayout hinzu, um die Ansicht zu erhalten
Ehrlich gesagt bin ich mir nicht sicher, ob diese Lösung möglich ist. Ich bin mir nicht sicher, ob Sie ein LinearLayout über dem Maps-Fragment hinzufügen können … Ich denke, es ist in Ordnung, aber da ich noch nie mit Maps API gearbeitet habe, bin ich mir nicht sicher.
Snackbar.make(findViewById(R.id.dummy_layout_for_snackbar), "Click the pin for more options", Snackbar.LENGTH_LONG).show();
Beide der ersten beiden Methoden funktionieren gut; aber um den ersten zu verwenden, musste ich das Ganze verschieben Snackbar.make() Aktion hinein onCreate() seit mapFragment ist keine globale Variable. Das einzig Seltsame, was passiert ist, ist, dass in beiden Fällen der Snackbar-Text standardmäßig schwarz statt weiß angezeigt wird, aber ich kann ihn einfach manuell im Code ändern.
– Kelvin Kellner
3. August 2016 um 16:41 Uhr
Die Nachricht wird hinter der unteren Navigationsleiste angezeigt, wenn die folgende Methode verwendet wird, um eine Ansicht zu erhalten getWindow().getDecorView().getRootView()
Wie Shahab Rauf betont, kann das Abrufen der Ansicht über getDecorView() die Snackbar hinter der Navigationsleiste unten platzieren. Ich verwende den folgenden Code: (Verwenden und erweitern Sie zu Ihrer Freude)
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();
}
}
Angenommen, ich habe eine Basisaktivität, einen Splashscreen und eine Hauptaktivität. Jetzt möchte ich die Snackbar sowohl im Splashscreen als auch in der Hauptaktivität anzeigen. Ich habe Ihre Methode in BaseActivity aufgerufen. Aber es zeigt die Snackbar in keinem von ihnen.
– Aman Verma
12. Januar 2019 um 11:41 Uhr
OK, also sind alle oben genannten Lösungen entweder zu komplex oder irrelevant.
Die einfachste Lösung ist, diese Funktion ÜBERALL zu verwenden
showSnackBar("Test Message in snackbar", requireActivity())
Viel Spaß beim Codieren!
Suraj Bahadur
Der einfachste Weg, dies zu tun, besteht darin, den Vorteil zu nutzen Erweiterungsfunktion in Kotlin.
Schritt 1: Erstellen Sie eine Kotlin-Datei, dh Extensions.kt und fügen Sie den folgenden Code ein
Für Aktivität:
fun Activity.showSnackBar(msg:String){
Snackbar.make(this.findViewById(android.R.id.content), msg, Snackbar.LENGTH_SHORT)
.setAction("Ok"){
}
.show()
}
Für Fragment:
fun Fragment.showSnackBar(msg:String){
Snackbar.make(this.requireActivity().findViewById(android.R.id.content), msg, Snackbar.LENGTH_SHORT)
.setAction("Ok"){
}
.show()
}
Schritt 2: Nennen Sie es wie folgt:
showSnackBar("PASS HERE YOUR CUSTOM MESSAGE")
Rami Allusch
Ich würde sagen, dass findViewByIdist der beste Ansatz. Als verwenden getWindow().getDecorView().getRootView() bewirkt, dass die Nachricht hinter der unteren Navigationsleiste angezeigt wird.
In meinem Fall musste ich kein Dummy-Element in XML erstellen. Ich habe den folgenden Code verwendet
Snackbar.make(findViewById(R.id.container),"This will start payment process.", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
Snackbar.make(relativeLayout,"You are displaying a Snackbar",Snackbar.LENGTH_SHORT).show();
Für andere Layouts ändern Sie einfach den Namen der Layoutbeispiele:
Snackbar.make(linearLayout,"You are displaying a Snackbar",Snackbar.LENGTH_SHORT).show();
Snackbar.make(frameLayout,"You are displaying a Snackbar",Snackbar.LENGTH_SHORT).show();
10559700cookie-checkEine Snackbar ohne Aussicht bauen?yes
Versuchen Sie “findViewById()” durch “getWindow().getDecorView().getRootView()” zu ersetzen
– W0rmH0le
3. August 2016 um 16:09 Uhr