Atualizar fragmento ao recarregar

110

Em um aplicativo Android, estou carregando dados de um Db em um TableViewdentro de a Fragment. Mas quando eu recarrego o Fragmentele exibe os dados anteriores. Posso preencher novamente o Fragmentcom dados atuais em vez de dados anteriores?

Samantha Withanage
fonte
mostre-nos algum código, por favor. Onde você carrega seus dados, onde você começa seu fragmento, onde você armazena seus valores?
AS
Isso deve resolver seu problema descrito porly: stackoverflow.com/questions/6503189/…
Benjamin W.
forneça mais fragmentos de código de informações
nikvs
Tente usar Swipe-to-Refresh para seu aplicativo, consulte stackoverflow.com/questions/41469040/fragment-refresh/…
Imtiaz Mamun

Respostas:

207

Eu acho que você deseja atualizar o conteúdo do fragmento na atualização do banco de dados

Em caso afirmativo, destaque o fragmento e reconecte-o

// Reload current fragment
Fragment frg = null;
frg = getSupportFragmentManager().findFragmentByTag("Your_Fragment_TAG");
final FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.detach(frg);
ft.attach(frg);
ft.commit();

Your_Fragment_TAG é o nome que você deu ao seu fragmento quando o criou

Este código é para a biblioteca de suporte.

Se você não oferece suporte a dispositivos mais antigos, basta usar getFragmentManager em vez de getSupportFragmentManager

[EDITAR]

Este método requer que o Fragment tenha uma tag.
Caso você não o tenha, o método de @Hammer é o que você precisa.

Phantômaxx
fonte
3
Isso dá o seguinte erro - java.lang.RuntimeException: Falha ao entregar o resultado ResultInfo {who = null, request = 2, result = 3, data = null} para a atividade {xont.virtusel.v4.controller / xont.virtusel.v4.controller .sale.InvocieBrandActivity}: java.lang.IllegalStateException: Não é possível executar esta ação após onSaveInstanceState
Samantha Withanage
1
@Elizabeth certifique-se de que seu fragmento tenha uma tag configurada corretamente
Phantômaxx
1
@Rotwang Obrigado por sua resposta Eu apenas peguei um atalho ao invés de fazer o código longo, mas isso ajudou a pavimentar o caminho :)
Si8
1
Esta solução não está mais funcionando na nova versão do support-v4-library (25.1.0). Explicação aqui: stackoverflow.com/questions/41270858/…
Brahim Bouaboud
1
Aviso: este truque funciona no Oreo apenas se você estiver usando Fragmentos de Suporte!
corrida de
146

Isso irá atualizar o fragmento atual:

FragmentTransaction ft = getFragmentManager().beginTransaction();
if (Build.VERSION.SDK_INT >= 26) {
   ft.setReorderingAllowed(false);
}
ft.detach(this).attach(this).commit();
Mbengue Assane
fonte
1
onde colocar esse código? dentro da atividade ou se fragmentar?
Narendra Singh
2
Você o coloca dentro do fragmento que precisa ser atualizado.
Mbengue Assane
1
@SagarChavada onde você colocou o código? Você deve colocá-lo em um evento único, como quando os dados são atualizados.
Mbengue Assane
5
Recursão, recursão, chamadas intermináveis
zulkarnain shah
2
Usar isso cria dentro de onResume no fragmento faz um loop, como evitá-lo?
Soul
32

Caso você não tenha a tag de fragmento, o código a seguir funciona bem para mim.

Fragment currentFragment = getActivity().getFragmentManager().findFragmentById(R.id.fragment_container);
if (currentFragment instanceof "NAME OF YOUR FRAGMENT CLASS") {
 FragmentTransaction fragTransaction =   (getActivity()).getFragmentManager().beginTransaction();
 fragTransaction.detach(currentFragment);
 fragTransaction.attach(currentFragment);
 fragTransaction.commit();}
}
Martelo
fonte
1
qual será o ID do fragmento, eu não declarei o ID do fragmento em nenhum lugar. Como e onde declará-lo?
Narendra Singh,
Não consigo usar getActivity()na minha atividade. Devo usar Activity.this...?
Si8
@NarendraJi é o id do FrameLayout apenas onde você coloca seus fragmentos no contêiner.
Lokesh
Remova essa cinta extra. Isso me causou muitos problemas.
Abhishek
9

você pode atualizar seu fragmento quando estiver visível para o usuário, basta adicionar este código em seu fragmento. Isso irá atualizar seu fragmento quando estiver visível.

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser) {
        // Refresh your fragment here          
  getFragmentManager().beginTransaction().detach(this).attach(this).commit();
        Log.i("IsRefresh", "Yes");
    }
}
Kaushik Khambhadiya
fonte
tão lento que leva 3 segundos até recarregar
Omar Boshra
Isso parece estar funcionando bem com o adaptador viewpager
DragonFire
2
setUserVisibleHint está obsoleto
Sai Aditya
Funcionou para mim, obrigado pela solução.
hetsgandhi 01 de
7

Para atualizar o fragmento a resposta aceita não funcionará no Nougat e na versão superior. Para fazer funcionar em todos os sistemas operacionais, você pode fazer o seguinte.

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        fragmentManager.beginTransaction().detach(this).commitNow();
        fragmentManager.beginTransaction().attach(this).commitNow();
    } else {
        fragmentManager.beginTransaction().detach(this).attach(this).commit();
    }
Sachin Jagtap
fonte
5

Você não pode recarregar o fragmento enquanto ele estiver anexado a uma atividade, onde você obtém a Fragment Already Addedexceção " ".

Portanto, o fragmento deve ser primeiro destacado de sua atividade e depois anexado. Tudo pode ser feito usando a API fluente em uma linha:

getFragmentManager().beginTransaction().detach(this).attach(this).commit();

Atualização: para incorporar as alterações feitas na API 26 e superior:

FragmentTransaction transaction = mActivity.getFragmentManager()
                        .beginTransaction();
                if (Build.VERSION.SDK_INT >= 26) {
                    transaction.setReorderingAllowed(false);
                }
                transaction.detach(this).attach
                        (this).commit();

Para obter mais descrições da atualização, consulte https://stackoverflow.com/a/51327440/4514796

Ali Nem
fonte
2
Forneça sua resposta com descrições claras. Não escreva o código, dê a explicação sobre o código que você compartilhou, para que outras pessoas também possam entender e isso será útil. Solicito que você leia a seção de perguntas frequentes para usar o Stack Overflow de maneira eficaz.
Sankar Ganesh
3
   MyFragment fragment = (MyFragment) getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG);
        getSupportFragmentManager().beginTransaction().detach(fragment).attach(fragment).commit();

isso só funcionará se você usar FragmentManagerpara inicializar o fragmento. Se você tiver <fragment ... />em XML, não chamará de onCreateViewnovo. Perdi meus 30 minutos para descobrir isso.

Irshu
fonte
1

Aqui está o que eu fiz e funcionou para mim, eu uso o firebase e quando o usuário está logado, eu queria atualizar o fragmento atual primeiro, você precisará solicitar o contexto da atividade porque o fragmento não tem uma maneira de obter contexto, a menos que você o defina em Activity ou context aqui é o código que usei e trabalhei na linguagem kotlin, acho que você poderia usar o mesmo na classe java

   override fun setUserVisibleHint(isVisibleToUser: Boolean) {
    super.setUserVisibleHint(isVisibleToUser)
    val context = requireActivity()
    if (auth.currentUser != null) {
        if (isVisibleToUser){
            context.supportFragmentManager.beginTransaction().detach(this).attach(this).commit()
        }
    }

}
HardiBSalih
fonte
0

Use um ContentProvidere carregue seus dados usando um 'CursorLoader'. Com esta arquitetura, seus dados serão recarregados automaticamente nas alterações do banco de dados. Use estruturas de terceiros para o seu ContentProvider- você realmente não quer implementá-lo sozinho ...

Artkoenig
fonte
0

Eu tive o mesmo problema, mas nenhuma das opções acima funcionou para o meu. ou houve um problema de backstack (depois de carregar quando o usuário pressionou de volta, ele iria para o mesmo fragmento novamente) ou ele não chamou oonCreaetView

finalmente eu fiz isso:

public void transactFragment(Fragment fragment, boolean reload) {
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
    if (reload) {
        getSupportFragmentManager().popBackStack();
    }
    transaction.replace(R.id.main_activity_frame_layout, fragment);
    transaction.addToBackStack(null);
    transaction.commit();
}

bom ponto é que você não precisa da tag ou id do fragmento também. se você quiser recarregar

Emad
fonte
0

Faça uso do método onResume ... tanto na atividade do fragmento quanto na atividade que contém o fragmento.

Mwangi Gituathi
fonte
0
getActivity().getSupportFragmentManager().beginTransaction().replace(GeneralInfo.this.getId(), new GeneralInfo()).commit();

GeneralInfo é minha aula de fragmento GeneralInfo.java

Eu o coloquei como um método na classe de fragmento:

public void Reload(){
    getActivity().getSupportFragmentManager().beginTransaction().replace(LogActivity.this.getId(), new LogActivity()).commit();
}
Brayan Steven Martínez Vanegas
fonte
0

Por exemplo, com TabLayout: basta implementar OnTabSelectedListener. Para recarregar a página, você pode usar implementar SwipeRefreshLayout.OnRefreshListener iepublic class YourFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {

o método onRefresh () será @Override da interface, ou seja:

@Override
public void onRefresh() {
 loadData();
}

Aqui está o layout:

<com.google.android.material.tabs.TabLayout
    android:id="@+id/tablayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/colorPrimaryLighter"
    app:tabGravity="fill"
    app:tabIndicatorColor="@color/white"
    app:tabMode="fixed"
    app:tabSelectedTextColor="@color/colorTextPrimary"
    app:tabTextColor="@color/colorTextDisable" />

Código em sua atividade

TabLayout tabLayout = (TabLayout) findViewById (R.id.tablayout); tabLayout.setupWithViewPager (viewPager);

    tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            if (tab.getPosition() == 0) {
                yourFragment1.onRefresh();
            } else if (tab.getPosition() == 1) {
                yourFragment2.onRefresh();
            }
        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {

        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

        }
    });
Cara JavaEE
fonte
-2
protected void onResume() {
        super.onResume();
        viewPagerAdapter.notifyDataSetChanged();
    }

Escreva viewpagerAdapter.notifyDataSetChanged (); em onResume () em MainActivity. Boa sorte :)

Handy Kim
fonte
-2

Caminho mais fácil

faça um método estático público contendo viewpager.setAdapter

tornar o adaptador e o visualizador estáticos

public static void refreshFragments(){
        viewPager.setAdapter(adapter);
    }

ligue para qualquer lugar, qualquer atividade, qualquer fragmento.

MainActivity.refreshFragments();
ryan christoper lucasan
fonte