I have a Tab Activity that has x
amount of tabs. All the tabs load properly on the first load. If I go x+2
tabs away from a tab and then go back, some of the data and elements are missing.
I used the Android Studio's own Tabbed Activity
generated template, as well as the Fragment templates for the tabs.
I have reviewed SO and a few others, but they do not seem to fit my model exactly. Or if they do, Im not seeing it.
Any help?
Here is my Master Tabbed Activity with some of the relevant imports.
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
public class MasterTabActivity extends AppCompatActivity {
public static Intent newIntent(Context packageContext) {
Intent intent = new Intent(packageContext, MasterTabActivity.class);
Bundle bundle = new Bundle();
intent.putExtras(bundle);
return intent;
}
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_master_tab);
Bundle bundle = getIntent().getExtras();
if (bundle != null) {
//get some data
}
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar ab = getSupportActionBar();
if (ab != null) {
ab.setDisplayHomeAsUpEnabled(true);
}
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
// Titles
tabLayout.addTab(tabLayout.newTab().setText("Details"));
tabLayout.addTab(tabLayout.newTab().setText("Photos"));
tabLayout.addTab(tabLayout.newTab().setText("Notes"));
//Add ICONS TO TEXT
tabLayout.getTabAt(0).setIcon(R.drawable.ic_details);
tabLayout.getTabAt(1).setIcon(R.drawable.ic_photos);
tabLayout.getTabAt(2).setIcon(R.drawable.ic_notes);
tabLayout.setTabTextColors(
ContextCompat.getColor(this, R.color.colorPrimary), //unselected
ContextCompat.getColor(this, R.color.colorDarkText) //selected
);
//Set the initial selected icons tab color
tabLayout.getTabAt(0).getIcon().setColorFilter(ContextCompat.getColor(getApplicationContext(), R.color.colorDarkText), PorterDuff.Mode.SRC_IN);
tabLayout.getTabAt(1).getIcon().setColorFilter(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary), PorterDuff.Mode.SRC_IN);
tabLayout.getTabAt(2).getIcon().setColorFilter(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary), PorterDuff.Mode.SRC_IN);
// tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
mViewPager.setCurrentItem(tab.getPosition());
tab.getIcon().setColorFilter(ContextCompat.getColor(getApplicationContext(), R.color.colorDarkText), PorterDuff.Mode.SRC_IN);
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
tab.getIcon().setColorFilter(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary), PorterDuff.Mode.SRC_IN);
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
refreshData();
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return DetailsFragment.newInstance(createdCallKey);
case 1:
return PhotosFragment.newInstance(createdCallKey);
case 2:
return NotesFragment.newInstance(createdCallKey);
default:
return null;
}
}
@Override
public int getCount() {
return 3;
}
}
}
And a sample of the fragments. At this point they are pretty much setup the same, save some basic GUI elements.
import android.support.v4.app.Fragment;
public class DetailsFragment extends Fragment {
public DetailsFragment() {
// Required empty public constructor
}
public static DetailsFragment newInstance(String callKey) {
DetailsFragment fragment = new DetailsFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_details, container, false);
//do all the view setup
return rootView;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
}
@Override
public void onDetach() {
super.onDetach();
}
}
In my Fragments
I query the Tabbed Activity
for some data. When a fragment moves more than x+2
tabs away, the Fragments onPause
method (along with the other teardown methods) is called. Check the lifecycle documents for all the stages of the fragment.
When you return to the tab, the onCreateView
method (along with the other build methods baring 1onAttach1 and onCreate
. In my example above, the fragment queries the Activity in onCreate
.
So I created a refreshData method:
private void refreshData() {
someTextElement.setText(((MasterTabActivity) getActivity()).getCallDetailsDictionary().getString("CALdCallTaken").getString("SomeKey"));
}
And moved the call to refreshData
into onStart
, first checking that the data in the activity is not null.
@Override
public void onStart() {
super.onStart();
Log.w(TAG, "-------------- onStart");
if (((MasterTabActivity) getActivity()).getCallDetailsDictionary() != null) {
refreshData();
}
}
Now, whenever that view returns into view, it will call onStart
and refresh its data.