Android Dialog verstecken, statt zu schliessen

RezaScript

Bekanntes Mitglied
Hallo,

ich benutze DialogFragment und habe ein Problem beim Schliessen des Dialogs.

Wenn der Dialog geschlossen wird, gehen in der View alle Änderungen verloren. Beim nächsten Aufruf des Dialogs sieht die View aus wie am Anfang und das möchte ich vermeiden. Beim Schliessen sollen also alle Änderungen bleiben, so wie sie waren.

Ich habe zwar schon eine Lösung dafür aber mir gefällt diese Lösung nicht. Die Lösung wäre, via Interface alle Änderungen an Activity geben und beim erneuten Aufruf überprüfen, welche Änderungen existieren und diese dann entsprechend setzen. Das würde zwar funktionieren, ist bei meinem View aber viel zu aufwändig! Den die View des Dialogs enthält viele Details wie Audio, Video, Textfelder, Animationen und und und.

Ich denke, dass es hierbei eine einfachere Lösung geben muss. Ungefähr so stelle ich es mir vor:
Bei onDismiss() soll der Dialog nicht geschlossen werden, sondern lediglich "versteckt", wie z. B. dialog.setVisibility(View.GONE);

Damit der Dialog nicht geschlossen wird, benutze ich in onCreateView(): setCancelable(false);
Beim Überschreiben von onDismiss() würde ich gerne setVisibility(View.GONE); verwenden, finde dazu aber keine Referenz. Mit getDialog().setVisibility(View.GONE); scheint es jedenfalls nicht zu funktionieren.
 

Jw456

Top Contributor
Hallo vielleicht hilft das Objekt von Fragment nicht zu zerstören.
Bein zweiten Aufruf also kein neues Objekt von der Fragment Klasse zu erstellen.
Das gleiche Objekt für den zweiten Aufruf wider zu benutzen.

Ein klassischer Start geht ja in etwa so

Java:
MyDialogFragment dialogFragment = new MyDialogFragment();
FragmentTranscation ft = getSupportFragmentManager().beginTransaction();
Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
ft.addToBackStack(null);
dialogFragment.show(ft, "dialog");

Teste doch vor dem Start ob das „dialogfragment“ noch exitirt.
Dazu würde ich die Variable aus Instanzvariable in der Activity halten.

Dies könnte ein Versuch wert sein habe es nicht getestet.
 

KonradN

Super-Moderator
Mitarbeiter
Also generell ist es aus meiner Sicht immer eine gute Idee, Daten und UI zu trennen. Die UI zeigt dann die Daten des Models an. Aber ein I Element besitzt die Daten nicht.

So kann ein Fragment die Daten einer Instanz einer Modelklasse anzeigen, Änderungen können in der Instanz wiedergespiegelt werden u.s.w. Aber die Instanz selbst kann dann auch an anderer Stelle referenziert sein. Bei einer Android App könnte dies in der Activity sein.

Dann wäre es also kein Thema, wenn das Fragment geschlossen und wieder neu geöffnet wird (so beim Öffnen wieder die Daten der einen Instanz verwendet werden).

Also eigentlich ein 08/15 Pattern, das man immer wieder sieht und da dürfte es eigentlich keinen Grund geben, irgendwie zu tricksen um ein Fragment, das geschlossen wird, ggf doch nicht zu schließen oder so.
 

Jw456

Top Contributor
Hallo hier mal ein Beispiel mit ViewModel
Template Bottom Navigation Activity vom Studio.

Ich habe der Activity ein Model hinzugefügt in dem ich den String vom EditText im Fragment Dashboard speichere.
Mit dem Button wir es gespeichert.

Du kannst natürlich auch einen observer zum Speichen benutzen.


Java:
package com.example.myapplication;

import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;

public class MainActivityViewModel extends ViewModel {
    private final MutableLiveData<String> mText1 ;

    public MainActivityViewModel() {

        mText1 = new MutableLiveData<>();
        mText1.setValue("");
    }

    public LiveData<String> getText1() {
        return mText1;
    }

    public void setEdittext(String text) {
        mText1.setValue(text);
    }

}

Java:
package com.example.myapplication.ui.dashboard;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;

import com.example.myapplication.MainActivityViewModel;
import com.example.myapplication.databinding.FragmentDashboardBinding;

public class DashboardFragment extends Fragment {

    private FragmentDashboardBinding binding;

    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        DashboardViewModel dashboardViewModel =
                new ViewModelProvider(this).get(DashboardViewModel.class);
        MainActivityViewModel activityViewModel= new ViewModelProvider(getActivity()).get(MainActivityViewModel.class);



        binding = FragmentDashboardBinding.inflate(inflater, container, false);
        View root = binding.getRoot();

        final TextView textView = binding.textDashboard;
        dashboardViewModel.getText().observe(getViewLifecycleOwner(), textView::setText);

        activityViewModel.getText1().observe(getViewLifecycleOwner(), binding.editText1::setText);


        binding.button.setOnClickListener(item -> {
            activityViewModel.setEdittext(binding.editText1.getText().toString());
        });

        return root;
    }



    @Override
    public void onDestroyView() {
        super.onDestroyView();
        binding = null;
    }
}

XML:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
    tools:context=".ui.dashboard.DashboardFragment">

    <TextView
        android:id="@+id/text_dashboard"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:textAlignment="center"
        android:textSize="20sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <EditText
        android:id="@+id/editText1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:ems="10"
        android:inputType="textPersonName"
        android:text="Name"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.497"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"
        android:text="Button"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/editText1" />
</androidx.constraintlayout.widget.ConstraintLayout>
 

Jw456

Top Contributor
Damit der Dialog nicht geschlossen wird, benutze ich in onCreateView(): setCancelable(false);
Bedeutet für mich nicht das das Objekt nicht zerstört wird beim beenden zB beim Klick des Ok Button. Es verhindert nur das der Dialog nicht von außen zb der Activity abgebrochen werden kann. Ohne das einer der Dialog Button betätigt wird. Mert macht das nicht. Ist für das was du wisst nicht zu gebrauchen.



Eine andere Variante wäre den Dialog als Singelton zu halten.
Und natürlich selbst im Dialog auch zu beenden.

Was aber nur gehen wird bei einem Start mit FragmentManager.
Nicht neuer mit NavController.


Wobei ich das neuere ViewModel den vorrang geben würden.

Wollte es einfach nur mal erwähnt haben das es früher auch ging. Und das ViewModel von Android ist („ähnlich, fast ein Singelton ist“) wenn es an die Activity gekoppelt ist. Ist ja auch dazu gedacht um Daten zwischen den Fragmenten einfach zu tauschen.


[CODE lang="java" title="In der Activity"]FragmentManager fm = getFragmentManager();
DashboardFragment dashboardFragment = DashboardFragment.getInstance();
dashboardFragment.show(fm, "Dashboard");[/CODE]

Java:
public class DashboardFragment extends DialogFragment {

    private FragmentDashboardBinding binding;
    private static DashboardFragment single_instance = null;

    public static DashboardFragment getInstance() {
        if (single_instance == null)
            single_instance = new DashboardFragment();
        return single_instance;
    }

    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        binding = FragmentDashboardBinding.inflate(inflater, container, false);
        View root = binding.getRoot();

        binding.textDashboard.setText("This is dashboard fragment");

        binding.button.setOnClickListener(item -> {
            dismiss();
        });
        return root;
    }


    @Override
    public void onDestroyView() {
        super.onDestroyView();
        binding = null;
    }
}
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
J Input Dialog - ist das so richtig ? Android & Cross-Platform Mobile Apps 1
L Leerer Dialog Android & Cross-Platform Mobile Apps 0
L Dialog anzeigen wenn auf Button gedrückt wird. Android & Cross-Platform Mobile Apps 4
B Android Alert Dialog mit sound oder Android & Cross-Platform Mobile Apps 1
J Dialog in Fragment Android & Cross-Platform Mobile Apps 6
B Senden via Dialog? Android & Cross-Platform Mobile Apps 6
K Android Activity for result aus Dialog Android & Cross-Platform Mobile Apps 1
N Android Retain Dialog verschwindet beim drehen Android & Cross-Platform Mobile Apps 4
T Android - Toast Dialog oder was anders? Android & Cross-Platform Mobile Apps 3
A Android Probleme mit Dialog Android & Cross-Platform Mobile Apps 4
A Android Dialog wird nicht sofort angezeigt Android & Cross-Platform Mobile Apps 12
L Custom Dialog Button event Android & Cross-Platform Mobile Apps 2
I modaler Dialog Android & Cross-Platform Mobile Apps 2
K Android Erstellt Ordner statt Datei. Android & Cross-Platform Mobile Apps 3
N Android EditText: Numpad statt Tastatur einblenden Android & Cross-Platform Mobile Apps 2
G trotz Android 4.1 erscheint option menu statt action bar Android & Cross-Platform Mobile Apps 5
F MIDLET Pascal statt J2ME? Android & Cross-Platform Mobile Apps 6
J Android I9000 320x533 statt 480x 800 Android & Cross-Platform Mobile Apps 6
Bastifantasti Pixon 12: Games in 480x800 statt 240x400 Android & Cross-Platform Mobile Apps 17

Ähnliche Java Themen


Oben