Мне нужно передать данные между 5 fragments
и одним Activity
, те fragments
отправлять данные один за другим, когда я достигаю 5'th fragment
, тогда мне нужно сохранить все данные 5 fragments
, как мы можем это сделать. любая идея велика.
Передача данных между фрагментами в действие
Ответ 1
Передавайте данные из каждого фрагмента в действие, когда активность получает все данные, а затем обрабатывает их. Вы можете передавать данные с помощью интерфейсов.
Fragment:
public class Fragment2 extends Fragment {
public interface onSomeEventListener {
public void someEvent(String s);
}
onSomeEventListener someEventListener;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
someEventListener = (onSomeEventListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement onSomeEventListener");
}
}
final String LOG_TAG = "myLogs";
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment2, null);
Button button = (Button) v.findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
someEventListener.someEvent("Test text to Fragment1");
}
});
return v;
}
}
Активность:
public class MainActivity extends Activity implements onSomeEventListener{
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Fragment frag2 = new Fragment2();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.add(R.id.fragment2, frag2);
ft.commit();
}
@Override
public void someEvent(String s) {
Fragment frag1 = getFragmentManager().findFragmentById(R.id.fragment1);
((TextView)frag1.getView().findViewById(R.id.textView)).setText("Text from Fragment 2:" + s);
}
}
Ответ 2
Следующая ссылка объясняет конструкцию для связи между фрагментами.
Чтобы позволить фрагменту связываться с его активностью, вы можете определить интерфейс в классе Fragment и реализовать его в рамках Activity. Фрагмент фиксирует реализацию интерфейса во время его жизненного цикла onAttach() и затем может вызвать методы интерфейса для связи с Activity.
Ниже приведен пример взаимодействия фрагментов с активностью:
public class HeadlinesFragment extends ListFragment {
OnHeadlineSelectedListener mCallback;
// Container Activity must implement this interface
public interface OnHeadlineSelectedListener {
public void onArticleSelected(int position);
}
@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 = (OnHeadlineSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnHeadlineSelectedListener");
}
}
...
}
Теперь фрагмент может доставлять сообщения активности, вызывая метод onArticleSelected() (или другие методы в интерфейсе), используя экземпляр mCallback интерфейса OnHeadlineSelectedListener.
Например, следующий метод в фрагменте вызывается, когда пользователь нажимает на элемент списка. Фрагмент использует интерфейс обратного вызова для доставки события родительской активности.
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
// Send the event to the host activity
mCallback.onArticleSelected(position);
}
Внедрить интерфейс
Чтобы получать обратные вызовы событий из фрагмента, его активная деятельность должна реализовывать интерфейс, определенный в классе фрагмента.
Например, следующее действие реализует интерфейс из приведенного выше примера.
public static class MainActivity extends Activity
implements HeadlinesFragment.OnHeadlineSelectedListener{
...
public void onArticleSelected(int position) {
// The user selected the headline of an article from the HeadlinesFragment
// Do something here to display that article
}
}
Предоставить сообщение фрагменту
Активность хоста может доставлять сообщения фрагменту, захватывая экземпляр Fragment с помощью findFragmentById(), а затем напрямую вызывает общедоступные методы фрагмента.
Например, представьте, что приведенная выше активность может содержать другой фрагмент, используемый для отображения элемента, указанного данными, возвращаемыми в вышеупомянутом методе обратного вызова. В этом случае активность может передавать информацию, полученную методом обратного вызова, другому фрагменту, который будет отображать элемент:
public static class MainActivity extends Activity
implements HeadlinesFragment.OnHeadlineSelectedListener{
...
public void onArticleSelected(int position) {
// The user selected the headline of an article from the HeadlinesFragment
// Do something here to display that article
ArticleFragment articleFrag = (ArticleFragment)
getSupportFragmentManager().findFragmentById(R.id.article_fragment);
if (articleFrag != null) {
// If article frag is available, we're in two-pane layout...
// Call a method in the ArticleFragment to update its content
articleFrag.updateArticleView(position);
} else {
// Otherwise, we're in the one-pane layout and must swap frags...
// Create fragment and give it an argument for the selected article
ArticleFragment newFragment = new ArticleFragment();
Bundle args = new Bundle();
args.putInt(ArticleFragment.ARG_POSITION, position);
newFragment.setArguments(args);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack so the user can navigate back
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
}
}
}
Ответ 3
Вам нужно вернуться к информации о вашем фрагменте. И ваша активность отправляет информацию на ее фрагменты:
// In fragment A
((ParentActivity)getActivity()).dispatchInformations("test");
// In ParentActivity
public void dispatchInformations(String mesg){
fragmentB.sendMessage(mesg);
}
Это основной пример
Ответ 4
Я пробовал все выше, и это не помогло мне. Вот как я заставил его работать. Я использовал интерфейс как средство для передачи данных из фрагмента в действие.
FragmentToActivity.java
public interface FragmentToActivity {
void communicate(String comm);
}
FragmentOne
public class FragmentOne extends Fragment {
private FragmentToActivity mCallback;
@Override
public void onAttach(Context context) {
super.onAttach(context);
try {
mCallback = (FragmentToActivity) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString()
+ " must implement FragmentToActivity");
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_login, container,
false);
sendData("Andrews");
return v;
}
@Override
public void onDetach() {
mCallback = null;
super.onDetach();
}
public void onRefresh() {
Toast.makeText(getActivity(), "Fragment : Refresh called.",
Toast.LENGTH_SHORT).show();
}
private void sendData(String comm)
{
mCallback.communicate(comm);
}
}
}
Мероприятие 1
public class Account extends AppCompatActivity implements
FragmentToActivity{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
public void communicate(String s) {
Log.d("received", s);
}
}
Ответ 5
Вы можете использовать шаблон Communicator, описанный в приведенных выше ответах. Кроме того, вы можете использовать RxJava2. Для лучшей развязки и эффективности.
1- Создать шину:
public final class RxBus {
private static final BehaviorSubject<Object> behaviorSubject
= BehaviorSubject.create();
public static BehaviorSubject<Object> getSubject() {
return behaviorSubject;
}
}
2- активность или фрагмент отправителя
//the data to be passed
MyData data =getMyData();
RxBus.getSubject().onNext(data) ;
3 - активность приемника или фрагмент
private Subscription subscription;
public onCreate(Bundle savedInstanceState){
subscription = RxBus.getSubject()
.subscribe(new Subscriber<Object>() {
@Override
public void onNext(Object o) {
if (o instanceof MyData) {
Log.d("tag", (MyData)o.getData();
}
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
}
4-unSubscribe, чтобы избежать проблем с памятью:
@Override
protected void onDestroy() {
super.onDestroy();
if(subscription!=null){
subscription.unsubscribe();
}
}
Ответ 6
Там действительно простой способ передать данные из фрагмента в другое действие, которое не является его контейнером.
1) Во Фрагменте: Когда вы инициируете действие, скажите onButtonClick, передайте данные, которые вы хотите передать как дополнительные в своих намерениях, как таковые:
Intent intent = new Intent(getActivity(), MapsActivity.class);
intent.putExtra("data", dataString);
startActivity(intent);
2) В принимающей операции: в методе onCreate создайте Bundle для извлечения переданной информации, как таковой:
Bundle extras = getIntent().getExtras();
if (extras != null) {
receivingString = extras.getString("data");
} else {
// handle case
}
Надеюсь, что это помогло:)