1

My app has a tab bar that should be visible at all times. The first tab contains a ListFragment. When I click on an item within, it loads a new activity that creates a detail fragment displaying the contents of the object in the list. I would like to display this content without having to start a new activity because it also destroys the tab bar!

Any help would be greatly appreciated!

To illustrate, here are some screenshots and code:

ListFragment After an item in the list has been clicked

This is the code for the FragmentActivity that creates the tabs:

public class MainFragmentActivity extends FragmentActivity
    implements ActionBar.TabListener {

SectionsPagerAdapter sectionsPagerAdapter = null;
ViewPager viewPager = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final ActionBar actionBar = getActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

    getActionBar().setDisplayShowHomeEnabled(false);
    getActionBar().setDisplayShowTitleEnabled(false);

    sectionsPagerAdapter =
            new SectionsPagerAdapter
                    (
                            getSupportFragmentManager());

    viewPager = (ViewPager) findViewById(R.id.pager);
    viewPager.setAdapter(sectionsPagerAdapter);

    viewPager.setOnPageChangeListener(
            new ViewPager.SimpleOnPageChangeListener() {
                @Override
                public void onPageSelected(int position) {
                    actionBar.setSelectedNavigationItem(position);
                }
            });    // End of sectionPageAdapter.

    Tab browseTab = actionBar.newTab();
    browseTab.setIcon(R.drawable.search);
    browseTab.setTabListener(this);
    actionBar.addTab(browseTab);

    Tab myStuffTab = actionBar.newTab();
    myStuffTab.setIcon(R.drawable.my_stuff);
    myStuffTab.setTabListener(this);
    actionBar.addTab(myStuffTab);

    Tab profileTab = actionBar.newTab();
    profileTab.setIcon(R.drawable.profile);
    profileTab.setTabListener(this);
    actionBar.addTab(profileTab);

    Tab settingsTab = actionBar.newTab();
    settingsTab.setIcon(R.drawable.settings);
    settingsTab.setTabListener(this);
    actionBar.addTab(settingsTab);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public void onTabSelected(ActionBar.Tab tab,
                          FragmentTransaction fragmentTransaction) {
    viewPager.setCurrentItem(tab.getPosition());
}

@Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}

@Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}

public class SectionsPagerAdapter extends FragmentStatePagerAdapter {

    public SectionsPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        switch (position) {

            case 0:
                Fragment browseFragment = new BrowseFragment();
                Bundle browseArgs = new Bundle();
                browseArgs.putInt(BrowseFragment.sectionNumberKey, position + 1);
                browseFragment.setArguments(browseArgs);
                return browseFragment;

            case 1:
                Fragment myStuffFragment = new MyStuffFragment();
                Bundle myStuffArgs = new Bundle();
                myStuffArgs.putInt(BrowseFragment.sectionNumberKey, position + 1);
                myStuffFragment.setArguments(myStuffArgs);
                return myStuffFragment;

            case 2:
                Fragment profileFragment = new ProfileFragment();
                Bundle profileArgs = new Bundle();
                profileArgs.putInt(BrowseFragment.sectionNumberKey, position + 1);
                profileFragment.setArguments(profileArgs);
                return profileFragment;

            case 3:
                Fragment settingsFragment = new SettingsFragment();
                Bundle settingsArgs = new Bundle();
                settingsArgs.putInt(BrowseFragment.sectionNumberKey, position + 1);
                settingsFragment.setArguments(settingsArgs);
                return settingsFragment;
        }
        return null;
    }

    // There are always 4 tabs
    @Override
    public int getCount() {
        return 4;
    }

    // Return a CharSequence for the selected tab
    @Override
    public CharSequence getPageTitle(int position) {
        switch (position) {
            case 0:
                return getString(R.string.title_section1).toUpperCase();
            case 1:
                return getString(R.string.title_section2).toUpperCase();
            case 2:
                return getString(R.string.title_section3).toUpperCase();
            case 3:
                return getString(R.string.title_section4).toUpperCase();

        }
        return null;
    }
}

}    // End of class.

This is the code for the first tab:

public class BrowseFragment extends ListFragment {


public static String sectionNumberKey = "sec_num";
private String activityName = "Browse";

int currentPosition = 0;

List<Listing> listings = new ListingData().getListings();

public BrowseFragment() {}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    BrowseArrayAdapter adapter = new BrowseArrayAdapter(getActivity(),
            R.layout.browselist_item,
            listings);
    setListAdapter(adapter);
}

@Override
public View onCreateView(LayoutInflater inflater,
                         ViewGroup container,
                         Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_browse,
            container, false);

    TextView tv = (TextView) rootView.findViewById(R.id.section_label);

    int intSectionNumber = getArguments().getInt(sectionNumberKey);
    String numAsString = Integer.toString(intSectionNumber);
    tv.setText(numAsString);

    activityName += " " + numAsString;
    return rootView;
}


@Override
public void onListItemClick(ListView l, View v, int position, long id) {
    showDetails(position);
}

void showDetails(int index) {
    currentPosition = index;

    Intent intent = new Intent();
    intent.setClass(getActivity(), BrowseDetailsActivity.class);
    intent.putExtra("index", index);
    startActivity(intent);
}

And here is the code for the Detail Activity:

public class BrowseDetailsActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if (savedInstanceState == null) {
        // During initial setup, plug in the details fragment.
        BrowseDetailFragment details = new BrowseDetailFragment();
        details.setArguments(getIntent().getExtras());
        getFragmentManager().beginTransaction().add(android.R.id.content, details).commit();
    }
}
}
Matt Mac
  • 437
  • 8
  • 22
  • what problem you are getting? – ρяσѕρєя K Feb 13 '15 at 13:18
  • When I click the item in the list, the tabbar gets destroyed. I can't work out how to bypass the need to use the BrowseDetailsActivity. – Matt Mac Feb 13 '15 at 13:21
  • Create a callback between `MainActivity` and `BrowseFragment` and use that in `BrowseFragment#OnClick` to communicate when a list-item is clicked and in MainActivity load the `BrowseDetailFragment` either by add/replacing the current fragment. – blizzard Feb 13 '15 at 13:36
  • @MattMac http://stackoverflow.com/questions/34683837/what-is-the-best-way-to-use-details-fragment-inside-list-fragment could you check this question i created that regarding your answer :) – shanks Jan 08 '16 at 19:42

1 Answers1

1

Basicly you just have to use the content of the onCreate method from your BrowseDetailActivity in the showDetails method of your BrowseFragment. In this way, you can drop your BrowseDetailsActivity.

BrowseFragment.java

void showDetails(int index) {
    BrowseDetailFragment details = BrowseDetailFragment.newInstance(index);
    getChildFragmentManager().beginTransaction().add(details).commit();
}

And use the static newInstance method inside your BrowseDetailFragment like so:

BrowseDetailFragment.java

public class BrowseDetailFragment extends Fragment {

    private int position;

    public static BrowseDetailFragment newInstance(int position) {
        BrowseDetailFragment fragment = new BrowseDetailFragment();
        fragment.position = position;
        return fragment;
    }

    public BrowseDetailFragment() {
        //Required empty constructor
    }

    //Lifecycle methods and logics
}

Make sure to provide some navigation option so users can return to your list.

Hookah_Smoka
  • 374
  • 1
  • 2
  • Thanks for the help :) I understand what we're trying to do, and it nearly works! My error is in BrowseFragment on the line: getFragmentManager().beginTransaction().add(details).commit(); The message is "Cannot resolve method 'add(bandy.mobileapp.BrowseDetailFragment)'" and "Error:(76, 48) error: no suitable method found for add(BrowseDetailFragment) method FragmentTransaction.add(Fragment,String) is not applicable (actual and formal argument lists differ in length) method FragmentTransaction.add(int,Fragment) is not applicable" etc etc – Matt Mac Feb 13 '15 at 23:11