Primico
Primico

Reputation: 2455

Android Back Button with Fragments in Tabs

I am using tabs to switch between different lists in my app. When a user touches an item in a list, the following is the code to show and hide the detail. I am wondering how to add a back-button that goes back to the correct list it came from. I am replacing fragments so I don't know if the standard back button works in my case?

    public class MainActivity extends AppCompatActivity implements 
        NavigationView.OnNavigationItemSelectedListener,
                    TabLayout.OnTabSelectedListener,
                    CustomerFragment.CustomerListListener,
                    CustomerDetailListener {

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

            Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
            setSupportActionBar(toolbar);

            ActionBar actionBar = getSupportActionBar();
            actionBar.setHomeButtonEnabled(true);
            actionBar.setDisplayHomeAsUpEnabled(true);
            actionBar.setDisplayShowHomeEnabled(true);
        }

        public void onShowCustomerDetail(Customer customer){
                HostFragment hostFragment = (HostFragment) customPagerAdapter.getItem(viewPager.getCurrentItem());
                CustomerDetailFragment fragment = CustomerDetailFragment.newInstance(customer);
                hostFragment.replaceFragment(fragment, true);
        }

        public void onCloseCustomerDetail() {
            HostFragment hostFragment = (HostFragment) customPagerAdapter.getItem(viewPager.getCurrentItem());
            CustomerFragment fragment = new CustomerFragment();
            hostFragment.replaceFragment(fragment, true);
        }

        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            // just for testing. will do switch case here
            onBackPressed();
        }

        @Override
        public void onBackPressed() {
            if (getFragmentManager().getBackStackEntryCount() > 0) {
                getFragmentManager().popBackStack();
            } else {
                super.onBackPressed();
            }
        }
}

CustomPagerAdapter:

public class CustomPagerAdapter extends FragmentStatePagerAdapter {
    private final List<String> tabTitles = new ArrayList<String>() {{
        add("Messages");
        add("Customers");
        add("Jobs");
        add("Maps");
    }};

    private List<Fragment> tabs = new ArrayList<>();

    public CustomPagerAdapter(FragmentManager fragmentManager) {
        super(fragmentManager);
        initializeTabs();
    }

    private void initializeTabs() {
        tabs.add(HostFragment.newInstance(new MessageFragment()));
        tabs.add(HostFragment.newInstance(new CustomerFragment()));
        tabs.add(HostFragment.newInstance(new JobFragment()));
        tabs.add(HostFragment.newInstance(new MapFragment()));
    }

    @Override
    public Fragment getItem(int position) {
        return tabs.get(position);
    }

    @Override
    public int getCount() {
        return tabs.size();
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return tabTitles.get(position);
    }
}

HostFragment:

public class HostFragment extends BackStackFragment {
    private Fragment fragment;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        View view = inflater.inflate(R.layout.fragment_host, container, false);
        if (fragment != null) {
            replaceFragment(fragment, false);
        }
        return view;
    }

    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();
        }
    }

    public static HostFragment newInstance(Fragment fragment) {
        HostFragment hostFragment = new HostFragment();
        hostFragment.fragment = fragment;
        return hostFragment;
    }
}

Upvotes: 0

Views: 3662

Answers (4)

Primico
Primico

Reputation: 2455

Because of the way I set up my fragments inside tabs using Child Fragment Manager, I had to do this in my onBackPressed to make it work:

@Override
public void onBackPressed() {
    HostFragment hostFragment = (HostFragment) customPagerAdapter.getItem(viewPager.getCurrentItem());
    FragmentManager fm = hostFragment.getChildFragmentManager();
    if (fm.getBackStackEntryCount() > 0) {
        fm.popBackStack();
    } else {
        super.onBackPressed();
    }
}

Upvotes: 2

Nazim ch
Nazim ch

Reputation: 854

Write a fuction onBackpress()

 @Override
 public void onBackPressed() {
    new AlertDialog.Builder(this)
    .setTitle("Exit?")
    .setMessage("Do you really want to exit?")
    .setNegativeButton("No")
    .setPositiveButton("Yes", new OnClickListener() {

        public void onClick(DialogInterface arg0, int arg1) {
            YourActivityname.super.onBackPressed();
        }
    }).create().show();
 }

Upvotes: 0

BlackHatSamurai
BlackHatSamurai

Reputation: 23483

All you need to do is add the fragment to the back stack when you create your fragment. It would look something like this:

CustomerDetailFragment fragment=CustomerDetailFragment.newInstance(customer);

getFragmentManager().beginTransaction()
                                .addToBackStack("Fragment Tag")
                                .replace(R.id.yourContainer, fragment, "Fragment Tag")
                                .commit();

Once you have this, you can just use the home back button to pop the fragments off the stack. If you want to use a custom button to go back, you would have to implement your own popping of the stack, which would call getFragmentManager().popBackStack();

Upvotes: 0

Jitesh Mohite
Jitesh Mohite

Reputation: 34210

First of all you need to add fragments in backstack while using it

see below code for creating a fragment and adding inside it to backstack

public final static String TAG_FRAGMENT = "HostFragment"; // used inside every fragment 

final HostFragment fragment = new HostFragment();
    final FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    transaction.replace(R.id.fragment, fragment, TAG_FRAGMENT);
    transaction.addToBackStack(TAG_FRAGMENT);
    transaction.commit();

After that inside activity onBackPressed() you need to pop fragment every backpressed that you want.

@Override
public void onBackPressed() {
    if (getFragmentManager().getBackStackEntryCount() > 0) {
        getFragmentManager().popBackStack(); // pop fragment here
    } else {
        super.onBackPressed(); // after nothing is there default behavior of android works.
    }
}

Upvotes: 0

Related Questions