in an android app, I use a TabLayout to display multiple Fragments in a single activity.
I want the tabs to be labeled with icons and a two line heading.
In the Activity's onCreate I initialise the SectionsPageAdapter and the TabLayout like:
private SectionsPagerAdapter mSectionsPagerAdapter;
protected void onCreate(Bundle savedInstanceState) {
...
// 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);
// add a PageChangeListener to be able to detect which tab is activated
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener(){
...
});
...
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
tabLayout.setTabGravity(TabLayout.GRAVITY_CENTER);
//Set icons for tabs
tabLayout.getTabAt(0).setIcon(R.drawable.ic0);
tabLayout.getTabAt(1).setIcon(R.drawable.ic1);
tabLayout.getTabAt(2).setIcon(R.drawable.ic2);
}
And in the SectionpagerAdapter I define the PageTitles using:
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "First \nTab";
case 1:
return "Second \nTab";
case 2:
return "Third \nTab";
}
return null;
}
But when i run the app, the PageTitles aren't broken in two lines, but shortened with ... to fit the screen.
How to enable multiline PageTitles for the Tabs?
tabLayout.getTabAt(i).setCustomView(yuorTabView);
And you can customize your own TabView
Related
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);
}});
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()
I am using google's SlidingTabLayout in my view, but i want to add dynamically new tabs to it.
I'm using this http://developer.android.com/samples/SlidingTabsBasic/src/com.example.android.common/view/SlidingTabLayout.html
This is my code which initialize it:
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
//this ^ is a FragmentStatePagerAdapter
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
// Assiging the Sliding Tab Layout View
tabs = (SlidingTabLayout) findViewById(R.id.tabs);
// Setting the ViewPager For the SlidingTabsLayout
tabs.setViewPager(mViewPager);
I have absolutely no idea how to add a Tab.
I thought about changing the ViewPager but in the SlidingTabLayout there is a comment:
/**
* Sets the associated view pager. Note that the assumption here is that the pager content
* (number of tabs and tab titles) does not change after this call has been made.
*/
public void setViewPager(ViewPager viewPager) {
There's probably a nicer, more efficient way, but simply calling setViewPager() every time you add a page to your ViewPager will work.
Here is a nice tutorial. http://www.android4devs.com/2015/01/how-to-make-material-design-sliding-tabs.html
In short, you can supply them with your Pager Adapter. Override the getPageTitle method in order to supply something custom. E.g.
#Override
public CharSequence getPageTitle(int position) {
return _items[position].getDisplayName();
}
I have a FragmentActivity and some fragment in my app.
i need to have Swip ActionBar-Tabs Just inside one fragment , but when i use ActionBar and ViewPager in my project to make Swip ActionBar Tab , make ActionBar in all of fragment No just in one,
hove i can make ActionBar just inside one fragment that not shown in other fragment?
actionabar = getActionBar();
actionabar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
viewpager = (ViewPager) findViewById(R.id.pager);
FragmentManager fm = getSupportFragmentManager();
/** Defining a listener for pageChange */
ViewPager.SimpleOnPageChangeListener pageChangeListener = new ViewPager.SimpleOnPageChangeListener(){
#Override
public void onPageSelected(int position) {
super.onPageSelected(position);
actionabar.setSelectedNavigationItem(position);
}
};
/** Setting the pageChange listner to the viewPager */
viewpager.setOnPageChangeListener(pageChangeListener);
/** Creating an instance of FragmentPagerAdapter */
MyFragmentPagerAdapter fragmentPagerAdapter = new MyFragmentPagerAdapter(fm);
viewpager.setAdapter(fragmentPagerAdapter);
actionabar.setDisplayShowTitleEnabled(true);
Tab tab = actionabar.newTab().setText("My Friends").setTabListener(tabListener);
actionabar.addTab(tab);
tab = actionabar.newTab().setText("Android Version").setTabListener(tabListener);
actionabar.addTab(tab);
tab = actionabar.newTab().setText("Android Phones").setTabListener(tabListener);
actionabar.addTab(tab);
Use TabHost (http://developer.android.com/reference/android/support/v4/app/FragmentTabHost.html) instead of ActionBar navigation mode.
I've been programming for android for approximately seven weeks. I've started on a application that use the template "Tabs + Swipe", that was introduced in "IceCreamSandwich"(API level 14).
There are plenty question on stack-overflow concerning Fragments, but i haven't been able to find a solutions for my specific problem.
My problem is that the template "Tabs + Swipe" has 1 FragmentActivity which instantiate 3 tabs and the autogenerated onCreate method look like this:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Create the adapter that will return a fragment for each of the three primary sections
// of the app.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the action bar.
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
// When swiping between different sections, select the corresponding tab.
// We can also use ActionBar.Tab#select() to do this if we have a reference to the tab.
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
// For each of the sections in the app, add a tab to the action bar.
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
// Create a tab with text corresponding to the page title defined by the adapter.
// Also specify this Activity object, which implements the TabListener interface, as the
// listener for when this tab is selected.
actionBar.addTab(actionBar.newTab().setText(mSectionsPagerAdapter.getPageTitle(i)).setTabListener(this));
}
}
I want to make 3 fragments, 1 for each tab. How should i inflate my tab1.xml, tab2.xml and tab3.xml layout from the different fragments classes? Should i use the getItem method from the the class "PagerAdapter extends FragmentPagerAdapter"?
#Override
public Fragment getItem(int i) {
// pseudo-code explanation
switch (i) {
case 0:
inflate tab1.xml;
case 1:
inflate tab2.xml;
case 2:
inflate tab3.xml;
}
return fragment;
}
It's my first question here, so hope it's to understand.
Thanx Michael
the getItem() method should return the fragment. So it should look like this:
#Override
public Fragment getItem(int i) {
// pseudo-code explanation
Fragment fragment;
switch (i) {
case 0:
fragment = new FragmentTab1() // which inflates tab1.xml in its onCreateView() method;
case 1:
fragment = new FragmentTab2(); //etc.
case 2:
fragment = new FragmentTab3();
}
return fragment;
}