Wie ändere ich die Ansicht innerhalb eines Fragments?
Lesezeit: 7 Minuten
sksamuel
Ich habe ein Fragment, das seine Ansicht wie erwartet in onCreateView erstellt. Allerdings möchte ich die Ansicht regelmäßig ändern.
Mein Anwendungsfall ist, dass das Fragment einige Daten von einem Webdienst anzeigt. Wenn ein Benutzer eine Option aus einer Liste auswählt (ein anderes Fragment), sollte dieses Fragment zu einem Fortschrittsbalken wechseln und nach dem Laden wieder zur Datenansicht wechseln.
Ich könnte zwei Fragmente erstellen – das Ladefragment und das Anzeigefragment, aber es scheint, dass ich, da dies ein gekapseltes Ereignis ist, lieber alles in einem Fragment machen würde.
Grundsätzlich frage ich, was das Äquivalent von setContentView in einem Fragment ist.
Spieler
Sie können verwenden Fragment.getView(). Dies gibt die Ansicht des Containers zurück, der die enthält Fragment. In dieser Ansicht können Sie anrufen removeAllViews. Erstellen Sie dann Ihre neuen Ansichten und fügen Sie sie der Ansicht hinzu, aus der Sie gekommen sind getView().
Diese Antwort ist technisch falsch. getView() gibt die zurück View bereitgestellt in onCreateView() nicht der Behälter View
– btalb
3. Oktober 2014 um 8:55 Uhr
Guter Punkt. Es ist jedoch immer noch eine Antwort auf die Frage von @monkjack.
– bplayer
3. Oktober 2014 um 9:36 Uhr
getView() gibt die Ansicht zurück, hat aber keine removeAllViews() Methode. Diese Methode scheint in der ViewGroup. Übersehe ich etwas?
– Tim
4. Februar 2015 um 15:14 Uhr
Das ist richtig. Aber es ist durchaus machbar, dass die Ansicht eine ViewGroup sein wird. Allerdings nicht sehr robust.
– bplayer
5. Februar 2015 um 10:36 Uhr
Solostaran14
Wenn Sie aus irgendeinem Grund die Ansicht des gesamten Fragments ändern möchten (z. B. eine asynchrone URL-Anforderung, die die Ansicht bei Erfolg ändert), können Sie entweder die FragmentTransaction in der übergeordneten Aktivität verwenden und spontan ein neues Fragment erstellen.
Oder Sie können das Fragment behalten und eine Methode dieses Fragments aufrufen, die sich selbst aktualisiert. Beispiel: In der übergeordneten Aktivität erstelle und speichere ich eine Liste von Fragmenten List<RefreshFragment> mFragmentList.
Hier ist die Klasse RefreshFragment (und alle meine Fragmente erweitern diese in meinem Beispiel):
public class RefreshFragment extends Fragment {
protected Data data; // here your asynchronously loaded data
public void setData(Data data) {
this.data = data;
// The reload fragment code here !
if (! this.isDetached()) {
getFragmentManager().beginTransaction()
.detach(this)
.attach(this)
.commit();
}
}
}
Dann kann ich in meiner Aktivität asynchroner Rückruf anrufen:
for (RefreshFragment f : mFragmentList) f.setData(data);
So wird jedes Fragment mit den korrekten Daten aktualisiert und das aktuell angehängte Fragment aktualisiert sich sofort selbst. Sie müssen natürlich Ihr eigenes onCreateView in den Fragmenten bereitstellen.
Wichtig ist, dass sich ein Fragment selbst mit nachladen kann getFragmentManager().
Heutzutage würde ich vorschlagen, zu verwenden ViewModel zu diesem Zweck.
Das Problem ist, dass das Fragment niemals getrennt wird, wenn Sie Ihre Daten laden oder wenn der Benutzer auf eine Schaltfläche klickt …
– Waza_Be
25. Dezember 2013 um 12:55 Uhr
@Waza_Be Ich denke, es ist ein Typ und sollte so aussehen: if (!this.isDetached()) {.
– sulai
4. November 2015 um 13:22 Uhr
Ich glaube, dies ist der beste Ansatz für das Problem mit der Ansicht des Aktualisierungsfragments. Wenn Sie dem Muster folgen, in dem Sie Fragmente als Ansichten und Aktivitäten als Controller verwenden, ist das großartig. Es ist sehr ordentlich, es ermöglicht mir, die Vorteile der Vererbung zu nutzen und die gesamte Ansichtslogik an einem Ort zu sammeln – OnCreateView. Ich hoffe, dass ich keine wesentlichen Nachteile dieses Ansatzes finden werde, die mich veranlassen würden, nach einem anderen zu suchen.
– Warwara Kalinina
25. November 2015 um 16:51 Uhr
Dies sollte die Antwort sein, die besser funktioniert hat als jede andere Lösung, die ich ausprobiert habe. Danke, du hast meinen Speck gerettet!
– JPM
18. Februar 2016 um 20:08 Uhr
Ich denke, das Fragment ist so konzipiert, dass es mit fester Ansicht funktioniert. Daher denke ich, dass es hier die beste Entscheidung ist, das Fragment-Objekt neu zu erstellen.
Vergrößern Sie die „Dummy“-Standardansicht in der onCreateView-Methode des Fragments und verwenden Sie sie als Platzhalter, um Ansichten nach Bedarf hinzuzufügen
und wann immer Sie zwischen den beiden wechseln möchten (denken Sie daran, dies in Ihrer Benutzeroberfläche / Ihrem Hauptthread zu tun), tun Sie einfach so etwas wie
Hier ist eine einfachere Lösung: Speichern Sie die Aufblasvorrichtung und den Behälter, die Sie in onCreateView erhalten, und verwenden Sie sie später. Zum Beispiel:
private LayoutInflater mInflater;
private ViewGroup mRootView;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mInflater = inflater;
mRootView = container;
return null;
}
public void someCallBackLater() {
// mRootView.removeAllViews(); // in case you call this callback again...
mInflater.inflate(R.layout.my_layout, mRootView);
}
Es wird empfohlen, die Ansicht in onCreateView aufzublasen: It is recommended to only inflate the layout in this method and move logic that operates on the returned View to onViewCreated(View, Bundle).developer.android.com/reference/androidx/fragment/app/…
– Bruno Bieri
20. Januar 2021 um 10:21 Uhr
bool.dev
Sie können Transaktionen entfernen und hinzufügen verwenden. Ich habe ein Fragment verwendet, in das ich jede Ansicht laden kann. Der Konstruktor des Fragments muss eine Ganzzahl haben, diese Ganzzahl ist R.layout …. Ich entferne einfach das alte Fragment und füge ein neues hinzu. !!! Es funktioniert nur, wenn Sie dieses Fragment dynamisch machen und nicht im XML-Layout. Erstellen Sie einfach so etwas wie ein LinearLayout R.id.fragment_layout
Es wird empfohlen, die Ansicht in onCreateView aufzublasen: It is recommended to only inflate the layout in this method and move logic that operates on the returned View to onViewCreated(View, Bundle).developer.android.com/reference/androidx/fragment/app/…
– Bruno Bieri
20. Januar 2021 um 10:21 Uhr
JoachimR
Mit der Antwort von Solostaran14 mache ich das jetzt:
Schnittstelle:
public interface FragmentReattachListener {
public void reAttach();
}
Fragment:
public class MyFragment extends Fragment implements FragmentReattachListener {
//...
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//...
App.registerFragmentReattachListener(this);
//...
}
//...
@Override
public void reAttach() {
FragmentManager f = getFragmentManager();
if (f != null) {
f.beginTransaction()
.detach(this)
.attach(this)
.commit();
}
}
}
aus der Anwendungsklasse:
private static void reattachFragments() {
if (fragmentReattachListeners.size() > 0) {
for (FragmentReattachListener listener : fragmentReattachListeners) {
listener.reAttach();
}
}
}
Ich stimme zu: besser mit einer Schnittstelle.
– Solostaran14
23. November 2015 um 14:03 Uhr
10655400cookie-checkWie ändere ich die Ansicht innerhalb eines Fragments?yes