Get PagerSlidingTabStrip page title onPageSelected - android

I'm trying to get the selected page title from a PagerSlidingTabStrip to display on a toast. The page titles are generated from a dynamic list. I am able to get the current page position to display on a toast using:
tabStrip.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
Toast.makeText(getActivity(), "Page position: " + position, Toast.LENGTH_SHORT).show();
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
How can I get the current/selected page title?

Create your own adapter for the PagerSlidingTabStrip(this is a viewpager right?) that will manage the titles and also positions.
ViewPager viewPager;
ViewPagerAdapter vpAdapter;
In mainActivity
viewPager = (ViewPager) findViewById(R.id.pager);
vpAdapter = new ViewPagerAdapter(getSupportFragmentManager(), 2, this, clock, history);
ViewPagerAdapter
public class ViewPagerAdapter extends FragmentPagerAdapter {
private int nTabs;
private Context context;
private Fragment fragment1, fragment2;
private CharSequence[] titles;
public ViewPagerAdapter(FragmentManager fm, int nTabs, Context context, Fragment fragment1, Fragment fragment2) {
super(fm);
this.fragment1= fragment1;
this.fragment2= fragment2;
this.context =context;
this.nTabs = nTabs;
titles = new CharSequence[]{context.getText(R.string.Title_tab1), context.getText(R.string.Title_tab2)};
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return fragment1;
case 1:
return fragment2;
default:
return fragment1;
}
}
#Override
public int getCount() {
return nTabs;
}
#Override
public CharSequence getPageTitle(int position) {
return titles[position];
}
}
and don't forget to set the adapter on the viewpager
viewPager.setAdapter(vpAdapter);

Related

Fragment onCreateView getting called multiple time so that new instance of fragment is created every time

I am trying to add the fragments on page change of view pager. but every time when i scroll the view pager, new instant of fragment is created.
public void initializeViewPager(int currentPage, String selectedCardNumber) {
currentPosition = currentPage;
FragmentPagerAdapter journeyViewPagerAdapter =
new ViewPagerAdapter(getSupportFragmentManager());
ViewPager.OnPageChangeListener onPageChangeListener = new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
//Default Implementation
}
#Override
public void onPageSelected(int position) {
currentPosition = position;
addFragments(position, selectedCardNumber);
handleScrollState();
}
#Override
public void onPageScrollStateChanged(int state) {
//Default Implementation
}
};
viewPager.addOnPageChangeListener(onPageChangeListener);
initCarousalAdapter();
}
addFragments() method
private void addFragments(int position, final String selectedCardNumber) {
FragmentTransaction fragTransaction = getSupportFragmentManager().beginTransaction();
Bundle bundle = new Bundle();
bundle.putInt(ApplicationConstants.SELECTED__TYPE, position);
bundle.putString(DataConstants.SELECTED__NUMBER, selectedCardNumber);
switch (position) {
case 1:
OffersFragmentOne fragment = OffersFragmentOne.getInstance();
fragment.setArguments(bundle);
fragTransaction.replace(R.id.btmt_fragment_container, fragment);
break;
case 2:
OffersFragmentTwo mtFragment = OffersFragmentTwo.getInstance();
mtFragment.setArguments(bundle);
fragTransaction.replace(R.id.btmt_fragment_container, mtFragment);
break;
case 3:
OffersFragmentThree poFragment = OffersFragmentThree.getInstance();
poFragment.setArguments(bundle);
fragTransaction.replace(R.id.btmt_fragment_container, poFragment);
break;
default:
//Default Implementation
}
fragTransaction.commit();
}
getInstance() method
private static OffersFragmentOne offersFragmentOne;
public static OffersFragmentOne getInstance() {
if (OffersFragmentOne == null) {
offersFragmentOne = new OffersFragmentOne();
}
return offersFragmentOne;
}
ViewPagerAdapter.java
public class ViewPagerAdapter extends FragmentPagerAdapter {
private final int[] carousalImages = {R.drawable.ic_po_carousal_banner,
R.drawable.ic_bt_carousal_banner,
R.drawable.ic_mt_carousal_banner, R.drawable.ic_po_carousal_banner,
R.drawable.ic_bt_carousal_banner};
public ViewPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
#Override
public Fragment getItem(int position) {
CarousalFragment frag = new CarousalFragment();
CarousalFragmentPresenter.createAndAttach(frag, carousalImages[position]);
return frag;
}
#Override
public int getCount() {
return carousalImages != null ? carousalImages.length : 0;
}
}
You should write your switch case in getItem and don't required bundle and fragment transaction because getItem itself returns selected Fragment and will bind with ViewPager
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
CarousalFragment();
break;
case 1:
OffersFragmentOne.getInstance();
break;
case 2:
OffersFragmentTwo.getInstance();
break;
case 3:
OffersFragmentThree.getInstance();
break;
default:
//Default Implementation
}
}
OnPageChangeListener just give you the position of selected and scrolled item or fragment, so don't required to add fragment from onPageSelected
ViewPager.OnPageChangeListener onPageChangeListener = new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
//Default Implementation
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
//Default Implementation
}
};
How about creating the fragment instances in the container activity or so of the view pager? That way they should be created only when the container is created.
EDIT: Adding example code.
Example:
public class ContainerActivity extends AppCompatActivity {
private FragmentOne fragmentOne;
private FragmentTwo fragmentTwo;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.container_with_view_pager);
fragmentOne = FragmentOne.getInstance();
fragmentTwo = FragmentTwo.getInstance();
ViewPager viewPager = findViewById(R.id.viewpager);
setupViewPager(viewPager);
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(fragmentOne, "Fragment One");
adapter.addFragment(fragmentTwo, "Fragment Two");
viewPager.setAdapter(adapter);
}
}

Implement Listener with ViewPager

I have a Main Activity with a Tablayout, which contains 3 Fragments. There's a FAB in the Main Activity that sits on tops of all the Fragments as a I swipe. I need to create an interface, so that when the FAB is clicked, my ViewPager is alerted and performs a certain action. Does anyone know how I could create this listener?
The Listener should just return a boolean indicating that the Fab was clicked.
I added an Interface in my Main Activity but am not sure how to utilize it and connect it to my ViewPagerAdapter Class?
Here is my Main Activity:
public class MainActivity extends AppCompatActivity {
private ViewPager viewPager;
private ArrayList<Fragment> fragments = new ArrayList<>();
private ArrayList<String> titles = new ArrayList<>();
//MY LISTENER....
private static SwitchFragmentsListener switchFragsListener;
public static interface SwitchFragmentsListener{
public void doISwitch(boolean change);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
CollapsingToolbarLayout collapsingToolbarLayout = (CollapsingToolbarLayout)findViewById(R.id.collapsing_toolbar);
setSupportActionBar(toolbar);
fragments.addAll(Arrays.asList(new Tasks(),new Calendar(),new Contacts()));
titles.addAll(Arrays.asList(getResources().getString(R.string.fragment_task_title),
getResources().getString(R.string.fragment_cal_title),getResources().getString(R.string.fragment_contacts_title)));
TabLayout tabLayout = (TabLayout)findViewById(R.id.tabs);
final FloatingActionButton fab = (FloatingActionButton)findViewById(R.id.fab);
fab.hide();
viewPager = (ViewPager)findViewById(R.id.container);
ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager(),fragments,titles);
viewPager.setAdapter(viewPagerAdapter);
viewPager.setCurrentItem(1);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
if (position == 1) {
fab.hide();
}else {
fab.show();
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
tabLayout.setupWithViewPager(viewPager);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
fabAction();
}
});
if (savedInstanceState==null){
if (getSupportActionBar()!=null){
getSupportActionBar().setDisplayShowTitleEnabled(true);
}
}
}
public interface FragChangeListener{
public void doIChange(boolean change);
}
public void fabAction(){
int current = viewPager.getCurrentItem();
switch (current){
case 0:{
//NEED TO IMPLEMENT LISTENER HERE
break;
}
case 2:{
Toast.makeText(this, "IN TAB 3", Toast.LENGTH_LONG).show();
break;
}
}
}}
And My ViewPagerAdapter
public class ViewPagerAdapter extends FragmentPagerAdapter {
ArrayList<Fragment> fragments;
ArrayList<String> titles;
private Fragment mFragmentAtPos0;
private FragmentManager fragManager;
//NEED TO IMPLEMENT THE LISTENER IN THIS CLASS TELLING ME THAT THE BUTTON WAS CLICKED IN MAIN ACTIVITY
public ViewPagerAdapter(FragmentManager fm, ArrayList<Fragment> fragments, ArrayList<String>titles) {
super(fm);
this.fragments = fragments;
this.titles = titles;
fragManager = fm;
}
#Override
public Fragment getItem(int position) {
if (position == 0)
{
mFragmentAtPos0 = new AddContact();
fragManager.beginTransaction().replace(R.id.container,mFragmentAtPos0).commit();
notifyDataSetChanged();
return mFragmentAtPos0;
}else{
return fragments.get(position);
}
}
#Override
public int getCount() {
return fragments.size();
}
#Override
public CharSequence getPageTitle(int position) {
return titles.get(position);
}
#Override
public int getItemPosition(Object object)
{
if (object instanceof Tasks && mFragmentAtPos0 instanceof AddContact)
return POSITION_NONE;
return POSITION_UNCHANGED;
}
}
when the FAB is clicked, my ViewPager is alerted and performs a
certain action
I think you don't need to create listener in this case. You can detect the click FAB and pass it to the adapter directly. In your adapter, just create a method to get the action click of FAB.
In your ViewPagerAdapter, create method
public void clickFAB() {
// your code here
}
and in SwitchFragmentsListener, just call it:
ViewPagerAdapter viewPagerAdapter;
public void fabAction(){
int current = viewPager.getCurrentItem();
switch (current){
case 0:{
//NEED TO IMPLEMENT LISTENER HERE
viewPagerAdapter.clickFAB();
break;
}
case 2:{
Toast.makeText(this, "IN TAB 3", Toast.LENGTH_LONG).show();
break;
}
}
}}

unable to set the FragmentStatePagerAdapter in ViewPager

I would like to set the object of subclass of FragmentStatePagerAdapter in ViewPager by the method
viewPager.setAdapter(myPagerAdapter);
But i got error as follows
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v4.app.Fragment.setMenuVisibility(boolean)' on a null object reference
at android.support.v4.app.FragmentStatePagerAdapter.instantiateItem(FragmentStatePagerAdapter.java:120)
at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:1006)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1154)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1088)
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1614)
Please help me to fix this issue.
The code snippet is
public class MainActivity extends AppCompatActivity {
Toolbar toolbar;
TabLayout tabLayout;
ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar)findViewById(R.id.toolbar);
toolbar.setTitle("My App");
toolbar.setSubtitle("this is my test");
tabLayout = (TabLayout)findViewById(R.id.tablayout);
tabLayout.addTab(tabLayout.newTab().setText("Left"));
tabLayout.addTab(tabLayout.newTab().setText("Cent"));
tabLayout.addTab(tabLayout.newTab().setText("Right"));
viewPager = (ViewPager)findViewById(R.id.viewpage);
MyPagerAdapter myPagerAdapter = new MyPagerAdapter(
getSupportFragmentManager(),
tabLayout.getTabCount()
);
viewPager.setAdapter(myPagerAdapter);
//viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
}
}
public class MyPagerAdapter extends FragmentStatePagerAdapter {
int tabCount;
public MyPagerAdapter(FragmentManager fm, int tabCount) {
super(fm);
this.tabCount = tabCount;
}
#Override
public Fragment getItem(int position) {
switch (position){
case 1:
Fragment1 fragment1 = new Fragment1();
return fragment1;
case 2:
Fragment2 fragment2 = new Fragment2();
return fragment2;
case 3:
Fragment3 fragment3 = new Fragment3();
return fragment3;
default:
return null;
}
}
#Override
public int getCount() {
return tabCount;
}
}
While you should probably be using tabLayout.setupWithViewPager(viewPager);
Here's the problem
switch (position){
// case 1, 2, 3...
default:
return null; // Here
Did you forget that lists start indexing at position 0? You've returned a null Fragment
Try the following.
MyPagerAdapter.java
public class MyPagerAdapter extends FragmentStatePagerAdapter {
private Context mContext;
private List<Fragment> mFragments = new ArrayList<>();
public FragmentPagerAdapter(Context context, FragmentManager fm) {
super(fm);
this.mContext = context;
}
public void addFragment(Fragment fragment) {
mFragments.add(fragment);
}
#Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
#Override
public int getCount() {
return mFragments.size();
}
}
In your MainActivity,
private void setUpViewPager(ViewPager viewPager) {
adapterViewPager = new MyPagerAdapter(getApplicationContext(), getSupportFragmentManager());
adapterViewPager.addFragment(new AFragment());
viewPager.setAdapter(adapterViewPager);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}
private void setUpTabLayout(TabLayout tabLayout) {
tabLayout.setupWithViewPager(viewPager);
for (int i = 0; i < tabLayout.getTabCount(); i++) {
TabLayout.Tab tab = tabLayout.getTabAt(i);
//set your tab text, image etc here.
}
tabLayout.requestFocus();
}
Then in your onCreate(), just use the methods accordingly. setUpViewPager() follow by setUpTabLayout()

How to prevent Fragment from loading data every time from server when swiping Tabs in TabLayout in android?

I am a newbie with Fragments. I have 5 different Fragmentsin my TabLayout. In each fragment I am loading data from the server.
My problem is as follows:
When the first fragment loads it calls the function and loads data from the server and displays on the RecyclerView.
Then When I swipe to the second tab the server data loads and so on. But when I swipe again to say fragment one the data is loading again from the server and the RecyclerView needs to be set again.
Is there anyway where I can load the server data only once (without saving it to a local database) and set the recyclerview only once so that no matter how many times I swipe the tab the data does not load again? I have referred here but i really didnt understand how to solve my problem.I am posting a snippet of my code.
TabActivity
public class TabActivity extends AppCompatActivity {
ViewPager viewpager;
Toolbar toolbar;
TabLayout tablayout;
ViewPagerAdapter viewPagerAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tab_activity);
initialize();
}
private void initialize() {
viewpager = (ViewPager) findViewById(R.id.viewpager);
toolbar = (Toolbar) findViewById(R.id.toolbar);
tablayout = (TabLayout) findViewById(R.id.tablayout);
setSupportActionBar(toolbar);
viewPagerAdapter=new ViewPagerAdapter(getSupportFragmentManager());
viewpager.setAdapter(viewPagerAdapter);
tablayout.setTabsFromPagerAdapter(viewPagerAdapter);
tablayout.setupWithViewPager(viewpager);
}
}
class ViewPagerAdapter extends FragmentStatePagerAdapter implements ViewPager.OnPageChangeListener {
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:return LocatedEvents.newInstance();
case 1:return QrCodeScanner.newInstance();
case 2:return NewsFeed.newInstance();
case 3:return CreatePoll.newInstance();
case 4:return MyProfile.newInstance();
}
return NewsFeed.newInstance();
}
#Override
public int getCount() {
return 5;
}
#Override
public CharSequence getPageTitle(int position) {
return "Tab " + (position + 1);
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
}
NewsFeed Fragment
public class NewsFeed extends Fragment {
#Nullable
public static NewsFeed newInstance() {
return new NewsFeed();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.newsfeed_fragment, container, false);
load_data();
return view;
}
}
Avoid creating new Fragments every time in
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return LocatedEvents.newInstance();
case 1:
return QrCodeScanner.newInstance();
case 2:
return NewsFeed.newInstance();
case 3:
return CreatePoll.newInstance();
case 4:
return MyProfile.newInstance();
}
return NewsFeed.newInstance();
}
Make an array of fragments and pass it to your Adapter.Something like this
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dashboard);
initFragments();
}
private void initFragments() {
ArrayList < Fragment > fragmentArrayList = new ArrayList < > ();
fragmentArrayList.add(LocatedEvents.newInstance());
fragmentArrayList.add(QrCodeScanner.newInstance());
fragmentArrayList.add(NewsFeed.newInstance());
fragmentArrayList.add(MyProfile.newInstance();
viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager(), fragmentArrayList); viewpager.setAdapter(viewPagerAdapter); tablayout.setTabsFromPagerAdapter(viewPagerAdapter); tablayout.setupWithViewPager(viewpager);
}
And in your adapter change it to
private ArrayList < Fragment > fragments;
public ViewPagerAdapter(FragmentManager fm, ArrayList < Fragment > fragments) {
super(fm);
this.fragments = fragments;
}
#Override
public Fragment getItem(int position) {
return fragments.get(position);
}
#Override
public int getCount() {
return fragments.size();
}

ViewPager recreate fragments all the time

I am using ViewPager with my fragments. All fragments has animation and it does not work when switching back maybe because ViewPager saves somehow state of near Fragments, do you have some idea how to avoid it?
getItemPosition() doesn't make anything in this case
private class MyFragmentPagerAdapter extends FragmentPagerAdapter {
public MyFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public CharSequence getPageTitle(int position) {
return null;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return GetStartedOneFragment.newInstance();
case 1:
return GetStartedTwoFragment.newInstance();
case 2:
return GetStartedThreeFragment.newInstance();
case 3:
return GetStartedFourFragment.newInstance();
case 4:
return GetStartedFiveFragment.newInstance();
case 5:
return GetStartedSixFragment.newInstance();
default:
return GetStartedOneFragment.newInstance();
}
}
#Override
public int getCount() {
return PAGE_COUNT;
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
}
I used a Fragment as a slider content, see the sample code below. Feel free to ask more details if required.
I have 4 flight modes in the example. The ViewPager is used with the associated adapter (ScreenSlidePagerAdapter).
You can see the app in the Play Store to see the slider (search "Flight Recorder 24").
// In the main fragment java code
private View headerView;
private ViewPager mPager;
public ScreenSlidePagerAdapter mPagerAdapter;
// ...
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
super.onCreateView(inflater, container, savedInstanceState);
View mainView = inflater.inflate(R.layout.monitoring_fragment,container, false);
// The header of the list
View view = inflater.inflate(R.layout.header_monitoring_fragment, mListView, false);
headerView = view;
//...
mPager = (ViewPager) view.findViewById(R.id.pager);
FragmentManager fm = getChildFragmentManager();
mPagerAdapter = new ScreenSlidePagerAdapter(fm);
mPager.setAdapter(mPagerAdapter);
mPager.setCurrentItem(UserConfiguration.getUserConf().getPositionFromFlightMode());
// Attach the page change listener inside the activity
mPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener()
{
// This method will be invoked when a new page becomes selected.
#Override
public void onPageSelected(int position)
{
int flight_mode = UserConfiguration.getFlightModeFromPosition(position);
UserConfiguration.getUserConf().setFlightMode(flight_mode);
}
// This method will be invoked when the current page is scrolled
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
{
// Code goes here
}
// Called when the scroll state changes:
// SCROLL_STATE_IDLE, SCROLL_STATE_DRAGGING, SCROLL_STATE_SETTLING
#Override
public void onPageScrollStateChanged(int state)
{
// Code goes here
}
});
// ...
}
// ...
// Slider adapter
private class ScreenSlidePagerAdapter extends FragmentPagerAdapter
{
public ScreenSlidePagerAdapter(FragmentManager fm)
{
super(fm);
}
#Override
public Fragment getItem(int position)
{
// position to flight mode
int flight_mode = UserConfiguration.getFlightModeFromPosition(position);
FlightModeFragment flightModeFragment = FlightModeFragment.newInstance(flight_mode);
return flightModeFragment;
}
public int getItemPosition(Object object)
{
return POSITION_NONE;
}
#Override
public int getCount()
{
return 4;
}
}
Then you have to create a Fragment with your slider content (here the class FlightModeFragment), it will be instanciated with an integer to identify the page embedded into a Bundle savedInstanceState (I have 4 pages).
public class FlightModeFragment extends Fragment
{
LinearLayout mainLayout;
ImageView live15minImageView;
ImageView modeImageView;
ImageView imageViewLeft;
ImageView imageViewRight;
private TextView textViewRecord;
private TextView textViewGps;
int flight_mode = UserConfiguration.AC_LISTENER_TRAVEL_RECORDER_MODE;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// handle fragment arguments
Bundle arguments = getArguments();
if(arguments != null)
{
flight_mode = arguments.getInt("flight_mode");
}
}
// ...
}

Categories

Resources