viewpager setCurrentItem not changing tablayout selected color - android

i am using viewpager and tab layout
viewPager.setAdapter(Adapter);
tablayout.setupWithViewPager(viewPager);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
int cPage;
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
cPage = position;
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
now when i swipe selected tab color is changing but when i call
viewPager.setCurrentItem(1, true);
its not changing new tab layout color . say
i have 2 tabs when i am 1st it setting text color green for 1st tab and when i swipe it giving 2nd tab color green .. but when i call
viewPager.setCurrentItem(1, true);
in this my 1st tab is green not 2nd tab

https://stackoverflow.com/a/35843370/4302046
// mViewPager.setCurrentItem(position);
mTabLayout.getTabAt(position).select();

Try this worked for me...
tabLayout.setScrollPosition(position,0f,true);

In your activity:
// init TabLayout
TabLayout tabLayout = (TabLayout) view.findViewById(R.id.tab_layout);
if (mCallFrom.equalsIgnoreCase(ActivityConstantUtils.sCalledFromActPanel)) {
// To add Memory
tabLayout.addTab(tabLayout.newTab().setText(R.string.add_memory_caption));
tabLayout.addTab(tabLayout.newTab().setText(R.string.add_memory_effects));
// tabLayout.addTab(tabLayout.newTab().setText(R.string.add_memory_frames));
} else {
// To add Memory from Recipe & Blog
tabLayout.addTab(tabLayout.newTab().setText(R.string.add_memory_caption));
tabLayout.setSelectedTabIndicatorColor(Color.TRANSPARENT);
}
changeTabsFont(tabLayout);
showDivider(tabLayout);
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
final ViewPager viewPager = (ViewPager) getActivity().findViewById(R.id.pager);
final PagerAdapter adapter = new PagerAdapter(this.getFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
if (tab.getPosition() == 1) {
Utils.hideSoftKeyboard(view, getActivity());
}
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
//Style apply to tablayout
<style name="ActPanelTabLayout.Theme" parent="Widget.Design.TabLayout">
<item name="tabIndicatorColor">#color/memory_color_80</item>\
<item name="android:textColor">#color/act_tab_black</item>
<item name="tabSelectedTextColor">#color/act_tab_selector_text_color</item>
<item name="tabTextAppearance">#style/TextAppearance.Jacksonville.ActTab</item>
</style>

Faced unique problem. When we set setCurrentItem. It does not change tablayout's tab. Then you have to addOnPageChangeListener on viewpager in which you have to select the tablayout's tab manually for selected viewpager's position. Then setupWithViewPager.
Note : setupWithViewPager needs to be set only after addOnPageChangeListener added. God knows why. This is what worked. if I setupWithViewPager before, it does not work. Again, almighty only knows.
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
viewPager.setCurrentItem(position,false);
tabLayout.getTabAt(position).select();
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
/*
NOTE: This is setup after addOnPageChangeListener. Don't know why but this is what works. Otherwise tabLayout.does not select.
*/
tabLayout.setupWithViewPager(this.viewPager);

Had the same issue, with tab in TabLayout not being selected after we have swiped the ViewPager, i.e. when we were swiping the ViewPager the tab stood the same.
Solution (Kotlin):
viewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
override fun onPageSelected(position: Int) {
viewPager.setCurrentItem(position, false)
tabLayout.getTabAt(position)?.select()
}
override fun onPageScrollStateChanged(state: Int) {}
})

viewPager.setCurrentItem(1, true);
has to be run on UI Thread

This is known bug in Design support library even in version 24.1.1 it exists, i was able to find a work around for this issue by using a co-ordinator layout as the parent(root) layout

Related

Issue with tablayout, on switching to the second tab it will jump back to the first tab

I am trying to create a tab layout for my program.
There are two tabs. If I try to switch to Tab2 instead of staying on Tab2, it changes back to Tab1. I have 0 clue what is causing this problem.
Here is my code
MainActivity:
tabLayout = findViewById(R.id.tablayout);
viewPager2 = findViewById(R.id.viewpager);
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentAdapter = new CustomAdapter(fragmentManager, getLifecycle());
viewPager2.setAdapter(fragmentAdapter);
tabLayout.addTab(tabLayout.newTab().setText("Tab1"));
tabLayout.addTab(tabLayout.newTab().setText("Tab2"));
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager2.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
#Override
public void onPageScrollStateChanged(int state) {
tabLayout.selectTab(tabLayout.getTabAt(state));
}
});
CustomAdapter:
public class CustomAdapter extends FragmentStateAdapter {
public CustomAdapter(#NonNull FragmentManager fragmentManager, #NonNull Lifecycle lifecycle) {
super(fragmentManager, lifecycle);
}
#NonNull
#Override
public Fragment createFragment(int position) {
if(position == 1) return new BlankFragment1();
return new BlankFragment2();
}
#Override
public int getItemCount() {
return 2;
}
Following the official docs here you can use a TabLayoutMediator to link the tab layout and pager instead of doing it with your own listeners.
However, the root of the problem you observed is that state in onPageScrollStateChanged is not the position that it scrolled to - it is an integer representing the scroll state. Since SCROLL_STATE_IDLE is 0, and SCROLL_STATE_DRAGGING is 1, as soon as you stopped dragging it would snap back to tab 0.
Using TabLayoutMediator (recommended)
To use the TabLayoutMediator replace your addOnTabSelectedListener, registerOnPageChangeCallback, and manually setting the tabs (addTab) with this, which links the tabs to the view pager and provides a method to set the tab titles
// remove the "addTab" calls, "addOnTabSelectedListener",
// and "registerOnPageChangeCallback"
new TabLayoutMediator(tabLayout, viewPager2,
(tab, position) -> tab.setText("Tab" + (position + 1))
).attach();
Using your own listeners
It is still possible to use your own listeners, but you have to change the view pager listener to use onPageSelected instead of onPageScrollStateChanged, like this:
viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
#Override
public void onPageSelected(int position) {
tabLayout.selectTab(tabLayout.getTabAt(position));
}
});
Note: The positions are 0-based, so you are showing "BlankFragment2" in position 0 and "BlankFragment1" in position 1 (not sure if that is what you intended).

How use TabItem through TabLayout in Android

Recently google added android.support.design.widget.TabItem in supportDesign as documentation said:
TabItem is a special 'view' which allows you to declare tab items for
a TabLayout within a layout. This view is not actually added to
TabLayout, it is just a dummy which allows setting of a tab items's
text, icon and custom layout.
But when I add TabItems to my TabLayout:
<android.support.design.widget.TabLayout
android:layout_height="wrap_content"
android:layout_width="match_parent">
<android.support.design.widget.TabItem
android:text="#string/tab_text"/>
<android.support.design.widget.TabItem
android:icon="#drawable/ic_android"/>
</android.support.design.widget.TabLayout>
Nothing displayed (in fact place of Tabs exist but Icon/Text not). Does any one knows How to use TabItem through xml?
Based on this answer, TabItem with tabLayout.setupViewPager have conflict and Icons disappear. To make it work you should implement two methods like following and avoid using setupViewPager method:
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
pager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
tabLayout.getTabAt(position).select();
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
you should set these attributes for the TabItems
android:layout_width
android:layout_height
Cheers

Set selected tab indicator in Java code

I have a NavigationView that I want to setup to work along with a ViewPager and a TabLayout.
A click on an item from the NavigationView shall :
Take the user to the corresponding fragment
Set the TabLayout indicator accordingly
I managed to accomplish the first task using mViewPager.setCurrentItem() but I am unable to fix the second one. I tried :
To retrieve the tab via the TabLayout and "select" it :
mTabLayout.getTabAt(TAB_POSITION).select();
but it was a bust. (Tab indicator)
to call mTabLayout.setupWithViewPager(mViewPager); after each click on an item but same result. (TabLayout tab selection).
EDIT - code :
mViewPager = (ViewPager) findViewById(R.id.viewpager);
mViewPager.setAdapter(mAdapter);
mTabLayout = (TabLayout) findViewById(R.id.tablayout);
mTabLayout.setupWithViewPager(mViewPager);
mViewPager.addOnPageChangeListener(new PageChangeListener());
.....
.....
class PageChangeListener implements ViewPager.OnPageChangeListener {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
switch (position) {
case 0:
mTabLayout.getTabAt(0).select();
break;
case 1:
mFloatingAddButton.setVisibility(View.VISIBLE);
mTabLayout.getTabAt(1).select();
break;
default:
mFloatingAddButton.setVisibility(View.INVISIBLE);
mTabLayout.getTabAt(2).select();
break;
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
}
How can I manage to tie everything together ?
In the method setupWithViewPager of class TabLayout, we can see that a callback is set on the view pager :
viewPager.addOnPageChangeListener(new TabLayoutOnPageChangeListener(this));
In the class TabLayoutOnPageChangeListener, here is the method onPageSelected :
public void onPageSelected(int position) {
final TabLayout tabLayout = mTabLayoutRef.get();
if (tabLayout != null && tabLayout.getSelectedTabPosition() != position) {
// Select the tab, only updating the indicator if we're not being dragged/settled
// (since onPageScrolled will handle that).
tabLayout.selectTab(tabLayout.getTabAt(position),
mScrollState == ViewPager.SCROLL_STATE_IDLE);
}
}
So here we can see that the tablayout should select the good tab when the viewpager changes its content.
Did you call setupWithViewPager right after setting the adapter of your ViewPager ?

TabLayout update tab content with a custom view

I'm using TabLayout of the new material design and i have a problem, i can't update tab content of a custom view once the tab is created:
I can simplify my method inside my PagerAdapter with
public View setTabView(int position, boolean selected) {
View v = LayoutInflater.from(context).inflate(R.layout.default_tab_view, null);
tv = (TextView) v.findViewById(R.id.tabTextView);
if(selected)
tv.setText("SELECTED");
else
tv.setText("UNSELECTED");
return v;
}
And in activity i can simplify my code with:
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
ViewPager pager = (ViewPager) findViewById(R.id.viewpager);
PagerAdapter adapter = new PagerAdapter(getSupportFragmentManager());
pager.setAdapter(adapter);
tabLayout.setupWithViewPager(pager);
for (int i = 0; i < tabLayout.getTabCount(); i++) {
boolean isFirstTab = i == 0;
TabLayout.Tab tab = tabLayout.getTabAt(i);
View v;
v = adapter.setTabView(i, isFirstTab);
v.setSelected(isFirstTab);
tab.setCustomView(v);
}
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
adapter.setTabView(tab.getPosition(), true);
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
adapter.setTabView(tab.getPosition(), false);
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
The tabs' titles are set right when the app starts but when i change tab, the content still remains the same.
Ok I think it's bug on android design support library v22.
Because You are talking about the changes in content but I can't change the color of Text. Once the tab are created and if you change the layout it will not reflecting.
And As i have seen your code you are giving the custom layout using setCustomView. and for changing a text you are calling again the method setTabView(). Instead of that there should be method getCustomView() so that you can change the layout. There is a method in a TabLayout.Tab.getCustomView but it doesn't have identifier and I have report this bug.
https://code.google.com/p/android/issues/detail?id=177492
[Update 08-07-2015]
Finally bug is accepted by android bug source traking and marked as Future Release . So we can say that bug will no more exist on future library.
and we can have method getCustomView() so that we can easily get our custom view.
[Update 18-08-2015]
Finally the bug is resolved Released in the v23 support libs .
Just update support library using SDK manager and you have getCustomView() as a public.
just change this line in gradle
compile 'com.android.support:design:23.0.0'
and make sure compile and target sdk set to 23.
please check my code working fine for me
TabLayout.Tab tab=tabLayout.getTabAt(position);
View view=tab.getCustomView();
TextView txtCount= (TextView)
view.findViewById(R.id.txtCount);
txtCount.setText(count+"");
Well ok, I might have found a very tricky solution just because I didn't have any time to wait for next support-library version. Here's what I did:
Set pager adapter to your TabLayout tabLayout.setTabsFromPagerAdapter(pagerAdapter);
Add listener to your ViewPager
customViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
tabLayout.getTabAt(position).select();
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
Add listener to your TabLayout
tabLayout.setOnTabSelectedListener(new
TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
if (!isTabUpdating) {
isTabUpdating = true;
final int pos = tab.getPosition();
customViewPager.setCurrentItem(pos);
// Clears and populates all tabs
tabLayout.setTabsFromPagerAdapter(pagerAdapter);
invalidateTabs(pos);
}
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
if (!isTabUpdating) {
isTabUpdating = true;
final int pos = tab.getPosition();
customViewPager.setCurrentItem(pos);
// Clears and populates all tabs
tabLayout.setTabsFromPagerAdapter(pagerAdapter);
invalidateTabs(pos);
}
}
});
Add method for re-drawing all tabs
private void invalidateTabs(int selected) {
for (int i = 0; i < tabLayout.getTabCount(); i++) {
tabLayout.getTabAt(i).setCustomView(pagerAdapter.getTabView(i, i == selected));
}
isTabUpdating = false;
}
Ok, so let me explain know a little bit. First of all, you might wonder why did I used setTabsFromPagerAdapter() instead of setupWithViewPager. In the beginning I used setupWithViewPager but somehow my it didn't work correctly with my pager and the 1st item wasn't been able to be selected.
The second thing you might admit - every time I'm selecting a tab I'm deleting all of them. Well, that was kind of easy problem, you see I android sources when you call Tab.setCustomView(View) it checks the parent of the view and if it's not null - it removes all childviews. However if you pass newly-instantiated item you'll ADD another view instead of replacing the old one:
View custom = tab.getCustomView();
if(custom != null) {
ViewParent icon = custom.getParent();
if(icon != this) {
if(icon != null) {
// You wont get here
((ViewGroup)icon).removeView(custom);
}
this.addView(custom);
}
...
So, I ended up with setting all listeners by myself and re-creating all tabs every time on page/tab changes. That's NOT good solution, but as far as can't wait for Google to update their lib - this's probably the only solution to achieve such effect. (Just in case you're wondering why is this so complicated - I needed to have Tabs with custom views (text + image) which could change their view-properties (font color, image) when they're selected/unselected)
BTW - Here's the getTabView(...) method from 4th step:
public View getTabView(int pos, boolean isSeleted) {
View tabview = ((LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout
.tab_sessioninfo,
null, false);
final ImageView ivTabIcon = (ImageView) tabview.findViewById(R.id.iv_tab_icon);
final TextView tvTabTittle = (TextView) tabview.findViewById(R.id.tv_tab_title);
if (isSeleted) {
tvTabTittle.setTextColor(context.getResources().getColor(R.color.tab_indicator));
}
switch (pos) {
case 0:
tvTabTittle.setText("1st Tab");
ivTabIcon.setImageResource(isSeleted ? R.drawable.ic_icon1_selected : R.drawable.ic_icon1);
break;
case 1:
tvTabTittle.setText("2nd Tab");
ivTabIcon.setImageResource(isSeleted ? R.drawable.ic_icon2_selected : R.drawable.ic_icon2);
break;
case 2:
tvTabTittle.setText("3rd Tab");
ivTabIcon.setImageResource(isSeleted ? R.drawable.ic_icon3_selected : R.drawable.ic_icon3);
break;
}
return tabview;
}
P.S. If you know better solution for all this stuff let me know!
UPDATE
Better solution could be approached by using Reflection:
Easy setup
tabLayout.setupWithViewPager(customViewPager);
customViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
for (int i = 0; i <tabLayout.getTabCount(); i++){
updateTab(tabLayout.getTabAt(i), position == i);
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
Update Tab
private void updateTab(TabLayout.Tab tab, boolean isSelected){
Method method = null;
try {
method = TabLayout.Tab.class.getDeclaredMethod("getCustomView", null);
method.setAccessible(true);
View tabview = (View) method.invoke(tab, null);
final ImageView ivTabIcon = (ImageView) tabview.findViewById(R.id.iv_tab_icon);
final TextView tvTabTittle = (TextView) tabview.findViewById(R.id.tv_tab_title);
if (isSeleted) {
tvTabTittle.setTextColor(context.getResources().getColor(R.color.tab_indicator));
}
switch (pos) {
case 0:
tvTabTittle.setText("1st Tab");
ivTabIcon.setImageResource(isSeleted ? R.drawable.ic_icon1_selected : R.drawable.ic_icon1);
break;
case 1:
tvTabTittle.setText("2nd Tab");
ivTabIcon.setImageResource(isSeleted ? R.drawable.ic_icon2_selected : R.drawable.ic_icon2);
break;
case 2:
tvTabTittle.setText("3rd Tab");
ivTabIcon.setImageResource(isSeleted ? R.drawable.ic_icon3_selected : R.drawable.ic_icon3);
break;
}
tab.setCustomView(tabview);
} catch (Exception e) {
e.printStackTrace();
}
}
UPDATE
New support library has public method for getCustomView(), so you don't need reflection no more!
please check my code working fine for me
TabLayout.Tab tab=tabLayout.getTabAt(position);
View view=tab.getCustomView();
TextView txtCount= (TextView) view.findViewById(R.id.txtCount);
txtCount.setText(count+"");
Have a look the Answer you need to set the layout as expected by you. If you want to change the Tab Content then make changes in Tab.setOnTabSelectedListener()
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
if(tab.getPosition()==1){
tabLayout.setTabTextColors(ContextCompat.getColor(getActivity(), R.color.unselected_tab),ContextCompat.getColor(getActivity(), R.color.tab_selection));
}else{
tabLayout.setTabTextColors(ContextCompat.getColor(getActivity(), R.color.unselected_tab),ContextCompat.getColor(getActivity(), R.color.white));
}
// same thing goes with other tabs too
// Just change your tab text on selected/deselected as above
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
tab.setCustomView(null);
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
Documents are very poor on this topic. We can use setCustomView method of tabs to set custom view. Following is a working example without any need of creating custom adapters:
tab_layout.xml
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="#dimen/tab_height"
android:background="#color/primary_dark" />
custom_tab_item.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="#dimen/tab_height"
android:orientation="horizontal"
android:padding="#dimen/tab_padding">
<ImageView
android:id="#+id/tabIcon"
android:layout_width="#dimen/tab_icon"
android:layout_height="#dimen/tab_icon"
android:layout_centerVertical="true"/>
<TextView
android:id="#+id/tabTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="#+id/tabIcon"
android:textColor="#color/white" />
<TextView
android:id="#+id/tabSubTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/tabTitle"
android:layout_toEndOf="#+id/tabIcon"
android:textColor="#color/white" />
</RelativeLayout>
MainActivity.kt
TabLayoutMediator(binding.tabLayout, binding.viewPager) { tab, position ->
when (position) {
0 -> {
tab.setCustomView(R.layout.tab_item)
tab.customView?.findViewById<ImageView>(R.id.tabIcon)
?.setImageResource(R.drawable.tab1)
tab.customView?.findViewById<TextView>(R.id.tabTitle)?.setText(R.string.tab1)
}
1 -> {
tab.setCustomView(R.layout.tab_item)
tab.customView?.findViewById<ImageView>(R.id.tabIcon)
?.setImageResource(R.drawable.tab2)
tab.customView?.findViewById<TextView>(R.id.tabTitle)
?.setText(R.string.tab2)
}
}
}.attach()

TabLayout tab selection

How should I select a tab in TabLayout programmatically?
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
If you know the index of the tab you want to select, you can do it like so:
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
TabLayout.Tab tab = tabLayout.getTabAt(someIndex);
tab.select();
This technique works even if you're using the TabLayout by itself without a ViewPager (which is atypical, and probably bad practice, but I've seen it done).
This is how I solved it:
void selectPage(int pageIndex){
tabLayout.setScrollPosition(pageIndex,0f,true);
viewPager.setCurrentItem(pageIndex);
}
Use this:
tabs.getTabAt(index).select();
Keep in mind that, if currentTabIndex and index are same then this sends your flow to onTabReselected and not onTabSelected.
Use this:
<android.support.design.widget.TabLayout
android:id="#+id/patienthomescreen_tabs"
android:layout_width="match_parent"
android:layout_height="72sp"
app:tabGravity="fill"
app:tabMode="fixed"
app:tabIndicatorColor="#android:color/white"
app:tabSelectedTextColor="#color/green"/>
After in OnClickListener:
TabLayout tabLayout = (TabLayout) findViewById(R.id.patienthomescreen_tabs);
TabLayout.Tab tab = tabLayout.getTabAt(someIndex);
tab.select();
Keep in mind that, if currentTabIndex and index are same then this sends your flow to onTabReselected and not onTabSelected.
This is probably not the ultimate solution, and it requires that you use the TabLayout together with a ViewPager, but this is how I solved it:
void selectPage(int pageIndex)
{
viewPager.setCurrentItem(pageIndex);
tabLayout.setupWithViewPager(viewPager);
}
I tested how big the performance impact of using this code is by first looking at the CPU- and memory monitors in Android Studio while running the method, then comparing it to the load that was put on the CPU and memory when I navigated between the pages myself (using swipe gestures), and the difference isn't significantly big, so at least it's not a horrible solution...
Hope this helps someone!
Just set viewPager.setCurrentItem(index) and the associated TabLayout would select the respective tab.
With the TabLayout provided by the Material Components Library just use the selectTab method:
TabLayout tabLayout = findViewById(R.id.tab_layout);
tabLayout.selectTab(tabLayout.getTabAt(index));
It requires version 1.1.0.
If you can't use tab.select() and you don't want to use a ViewPager, you can still programmatically select a tab. If you're using a custom view through TabLayout.Tab setCustomView(android.view.View view) it is simpler. Here's how to do it both ways.
// if you've set a custom view
void updateTabSelection(int position) {
// get the position of the currently selected tab and set selected to false
mTabLayout.getTabAt(mTabLayout.getSelectedTabPosition()).getCustomView().setSelected(false);
// set selected to true on the desired tab
mTabLayout.getTabAt(position).getCustomView().setSelected(true);
// move the selection indicator
mTabLayout.setScrollPosition(position, 0, true);
// ... your logic to swap out your fragments
}
If you aren't using a custom view then you can do it like this
// if you are not using a custom view
void updateTabSelection(int position) {
// get a reference to the tabs container view
LinearLayout ll = (LinearLayout) mTabLayout.getChildAt(0);
// get the child view at the position of the currently selected tab and set selected to false
ll.getChildAt(mTabLayout.getSelectedTabPosition()).setSelected(false);
// get the child view at the new selected position and set selected to true
ll.getChildAt(position).setSelected(true);
// move the selection indicator
mTabLayout.setScrollPosition(position, 0, true);
// ... your logic to swap out your fragments
}
Use a StateListDrawable to toggle between selected and unselected drawables or something similar to do what you want with colors and/or drawables.
A bit late but might be a useful solution.
I am using my TabLayout directly in my Fragment and trying to select a tab quite early in the Fragment's Lifecycle.
What worked for me was to wait until the TabLayout finished drawing its child views by using android.view.View#post method. i.e:
int myPosition = 0;
myFilterTabLayout.post(() -> { filterTabLayout.getTabAt(myPosition).select(); });
You can try solving it with this:
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
TabLayout.Tab tab = tabLayout.getTabAt(pos);
if (tab != null) {
tab.select();
}
Newest simple solution worked for me:
binding.tablayout.selectTab(binding.tablayout.getTabAt(tabPosisiton))
or
with(binding.tablayout) {
selectTab(getTabAt(tabPosisiton))
}
and tabPosition start from 0
try this
new Handler().postDelayed(
new Runnable(){
#Override
public void run() {
if (i == 1){
tabLayout.getTabAt(0).select();
} else if (i == 2){
tabLayout.getTabAt(1).select();
}
}
}, 100);
Kotlin Users:
Handler(Looper.getMainLooper()).postDelayed(
{ tabLayout.getTabAt(position).select() }, 100
)
This will also scroll your tab layout in case if it needs to scroll.
you should use a viewPager to use viewPager.setCurrentItem()
viewPager.setCurrentItem(n);
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) {
}
});
A combined solution from different answers is:
new Handler().postDelayed(() -> {
myViewPager.setCurrentItem(position, true);
myTabLayout.setScrollPosition(position, 0f, true);
},
100);
I am using TabLayout to switch fragments. It works for the most part, except whenever I tried to select a tab programmatically using tab.select(), my TabLayout.OnTabSelectedListener would trigger the onTabSelected(TabLayout.Tab tab), which would cause me much grief. I was looking for a way to do programmatic selection without triggering the listener.
So I adapted #kenodoggy 's answer to my use. I was further facing a problem where some of the internal objects would return null (because they weren't created yet, because I was answering onActivityResult() from my fragment, which occurs before onCreate() in the case the activity is singleTask or singleInstance) so I wrote up a detailed if/else sequence which would report the error and fall through without the NullPointerException that would otherwise trigger. I use Timber for logging, if you're not using that substitute with Log.e().
void updateSelectedTabTo(int position) {
if (tabLayout != null){
int selected = tabLayout.getSelectedTabPosition();
if (selected != -1){
TabLayout.Tab oldTab = tabLayout.getTabAt(0);
if (oldTab != null){
View view = oldTab.getCustomView();
if (view != null){
view.setSelected(false);
}
else {
Timber.e("oldTab customView is null");
}
}
else {
Timber.e("oldTab is null");
}
}
else {
Timber.e("selected is -1");
}
TabLayout.Tab newTab = tabLayout.getTabAt(position);
if (newTab != null){
View view = newTab.getCustomView();
if (view != null){
view.setSelected(false);
}
else {
Timber.e("newTab customView is null");
}
}
else {
Timber.e("newTab is null");
}
}
else {
Timber.e("tablayout is null");
}
}
Here, tabLayout is my memory variable bound to the TabLayout object in my XML. And I don't use the scrolling tab feature so I removed that as well.
If you are using TabLayout with viewPager then this helps you. You set the TabLayout with ViewPager in addOnpagelistener.
if you want to set the TabLayout position directly(not click on the Tab individual) try below code tabLayout.getTabAt(position_you_want_to_set).select()
/* will be invoked whenever the page changes or is incrementally scrolled*/
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
tabLayout.getTabAt(position).select();
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
This won't work for app that has ViewPager2 Implemented, For that, you need to use
viewPager2.setCurrentItem(position);
inside onConfigureTab, onConfigureTab if found when we use TabLayoutMediator
i.e
TabLayoutMediator tabLayoutMediator = new TabLayoutMediator(
tabLayout, viewPager2, new TabLayoutMediator.TabConfigurationStrategy() {
#Override
public void onConfigureTab(#NonNull TabLayout.Tab tab, int position) {
switch (position){
case 0 : tab.setIcon(getResources().getDrawable(R.drawable.camera));
break;
case 1 : tab.setText("CHAT");
viewPager2.setCurrentItem(position); // when app starts this will be the selected tab
break;
case 2 : tab.setText("STATUS");
break;
case 3 : tab.setText("CALL");
break;
}
}
}
);
tabLayoutMediator.attach();
add for your viewpager:
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
array.clear();
switch (position) {
case 1:
//like a example
setViewPagerByIndex(0);
break;
}
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
//on handler to prevent crash outofmemory
private void setViewPagerByIndex(final int index){
Application.getInstance().getHandler().post(new Runnable() {
#Override
public void run() {
viewPager.setCurrentItem(index);
}
});
}
By default if you select a tab it will be highlighted. If you want to select Explicitly means use the given commented code under onTabSelected(TabLayout.Tab tab) with your specified tab index position. This code will explains about change fragment on tab selected position using viewpager.
public class GalleryFragment extends Fragment implements TabLayout.OnTabSelectedListener
{
private ViewPager viewPager;public ViewPagerAdapter adapter;private TabLayout tabLayout;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_gallery, container, false);
viewPager = (ViewPager) rootView.findViewById(R.id.viewpager);
adapter = new ViewPagerAdapter(getChildFragmentManager());
adapter.addFragment(new PaymentCardFragment(), "PAYMENT CARDS");
adapter.addFragment(new LoyaltyCardFragment(), "LOYALTY CARDS");
viewPager.setAdapter(adapter);
tabLayout = (TabLayout) rootView.findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
tabLayout.setOnTabSelectedListener(this);
}
#Override
public void onTabSelected(TabLayout.Tab tab) {
//This will be called 2nd when you select a tab or swipe using viewpager
final int position = tab.getPosition();
Log.i("card", "Tablayout pos: " + position);
//TabLayout.Tab tabdata=tabLayout.getTabAt(position);
//tabdata.select();
tabLayout.post(new Runnable() {
#Override
public void run() {
if (position == 0) {
PaymentCardFragment paymentCardFragment = getPaymentCardFragment();
if (paymentCardFragment != null) {
VerticalViewpager vp = paymentCardFragment.mypager;
if(vp!=null)
{
//vp.setCurrentItem(position,true);
vp.setCurrentItem(vp.getAdapter().getCount()-1,true);
}
}
}
if (position == 1) {
LoyaltyCardFragment loyaltyCardFragment = getLoyaltyCardFragment();
if (loyaltyCardFragment != null) {
VerticalViewpager vp = loyaltyCardFragment.mypager;
if(vp!=null)
{
vp.setCurrentItem(position);
}
}
}
}
});
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
//This will be called 1st when you select a tab or swipe using viewpager
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
//This will be called only when you select the already selected tab(Ex: selecting 3rd tab again and again)
}
private PaymentCardFragment getLoyaltyCardFragment() {
Fragment f = adapter.mFragmentList.get(viewPager.getCurrentItem());
if(f instanceof PaymentCardFragment)
{
return (PaymentCardFragment) f;
}
return null;
}
private LoyaltyCardFragment getPaymentCardFragment() {
Fragment f = adapter.mFragmentList.get(viewPager.getCurrentItem());
if(f instanceof LoyaltyCardFragment)
{
return (LoyaltyCardFragment) f;
}
return null;
}
class ViewPagerAdapter extends FragmentPagerAdapter {
public List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
}
}
This can help too
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int i, float v, int i1) {
}
#Override
public void onPageSelected(int i) {
tablayout.getTabAt(i).select();
}
#Override
public void onPageScrollStateChanged(int i) {
}
});
You can set TabLayout position using following functions
public void setTab(){
tabLayout.setScrollPosition(YOUR_SCROLL_INDEX,0,true);
tabLayout.setSelected(true);
}
If it so happens that your default tab is the first one(0) and you happen to switch to a fragment, then you must manually replace the fragment for the first time. This is because the tab is selected before the listener gets registered.
private TabLayout mTabLayout;
...
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_tablayout, container, false);
mTabLayout = view.findViewById(R.id.sliding_tabs);
mTabLayout.addOnTabSelectedListener(mOnTabSelectedListener);
getActivity().getSupportFragmentManager().beginTransaction()
.replace(R.id.tabContent, MyFirstFragment.newInstance()).commit();
return view;
}
Alternatively, you can consider calling getTabAt(0).select() and overriding onTabReselected like so:
#Override
public void onTabReselected(TabLayout.Tab tab) {
// Replace the corresponding tab fragment.
}
This would work because you are essentially replacing the fragment on every tab reselect.
If you have trouble understanding, this code can help you
private void MyTabLayout(){
TabLayout.Tab myTab = myTabLayout.newTab(); // create a new tab
myTabLayout.addTab(myTab); // add my new tab to myTabLayout
myTab.setText("new tab");
myTab.select(); // select the new tab
}
You can also add this to your code:
myTabLayout.setTabTextColors(getColor(R.color.colorNormalTab),getColor(R.color.colorSelectedTab));
Try this way.
tabLayout.setTabTextColors(getResources().getColor(R.color.colorHintTextLight),
getResources().getColor(R.color.colorPrimaryTextLight));
if u are using TabLayout without viewPager this helps
mTitles = getResources().getStringArray(R.array.tabItems);
mIcons = getResources().obtainTypedArray(R.array.tabIcons);
for (int i = 0; i < mTitles.length; i++) {
tabs.addTab(tabs.newTab().setText(mTitles[i]).setIcon(mIcons.getDrawable(i)));
if (i == 0) {
/*For setting selected position 0 at start*/
Objects.requireNonNull(Objects.requireNonNull(tabs.getTabAt(i)).getIcon()).setColorFilter(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary), PorterDuff.Mode.SRC_IN);
}
}
tabs.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
Objects.requireNonNull(tab.getIcon()).setColorFilter(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary), PorterDuff.Mode.SRC_IN);
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
Objects.requireNonNull(tab.getIcon()).setColorFilter(ContextCompat.getColor(getApplicationContext(), R.color.white), PorterDuff.Mode.SRC_IN);
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
Kotlin fix
viewPager.currentItem = 0
tabs.setupWithViewPager(viewPager)
TabLayout jobTabs = v.findViewById(R.id.jobTabs);
ViewPager jobFrame = v.findViewById(R.id.jobPager);
jobFrame.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(jobTabs));
this will select tab as view pager swipe page
With Viewpager2, Kotlin none of the other answers helped, only this worked below. position is from fragment result listener in my case:
TabLayoutMediator(binding.tabLayout, binding.viewPager2) { _, _ ->
binding.viewPager2 = position
}.attach()

Categories

Resources