2015-08-24 14 views
6

Ich bin mit dem SupportSnackbar mit CoordinatorLayout deaktivieren entlassen

  • FloatingActionButton
  • Snackbar
  • CoordinatorLayout

Ich brauche die CoordinatorLayout so, dass, wenn SnackBar ist die gezeigt FloatingActionButton bewegt sich um Platz für die Snackbar zu machen. Zum besseren Verständnis überprüfen Sie diese video.

Ich benutze SnackBar für Double-Back, um die Anwendung zu beenden, aber die SnackBar kann entlassen werden.

Gibt es eine Möglichkeit, die Kündigung auf der SnackBar zu deaktivieren?

Snackbar snackbar = Snackbar.make(view, R.string.press_back_again_to_exit, Snackbar.LENGTH_SHORT); 
snackbar.setAction(R.string.ok, new View.OnClickListener() { 
    @Override 
    public void onClick(View v) 
    { 

    } 
}); 
snackbar.setActionTextColor(getResources().getColor(R.color.white)); 

View view = snackbar.getView(); 
view.setBackgroundColor(getResources().getColor(R.color.orange_warning)); 

snackbar.show(); 

Layout-

<android.support.design.widget.CoordinatorLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <android.support.v4.widget.DrawerLayout 
     android:id="@+id/drawer_layout" 
     xmlns:sothree="http://schemas.android.com/apk/res-auto" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:background="@color/white" 
     android:fitsSystemWindows="true"> 

     <com.sothree.slidinguppanel.SlidingUpPanelLayout 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:gravity="bottom" 
      sothree:umanoFadeColor="@android:color/transparent" 
      sothree:umanoPanelHeight="100dp" 
      sothree:umanoShadowHeight="4dp"> 

      <!-- Toolbar and main content --> 
      <LinearLayout 
       android:id="@+id/toolbar_and_content" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:orientation="vertical"> 

       <include layout="@layout/toolbar"/> 

       <!-- Your content layout --> 
       <FrameLayout 
        android:id="@+id/content_frame" 
        android:layout_width="match_parent" 
        android:layout_height="wrap_content" 
        android:orientation="vertical"/> 

      </LinearLayout> 

      <!-- Sliding up panel layout --> 
      <LinearLayout 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" 
       android:background="@color/darker_grey" 
       android:orientation="vertical"> 

       ... 

      </LinearLayout> 

     </com.sothree.slidinguppanel.SlidingUpPanelLayout> 


     <!-- Navigation drawer --> 
     <ExpandableListView 
      android:id="@+id/lv_left_drawer" 
      android:layout_width="280dp" 
      android:layout_height="match_parent" 
      android:layout_gravity="start" 
      android:background="@color/white" 
      android:childDivider="@android:color/transparent" 
      android:clickable="true" 
      android:divider="@color/divider_color" 
      android:dividerHeight="0.6dp" 
      android:fadeScrollbars="true" 
      android:groupIndicator="@null" 
      android:listSelector="@drawable/button_drawer_child_selector" 
      android:scrollbarSize="0dp"/> 

    </android.support.v4.widget.DrawerLayout> 

    <android.support.design.widget.FloatingActionButton 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="right|bottom" 
     android:layout_marginBottom="@dimen/floating_action_button_margin" 
     android:layout_marginRight="@dimen/floating_action_button_margin" 
     android:src="@drawable/ic_add" 
     android:visibility="invisible" 
     app:backgroundTint="@color/orange" 
     app:borderWidth="0dp" 
     app:elevation="6dp" 
     app:fabSize="normal"/> 

</android.support.design.widget.CoordinatorLayout> 

P. S.

Ich bin bewusst, this GitHub library, die diese Funktionalität hat, aber gibt es eine "native" Möglichkeit, es zu tun?

+0

Ich denke, es gibt keinen Weg –

+0

* I SnackBar für Doppel zurück bin mit der Anwendung * zu verlassen - Sie gehen gegen die UI-Muster der Plattform. SnackBars sind für kleines Feedback und nicht um den Benutzer nach Aktion zu fragen (wie ich annehme, Sie versuchen zu tun, wenn der Benutzer zweimal drückt) – Luksprog

+0

@Luksprog Ich bin mir dessen bewusst, das gleiche könnte mit einem Toast oder einem erreicht werden Crouton, aber es ist im Grunde das Gleiche, SnackBar sieht einfach schöner aus. Ich bin persönlich kein Fan von Double-Back zu verlassen, aber leider ist es nicht für mich zu entscheiden. – Marko

Antwort

5

Sie können die Dauer der Snackbar ändern, die angezeigt werden soll. Es wird ähnlich sein, entlassen zu deaktivieren.

int  LENGTH_INDEFINITE Show the Snackbar indefinitely. 

Überprüfen Sie docs.

wenn es nicht dies funktioniert Denn dann gibt es nur einen Weg, Implementieren Sie Ihre individuelle und Snackbar dismiss() Methode überschreiben und in diesem nichts tun. :) Als dismiss() ist eine öffentliche API.

+1

Funktioniert nicht, SnackBar ist immer noch entlassen, und bleibt dort für immer :) – Marko

+3

[entlassen oder für immer bleiben] können Sie ein wenig erklären . Das scheint widersprüchlich zu sein;) – theJango

+2

Wenn ich LENGTH_INDEFINITE setze geht die SnackBar nicht nach der Zeit weg ... (macht Sinn), aber ich kann sie immer noch ablehnen (nach rechts wischen und es geht weg). – Marko

1

war ich erfolgreich die Swipe-seitlich-to-entlassen Büffets mit dem folgenden Hack in deaktivieren (nach snackbar.show Aufruf())

((android.support.design.widget.CoordinatorLayout.LayoutParams) snackbar.getView().getLayoutParams()).setBehavior(null); 
+0

Awsome, ich muss es versuchen. Danke für deine Antwort! – Marko

+1

Das funktioniert nicht für mich. 'Snackbar Snackbar = Snackbar.make (this.rootView," Blah ", Snackbar.LENGTH_SHORT); snackbar.show(); ((CoordinatorLayout.LayoutParams) snackbar.getView(). getLayoutParams()). setBehavior (null); ' –

+0

Funktioniert nicht, zumindest wenn es im Fragment verwendet wird – Sparker0i

5

Ich bemerkte, dass, wenn show() -Methode aufgerufen wird, SnackbarLayout ist noch nicht vollständig initialisiert.

Um Dismiss zu sperren, müssen wir das Verhalten nach SnackbarLayout Initialisierung deaktivieren. der beste Ort, dies zu tun, ist zum Beispiel in OnPreDrawListener von SnackbarLayout

final Snackbar snack = Snackbar.make(getView(), "I can't be dissmiss", Snackbar.LENGTH_INDEFINITE); 
    snack.show(); 
    snack.getView().getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { 
     @Override 
     public boolean onPreDraw() { 
      snack.getView().getViewTreeObserver().removeOnPreDrawListener(this); 
       ((CoordinatorLayout.LayoutParams) snack.getView().getLayoutParams()).setBehavior(null); 
       return true; 
      } 
     }); 
6

Die Antwort über nur mit LENGTH_INDEFINITE nicht ausreichend ist.

Es ist nur nicht-dismissable wenn die Snackbar kein Kind von CoordinatorLayout ist. Wenn es ein Kind ist, können Sie immer noch die SnackBar wegwischen.

Was Sie in diesem Fall tun können, ist hören für die Kündigung wischen und einfach wieder die Snackbar anzeigen.

public void showAnnoyingSnackBar(View root, String text) { 
    Snackbar.make(root, text, Snackbar.LENGTH_INDEFINITE) 
     .setCallback(new Snackbar.Callback() { 
      @Override public void onDismissed(Snackbar snackbar, int event) { 
       // recursively call this method again when the snackbar was dismissed through a swipe 
       if (event == DISMISS_EVENT_SWIPE) showAnnoyingSnackBar(root, text); 
      } 
     }) 
     .show(); 
}