2

I'm new to Android development and am having trouble with the details the ActionBar swipeable tab model. I understand that each tab has a fragment and that the ViewPager handles calling each new fragment. After that I'm a little lost.

I've successfully created 4 tabs with their own layouts, but am having trouble changing layouts within each tab. From my research it seems I should start with a fragment with an empty layout, then add and replace fragments to it at the appropriate time.

In my code below, I want to add the "fragment_search_bar" to the empty "fragment_search" just one time. This seems to work, but when I navigate to the other tabs and come back, the search bar disappears. It sometimes appears again when I return to the search tab coming from the tab adjacent to it. Ideally I want the search bar to replaced by the next fragment of search results when the button is pressed (I think this will be easily done once I understand my current problem).

I'm pretty sure I'm just not completely familiar with fragment lifecycle even after extensive reading.

SearchFragment.java

public class SearchFragment extends Fragment {


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    View rootView = inflater.inflate(R.layout.fragment_search, container, false);


    if (rootView.findViewById(R.id.fragment_search_bar) == null) {
        FragmentSearchBar searchBar = new FragmentSearchBar();
        searchBar.setRetainInstance(true);
        FragmentManager fragmentManager = getFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.replace(R.id.fragment_search, searchBar, "search_bar");
        fragmentTransaction.addToBackStack("search_bar");
        fragmentTransaction.commit();
    }

fragment_search.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:id="@+id/fragment_search" >
</LinearLayout>

fragment_search_bar.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:id="@+id/fragment_search_bar" >

<EditText android:id="@+id/search_query"
    android:layout_weight="1"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:hint="@string/search_prompt" />
<Button android:id="@+id/search_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/search_button" />
</LinearLayout>

2 Answers2

0

I am not sure what causes your problem, can you add all the relevant components (the ViewPager, the FragmentPagerAdapter etc.) as well?

Here is what worked for me: I had the same idea as you, so I encapsulated the replacing functionality inside a class HostFragment that comes with a replace method that is able to track the back navigation history.

public void replaceFragment(Fragment fragment, boolean addToBackstack) {
    if (addToBackstack) {
        getChildFragmentManager().beginTransaction().replace(R.id.hosted_fragment, fragment).addToBackStack(null).commit();
    } else {
        getChildFragmentManager().beginTransaction().replace(R.id.hosted_fragment, fragment).commit();
    }
}

All that method does is to replace the frame layout with the id R.id.hosted_fragment with the fragment provided to the method. Now I only have to initialize the pages of my ViewPager with instances of HostFragment that host the specific type of fragment I need. As is required with view pagers, that work is done inside a custom FragmentPagerAdapter class. To also show a clickable tab bar, I also included a tab layout.

Check my tutorial on this topic for further details and a complete working example on GitHub!

marktani
  • 7,578
  • 6
  • 37
  • 60
0

It sounds like you need to cache your pages. Try

mViewPager.setOffscreenPageLimit(3);

add this line where you call your viewpager. When you navigate to other tabs, android only saves the current fragment, one left and one right. So setting offscreenpagelimit to 3 will tell android to save current, and 3 right and 3 left.

Musicdad
  • 55
  • 1
  • 2
  • 12