Eine Snackbar ohne Aussicht bauen?

Lesezeit: 8 Minuten

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();
}
}

Hier ist auch der Aktivitäts-XML-Code:

<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" />

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

Benutzer-Avatar
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.

<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>

und dann:

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()

    – Shahab Rauf

    10. Mai 2017 um 8:24 Uhr


Benutzer-Avatar
Umasankar

Versuchen Sie dies bei jeder Aktivität:

snackbar(findViewById(android.R.id.content),"your text")

  • Wie können wir das nutzen

    – Kischan Solanki

    19. Juni 2020 um 15:25 Uhr

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

fun showSnackBar(message: String?, activity: Activity?) {
    if (null != activity && null != message) {
        Snackbar.make(
            activity.findViewById(android.R.id.content),
            message, Snackbar.LENGTH_SHORT
        ).show()
    }
}

Möchten Sie diese Funktion in Aktivität aufrufen?

showSnackBar("Test Message in snackbar", this)

Möchten Sie diese Funktion in Fragment aufrufen?

showSnackBar("Test Message in snackbar", requireActivity())

Viel Spaß beim Codieren!

Benutzer-Avatar
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")

Benutzer-Avatar
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();

und meine XML-Datei ist wie folgt

<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>

Benutzer-Avatar
Wincelee

Fügen Sie ein beliebiges Layout hinzu und weisen Sie dem Layout ein folgendes ID-Beispiel zu:

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

    <fragment
        android:id="@+id/map_fragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        />

</RelativeLayout>

Suchen Sie in Ihrer Aktivität das Layout mit findViewById:

RelativeLayout relativeLayout = findViewById(R.id.relativeLayout);

Beispiel für andere Layouts bzw. solange Sie den Layouts ihre Id’s zuweisen:

LinearLayout relativeLayout = findViewById(R.id.linearLayout);
FrameLayout frameLayout = findViewById(R.id.frameLayout);

Anzeigen der Snackbar:

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();

1055970cookie-checkEine Snackbar ohne Aussicht bauen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy