So lassen Sie einen Dialog in Android von unten nach in der Mitte des Bildschirms gleiten

69

Ich möchte einen Dialog über meine Aktivität mit Animation anzeigen. Mein Dialog wird vom Ende der Aktivität zur Mitte der Aktivität verschoben.

/****Bearbeiten****/

Es tut mir leid, dass meine Frage unklar ist. Ich meine, mein Dialog wird von unten nach Mitte verschoben, aber die Unterseite des Dialogs befindet sich wie im folgenden Bild auf der Unterseite der AktivitätGeben Sie hier die Bildbeschreibung ein

MichaelP
quelle
Werfen Sie einen Blick auf github.com/Ali-Rezaei/SlidingDrawer , das es ermöglicht, mit wenigen Codezeilen von jeder Seite zu gleiten.
Ali
Ich sehe kein Beispiel, Sie haben eine Layout-XML angegeben, aber wie wird sie im Code verwendet? Kannst du bitte ein Beispiel geben?
Kuldeep
Dies ist für die meisten Menschen veraltet, aber immer noch ist es wert für Neulinge unter Hinweis darauf - nicht replizieren iOS Erfahrung auf Android. In den Richtlinien für das Materialdesign erfahren Sie, was getan werden sollte und was nicht, wie von Google ( material.io ) vorgeschlagen.
Milosmns

Antworten:

170

Dazu benötigen Sie 2 Animationen und legen diese im Ordner res / anim ab

  1. slide_up_dialog.xml
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromYDelta="50%p" android:toYDelta="0%p"
    android:duration="@android:integer/config_longAnimTime"/>

2.slide_out_down.xml

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="@android:integer/config_longAnimTime"
    android:fromYDelta="0%p"
    android:toYDelta="100%p" />

Jetzt müssen Sie einen benutzerdefinierten Stil in style.xml erstellen

<style name="DialogAnimation">
        <item name="android:windowEnterAnimation">@anim/slide_up_dialog</item>
        <item name="android:windowExitAnimation">@anim/slide_out_down</item>
</style>

Als nächstes soll das Android-Theme erweitert werden. Dialogthema in derselben style.xml und geben Sie den Verweis auf den von uns erstellten benutzerdefinierten Stil an.

<!-- Animation for dialog box -->
    <style name="DialogSlideAnim" parent="@android:style/Theme.Dialog">
        <item name="android:windowAnimationStyle">@style/DialogAnimation</item>
    </style>

Rufen Sie diesen Stil schließlich auf, wenn Sie den Dialog wie folgt erstellen.

dialog = new Dialog(new ContextThemeWrapper(this, R.style.DialogSlideAnim));

yep ... Jetzt ist der Dialog bereit zu gleiten ..... !!

Aktualisieren:

Wie von @MichealP vorgeschlagen, wird das Fenster unten platziert

getWindow().setGravity(Gravity.BOTTOM); 

und ändern Sie den Stil, um Tittle und Hintergrund zu entfernen

<item name="android:windowBackground">@null</item> 
<item name="android:windowFrame">@null</item> 
<item name="android:windowNoTitle">true</item>

Wie @ sikni8 vorgeschlagen hat, wird dadurch der schwarze Rand transparent

getWindow().setBackgroundDrawableResource(android.R.color.transparent);
Droidenkind
quelle
13
ich habe getWindow () hinzugefügt. setGravity (Gravity.BOTTOM); und <item name = "android: windowBackground"> ​​@ null </ item> <item name = "android: windowFrame"> @ null </ item> <item name = "android: windowNoTitle"> true </ item> Und dann es funktioniert wie ich es
mir
1
@ MichaelP Is kommt für mich nicht von unten. Es startet einfach eine Animation wie grow_from_middle, aber am unteren Bildschirmrand. Gibt es etwas, das ich verpasst habe?
Abhishek
2
Sie können getWindow().setBackgroundDrawableResource(android.R.color.transparent);den schwarzen Rand auch zur Laufzeit transparent machen.
Si8
1
Hallo @arunsoorya, ich habe Ihre Lösung implementiert, um den Dialog zu animieren, aber dann habe ich die "Android Action Bar Style Generator" -Dateien und das von ihm generierte Thema implementiert und jetzt den Stil, der zum Erstellen des Dialogs verwendet wurde. "TippDialog = neuer Dialog (c, R. style.DialogSlideAnim); " zeigt den Dialog mit einem transparenten Hintergrund. Was soll ich beheben? danke :)
newton_guima
1
Dies ist die Art von Antworten, die jeder gerne auf Stackoverflow finden würde. Vielen Dank.
andrea.rinaldi
18

Ich habe alle Antworten hier ausprobiert und es funktioniert bei mir nicht. Ich weiß, dass alle Antworten vor langer Zeit geschrieben wurden. Lassen Sie mich also zeigen, wie ich es zum Laufen bringe. Ich bin diesem Artikel gefolgt.

Kurz gesagt: Erstellen Sie res / anim / slide_up.xml

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate 
      android:duration="@android:integer/config_mediumAnimTime" 
      android:fromYDelta="100%" 
      android:interpolator="@android:anim/accelerate_interpolator" 
      android:toYDelta="0">
    </translate>
</set>

Erstellen Sie dann res / anim / slide_bottom.xml

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate 
        android:duration="@android:integer/config_mediumAnimTime" 
        android:fromYDelta="0%p" 
        android:interpolator="@android:anim/accelerate_interpolator" 
        android:toYDelta="100%p">
    </translate>
</set>

Fügen Sie dann einen Stil in res / values ​​/ styles.xml hinzu

<style name="DialogAnimation">
    <item name="android:windowEnterAnimation">@anim/slide_up_dialog</item>
    <item name="android:windowExitAnimation">@anim/slide_out_down</item>
</style>

Jetzt können Sie diesen Animationsstil wie unten beschrieben auf Ihren Dialog oder Ihr Alarmdialogfeld einstellen.

Dialog dialog = new Dialog(this);
dialog.getWindow().getAttributes().windowAnimations = animationSource;

Oder,

Dialog dialog = new Dialog(this);
WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
lp.copyFrom(dialog.getWindow().getAttributes());
lp.width = WindowManager.LayoutParams.MATCH_PARENT;
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
lp.gravity = Gravity.BOTTOM;
lp.windowAnimations = R.style.DialogAnimation;
dialog.getWindow().setAttributes(lp);

Ich habe ein Beispiel nur für Dialogfelder gezeigt, aber wie ich bereits sagte, können Sie diese Methode auch für Warnungsdialogfelder verwenden.

Jerin A Mathews
quelle
3
Ja, das ist die perfekte Antwort, die ich von allen hier gefunden habe.
Ramkesh Yadav
8

Sie können ein Modal Bottom Sheet ( Referenz ) verwenden.

  1. Fügen Sie die Designunterstützungsbibliothek hinzu

    implementation "com.android.support:design:$version_support"
    
  2. Erstellen Sie eine Fragment, die erweitert BottomSheetDialogFragmentund überschrieben wirdonCreateView

    class BottomDialogFragment : BottomSheetDialogFragment() { 
    
        companion object {
            fun newInstance() = BottomDialogFragment()
        }
    
        override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
            return inflater.inflate(R.layout.dialog_layout, container)
        }
    }
    
  3. Zeigen Sie den Dialog

    val dialog = BottomDialogFragment.newInstance()
    dialog.show(supportFragmentManager, BottomDialogFragment::class.java.simpleName)
    
Juan Cruz Soler
quelle
Wie sende ich Daten in BottomDIalogFragment?
Maveň
1
Genau wie bei einem regulären Fragment erstellen Sie ein Bundle und legen dort Daten ab
Juan Cruz Soler
5

Sie können Bottom Sheets verwenden. Ich habe einige Informationen darüber veröffentlicht.

Mit der Android Support Library 23.2 kündigte Google die Unterstützung für Bottom Sheets an. Laut Material Design sind Bottom Sheets Elemente, die nur als Ergebnis einer vom Benutzer initiierten Aktion angezeigt werden, mit der mehr Inhalt angezeigt wird.

Es gibt zwei Haupttypen von Bodenblechen:

Modale untere Blätter sind Alternativen zu Menüs oder einfachen Dialogen. Sie können auch verknüpfte Inhalte aus anderen Apps präsentieren. Sie sind in erster Linie für mobile.

Anhaltende untere Blätter enthalten In-App-Inhalte

Es gibt ein einfaches Beispiel

Das Erstellen eines BottomSheet unter Android ist recht einfach. Sie müssen lediglich ein CoordinatorLayout als Hauptelement Ihres Layouts verwenden und einer Ansicht ein BottomSheet-Verhalten hinzufügen.

1 Schritt - activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<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:background="#ffffff">

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    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:background="?attr/colorPrimary"
        app:popupTheme="@style/AppTheme.PopupOverlay" />

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

<Button
    android:id="@+id/btnButtonSheet"
    android:text="Camera"
    android:textColor="#1e1e1e"
    android:layout_marginLeft="16dp"
    android:layout_marginRight="16dp"
    android:layout_marginBottom="8dp"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

<!-- Adding bottom sheet after main content -->
<include layout="@layout/bottom_sheet" />

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

2 Schritt - fügen Sie bottom_sheet.xml hinzu

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/bottom_sheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#fff"
android:orientation="vertical"
app:behavior_hideable="true"
app:behavior_peekHeight="0dp"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:layout_gravity="center_vertical">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Select your options!"
        android:gravity="center"
        android:textColor="#1e1e1e"
        android:textSize="16dp"
        android:layout_margin="8dp"
        android:textStyle="bold" />

</LinearLayout>
<Button
    android:id="@+id/btnPhoto"
    android:text="Photo"
    android:textColor="#1e1e1e"
    android:layout_marginLeft="16dp"
    android:layout_marginRight="16dp"
    android:layout_marginBottom="8dp"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

<Button
    android:id="@+id/btnCamera"
    android:text="Camera"
    android:textColor="#1e1e1e"
    android:layout_marginLeft="16dp"
    android:layout_marginRight="16dp"
    android:layout_marginBottom="8dp"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

<Button
    android:id="@+id/btnCancel"
    android:text="Cancel"
    android:background="#a2a2a3"
    android:textColor="#1e1e1e"
    android:layout_marginLeft="16dp"
    android:layout_marginRight="16dp"
    android:layout_marginBottom="8dp"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

</LinearLayout>

3 Schritt - machen Sie Ihre MainActivity so:

public class MainActivity extends AppCompatActivity {

@BindView(R.id.btnButtonSheet)
Button btnBottomSheet;

@BindView(R.id.bottom_sheet)
LinearLayout layoutBottomSheet;

BottomSheetBehavior sheetBehavior;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ButterKnife.bind(this);

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    sheetBehavior = BottomSheetBehavior.from(layoutBottomSheet);


    sheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
        @Override
        public void onStateChanged(@NonNull View bottomSheet, int newState) {
            switch (newState) {
                case BottomSheetBehavior.STATE_HIDDEN:
                    break;
                case BottomSheetBehavior.STATE_EXPANDED: {
                    btnBottomSheet.setText("Close");
                }
                break;
                case BottomSheetBehavior.STATE_COLLAPSED: {
                    btnBottomSheet.setText("Expand");
                }
                break;
                case BottomSheetBehavior.STATE_DRAGGING:
                    break;
                case BottomSheetBehavior.STATE_SETTLING:
                    break;
            }
        }

        @Override
        public void onSlide(@NonNull View bottomSheet, float slideOffset) {

        }
    });
}

@OnClick(R.id.btnButtonSheet)
public void toggleBottomSheet() {
    if (sheetBehavior.getState() != BottomSheetBehavior.STATE_EXPANDED) {
        sheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
        btnBottomSheet.setText("Close Bottom sheet");
    } else {
        sheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
        btnBottomSheet.setText("Expand Bottom sheet");
    }
}
}
Faxriddin Abdullayev
quelle
Für Neulinge gibt es einen Anwendungsfall, wenn es nicht ratsam ist, untere Blätter zu verwenden, z. B. wenn Sie nicht möchten, dass Dialoge durch Herunterziehen mit dem Finger geschlossen werden können. Ein Anwendungsfall wäre eine Liste von Elementen, in denen Sie für jedes Element einen ItemTouchHelper verwenden. In diesem Fall müssen Sie so viele Methoden aus BottomSheetDialog überschreiben, dass es sinnlos wird, eine fertige Lösung zu verwenden.
Milosmns
1

Hier ist der einfachste Weg, um den Dialog beim Anzeigen zu animieren

dialog.setOnShowListener(new DialogInterface.OnShowListener() {

    @Override
    public void onShow(DialogInterface dialogInterface) {
        View view = dialog.getWindow().getDecorView();
        //for enter from left
        //ObjectAnimator.ofFloat(view, "translationX", -view.getWidth(), 0.0f).start(); 

        //for enter from bottom
        ObjectAnimator.ofFloat(view, "translationY", view.getHeight(), 0.0f).start();
    }

});

Machen Sie außerdem den Dialoghintergrund im Vollbildmodus transparent, wenn Sie von unten animieren

Window window = dialog.getWindow();
window.setLayout(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
window.setBackgroundDrawableResource(android.R.color.transparent);
Vamsi Smart
quelle
0

Zusätzlich zu Arunsooryas Antwort:

Ändern Sie slide_up_dialog.xml

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="@android:integer/config_longAnimTime"
    android:fromYDelta="0%p"
    android:toYDelta="100%p" />

Und slide_out_down.xml

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromYDelta="0%p" 
    android:toYDelta="50%p"
    android:duration="@android:integer/config_longAnimTime"/>
Bharath Lakshman
quelle
0

Die neue Material Design-Bibliothek bietet Ihnen den BottomSheetDialog für genaues Aussehen und einfachere Implementierung

Optional
quelle
0

Zusätzlich zu allen anderen Antworten können Sie diese Animation für die obere Leiste verwenden. Aktualisieren Sie von hier https://www.tutlane.com/tutorial/android/android-slide-up-down-animations-with-examples

slide_up.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/linear_interpolator">
    <scale
        android:duration="500"
        android:fromXScale="1.0"
        android:fromYScale="1.0"
        android:toXScale="1.0"
        android:toYScale="0.0" />
</set>

slide_down.xml

<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/linear_interpolator">
    <scale
        android:duration="500"
        android:fromXScale="1.0"
        android:fromYScale="0.0"
        android:toXScale="1.0"
        android:toYScale="1.0" />
</set>

Die Ausgabe sieht so aus

Geben Sie hier die Bildbeschreibung ein

Mock Changer
quelle