Complete beginner here..
I have used the "Tabbed Activity" default from the New Project Wizard.
I am trying to get it to swipe through 3 different fragments, however I simply cant see where to tell the program to do it. Do I load them in as an array, if yes where should I do it and how do I instantiate the different fragments?
Any pointers and/or solutions is very appreciated.
you can create a pager adapter from where you can call fragments based on tabs.
public class TabsPagerAdapter extends FragmentPagerAdapter {
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
// Top Rated fragment activity
return new TopRatedFragment();
case 1:
// Games fragment activity
return new GamesFragment();
case 2:
// Movies fragment activity
return new MoviesFragment();
}
return null;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 3;
}
}
and initialize the tabs values in onCreate method of main activity to get tabs working
private String[] tabs = { "Top Rated", "Games", "Movies" };
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initilization
viewPager = (ViewPager) findViewById(R.id.pager);
actionBar = getActionBar();
mAdapter = new TabsPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(mAdapter);
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Adding Tabs
for (String tab_name : tabs) {
actionBar.addTab(actionBar.newTab().setText(tab_name)
.setTabListener(this));
}
}
I know that this question is old, but hopefully it can help someone. This was really frustrating for me as well since I'm trying my best to learn Android but the wizard seems to have provided an incomplete template.
Anyways,
In fragment_main.xml, add some text to the TextView and the pages will show up now that there's content.
<TextView android:id="#+id/section_label" android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Hello World" />
Related
I'm not quite sure if there's a "best way" to tackle the following design issue.
I have a Tablayout with 2 Tabs in my MainActivity. Each Tab is a different Fragment. I go to Tab1 and see Fragment1. I need to launch a new Fragment (1A) from Fragment 1 and am not sure the best way to do it? I was thinking about one of these.
A) Take the Tabs out of my MainActivity and place them in a separate MainFragment, which gets launched with the app. That way when the user launches Fragment 1A, it replaces just the 1 MainFragment with the Tabs.
or
B) Keep the Tabs in the MainActivity and find a way to replace Fragment 1 with Fragment 1A when under Tab1.
Any suggestions would be appreciated. Thank you.
I think you shouldn't do both of points... Frag1 visible under Tab1 should contain all the layout (including initialy hidden) and logic for this view. If you need to show smth new it may be smaller (then popup, dialog etc.) or expand some layout, maybe with some animation (you may still use ViewPager inside Fragment inside ViewPager, disable touch events and manipulate scrolling programmatically...).
When Action picked by user is intended to show smth so-much-improtant that previous screen is not needed at all then you should probably open new Activity
PS. If you insist to replace current "screen" (in fact Activitys content) note that title of Tab1 may not representing what contains Frag1A. It very depends what kind of content you have there. You may consider move TabLayout/RecyclerView to e.g. FrameLayout container and add to it you Frag1A covering whole previous view including Tabs. In current design guidelines you can even find suggested solution for way of showing new fragment - with circular reveal animation
I do not understand very well what you want, but possibly this.
Use FragmentPagerAdapter..
public class TabsPagerAdapter extends FragmentPagerAdapter {
private static final int NUM_TABS = 3;
public TabsPagerAdapter(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() {
return NUM_TABS;
}
#Override
public CharSequence getPageTitle(int position) {
if (position == 0){
return "Tab 1";
}
if (position == 1){
return "Tab 2";
}
return "Tab 3";
}
In your activity...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Tabs
TabLayout tabs = (TabLayout) findViewById(R.id.tabs);
ViewPager pager = (ViewPager) findViewById(R.id.pager);
TabsPagerAdapter adapter = new TabsPagerAdapter(getSupportFragmentManager());
pager.setAdapter(adapter);
tabs.setupWithViewPager(pager);
}
I am trying to set up sliding tabs on top of an activity. I want this result :
I'm following the explanations of this example : http://developer.android.com/samples/SlidingTabsBasic/project.html
And I'm also looking at this video : https://www.youtube.com/watch?v=tRg_eDfQ8fk
I'm doing so because of this post : Action bar navigation modes are deprecated in Android L
I have 3 fragments for each of my tab. Each inflates a different layout and do different things. Now I need to connect them to my PageAdapter. I've already used an adaptor for a ListView. I used getView with the position to do my work
However with this PageAdapter I'm not sure what I need to proceed. Should I use this method to create my fragment :
public Object instantiateItem(ViewGroup container, int position) {
and if so, how should it be done ?
Thank you.
You must implement a FragmentPagerAdapter like this:
public class TabsPagerAdapter extends FragmentPagerAdapter {
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
return new FirstFragment();
case 1:
return new TwoFragment();
case 2:
return new ThreeFragment();
}
return null;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 3;
}
}
and set it to viewpager adapter:
mAdapter = new TabsPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(mAdapter);
I've integrated PagerSlidingTabStrips in my application which runs as expected on Swipe of tabs.
But selecting tabs on PagerSlidingTabStrips doesn't switch to that fragment which works perfectly on swiping between tabs.
FragmentManager fm = getSupportFragmentManager();
mPager = (ViewPager) findViewById(R.id.pager);
ViewPagerAdapter viewpageradapter = new ViewPagerAdapter(fm);
mPager.setAdapter(viewpageradapter);
pagerSlidingTabStrp = (PagerSlidingTabStrip) findViewById(R.id.pager_sliding_tab_strip);
pagerSlidingTabStrp.setShouldExpand(true);
pagerSlidingTabStrp.setViewPager(mPager);
pagerSlidingTabStrp.setOnPageChangeListener(ViewPagerListener);
// Capture ViewPager page swipes
ViewPager.SimpleOnPageChangeListener ViewPagerListener = new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
super.onPageSelected(position);
switch(position)
{
case 0:
setMotherActionBarTitle(getString(R.string.str_all_contacts_fragment));
break;
case 1:
setMotherActionBarTitle(getString(R.string.str_group_contacts_fragment));
break;
case 2:
setMotherActionBarTitle(getString(R.string.str_call_logs_fragment));
break;
}
}
};
ViewPagerAdapter
public class ViewPagerAdapter extends FragmentPagerAdapter implements IconTabProvider {
final int PAGE_COUNT = 3;
private final int[] ICONS = { R.drawable.tab_icon_zname_contact_selector, R.drawable.tab_icon_zname_friends_selector,
R.drawable.tab_icon_zname_call_log_selector };
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int item) {
switch (item) {
case 0:
ContactsFragment homeFragment = new ContactsFragment();
return homeFragment;
case 1:
GroupsFragment groupsFragment = new GroupsFragment();
return groupsFragment;
case 2:
CallLogsFragment callLogsFragment = new CallLogsFragment();
return callLogsFragment;
}
return null;
}
#Override
public int getCount() {
return PAGE_COUNT;
}
#Override
public int getPageIconResId(int position) {
return ICONS[position];
}
}
How to make selecting tabs works with PagerSlidingTabStrips? Morever PagerSlidingTabStrips tabs are not even clickabe.
Did I missed out to implement something? Or to add pagerSlidingTabStrips.setClickable(true)? or something?
Again the selector of PagerSlidingTabStrips tabs not selected proper drawable with selector. What could be possible the reason for that?
Here's a picture of it.
I've found out why clicking tab was not working with PagerSlidingTabStrips after I've looked out for other options with sliding tabs functionality like SlidingTabsLayout which also was not able to click tabs.
Found out problem was with my xml layout which covers whole as ViewPager which doesn't make tabs clickable of eitherPagerSlidingTabStrips or SlidingTabsLayout works.
<com.netdoers.zname.utils.PagerSlidingTabStrip
android:id="#+id/pager_sliding_tab_strip"
android:layout_width="fill_parent"
android:layout_height="45dip"
android:background="#android:color/white"
app:pstsDividerColor="#FFFFA500"
app:pstsIndicatorColor="#FFFFA500"
app:pstsTabPaddingLeftRight="14dip"
app:pstsUnderlineColor="#FFFFA500" />
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="45dp" />
Leaving same height in Viewpager as of PagerSlidingTabStips from top where PagerSlidingTabStrips rendered solved my issue.
Indeed the issue is in XML. The issue probably due to RelativeLayout is used om the XML. Consider using LinearLayout will ensure there's no overlap between views.
I want a tab layout in which, on every tab there are two fragments, One above showing a progress of a task that is completed by giving input in 3 tabs, from start to end, and another main fragment below that progress fragment that will be taking input.
That makes a title and detail in every tab, title fragment same and detail fragment (input fragment different on each tab)!
I tried all methods for two days :(
My Solution
i tried a layout that contains two framelayout for main fragment that is added into two tabs from ViewPager,showed here:
public static class ScreenSlidePagerAdapter extends
FragmentStatePagerAdapter {
public static ArrayList<Fragment> tabs_fragments = new ArrayList<Fragment>(
3);
public ScreenSlidePagerAdapter(FragmentManager fm,
ArrayList<Fragment> tabs) {
super(fm);
ScreenSlidePagerAdapter.tabs_fragments = tabs;
}
#Override
public Fragment getItem(int arg0) {
return tabs_fragments.get(arg0);
}
#Override
public int getCount() {
return tabs_fragments.size();
}
#Override
public int getItemPosition(Object object) {
if (tabs_fragments.contains(object)) {
return POSITION_UNCHANGED;
}
return POSITION_NONE;
}
public static void setItem(Fragment fr, int position) {
if (position <= 2 && position >= 0) {
tabs_fragments.remove(position);
tabs_fragments.add(position, fr);
} else
Log.d("adding tab", "wrong tab position to add fragment at");
}
}
On activity start i do this, see i get tab position that is used in main fragment for loading detail fragment for different tab positions:
mPager = (ViewPager) findViewById(R.id.pager);
// fragments for pagers
ArrayList<Fragment> tabs = new ArrayList<Fragment>();
tabs.add(new FrEventDetails());
tabs.add(new FrEventDetails());
tabs.add(new FrRuleSave());
mPagerAdapter = new ScreenSlidePagerAdapter(getFragmentManager(), tabs);
mPager.setAdapter(mPagerAdapter);
bar = getActionBar();
bar.setTitle("Add Rule");
bar.setSubtitle("select event for rule");
bar.setDisplayShowTitleEnabled(true);
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
bar.setDisplayHomeAsUpEnabled(true);
bar.addTab(bar.newTab().setText("Select Event")
.setTabListener(new TabListener(mPager)));
bar.addTab(bar.newTab().setText("Select Action")
.setTabListener(new TabListener(mPager)));
bar.addTab(bar.newTab().setText("Save Rule")
.setTabListener(new TabListener(mPager)));
if (savedInstanceState != null) {
bar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0));
}
mPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// When swiping between pages, select the
// corresponding tab.
if (bar.getSelectedNavigationIndex() != position)
bar.setSelectedNavigationItem(position);
tab = position;
}
and then when this fragment is attaching to activity I add a progress layout (title( for one frame-layout and based on the selected tab, add another fragment for detail frame layout(for input).
showed here:
public class FrEventDetails extends Fragment {
Context context;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context = (Context) activity;
int tab = AddRule1.tab;
android.app.FragmentTransaction ft = activity.getFragmentManager()
.beginTransaction();
ft.add(R.id.fr_rule_progress_container, new FrProgress());
if (tab == 1) {
ft.replace(R.id.fr_event_input_container, new FrActionSelect(),
"cell1_1").commit();
} else if (tab == 0) {
ft.replace(R.id.fr_event_action_container, new FrEventSelect(),
"cell1_2").commit();
}
}
NOTE* layout for this main fragment is simple containing two framelayouts.
result : It shows on start a title and detail beautifully on first tab, but on second tab, only main fragment and,
when i swipe to third fragment and come back, second fragment is filled beautifully (after 1 second of showing) but 1st fragment is now empty.
i can't understand what to do with this.
please give some solution to this tearful problem of two days
To Show all Tabs at the same time in start, increase PagerOffSetLimit (to 2 in this case for 3 tabs)
For refreshing state of fragment or calling some methods on your fragment in the tab beside your current tab, use the Pager.instantiateItem method.
One second delay is because you have on the animateLayoutChanges in your xml.
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;
}