Como passar uma variável de Activity para Fragment e devolvê-la?

135

Atualmente, estou criando um aplicativo para Android e quero passar uma data entre atividade e fragmento. Minha atividade possui um botão que abre o fragmento: DatePickerFragment.

Na minha atividade, mostro uma data que quero modificar com o fragmento. Então, eu quero passar a data para o datepicker e enviá-la de volta para a atividade.

Eu tentei muitas soluções, mas nenhuma está funcionando. O caminho mais fácil passaria por uma discussão, mas isso não pode ser feito com fragmentos.

Eugene Primako
fonte
Meu problema é exatamente o mesmo que o seu. Eu me pergunto por que os exemplos tratam apenas os fragmentos como os "usuários" do selecionador de datas, não a atividade que os iniciou.
Claudio

Respostas:

213

Para passar informações para um fragmento , você defineArguments ao criá-lo e pode recuperar esse argumento posteriormente no método onCreate ou onCreateView do seu fragmento.

Na função newInstance do seu fragmento, você adiciona os argumentos que deseja enviar:

/**
 * 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;
}

Depois, dentro do fragmento do método, onCreateou onCreateViewvocê pode recuperar os argumentos como este:

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

Se você deseja agora se comunicar do seu fragmento com a sua atividade (enviando ou não dados) , é necessário usar interfaces. A maneira como você pode fazer isso é explicada muito bem no tutorial de documentação da comunicação entre fragmentos. Como todos os fragmentos se comunicam por meio da atividade, neste tutorial, você pode ver como pode enviar dados do fragmento real para o contêiner de atividade dele para usar esses dados na atividade ou enviá-los para outro fragmento que sua atividade contém.

Tutorial de documentação:

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

jpardogo
fonte
10
Acho que o objetivo das pessoas fazer essa pergunta repetidamente é que ela não está realmente bem explicada na documentação.
Michael Alan Huff
1
Eu ainda estou confuso sobre o que é o melhor método de usar, seu, ou a abaixo respondida por @Elenasys
Yoann Hercouet
Há uma nova maneira de compartilhar dados entre fragmentos usando componentes de arquitetura (E / S '17): developer.android.com/topic/libraries/architecture/…
jpardogo
E os fragmentos criados dentro do layout XML?
Ralphgabb
Não quero mais usar o método estático.
Ahamadullah Saikat
89

Enviando dados de Activitypara umFragment

Atividade:

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();

Fragmento:

Lendo o valor no fragmento

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

Mas se você deseja enviar valores de Fragmento para Atividade, leia a resposta de jpardogo, precisa de interfaces, mais informações: Comunicação com outros Fragmentos

Jorgesys
fonte
2
Como passar um objeto personalizado? Eu costumava Parcelable, mas que me deuclass cast exception
víbora
esta solução não está funcionando para mim, não consigo encontrar de onde importar as transações
thebeancounter
Bem, se você carregar o fragmento em sua atividade, poderá enviar valores via pacote definido em sua transação. Explique qual é o seu cenário?
Jorgesys
8

graças a @ ρяσѕρєя K e Terry ... isso me ajuda muito e funciona perfeitamente

Em Activity, você envia dados com a intenção de:

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

e no método 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);
}

reference: Enviar dados da atividade para fragmentar no android

mahmoud zaher
fonte
7

Use a biblioteca EventBus para passar o evento que pode conter sua variável e para trás. É uma boa solução, pois mantém suas atividades e fragmentos fracamente acoplados

https://github.com/greenrobot/EventBus

SemaphoreMetaphor
fonte
4
Não posso dizer que essa não é uma boa solução, mas existe uma palavra de cautela. Embora o EventBus seja tremendamente fácil de usar, aqui também está o seu perigo. Se você começar a adicionar muitos sinais, a natureza fracamente acoplada pode dificultar o rastreamento de quem está ligando para quem e onde ocorrem diferentes eventos.
Johan Paul
2

Para todos os desenvolvedores do Kotlin por aí:

Aqui está a solução proposta do Android Studio para enviar dados ao seu fragmento (= quando você cria um fragmento em branco com Arquivo -> Novo -> Fragmento -> Fragmento (em branco) e verifica "incluir métodos de fábrica de fragmentos").

Coloque isso no seu fragmento:

class MyFragment: Fragment {

...

    companion object {

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

.applyé um bom truque para definir dados quando um objeto é criado ou como eles afirmam aqui :

Chama a função especificada [bloco] com thisvalor como seu receptor e retorna thisvalor.

Em sua atividade ou fragmento, faça:

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

e leia os argumentos em seu fragmento, como:

private var isMyBoolean = false

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

Para "enviar" os dados de volta à sua Atividade , basta definir uma função na sua Atividade e faça o seguinte no seu Fragmento:

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

Aproveite a magia do Kotlin!

Paul Spiesberger
fonte
1

Enviando dados da Atividade para Fragmentos Vinculados por XML

Se você criar um fragmento no Android Studio usando um dos modelos, por exemplo, Arquivo> Novo> Fragmento> Fragmento (lista), o fragmento será vinculado via XML. O método newInstance é criado no fragmento, mas nunca é chamado, portanto não pode ser usado para passar argumentos.

Em vez disso, na Atividade, substitua o método onAttachFragment

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

Em seguida, leia os argumentos no método fragmento onCreate conforme as outras respostas

Dale
fonte
0

Você pode simplesmente instanciar seu fragmento com um pacote:

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