Recover data from Fragment

Asked

Viewed 2,120 times

0

I have an Activity with 4 tabs, in each tab I carry a different Fragment, in each Ragment I have a flumulario, and in the last I have the Register button, when I click Register I want to get the data of all other Ragments, I thought about creating a class with the form data and every time I step from Fragment I store in an object and going from Fragment to Fragment, but I do not know where I will feed this object, I tried in onPause method but it is not right because Fragment is not paused when accessing the other.

I put an onPause on each fragment to test.

public void onPause(){
super.onPause();
Log.i("PAUSE", "pause A");
}

The logs of Fragmente A, B, C and D are equal only by changing pause A/B/C/D. But what happens is this, when I navigate between tabs, it appears the onPause information not from what was paused, but from the previous one. For example, I am in A, I pass to B nothing happens, when I pass to C, appears in the Log, "test A", when I pass to D appears "test B". And to return is also the same thing, when I go from D to C nothing happens. Ai from C to D appears "pause D"

Activity

package br.com.android.controledevisitas.view;

import java.util.HashMap;
import java.util.List;
import java.util.Vector;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.widget.TabHost;
import android.widget.TabHost.TabContentFactory;
import br.com.android.controledevisitas.R;
import br.com.android.controledevisitas.adapter.ViewPagerAdapter;
import br.com.android.controledevisitas.fragment.RealizaVisitaFragmentA;
import br.com.android.controledevisitas.fragment.RealizaVisitaFragmentB;
import br.com.android.controledevisitas.fragment.RealizaVisitaFragmentC;
import br.com.android.controledevisitas.fragment.RealizaVisitaFragmentD;
import br.com.android.controledevisitas.model.Visita;

public class RealizarVisitaActivity extends FragmentActivity implements
        TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener {
    public Visita visita = new Visita();

    private TabHost mTabHost;
    private ViewPager mViewPager;
    private HashMap<String, TabInfo> mapTabInfo = new HashMap<String, RealizarVisitaActivity.TabInfo>();
    private PagerAdapter mPagerAdapter;

    public String teste;

    // Informação da Tab
    private class TabInfo {
        private String tag;
        private Class<?> clss;
        private Bundle args;
        private Fragment fragment;

        TabInfo(String tag, Class<?> clazz, Bundle args) {
            this.tag = tag;
            this.clss = clazz;
            this.args = args;
        }
    }

    // Um simples factory que retorna View para o TabHost
    class TabFactory implements TabContentFactory {

        private final Context mContext;

        public TabFactory(Context context) {
            mContext = context;
        }

        public View createTabContent(String tag) {
            View v = new View(mContext);
            v.setMinimumWidth(0);
            v.setMinimumHeight(0);
            return v;
        }
    }

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Infla o layout
        setContentView(R.layout.realizavisita);
        // setContentView(R.layout.realizarvisita_a);
        // Inicializa o TabHost
        this.initialiseTabHost(savedInstanceState);
        if (savedInstanceState != null) {
            // Define a Tab de acordo com o estado salvo
            mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab"));
        }
        // Inicializa o ViewPager
        this.intialiseViewPager();
    }

    protected void onSaveInstanceState(Bundle outState) {
        // salva a Tab selecionada
        outState.putString("tab", mTabHost.getCurrentTabTag());
        super.onSaveInstanceState(outState);
    }

    private void intialiseViewPager() {

        List<Fragment> fragments = new Vector<Fragment>();
        fragments.add(Fragment.instantiate(this,
                RealizaVisitaFragmentA.class.getName()));
        fragments.add(Fragment.instantiate(this,
                RealizaVisitaFragmentB.class.getName()));
        fragments.add(Fragment.instantiate(this,
                RealizaVisitaFragmentC.class.getName()));
        fragments.add(Fragment.instantiate(this,
                RealizaVisitaFragmentD.class.getName()));
        this.mPagerAdapter = new ViewPagerAdapter(super.getSupportFragmentManager(), fragments);
        this.mViewPager = (ViewPager) super.findViewById(R.id.viewpager);
        this.mViewPager.setAdapter(this.mPagerAdapter);
        this.mViewPager.setOnPageChangeListener(this);
    }

    private void initialiseTabHost(Bundle args) {
        mTabHost = (TabHost) findViewById(android.R.id.tabhost);
        mTabHost.setup();
        TabInfo tabInfo = null;
        RealizarVisitaActivity.AddTab(this, this.mTabHost, this.mTabHost
                .newTabSpec("Tab1").setIndicator("A"), (tabInfo = new TabInfo(
                "Tab1", RealizaVisitaFragmentA.class, args)));
        this.mapTabInfo.put(tabInfo.tag, tabInfo);
        RealizarVisitaActivity.AddTab(this, this.mTabHost, this.mTabHost
                .newTabSpec("Tab2").setIndicator("B"), (tabInfo = new TabInfo(
                "Tab2", RealizaVisitaFragmentB.class, args)));
        this.mapTabInfo.put(tabInfo.tag, tabInfo);
        RealizarVisitaActivity.AddTab(this, this.mTabHost, this.mTabHost
                .newTabSpec("Tab3").setIndicator("C"), (tabInfo = new TabInfo(
                "Tab3", RealizaVisitaFragmentC.class, args)));
        this.mapTabInfo.put(tabInfo.tag, tabInfo);
        RealizarVisitaActivity.AddTab(this, this.mTabHost, this.mTabHost
                .newTabSpec("Tab4").setIndicator("D"), (tabInfo = new TabInfo(
                "Tab4", RealizaVisitaFragmentD.class, args)));
        this.mapTabInfo.put(tabInfo.tag, tabInfo);
        mTabHost.setOnTabChangedListener(this);
    }

    private static void AddTab(RealizarVisitaActivity activity,
            TabHost tabHost, TabHost.TabSpec tabSpec, TabInfo tabInfo) {
        // Attach uma Tab view factory para o spec
        tabSpec.setContent(activity.new TabFactory(activity));
        tabHost.addTab(tabSpec);
    }

    public void onTabChanged(String tag) {
        // Avisa para o mViewPager qual a Tab que está ativa
        int pos = this.mTabHost.getCurrentTab();
        this.mViewPager.setCurrentItem(pos);
    }

    @Override
    public void onPageScrolled(int position, float positionOffset,
            int positionOffsetPixels) {
    }

    @Override
    public void onPageSelected(int position) {
        this.mTabHost.setCurrentTab(position);
    }

    @Override
    public void onPageScrollStateChanged(int state) {
    }

    public void onResume() {
        super.onResume();

    }

    public void onPause() {
        super.onPause();
    }
}

Viewpageradapter

package br.com.android.controledevisitas.adapter;

import java.util.List;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

public class ViewPagerAdapter extends FragmentPagerAdapter{
     private List<Fragment> mFragments;

      public ViewPagerAdapter(FragmentManager fm, List<Fragment> fragments) {
        super(fm);

        mFragments = fragments;
      }

      @Override
      public Fragment getItem(int i) {  
        return mFragments.get(i);
      }

      @Override 
      public int getCount() {
        return mFragments.size();
      }
}
  • Is using the ViewPager to show the Fragments?

  • Yes I am, I did following this tutorial here. http://wcabralti.blogspot.com.br/2013/03/tabs-fragments-swipe-em-android.html

  • So I was able to pass the data already, but so, to get everything I have to complete, then to get the data of the 3rd tab I have to go back to the 1st, then I go to the 4th and register, if I go straight he is without the data of the 3rd. :/

  • The problem of data loss is because of the behavior of ViewPager, a glance at this question (http://answall.com/questions/16682/seekbar-behaviorsunexpectedlyway of working offsetPageLimit. The data of Fragment you can get through the Adapter that he used in the ViewPager, access to View of Fragment to get the data.

  • Sorry but I program on android less than 1 month, as I will do to use the Adapter Viewpager.

  • Edit your question and include your code Activity. Where instance the Adapter and also the code of Adapter.

  • ready, up-to-date

  • Hello good! I am having the same problem of a screen with Tabs and with difficulty to pick up the various fields in each Ragment, as Wakin mentioned I try to get the data using the Adapter but I get a Nullpointerexception, I put a question here on the forum, unfortunately there was no response and I’m having to comment here in the hope of having a north of what this being there, I do not see how to use Interfaces that is recommended in the Tabs documentation.

Show 3 more comments

1 answer

0


To better understand why the onPause of Fragment A is only called when it goes to the Fragment C, I’ll try to explain the behavior of ViewPager.

Viewpager by default only stores 2 items in memory. What is visible and what is next for the transition effect to be more fluid.

The attribute OffscreenPageLimit controls this effect, by default it is 1.

If in your case the Layouts are simple, you can set it as 3, so that none of your Fragments be destroyed.

For the problem of data loss, there are two ways to address the problem:

  1. Setar the OffscreenPageLimit of ViewPager to 3, so no Fragment will be destroyed. And the data will not be lost. Simply access Fragments for Adapter to recover the data. Reinforcement that this is only a good alternative if the Layouts are not complex, so there is no excessive memory expenditure
  2. When the Fragment is destroyed and, that is, when the method onDestroyView is called. Just save the data in the Activity. In his Fragment would have something like:

    @Override
    public void onDestroyView() {
        // Usar o método findViewById, pegando os dados que for de interesse
        // Nesse caso há duas formas:
        //  1. Acessar a instância da Activity com getActivity(), fazer um cast e ir setando os dados.
        ((SuaActivity) getActivity()).salvarDados(...);
        //  2. Criar um Listener, setar e chama-lo nesse momento passando os dados
        mSaveStateListener.salvarDados(...);
    
        super.onDestroyView(); // Chamar o metodo da superclasse
    }
    

    The second way involves: Creating an interface Listener, set a Listener in each Fragment through the Activity. That one Listener will be called to save the data when the Fragment is destroyed.

To access the Fragments who are in the Adapter, and retrieve the form data, you can do so within Activity:

public void confirmaFormulario() {
    RealizaVisitaFragmentA visitaA = mAdapter.getItem(0);
    RealizaVisitaFragmentB visitaB = mAdapter.getItem(1);
    // Mesma coisa com os demais fragmentos

    // Chama os metodos do Fragment para recuperar os dados
}

This method should be called when the button that is on Fragment 4 is clicked.

  • If you have any questions, just say the word and I’ll hold you to the point.

  • You have to make sure that the Adapter was created. Where did you put this code? How is the last click button processing Fragment?

  • Sorry, I was traveling here, already got it, sorry for the inconvenience. And thank you so much for everything :)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.