I have created a PagerTabStrip for my ViewPager and it is all working fine. Using a switch and case, I have the titles set up for each page. However I can't find how to set the background colour or or text colour within the java. I can change the colour in the xml, but I want the colour to change with my switch and case.
Here is my code:
EDIT: Added more code
public class RemViewPagerActivity extends FragmentActivity {
private static final int NUM_PAGES = 3;
private ViewPager mPager;
private PagerAdapter mPagerAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view_pager_activity);
mPager = (ViewPager) findViewById(R.id.viewpager);
mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
mPager.setAdapter(mPagerAdapter); /
}
#Override
public void onBackPressed() {
if (mPager.getCurrentItem() == 1) {
super.onBackPressed();
} else if (mPager.getCurrentItem() == 0){
mPager.setCurrentItem(mPager.getCurrentItem() + 1);
}
else if (mPager.getCurrentItem() == 2){
mPager.setCurrentItem(mPager.getCurrentItem() - 1);
}
}
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter { // Sets the content of the adapter
public ScreenSlidePagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) { // Sets the fragment for each position
switch (position) {
case 0: return new Fragment1();
case 1: return new Fragment2();
case 2: return new Fragment3();
}
return null;
}
public CharSequence getPageTitle(int position) {
switch (position) {
case 0: return "1";
case 1: return "2";
case 2: return "3";
}
return null;
}
#Override
public int getCount() { // Sets the number of pages
return NUM_PAGES;
}
}
}
Code of view_pager_activity.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<android.support.v4.view.PagerTabStrip
android:id="#+id/pager_title_strip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:background="#33b5e5"
android:textColor="#fff"
android:paddingTop="4dp"
android:paddingBottom="4dp" />
</android.support.v4.view.ViewPager>
</RelativeLayout>
Thank you
Related
I have a tab setup with a VeiwPager and a MainActivity. When one particular tab, "B" is selected I want to Show Fragment B user interface and start doing something.
The method I have found to do this is to use a LocalBroadcastReceiver in Fragment "B" and have it call a method. The broadcast is sent from Main Activity inside the onTabSelected method.
Is this a good approach?
Activity.xml
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorPrimary"
app:tabGravity="fill"
app:tabMode="fixed" />
<android.support.v4.view.ViewPager
android:id="#+id/viewPager"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Activity.class
TabLayout tabLayout;
ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tab);
tabLayout = findViewById(R.id.tabLayout);
viewPager = findViewById(R.id.viewPager);
setUpviewPager();
tabLayout.setupWithViewPager(viewPager);
}
private void setUpviewPager() {
ViewPagerAdpater viewPagerAdapter = new ViewPagerAdpater(getSupportFragmentManager());
viewPager.setAdapter(viewPagerAdapter);
}
private class ViewPagerAdpater extends FragmentPagerAdapter {
ViewPagerAdpater(FragmentManager supportFragmentManager) {
super(supportFragmentManager);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new FirsFrag();
case 1:
return new FirsFrag();
case 2:
return new FirsFrag();
default:
return null;
}
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "First Tab";
case 1:
return "Second Tab";
case 2:
return "Third Tab";
default:
return "";
}
}
#Override
public int getCount() {
return 3;
}
#Override
public boolean isViewFromObject(#NonNull View view, #NonNull Object object) {
return view == object;
}
}
Thanks, just run this code, this adapter is FragmentPagerAdpater
so i have the classic viewpager in a tablayout that looks something like this:
My viewPagerAdapter class looks like this:
public class HomePagerAdapter extends FragmentPagerAdapter {
int mNumOfTabs;
public HomePagerAdapter(FragmentManager fm, int NumOfTabs) {
super(fm);
this.mNumOfTabs = NumOfTabs;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
TabHomeFragment tab1 = new TabHomeFragment();
return tab1;
case 1:
TabShopFragment tab2 = new TabShopFragment();
return tab2;
case 2:
TabMeFragment tab3 = new TabMeFragment();
return tab3;
default:
return null;
}
}
#Override
public int getCount() {
return mNumOfTabs;
}
}
So now on one of the tabs i need to add a fragment on top of it. so its a search fragment really. i do a search in the tab bar and i want the back end search results to appear in only ONE of the tabs (the first one). but i want the search results displayed in a fragment called searchFragmentResults and i want it to be laid out on top of the first tab. Then when user hits the back button it will just go back to the original content in the first tab. Is this possible with view pager ?
so visually when i hit the search icon on the first tabs tabBar it should bring up a searchView and when i search for the users query it should bring up a another fragment with the results but only in the tab that it started from. Here is an example:
i cant call fragtransaction.replace(somecontentview, somefragment); (or its add method) because i did not add them to a contentview. i let the viewpager do it for me. So how is this achieved ?
i figured out how to do this. The tab should be a fragment who's purpose is to only contain other fragments. the idea is based off of this SO. But i had a need to do it for a viewPager. Lets go through the steps. first the viewpager adapter:
public class HomePagerAdapter extends FragmentStatePagerAdapter {
//integer to count number of tabs
int tabCount;
private Fragment mCurrentFragment;
private String[] tabTitles = new String[]{"tab0", "tab1", "tab2", "tab3"};
//Constructor to the class
public HomePagerAdapter(FragmentManager fm, int tabCount) {
super(fm);
this.tabCount = tabCount;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
TabHomeContainerFragment tab1 = new Tab0ContainerFragment();
return tab1;
case 1:
TabShopFragment tab2 = new Tab1ContainerFragment();
return tab2;
case 2:
TabMeFragment tab3 = new Tab2ContainerFragment();
return tab3;
case 3:
TabBagFragment tab4 = new Tab3ContainerFragment();
return tab4;
default:
return null;
}
}
//Overriden method getCount to get the number of tabs
#Override
public int getCount() {
return tabCount;
}
public Fragment getCurrentFragment() {
return mCurrentFragment;
}
//* this is key to get the current tab to pop the fragments afterwards**/
#Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
if (getCurrentFragment() != object) {
mCurrentFragment = ((Fragment) object);
}
super.setPrimaryItem(container, position, object);
}
#Override
public CharSequence getPageTitle(int position) {
return tabTitles[position];
}
Lets go into a container to see how it would look:
add this to your xml for all the containers (along with anything else you want visually but they ALL must have the same id of container_framelayout:
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout android:id="#+id/container_framelayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android" />
</android.support.design.widget.CoordinatorLayout>
you dont have to put it in a coordinatorLayout i just find it fixes some bugs and works well.
In your fragments base class i copied almost the same code from the SO i mentioned above but slight modification if you want to add tag or not:
public void replaceFragment(Fragment fragment, boolean addToBackStack,String tag) {
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
if (addToBackStack) {
transaction.addToBackStack(null);
}
transaction.replace(R.id.container_framelayout, fragment,tag);
transaction.commit();
getChildFragmentManager().executePendingTransactions();
}
public boolean popFragment() {
Log.e("test", "pop fragment: " + getChildFragmentManager().getBackStackEntryCount());
boolean isPop = false;
if (getChildFragmentManager().getBackStackEntryCount() > 0) {
isPop = true;
getChildFragmentManager().popBackStack();
}
return isPop;
}
Now lets look at the activities layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#color/white"/>
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"
app:tabGravity="fill"
app:tabTextColor="#color/black"
app:tabSelectedTextColor="#android:color/darker_gray"
/>
Now i'll show you how to set up the tablayout in the activity hosting the tablayout:
its standard:
public class HomePageActivity implements TabLayout.OnTabSelectedListener {
private final int NUM_OF_TABS = 4;
#BindView(R.id.pager)
public ViewPager viewPager;
public HomePagerAdapter adapter;
#BindView(R.id.tabLayout)
TabLayout tabLayout;
#NonNull
#Override
public HomePagePresenter createPresenter() {
return new HomePagePresenter();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_homepage);
ButterKnife.bind(this);
initView();
}
private void initView() {
for (int i = 0; i < NUM_OF_TABS; i++)
tabLayout.addTab(tabLayout.newTab());
adapter = new HomePagerAdapter(getSupportFragmentManager(), tabLayout.getTabCount());
//Adding adapter to pager
viewPager.setAdapter(adapter);
tabLayout.addOnTabSelectedListener(this);
tabLayout.setupWithViewPager(viewPager);
// configure tab icons
int[] imageTabResId = {
R.drawable.welcome1,
R.drawable.welcome2,
R.drawable.welcome3,
R.drawable.welcome1};
for (int i = 0; i < imageTabResId.length; i++) {
tabLayout.getTabAt(i).setIcon(imageTabResId[i]);
}
}
/** this is key. we get the current fragment showing and pop it **/
#Override
public void onBackPressed() {
boolean isPopFragment = false;
isPopFragment = ((BaseFragment) adapter.getCurrentFragment()).popFragment();
if (!isPopFragment) {
finish();
}
}
#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) {
}
}
I guess the major part is onBackPress getting the current fragment.
I recently use AHBottomNavigation which have 5 item in bottom bar for example when
I click Home Button it goes to homeActivty which I have 3 tab bar. Everything until here is ok but I realize when we use AHBottomNavigation we should use fragment but
I need to use activities with bars and show AHBottomNavigation in all of them.
I use AHBottomNavigation in all of my activities to handle this and it work's and all of my activities have AHBottomNavigation but when i change activities,
AHBottomNavigation doesnt work as good as normal and it seems that there is a delay in it.
Is there any better solution for this or please inform me if I'm doing something wrong ?
HomeActivity.class
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
if (drawer != null) {
drawer.setDrawerListener(toggle);
}
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
//[START Tab ]
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
//[*End Tab]
//[Start Bottom N]
bottomNavigation();
}
private void setupViewPager(ViewPager viewPager){
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new Fragment1(),"Tab1");
adapter.addFragment(new Fragment2() , "Tab2");
adapter.addFragment(new Fragment3() , "Tab3");
viewPager.setAdapter(adapter);
}
public void bottomNavigation(){
// [START BottomNavigation]
// TODO add other activitys to setOnTabSelectedListener (HOME , SEARCH , ...)
AHBottomNavigation bottomNavigation = (AHBottomNavigation) findViewById(R.id.bottom_navigation);
// Create items
AHBottomNavigationAdapter navigationAdapter = new AHBottomNavigationAdapter(this, R.menu.bottom_navigation);
navigationAdapter.setupWithBottomNavigation(bottomNavigation);
bottomNavigation.setBehaviorTranslationEnabled(true);
bottomNavigation.setAccentColor(Color.parseColor("#3498db"));
bottomNavigation.setCurrentItem(0);
bottomNavigation.setOnTabSelectedListener(new AHBottomNavigation.OnTabSelectedListener() {
#Override
public boolean onTabSelected(int position, boolean wasSelected) {
switch (position){
case 0 :
break;
case 1 :
// Add
Intent goToAddStuff = new Intent(HomeActivity.this , AddStuffActivity.class);
startActivity(goToAddStuff);
finish();
break;
case 2 :
// Search
break;
case 3:
// Activity's
//My AONActivity have 2 tab too
Intent goToAON = new Intent(HomeActivity.this , AONActivity.class);
startActivity(goToAON);
finish();
break;
case 4:
//Account
break;
}
return true;
}
});
// [*END BottomNavigation]
}
content_home.xml
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context=".HomeActivity"
android:id="#+id/content_id"
tools:showIn="#layout/activity_home">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context=".HomeActivity">
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</RelativeLayout>
<FrameLayout
android:id="#+id/contentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/bottomBar" />
<include layout="#layout/bottom_navigation" />
</android.support.design.widget.CoordinatorLayout>
bottom_navigation.xml
<com.aurelhubert.ahbottomnavigation.AHBottomNavigation
android:id="#+id/bottom_navigation"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:layout_gravity="bottom">
</com.aurelhubert.ahbottomnavigation.AHBottomNavigation>
I also use AHBottomNavigation but you need due to Google Material Design you need to use Fragments, otherwise you implement it incorrect.
Here how it should be :
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
>
<FrameLayout
android:id="#+id/framelayout_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<com.aurelhubert.ahbottomnavigation.AHBottomNavigation
android:id="#+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
/>
</RelativeLayout>
This is some code just to show how is better to work with fragments if you have no idea, just I do not know your background and maybe you do not use it because you feel confused with this.
#Override
public void onTabSelected(int position, boolean wasSelected) {
Log.d(TAG, "Position " + position + " was selected" + wasSelected);
if(!wasSelected) {
getSupportFragmentManager()
.beginTransaction()
.replace(FRAME_LAYOUT,
createFragment(position),
createItemDescription(position))
.addToBackStack(null)
.commit();
}
}
private void createBottomNavigationMenu(int defaultCurrentItem){
for(int i = 0; i<5; i++){
// Create bottom navigation item
AHBottomNavigationItem item =
new AHBottomNavigationItem(createItemDescription(i),
createPicture(i));
// Add bottom navigation item
mBottomNavigation.addItem(item);
}
// Set current item programmatically
mBottomNavigation.setCurrentItem(defaultCurrentItem, true);
// Set background color
mBottomNavigation.setDefaultBackgroundColor(Color.parseColor("#56ABF8"));
// Disable the translation inside the CoordinatorLayout
mBottomNavigation.setBehaviorTranslationEnabled(false);
// Set listener
mBottomNavigation.setOnTabSelectedListener(this);
}
// Factory-method patterns
private Fragment createFragment(int position){
switch (position) {
case 1:
return new SettingsFragment_();
case 2:
return new StatisticsFragment_();
case 3:
return new MainFragment_();
case 4:
return new ForthFragment_();
case 5:
return new ReminderFragment_();
}
throw new IllegalArgumentException();
}
private String createItemDescription(int position){
switch (position){
case 1:
return BOT_NAV_ITEM_SETTINGS;
case 2:
return BOT_NAV_ITEM_STATISTICS;
case 3:
return BOT_NAV_ITEM_MAIN;
case 4:
return BOT_NAV_ITEM_FORTH;
case 5:
return BOT_NAV_ITEM_REMINDERS;
}
throw new IllegalArgumentException();
}
private int createPicture(int position){
switch (position){
case 1:
return R.mipmap.ic_settings;
case 2:
return R.mipmap.ic_statistics;
case 3:
return R.mipmap.ic_water;
case 4:
return R.mipmap.ic_launcher;
case 5:
return R.mipmap.ic_reminders;
}
throw new IllegalArgumentException();
}
I found the Solution :
I create HomeFragment which extent fragment like this :
HomeFragment.class
public class HomeFragment extends Fragment {
public static TabLayout tabLayout;
public static ViewPager viewPager;
private static int currentItem = 0;
AdapterFragment adapter;
public static HomeFragment newInstance(int someInt) {
HomeFragment frag = new HomeFragment();
Bundle args = new Bundle();
args.putInt("tab", someInt);
frag.setArguments(args);
return frag;
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("currentItem", viewPager.getCurrentItem());
}
public static HomeFragment newInstance() {
HomeFragment frag = new HomeFragment();
return frag;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
adapter= new AdapterFragment(getChildFragmentManager());
currentItem=getArguments() != null ? getArguments().getInt("tab") : 0;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
/**
*Inflate tab_layout and setup Views.
*/
View rootView = inflater.inflate(R.layout.fragment_home,container,false);
tabLayout = (TabLayout) rootView.findViewById(R.id.tablayout);
viewPager = (ViewPager) rootView.findViewById(R.id.viewpager);
/**
*Set an Adapter for the View Pager
*/
if (adapter==null) adapter=new AdapterFragment(getChildFragmentManager());
viewPager.setAdapter(adapter);
viewPager.setCurrentItem( currentItem);
/**
* Now , this is a workaround ,
* The setupWithViewPager dose't works without the runnable .
* Maybe a Support Library Bug .
*/
tabLayout.post(new Runnable() {
#Override
public void run() {
tabLayout.setupWithViewPager(viewPager);
}
});
return rootView;
}
public class AdapterFragment extends FragmentPagerAdapter {
public AdapterFragment(FragmentManager fm) {
super(fm);
}
/**
* Return fragment with respect to Position .
*/
#Override
public Fragment getItem(int position)
{
switch (position){
case 0 : return new Tab1Fragment();
case 1 : return new Tab2Fragment();
case 2 : return new Tab3Fragment();
}
return null;
}
#Override
public int getCount() {
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position){
case 0 :
return "Tab1";
case 1 :
return "Tab2";
case 2 :
return "Tab3";
}
return null;
}
}
And in my
MainActivity
bottomNavigation.setOnTabSelectedListener(new AHBottomNavigation.OnTabSelectedListener() {
#Override
public boolean onTabSelected(int position, boolean wasSelected) {
switch (position){
case 0 :
// Home
HomeFragment homeFragment = new HomeFragment();
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.content_id, homeFragment)
.commit();
break;
case 1:
break;
}
return true;
}
});
I hope this will help you
I have a project that uses Action Bar Tabs(with ViewPager).
Tabs move really smoothly when swiping between them, but I need to add two sub tabs, in TAB 2, then move to the next tabs or of course back, just like on the Glassdoor or Flipboard.
Please help.
MainActivity
public class MainActivity extends AppCompatActivity {
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return Tab1Fragment.newInstance();
case 1:
return Tab2Fragment.newInstance();
default:
return Tab3Fragment.newInstance();
}
}
#Override
public int getCount() {
// Show 3 total pages.
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Tab 1";
case 1:
return "Tab 2";
case 2:
return "Tab 3";
}
return null;
}
}
}
activity_main.xml
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="#dimen/appbar_padding_top"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/AppTheme.PopupOverlay">
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
Tab2Fragment- where i want to nest SubTab1Fragment and SubTab2Fragment
public class Tab2Fragment extends Fragment {
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
public Tab2Fragment() {
// Required empty public constructor
}
// TODO: Rename and change types and number of parameters
public static Tab2Fragment newInstance() {
Tab2Fragment fragment = new Tab2Fragment();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_tab2, container, false);
}
}
fragment_tab2.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.r3dm4n.testprojectapp.Tab2Fragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/hello_blank_fragment" />
I figured this out.
I've also posted a demo project on Github
In the MainActivity you need to return a new Fragment for the one you want "nested" like this:
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return Tab1Fragment.newInstance();
case 1:
return new Tab2Fragment();
default:
return Tab3Fragment.newInstance();
}
In TAB2 fragment, where you want the other nested fragments make the following changes:
public class Tab2Fragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_tab2, container, false);
ViewPager mViewPager = (ViewPager) view.findViewById(R.id.container_main);
SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getChildFragmentManager());
mViewPager.setAdapter(mSectionsPagerAdapter);
return view;
}
private class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return Nest1Fragment.newInstance(1);
default:
return Nest2Fragment.newInstance(2);
}
}
#Override
public int getCount() {
// Show 4 total pages.
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Nested 1";
default:
return "Nested 2";
}
}
}
}
fragment_tab2.xml
<android.support.v4.view.ViewPager
android:id="#+id/container_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
app:layout_scrollFlags="scroll|enterAlways">
<android.support.design.widget.TabLayout
android:id="#+id/tabs2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorPrimary" />
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/AppTheme.PopupOverlay">
</android.support.v7.widget.Toolbar>
</android.support.v4.view.ViewPager>
Take a look at this answer
It might help
ViewPager nested in ViewPager
Also while adding sub tabs You can add a condition like this in the listener for moving to next tab
if(mPager.getCurrentItem() >=2)
mParentPager.setCurrentItem()=mParentPager.getCurrenItem()+1
This for moving to previous tab
if(mPager.getCurrentItem() ==0)
mParentPager.setCurrentItem()=mParentPager.getCurrenItem()-1
I do not understand how can I transfer data from fragmentactivity to fragment, i have:
MainScreen.class
public class MainScreen extends FragmentActivity {
CollectionPagerAdapter mCollectionPagerAdapter;
ViewPager mViewPager;
public static String currentCityId;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tabs_collection);
mCollectionPagerAdapter = new CollectionPagerAdapter(getSupportFragmentManager());
final ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(false);
actionBar.setTitle(getString(R.string.app_name));
actionBar.setIcon(R.drawable.device_access_brightness_high);
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mCollectionPagerAdapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.mainmenu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_refresh:
Log.w("Refresh", "refresh");
break;
case R.id.action_options:
break;
case R.id.submenu_about:
break;
case R.id.submenu_help:
break;
case R.id.submenu_buy:
break;
case R.id.submenu_settings:
break;
case R.id.submenu_share:
break;
default:
break;
}
return true;
}
public class CollectionPagerAdapter extends FragmentStatePagerAdapter {
FragmentManager fm;
public CollectionPagerAdapter(FragmentManager fm) {
super(fm);
this.fm = fm;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new FragmentDay();
case 1:
return new FragmentHour();
case 2:
return new FragmentDaily();
default:
return new FragmentDay();
}
}
#Override
public int getCount() {
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return getString(R.string.tab_day);
case 1:
return getString(R.string.tab_hour);
case 2:
return getString(R.string.tab_daily);
default:
return getString(R.string.tab_day);
}
}
}
FragmentDay.class
public class FragmentDay extends Fragment {
TextView currentTemp;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.hour_screen, container, false);
Bundle args = getArguments();
currentTemp = (TextView)rootView.findViewById(R.id.day_current_temp);
return rootView;
}
}
main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:background="#drawable/bk_new">
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v4.view.PagerTitleStrip
android:id="#+id/pager_title_strip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:background="#33b5e5"
android:textColor="#fff"
android:paddingTop="4dp"
android:paddingBottom="4dp"/>
</android.support.v4.view.ViewPager>
and fragment.xml:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/dayScreen"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/bk_new">
<TextView
android:id="#+id/day_current_temp"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_centerHorizontal="true"
android:text="22 C"
android:textColor="#FFFFFF"
android:textSize="38dp"
android:layout_marginTop="270dp"/>
Read these articles (ViewPager Activity to notify a Fragment of a specific event, Updating fragments from Activity in a ViewPager, ViewPager - Update fragment from activity) and do not understand what to do!
I will be very grateful for the help!
When you say "transfer data" I'm assuming you mean variables so you can tweak your fragment in whichever way.
You can access the activity object at any time within the fragment using getActivity() method and cast it to your Activity implementation...
// Code in the fragment
((MainScreen) getActivity()).getSomeDataFromActivity()
There is an article here also by Google which describes patterns of communication between Fragment and Activity.