Search code examples
androiddeprecatedtabbed

Something like TabHost.onTabChanged()


I'm making a tabbed application and need a way to do an action on when I change a tab. The problem is that all I can find is about TabHost which relies on the deprecated TabActivity class. Even if it wasn't deprecated the pre-generated tabbed activity code doesn't even use it, so I'd have to build my main activity class from the ground up. So I want to know if there is another way to get that functionality

rough skeleton of the code

public class MainActivity extends AppCompatActivity implements TabHost.OnTabChangeListener{

public class SectionsPagerAdapter extends FragmentPagerAdapter {

}

}


Solution

  • Let's pretend that you are using Android Studio 1.5.1.

    When I create a project using the new-project wizard, and accept the defaults, except choosing "Tabbed Activity" as the template, on the activity-configuration page of the wizard, there is a drop-down for "Navigation Style". There are three options there: "Swipe Views", "Action Bar Tabs", and "Action Bar Spinner".

    Let's pretend that you chose "Action Bar Tabs".

    The resulting activity does not have implements TabHost.OnTabChangeListener, and I am not aware of any of their templates that do. Instead, you get this:

    import android.support.design.widget.TabLayout;
    import android.support.design.widget.FloatingActionButton;
    import android.support.design.widget.Snackbar;
    import android.support.v7.app.AppCompatActivity;
    import android.support.v7.widget.Toolbar;
    
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentManager;
    import android.support.v4.app.FragmentPagerAdapter;
    import android.support.v4.view.ViewPager;
    import android.os.Bundle;
    import android.view.LayoutInflater;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.View;
    import android.view.ViewGroup;
    
    import android.widget.TextView;
    
    public class MainActivity extends AppCompatActivity {
    
      /**
       * The {@link android.support.v4.view.PagerAdapter} that will
       * provide
       * fragments for each of the sections. We use a
       * {@link FragmentPagerAdapter} derivative, which will keep
       * every
       * loaded fragment in memory. If this becomes too memory
       * intensive, it
       * may be best to switch to a
       * {@link android.support.v4.app.FragmentStatePagerAdapter}.
       */
      private SectionsPagerAdapter mSectionsPagerAdapter;
    
      /**
       * The {@link ViewPager} that will host the section contents.
       */
      private ViewPager mViewPager;
    
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        Toolbar toolbar=(Toolbar)findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        // Create the adapter that will return a fragment for each of the three
        // primary sections of the activity.
        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);
        tabLayout.setupWithViewPager(mViewPager);
    
        FloatingActionButton fab=
          (FloatingActionButton)findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View view) {
            Snackbar.make(view, "Replace with your own action",
              Snackbar.LENGTH_LONG)
              .setAction("Action", null).show();
          }
        });
    
      }
    
    
      @Override
      public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
      }
    
      @Override
      public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id=item.getItemId();
    
        //noinspection SimplifiableIfStatement
        if (id==R.id.action_settings) {
          return true;
        }
    
        return super.onOptionsItemSelected(item);
      }
    
      /**
       * A placeholder fragment containing a simple view.
       */
      public static class PlaceholderFragment extends Fragment {
        /**
         * The fragment argument representing the section number for
         * this
         * fragment.
         */
        private static final String ARG_SECTION_NUMBER=
          "section_number";
    
        public PlaceholderFragment() {
        }
    
        /**
         * Returns a new instance of this fragment for the given
         * section
         * number.
         */
        public static PlaceholderFragment newInstance(
          int sectionNumber) {
          PlaceholderFragment fragment=new PlaceholderFragment();
          Bundle args=new Bundle();
          args.putInt(ARG_SECTION_NUMBER, sectionNumber);
          fragment.setArguments(args);
          return fragment;
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater,
                                 ViewGroup container,
                                 Bundle savedInstanceState) {
          View rootView=
            inflater.inflate(R.layout.fragment_main, container,
              false);
          TextView textView=
            (TextView)rootView.findViewById(R.id.section_label);
          textView.setText(getString(R.string.section_format,
            getArguments().getInt(ARG_SECTION_NUMBER)));
          return rootView;
        }
      }
    
      /**
       * A {@link FragmentPagerAdapter} that returns a fragment
       * corresponding to
       * one of the sections/tabs/pages.
       */
      public class SectionsPagerAdapter
        extends FragmentPagerAdapter {
    
        public SectionsPagerAdapter(FragmentManager fm) {
          super(fm);
        }
    
        @Override
        public Fragment getItem(int position) {
          // getItem is called to instantiate the fragment for the given page.
          // Return a PlaceholderFragment (defined as a static inner class below).
          return PlaceholderFragment.newInstance(position+1);
        }
    
        @Override
        public int getCount() {
          // Show 3 total pages.
          return 3;
        }
    
        @Override
        public CharSequence getPageTitle(int position) {
          switch (position) {
            case 0:
              return "SECTION 1";
            case 1:
              return "SECTION 2";
            case 2:
              return "SECTION 3";
          }
          return null;
        }
      }
    }
    

    If this is where you started, the proper response to "explain exactly what you are using right now" would have been "AppCompatActivity, ViewPager, and TabLayout".

    Let's pretend that this is what you have, more or less.

    In that case, call addOnPageChangeListener() on the ViewPager, passing in an OnPageChangeListener implementation. That will be called when the user switches tabs, whether via the TabLayout or by swipe gestures on the ViewPager itself.

    Now, it is entirely possible that this is not what you have, as I had to make a few guesses, given your limited explanation in your question.