Jestem całkiem nowy w używaniu Fragmentów.
Po prostu próbuję zbudować prostą przykładową aplikację, która używa fragmentów. Mój scenariusz jest taki, że mam dwie czynności z jednym fragmentem w każdej czynności. Pierwszy fragment ma edittext i przycisk. Drugi fragment zawiera widok tekstu. Po wpisaniu nazwy w edytorze i kliknięciu przycisku, w widoku tekstu w drugim fragmencie powinna wyświetlić się nazwa wpisana w edytorze pierwszego fragmentu.
Mogłem przesłać wartość z pierwszego fragmentu do jego aktywności, a następnie z tej czynności do drugiej. Teraz, jak użyć tej wartości w drugim fragmencie.
Oto kod Java :::
package com.example.fragmentexample;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class Fragment_1 extends Fragment{
OnFragmentChangedListener mCallback;
// Container Activity must implement this interface
public interface OnFragmentChangedListener {
public void onButtonClicked(String name);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
mCallback = (OnFragmentChangedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnHeadlineSelectedListener");
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View view = inflater.inflate(R.layout.fragment_fragment_1, container, false);
final EditText edtxtPersonName_Fragment = (EditText) view.findViewById(R.id.edtxtPersonName);
Button btnSayHi_Fragment = (Button) view.findViewById(R.id.btnSayHi);
btnSayHi_Fragment.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
String name = edtxtPersonName_Fragment.getText().toString();
FragmentManager fm = getFragmentManager();
Fragment_2 f2 = (Fragment_2) fm.findFragmentById(R.id.fragment_content_2);
Activity activity = getActivity();
if(activity != null)
{
Toast.makeText(activity, "Say&ing Hi in Progress...", Toast.LENGTH_LONG).show();
}
if(f2 != null && f2.isInLayout())
{
f2.setName(name);
}
else
{
mCallback.onButtonClicked(name);
}
}
});
return view;
}
}
MainActivity.Java
package com.example.fragmentexample;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Choreographer.FrameCallback;
import android.view.Menu;
public class MainActivity extends Activity implements Fragment_1.OnFragmentChangedListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
@Override
public void onButtonClicked(String name) {
// TODO Auto-generated method stub
Intent i = new Intent(this, SecondActivity.class);
i.putExtra("", name);
startActivity(i);
}
}
SecondActivity.Java
package com.example.fragmentexample;
import android.app.Activity;
import android.os.Bundle;
public class SecondActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
Bundle b = getIntent().getExtras();
Fragment_2 f2 = new Fragment_2();
f2.setArguments(b);
}
}
Fragment_2.Java
package com.example.fragmentexample;
import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class Fragment_2 extends Fragment{
View view;
TextView txtName;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
view = inflater.inflate(R.layout.fragment_fragment_2, container, false);
// Exception at this line
String name = getArguments().getString("message");
txtName = (TextView) view.findViewById(R.id.txtViewResult);
txtName.setText(name);
return view;
}
@Override
public void onAttach(Activity activity) {
// TODO Auto-generated method stub
super.onAttach(activity);
}
public void setName(String name)
{
txtName.setText("Hi " + name);
}
}
Otrzymuję następujący wyjątek :::
04-16 18:10:24.573: E/AndroidRuntime(713): FATAL EXCEPTION: main
04-16 18:10:24.573: E/AndroidRuntime(713): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.fragmentexample/com.example.fragmentexample.SecondActivity}: android.view.InflateException: Binary XML file line #8: Error inflating class fragment
04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1815)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1831)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.ActivityThread.access$500(ActivityThread.java:122)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1024)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.os.Handler.dispatchMessage(Handler.java:99)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.os.Looper.loop(Looper.java:132)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.ActivityThread.main(ActivityThread.java:4123)
04-16 18:10:24.573: E/AndroidRuntime(713): at java.lang.reflect.Method.invokeNative(Native Method)
04-16 18:10:24.573: E/AndroidRuntime(713): at java.lang.reflect.Method.invoke(Method.java:491)
04-16 18:10:24.573: E/AndroidRuntime(713): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
04-16 18:10:24.573: E/AndroidRuntime(713): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
04-16 18:10:24.573: E/AndroidRuntime(713): at dalvik.system.NativeStart.main(Native Method)
04-16 18:10:24.573: E/AndroidRuntime(713): Caused by: android.view.InflateException: Binary XML file line #8: Error inflating class fragment
04-16 18:10:24.573: E/AndroidRuntime(713): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:688)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.view.LayoutInflater.rInflate(LayoutInflater.java:724)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.view.LayoutInflater.inflate(LayoutInflater.java:479)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.view.LayoutInflater.inflate(LayoutInflater.java:391)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.view.LayoutInflater.inflate(LayoutInflater.java:347)
04-16 18:10:24.573: E/AndroidRuntime(713): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:223)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.Activity.setContentView(Activity.java:1786)
04-16 18:10:24.573: E/AndroidRuntime(713): at com.example.fragmentexample.SecondActivity.onCreate(SecondActivity.java:13)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.Activity.performCreate(Activity.java:4397)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1048)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1779)
04-16 18:10:24.573: E/AndroidRuntime(713): ... 11 more
04-16 18:10:24.573: E/AndroidRuntime(713): Caused by: java.lang.NullPointerException
04-16 18:10:24.573: E/AndroidRuntime(713): at com.example.fragmentexample.Fragment_2.onCreateView(Fragment_2.java:24)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:754)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:956)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1035)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.Activity.onCreateView(Activity.java:4177)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:664)
04-16 18:10:24.573: E/AndroidRuntime(713): ... 21 more
Jak uzyskać wartość z pakietu w SecondActivity.java do Fragment_2.Java?
źródło
Odpowiedzi:
krok 1. przesłanie danych z fragmentu do działania
krok 2. aby otrzymać te dane w Aktywności:
krok 3 . aby przesłać dane z działania do innego działania, należy postępować zgodnie z normalnym podejściem
krok 4, aby otrzymać te dane w działaniu
Krok 5. Z Activity możesz wysłać dane do Fragmentu z zamiarem:
i odebrać fragmentem w metodzie Fragment onCreateView:
źródło
bundle.putString("message", "From Activity");
Jak wspomniano na stronie programisty
komunikacja między fragmentami powinna odbywać się poprzez powiązane działanie.
Miejmy następujące elementy:
Implementacja FragmentA to:
Implementacja MainActivity to:
Implementacja FragmentB to:
Mam nadzieję, że to pomoże..
źródło
// We Fragment_1.java
// We Fragment_2.java
Mam nadzieję, że to ci pomoże.
źródło
putString
(lubputInt
) jest odpowiedzią!Ze strony dla programistów :
Możesz porozumiewać się między fragmentami za pomocą jego Aktywności. Za pomocą tego podejścia możesz komunikować się między działaniami i fragmentami .
Sprawdź również ten link.
źródło
Po pierwsze wszystkie odpowiedzi są prawidłowe, możesz przekazać dane z wyjątkiem obiektów niestandardowych za pomocą
Intent
. Jeśli chcesz przekazać niestandardowe obiekty, musisz zaimplementowaćSerialazable
lubParcelable
do niestandardowej klasy obiektów. Myślałem, że to zbyt skomplikowane ...Więc jeśli twój projekt jest prosty, spróbuj użyć
DataCache
. Zapewnia to bardzo prosty sposób przekazywania danych. Ref: Projekt Github CachePot1- Ustaw to na Widok lub Aktywność lub Fragment, który wyśle dane
2- Uzyskaj dane w dowolnym miejscu, jak poniżej
źródło
Najnowsze rozwiązanie do przekazywania danych między fragmentami można zaimplementować przy użyciu komponentów architektonicznych Androida, takich jak ViewModel i LiveData. Dzięki temu rozwiązaniu nie musisz definiować interfejsu do komunikacji i możesz czerpać korzyści z używania ViewModel, takie jak przetrwanie danych ze względu na zmiany konfiguracji.
W tym rozwiązaniu fragmenty zaangażowane w komunikację mają ten sam obiekt viewmodel, który jest powiązany z cyklem życia ich działania. Obiekt modelu widoku zawiera obiekt Liveata. Jeden fragment ustawia dane do przekazania do obiektu Liveata, a obserwatorzy drugiego fragmentu zmieniają dane i otrzymują dane.
Oto pełny przykład http://www.zoftino.com/passing-data-between-android-fragments-using-viewmodel
źródło
Przekazywanie argumentów między fragmentami. To dość późna odpowiedź na to pytanie, ale może to komuś pomóc!
Fragment_1.java
Wtedy w twoim
Fragment_2.java
możesz normalnie uzyskać parametry w twoimonActivityCreated
npźródło
Myślę, że dobrym sposobem rozwiązania tego problemu jest użycie niestandardowego interfejsu.
Załóżmy, że masz dwa fragmenty (A i B), które znajdują się w ramach tego samego działania i chcesz wysłać dane z punktu A do B.
Interfejs:
Czynność:
Fragment A:
Fragment B:
źródło
Komunikacja między fragmentami jest dość skomplikowana (uważam, że koncepcja słuchaczy jest trochę trudna do wdrożenia).
Do wyodrębnienia tych komunikatów często używa się „szyny zdarzeń”. Jest to biblioteka strony trzeciej, która zajmuje się tą komunikacją za Ciebie.
Często do tego używa się „Otto” i warto zajrzeć na stronę: http://square.github.io/otto/
źródło
Przekazywanie danych z fragmentu do innego fragmentu
Od pierwszego fragmentu
Na drugim fragmencie
źródło
Ta prosta implementacja pomaga w prostym przekazywaniu danych między fragmentami. Myślisz, że chcesz przekazać dane z „Frgement1” do „Fragment2”
We fragmencie 1 (ustaw dane do wysłania)
W metodzie Fragment2 onCreateView (Pobierz parametry)
źródło
Droga Kotlina
Skorzystaj z
SharedViewModel
propozycji w oficjalnej dokumentacji ViewModelNajpierw zaimplementuj fragment-ktx, aby łatwiej utworzyć instancję modelu widoku
Następnie wystarczy umieścić w modelu widoku dane, które będziesz udostępniać drugiemu fragmentowi
Następnie, aby zakończyć, po prostu utwórz wystąpienie viewModel w każdym fragmencie i ustaw wartość
selected
z fragmentu, dla którego chcesz ustawić daneFragment A
A potem po prostu nasłuchuj tej wartości w miejscu docelowym fragmentu
Fragment B.
Możesz też zrobić to w odwrotny sposób
źródło
W 100% działające rozwiązanie: (jeśli ci pomożesz, nie zapomnij uderzyć w górę)
W swoim pierwszym fragmencie umieść ten fragment kodu:
W drugim fragmencie utwórz metodę jak poniżej:
następnie zdefiniuj zmienną na poziomie klasy:
następnie utwórz inną metodę w drugim fragmencie, aby ustawić wartość:
źródło
Możesz osiągnąć swój cel za pomocą ViewModel i Live Data, które są usuwane przez Arnav Rao . Teraz podam przykład, aby wyjaśnić to dokładniej.
Najpierw zakładane
ViewModel
jest nazwaneSharedViewModel.java
.Wtedy fragment źródłowy to ten,
MasterFragment.java
z którego chcemy wysłać dane.I wreszcie fragment docelowy to miejsce,
DetailFragment.java
do którego chcemy odebrać dane.źródło
OK, po tylu kopaniu tutaj znalazłem proste rozwiązanie, właściwie nigdy nie powinieneś przekazywać danych z fragmentu na fragment, to zawsze zły pomysł, możesz przekazać dane z fragmentu A do aktywności i pobrać dane z aktywności we fragmencie B.
// w głównym działaniu
// teraz w FragmentB
źródło
stworzyłem coś naprawdę łatwego dla początkujących takich jak ja. utworzyłem przegląd tekstowy w moim pliku activity_main.xml i umieściłem
wtedy otrzymuję ten widok tekstu z pierwszego fragmentu
a następnie w drugim fragmencie otrzymuję wartość
mam nadzieję, że to pomoże!
źródło