Tab Layout Select method does not call onTabSelected in android - android

My application is using Tab Layout . I am creating four tabs in MainActivity(This is the activity which gets launched when i open the Application).
Each tab is associated with a fragment using viewpager . Please refer the below code:
TabLayout tabLayout;
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
pagerAdapter = new MainFragmentPagerAdapter(this, getSupportFragmentManager());
viewPager.setAdapter(pagerAdapter);
// Give the TabLayout the ViewPager
tabLayout = (TabLayout) findViewById(R.id.sliding_tabs);
tabLayout.setupWithViewPager(viewPager);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(viewPager) {
#Override
public void onTabSelected(TabLayout.Tab tab) {
super.onTabSelected(tab);
}});
This is what i am doing in the onCreate method of the MainActivity.
By default the application shows the first tab as the selected tab . But i want to show the 2ndTab as the selected tab every time application is launched fresh.
So for this i am using following code in the onResume method of MainActivity:
tabLayout.getTabAt(1).select(); //position 1 - means second tab , 0 means tab 1
This api selects the 2nd tab properly.
But Problem 1:-
it does not call the onTabSelected method which i have overridden.
Problem 2: Right After calling tab.select, when i try to get the fragment associated with the 2nd tab, it returns null.
#Override
public void onResume() {
tabLayout.getTabAt(1).select();
Fragment page = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.viewpager + ":" + 1); // position 1 is for 2nd tab.
}
here page is coming as NULL. But if i try to get the page after 2 seconds (using Android Handler postDelayed ). It gives me the proper page value .This is how i get it using handler:
#Override
public void onResume() {
tabLayout.getTabAt(1).select();
handler.postDelayed(getFragment, 2000);
}
private Runnable getFragment = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
Fragment page = null;
page = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.viewpager + ":" + 1); // position 1 is for 2nd tab
}
};
Now the page value will come proper from the run method.
So how do i resolve problem 1 and is the using handler solution good for second problem.

Hey please check the code below:
TabLayout tabLayout;
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
pagerAdapter = new MainFragmentPagerAdapter(this,getSupportFragmentManager());
viewPager.setAdapter(pagerAdapter);
// Give the TabLayout the ViewPager
tabLayout = (TabLayout) findViewById(R.id.sliding_tabs);
tabLayout.setupWithViewPager(viewPager);
viewPager.setCurrentItem(1);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setOnTabSelectedListener(new
TabLayout.ViewPagerOnTabSelectedListener(viewPager) {
#Override
public void onTabSelected(TabLayout.Tab tab) {
super.onTabSelected(tab);
}});

Related

SlidingTabLayout and ViewPager: how to load the current fragment and not the adjacent one at the same time?

I am trying to implement a sliding tab layout that and each fragment should only load when the tab is selected instead i get the adjacent fragment loading, I have tried setOffScreenPageLimit(1) as my code shows but still the adjacent fragment gets loaded any assistance please ???
private SlidingTabLayout tabLayout;
private ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
viewPager = (ViewPager) findViewById(R.id.viewpager);
viewPager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
viewPager.setOffscreenPageLimit(1);
tabLayout = (SlidingTabLayout) findViewById(R.id.tabs);
if (tabLayout != null) {
tabLayout.setViewPager(viewPager);
tabLayout.setDistributeEvenly(true);
tabLayout.setSelectedIndicatorColors(R.color.md_amber_600);
}
I can see you have used setOffScreenPageLimit as 1. It means you are loading only 1 extra screen at a time using viewPager, when actually you want to load nothing. It is not possible to set 0 value for setOffScreenPageLimit this method, actually you can set it but it will not work.
So, it is not possible to achieve this using view pager. If you still want to perform such a functionality, you can use FrameLayout and switch between the fragments based on tab selection.
Below is the tab selection code sample:
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
switchToTab(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});

Change tab index of fragments with tabs programmatically

I'm getting a null pointer exception when trying to switch tabs programmatically of a tablayout inside a fragment,
So I have my main activity that has a tab layout (4 tabs) each tab has a view pager holding a fragment, and each of these fragments has a tab layout (x amount of tabs) with a view pager holding a fragment,
i can switch the tabs of my main activity tab layout from any fragment like this
TabLayout tabLayout = MainActivity.tabLayout;
TabLayout.Tab tab = tabLayout.getTabAt(2);
tab.select();
but if i try to change the tabs of one of the fragments in the same way i get a null pointer
TabLayout tabLayout2 = tabFragOne.tabLayout;
TabLayout.Tab tab2 = tabLayout2.getTabAt(2);
tab2.select();
it only happens if I click the button in question when the app first opens, which suggests that the reason for it is that the fragment hasn't been attached or created yet,
for instance if i scroll across to the fragments tab i want to switch to, and then go back to the main activity and press the button in question it will work.
does anyone know the best way to fix this?
Ok ive found half the crux to this question is actually that im using a view pager adapter, a question here sheds a lot of light on my issue
The correct way to set selected Tab, we should set selected index from Pager instead.
final ViewPager pager = (ViewPager) findViewById(R.id.pager);
final TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(pager);
pager.setCurrentItem(0);//selected position
Here is my layout design in xml
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="#ffffff"
android:background="#color/al_white"
android:elevation="0dp" />
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ffffff"
app:tabTextColor="#494a43"
app:tabSelectedTextColor="#494a43"
app:tabIndicatorColor="#494a43"
app:tabIndicatorHeight="2dp"
app:tabMode="fixed"
app:tabGravity="fill" />
</android.support.design.widget.AppBarLayout>
TabLayout tabhost = (TabLayout) getActivity().findViewById(R.id.tabLayout);
tabhost.getTabAt(2).select();
I use this inside my fragment's create function... and it works perfectly
R.id.tabLayout is the tablayout id in your main activity layout.
you can use the setCurrentItem(Postion) in viewpager
example :
tabLayout.setOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
// tabLayout.setupWithViewPager(mViewPager);
mViewPager.setCurrentItem(4);
Simple example to automatically scroll from the last page to the first. Note: I added a dummy fragment at the first and last position.
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
if (position == 0) {
viewPager.setCurrentItem(viewPagerAdapter.getCount() - 2);
} else if (position == viewPagerAdapter.getCount() - 1) {
viewPager.setCurrentItem(1);
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
Using view pager, Its working simple and fine
public class ViewPagerAdapter extends FragmentStatePagerAdapter {
CharSequence Titles[]; // This will Store the Titles of the Tabs which are Going to be passed when ViewPagerAdapter is created
int NumbOfTabs;
String mode;
AllDeals deals;
MyDeals myDeals; those are my fragments
public ViewPagerAdapter(FragmentManager fm, int mNumbOfTabsumb, String moe) {
super(fm);
this.NumbOfTabs = mNumbOfTabsumb;
mode=moe;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
if(mode.equals("Deals")){
deals=new AllDeals();
return deals;
}
break;
case 1:
if(mode.equals("Deals")){
myDeals=new MyDeals();
return myDeals;
}
break;
default:
break;
}
return null;
}
#Override
public int getCount() {
return NumbOfTabs;
}
}
add this lines into ur activity
containerViewone.setVisibility(View.VISIBLE);
tabLayout.addTab(tabLayout.newTab().setText(getResources().getString(R.string.title_all_deals)));
tabLayout.addTab(tabLayout.newTab().setText(getResources().getString(R.string.title_my_deals)));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
tabLayout.setTabTextColors(getResources().getColor(R.color.tabunselect), getResources().getColor(R.color.black));
viewpagerad = new ViewPagerAdapter(getSupportFragmentManager(), Numboftabs, "Deals");
pager.setAdapter(viewpagerad);
pager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
Try this:
TabLayout tablayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); //your activity layout
tabLayout =(TabLayout)findViewById(R.id.tablayout); //your tab layout id
tabLayout.getTabAt(0).select(); //your tab index;
}
In Kotlin:
With TabLayout and ViewPager2 that works for me:
binding.tablayout.getTabAt(1)!!.select()

How to move to a specific tab from an activity in android

I am working on the following screen named FriendListActivity:
As you can see here , I am 3 tabs named CHAT,GROUPS and CONTACTS .Each tab is displaying some contents.For example Groups Tab is displaying the number of groups.On clicking each Group ,Group Chat Screen is opened .Now In Group Chat screen ,i have a toolbar .Consider the following code:
Toolbar toolbarGroupChat = (Toolbar) findViewById(R.id.toolbarGroupChat);
setSupportActionBar(toolbarGroupChat);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle(upperCase(group_name));
//ViewPager
viewPager = (ViewPager) findViewById(R.id.viewPager);
//Initializing PagerAdapter
PagerAdapter pagerAdapter = new PagerAdapter(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(pagerAdapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
PagerAdapter.java
public class PagerAdapter extends FragmentStatePagerAdapter {
private int noOfTabs;
public PagerAdapter(FragmentManager fm, int noOfTabs) {
super(fm);
this.noOfTabs = noOfTabs;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
ChatFragment chatFragment = new ChatFragment();
return chatFragment;
case 1:
GroupsFragment groupsFragment = new GroupsFragment();
return groupsFragment;
case 2:
ContactsFragment contactsFragment = new ContactsFragment();
return contactsFragment;
default:
return null;
}
}
#Override
public int getCount() {
return noOfTabs;
}
}
On clicking the arrow on the toolbar ,my application is moved to the screen containing three tabs.My problem is current selected tab is always CHAT tab ,when i am moving from an activity to FriendListActivity .When i am moving from Group Chat Screen to FriendListActivity,the current selected tab should be GROUPS Tab.
Solved.
Edited Working Code:
When we are moving from an Activity to a specific tab ,We need to pass the TAb number using intents from the Activity.Use the following code for handling click on the back button of the Toolbar .Override the getSupportParentActivityIntent() method:
public Intent getSupportParentActivityIntent() {
final Bundle bundle = new Bundle();
final Intent intent = new Intent(this, FriendsListActivity.class);
bundle.putString("TabNumber", tab_number);
intent.putExtras(bundle);
return intent;
}
Now inside the activity containing 3 tabs,use the following code:
final Intent intent = getIntent();
if (intent.hasExtra("TabNumber")) {
String tab = intent.getExtras().getString("TabNumber");
Log.e("TabNumberFriendList",tab);
switchToTab(tab);
}
public void switchToTab(String tab){
if(tab.equals("0")){
viewPager.setCurrentItem(0);
}else if(tab.equals("1")){
viewPager.setCurrentItem(1);
}else if(tab.equals("2")){
viewPager.setCurrentItem(2);
}
}
Use the setCurrentItem(int position) method of your ViewPager object to move to a specific tab.
You might have created a tabHost, so when it is done making, you should use -
tabHost.setCurrentTab(1);
and you can use same code with different parameters whenever you want to set another tab.
Ref
From the screenshot you must be using Tablayout, so from there you can use these two in build functions.
tabLayout.getSelectedTabPosition();
Save this tab in some variable and then onCreate set that integer value in this function..
tabLayout.getTabAt(<Your last selected tab>);
Hope this helps..:)
You can also use this piece of code:
Add public static TabToOpen = 1 in the group chat activity(say group_chat_activity).
then use setCurrentTab(group_chat_activity.TabToOpen) in onResume() of activity where your ViewPager object is to move to a specific tab. This is particularly useful when you need a button to access a particular tab in sliding activity.

Android: Updating tab content

I am new to Android development. I have a ViewPager which holds TabLayout (that has fixed number of tabs). The ViewPager has SectionPagerAdapter (that has a fragment corresponding to tabs).
Now, I want to update tab content when user selects the tab and as it becomes visible (or when user wants to refresh the content).
But I am not sure which is correct way I can do this.
So far till now I found two solutions:
1) Add listener to TabLayout:
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener()
{
#Override
public void onTabSelected(TabLayout.Tab tab)
{
mViewPager.setCurrentItem(tab.getPosition());
// Update tab containts here
}
#Override
public void onTabUnselected(TabLayout.Tab tab)
{
}
#Override
public void onTabReselected(TabLayout.Tab tab)
{
}
});
2) Use ViewPager.OnPageChangeListener to get callbacks for when a page fragment (inside Tab) becomes visible:
viewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener()
{
#Override
public void onPageSelected(int position)
{
// Update tab containts here
}
});
Can someone expert in this please advice me?
The way a viewpager adapter works (with tabs) is that once you add your fragments to the viewpager, then you basically need to add content to your fragments and let the adapter manage which fragment is visible when a given tab is selected.
So, by simply using : OnTabSelectedListenerinterface on your tabLayout, all you need to do is `setCurrentItem(tab.getPosition()); on your viewPager reference (from your layout).
You can have a method like this to add fragments to your viewPagerAdapter:
private void setupViewPager(ViewPager viewPager){
//then create an instance of your ViewPagerAdapter class here
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
//then add fragments for each TAB here
//by calling a method inside your Adapter like this
adapter.addFrag(new FragmentOne(), "TITLE HERE");
adapter.addFrag(new FragmentTwo(), "TITLE TWO");
//Now set your adapter here
viewPager.setAdapter(adapter);
}
Now in your fragments, you can show different content accordingly.
I hope this helps!

How to change ViewPager's page?

I'm using ViewPager in my app and define it in the main Activity. Inside onCreate method I load some number of pages from SharedPreferences and then pass it to PagerAdapter:
#Override
public int getCount() {
return numberOfPages;
}
The problem is that if I would change this number in Preferences (or another Activity) to some other less then page index I viewed before, my app crashes because this index is out of bounds when I return to the activity with this ViewPager. It can be fixed simply by changing active ViewPager's page. Is there any way to do it?
I'm not sure that I fully understand the question, but from the title of your question, I'm guessing that what you're looking for is pager.setCurrentItem( num ). That allows you to programatically switch to another page within the ViewPager.
I'd need to see a stack trace from logcat to be more specific if this is not the problem.
slide to right
viewPager.arrowScroll(View.FOCUS_RIGHT);
slide to left
viewPager.arrowScroll(View.FOCUS_LEFT);
Without checking your code, I think what you are describing is that your pages are out of sync and you have stale data.
You say you are changing the number of pages, then crashing because you are accessing the old set of pages. This sounds to me like you are not calling pageAdapter.notifyDataSetChanged() after changing your data.
When your viewPager is showing page 3 of a set of 10 pages, and you change to a set with only 5, then call notifyDataSetChanged(), what you'll find is you are now viewing page 3 of the new set. If you were previously viewing page 8 of the old set, after putting in the new set and calling notifyDataSetChanged() you will find you are now viewing the last page of the new set without crashing.
If you simply change your current page, you may just be masking the problem.
for switch to another page, try with this code:
viewPager.postDelayed(new Runnable()
{
#Override
public void run()
{
viewPager.setCurrentItem(num, true);
}
}, 100);
Supplemental answer
I was originally having trouble getting a reference to the ViewPager from other class methods because the addOnTabSelectedListener made an anonymous inner class, which in turn required the ViewPager variable to be declared final. The solution was to use a class member variable and not use the anonymous inner class.
public class MainActivity extends AppCompatActivity {
TabLayout tabLayout;
ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
tabLayout = (TabLayout) findViewById(R.id.tab_layout);
tabLayout.addTab(tabLayout.newTab().setText("Tab 1"));
tabLayout.addTab(tabLayout.newTab().setText("Tab 2"));
tabLayout.addTab(tabLayout.newTab().setText("Tab 3"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
viewPager = (ViewPager) findViewById(R.id.pager);
final PagerAdapter adapter = new PagerAdapter(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
// don't use an anonymous inner class here
tabLayout.addOnTabSelectedListener(tabListener);
}
TabLayout.OnTabSelectedListener tabListener = new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
};
// The view pager can now be accessed here, too.
public void someMethod() {
viewPager.setCurrentItem(0);
}
}

Categories

Resources