Как передать переменную от Activity to Fragment и передать ее обратно?

В настоящее время я делаю приложение для Android и хочу передать дату между активностью и фрагментом. У моей активности есть кнопка, которая открывает фрагмент: DatePickerFragment.

В своей деятельности я показываю дату, которую хочу изменить с помощью фрагмента. Поэтому я хочу передать дату в средство выбора даты и отправить ее обратно в действие.

Я перепробовал много решений, но ни одно из них не работает. Простой способ передать аргумент, но это не может быть сделано с фрагментами.

Ответ 1

Чтобы передать информацию фрагменту, вы устанавливаете Arguments при его создании, и вы можете получить этот аргумент позже с помощью метода onCreate или onCreateView вашего фрагмента.

В функции newInstance вашего фрагмента вы добавляете аргументы, которые хотите отправить ему:

/**
 * Create a new instance of DetailsFragment, initialized to
 * show the text at 'index'.
 */
public static DetailsFragment newInstance(int index) {
    DetailsFragment f = new DetailsFragment();
    // Supply index input as an argument.
    Bundle args = new Bundle();
    args.putInt("index", index);
    f.setArguments(args);
    return f;
}

Затем внутри фрагмента метода onCreate или onCreateView вы можете получить следующие аргументы:

Bundle args = getArguments();
int index = args.getInt("index", 0);

Если вы хотите теперь общаться со своим фрагментом со своей деятельностью (отправлять или не отправлять данные), вам нужно использовать интерфейсы. То, как вы можете это сделать, очень хорошо объяснено в руководстве по документированию связи между фрагментами. Поскольку все фрагменты обмениваются данными друг с другом через действие, в этом руководстве вы увидите, как вы можете отправлять данные из фактического фрагмента в его контейнер действий, чтобы использовать эти данные для действия или отправлять их в другой фрагмент, содержащийся в вашем действии.

Учебное пособие по документации:

http://developer.android.com/training/basics/fragments/communicating.html

Ответ 2

Отправка данных с Activity на Fragment

Активность:

Bundle bundle = new Bundle();
String myMessage = "Stackoverflow is cool!";
bundle.putString("message", myMessage );
FragmentClass fragInfo = new FragmentClass();
fragInfo.setArguments(bundle);
transaction.replace(R.id.fragment_single, fragInfo);
transaction.commit();

Фрагмент:

Чтение значения в фрагменте

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    String myValue = this.getArguments().getString("message");
    ...
    ...
    ...
}

Но если вы хотите отправить значения из Fragment в Activity, прочитайте ответ jpardogo, вам понадобятся интерфейсы, дополнительная информация: Общение с другими фрагментами

Ответ 3

Используйте библиотеку EventBus для передачи события, которое может содержать вашу переменную взад и вперед. Это хорошее решение, потому что оно держит ваши действия и фрагменты слабо связанными

https://github.com/greenrobot/EventBus

Ответ 4

спасибо @ρяσѕρєя K и Терри... это мне очень помогает и отлично работает

Из Activity вы отправляете данные с намерением:

Bundle bundle = new Bundle(); 
bundle.putString("edttext", "From Activity"); 
// set Fragmentclass Arguments
Fragmentclass fragobj = new Fragmentclass();
fragobj.setArguments(bundle);

и в методе Fragment onCreateView:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    // get arguments
    String strtext = getArguments().getString("edttext");    
    return inflater.inflate(R.layout.fragment, container, false);
}

ссылка: отправить данные из деятельности на фрагмент в Android

Ответ 5

Отправка данных из Activity во фрагменты, связанные с помощью XML

Если вы создаете фрагмент в Android Studio, используя один из шаблонов, например, Файл> Создать> Фрагмент> Фрагмент (Список), затем фрагмент связывается через XML. Метод newInstance создается во фрагменте, но никогда не вызывается, поэтому его нельзя использовать для передачи аргументов.

Вместо этого в Activity переопределите метод onAttachFragment

@Override
public void onAttachFragment(Fragment fragment) {
    if (fragment instanceof DetailsFragment) {
        Bundle args = new Bundle();
        args.putInt("index", index);
        f.setArguments(args);        
     }
}

Затем прочитайте аргументы в методе фрагмента onCreate согласно другим ответам

Ответ 6

Вы можете просто создать свой фрагмент с помощью пакета:

Fragment fragment = Fragment.instantiate(this, RolesTeamsListFragment.class.getName(), bundle);

Ответ 7

Сделай это в стиле Котлин

1) Создайте встроенную функцию:

inline fun <FRAGMENT : Fragment> FRAGMENT.putArgs(argsBuilder: Bundle.() -> Unit): FRAGMENT = this.apply { arguments = Bundle().apply(argsBuilder) }

2) Теперь вы можете использовать это расширение во всех фрагментах без дублирования кода:

class MyFragment: Fragment() {
    companion object {
        fun newInstance(name: String) = MyFragment().putArgs {
             putString("nameKey", name)
        }
    }
}

class MyFragment1: Fragment() {
     companion object {
         fun newInstance(boolean: Boolean) = MyFragment1().putArgs {
              putBoolean("booleanKey", boolean)
         }
     }
}

3) Создайте свои фрагменты:

val myFragment = MyFragment.newInstance("NAME")
val myFragment1 = MyFragment1.newInstance(true)

Ответ 8

Для всех разработчиков Kotlin:

Вот предлагаемое Android Studio решение для отправки данных в ваш фрагмент (= когда вы создаете пустой фрагмент с помощью файла → Новый → Фрагмент → Фрагмент (пустой) и вы отмечаете "включить фабрику фрагментов" ").

Поместите это в свой фрагмент:

class MyFragment: Fragment {

...

    companion object {

            @JvmStatic
            fun newInstance(isMyBoolean: Boolean) = MyFragment().apply {
                arguments = Bundle().apply {
                    putBoolean("REPLACE WITH A STRING CONSTANT", isMyBoolean)
                }
            }
     }
}

.apply - это хороший прием для установки данных при создании объекта, или как они утверждают здесь:

Вызывает указанную функцию [блок] со значением this в качестве получателя и возвращает значение this.

Затем в своей деятельности или фрагменте выполните:

val fragment = MyFragment.newInstance(false)
... // transaction stuff happening here

и прочитайте Аргументы в своем фрагменте, такие как:

private var isMyBoolean = false

override fun onAttach(context: Context?) {
    super.onAttach(context)
    arguments?.getBoolean("REPLACE WITH A STRING CONSTANT")?.let {
        isMyBoolean = it
    }
}

Чтобы "отправить" данные обратно в свою активность, просто определите функцию в своей активности и выполните следующие действия в своем фрагменте:

(activity as? YourActivityClass)?.callYourFunctionLikeThis(date) // your function will not be called if your Activity is null or is a different Class

Наслаждайся магией Котлина!