I'm developing an application for Android and need some help implementing Tabs
I need it to be compatible with android 2.2
I started to implement Tabs but now i dont know if it was the best idea
What I want is basically:
I want to open a activity where it will have the tabs
In each of the Tab, I want to load content dinamicly, like the play store apk:
My main problem is:
I have created a AsyncTask with an ProgressDialog for each fragment to load the data and show it on the fragment, but when the fragment activity open, it initialize all the tabs and makes to load all the fragments at the same time.
I want to load the Tab content only when the Tab becomes visible, because the user may want to see only one tab, so no need to get the other Tabs
How should I do that?
Should I use TabFragments or others methods?
My current Tab activiy is:
public class Tabs2 extends FragmentActivity implements OnTabChangeListener, OnPageChangeListener{
ViewPagerAdapter pageAdapter;
private ViewPager mViewPager;
private TabHost mTabHost;
private String interID;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Infla o layout
setContentView(R.layout.tablayout);
mViewPager = (ViewPager) findViewById(R.id.viewpager);
// Tab Initialization
initialiseTabHost();
// Fragments and ViewPager Initialization
List<Fragment> fragments = getFragments();
pageAdapter = new ViewPagerAdapter(getSupportFragmentManager(), fragments);
mViewPager.setAdapter(pageAdapter);
mViewPager.setOnPageChangeListener(Tabs2.this);
}
// Method to add a TabHost
private static void AddTab(Tabs2 activity, TabHost tabHost, TabHost.TabSpec tabSpec) {
tabSpec.setContent(activity.new MyTabFactory(activity));
tabHost.addTab(tabSpec);
}
// Manages the Tab changes, synchronizing it with Pages
public void onTabChanged(String tag) {
int pos = this.mTabHost.getCurrentTab();
this.mViewPager.setCurrentItem(pos);
}
// Manages the Page changes, synchronizing it with Tabs
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
int pos = this.mViewPager.getCurrentItem();
this.mTabHost.setCurrentTab(pos);
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
#Override
public void onPageSelected(int arg0) {
}
private List<Fragment> getFragments(){
List<Fragment> fList = new ArrayList<Fragment>();
// Put here your Fragments
fList.add(Fragment.instantiate(this, TabFragmentA.class.getName()));
fList.add(Fragment.instantiate(this, TabFragmentB.class.getName()));
fList.add(Fragment.instantiate(this, TabFragmentC.class.getName()));
return fList;
}
// Tabs Creation
private void initialiseTabHost() {
mTabHost = (TabHost) findViewById(android.R.id.tabhost);
mTabHost.setup();
// Put here your Tabs
Tabs2.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab1").setIndicator("Detalhes"));
Tabs2.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab2").setIndicator("Comentários"));
Tabs2.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab3").setIndicator("cenas"));
mTabHost.setOnTabChangedListener(this);
}
// Um simples factory que retorna View para o TabHost
class MyTabFactory implements TabContentFactory {
private final Context mContext;
public MyTabFactory(Context context) {
mContext = context;
}
public View createTabContent(String tag) {
View v = new View(mContext);
v.setMinimumWidth(0);
v.setMinimumHeight(0);
return v;
}
}
}
The ViewPagerAdatper:
public class ViewPagerAdapter extends FragmentPagerAdapter {
private List<Fragment> mFragments;
public ViewPagerAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
mFragments = fragments;
}
#Override
public Fragment getItem(int i) {
return mFragments.get(i);
}
#Override
public int getCount() {
return mFragments.size();
}
}
The XML for the Tabs activiy
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TabHost
android:id="#android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TabWidget
android:id="#android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="35dp"
android:orientation="horizontal"
android:gravity="bottom"
android:padding="0dip" />
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0" />
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:isScrollContainer="true"
android:scrollbars="vertical" />
</LinearLayout>
</TabHost>
For each Tab I used Fragments
public class TabFragmentA extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (container == null) {
return null;
}
// HERE I Call the AsyncTask and return the data with the layout
return (RelativeLayout) inflater.inflate(R.layout.layout_a, container, false);
}
}
since you are using a viewpager this is how a viewpager works and for good reason. A view pager by default loads the previous, current and next tab so that the content is ready when the user gets to the tab. you cannot change the viewpager to only load one page at a time.
If you notice this is exactly how the play store works
Related
I have a MainActivity which contains a Sliding drawer for menu and a FragmentContainer to switch fragments.
I have a Fragment called History which has a layout like this
<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"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical">
<com.astuetz.PagerSlidingTabStrip
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="#color/colorPrimary"
android:textColor="#FFFFFF"
app:pstsIndicatorColor="#FFFFFF" />
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/tabs" />
</RelativeLayout>
And the class looks like this
public class HistoryFragment extends Fragment {
public HistoryFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_history, container, false);
// Initialize the ViewPager and set an adapter
ViewPager pager = (ViewPager) view.findViewById(R.id.pager);
pager.setAdapter(new PagerAdapter(getActivity().getSupportFragmentManager()));
// Bind the tabs to the ViewPager
PagerSlidingTabStrip tabs = (PagerSlidingTabStrip) view.findViewById(R.id.tabs);
tabs.setViewPager(pager);
return view;
}
class PagerAdapter extends FragmentPagerAdapter {
private final String[] TITLES = {"Last Transaction", "History"};
public PagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public CharSequence getPageTitle(int position) {
return TITLES[position];
}
#Override
public int getCount() {
return TITLES.length;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new LastTransaction();
case 1:
return new AboutFragment();
}
return null;
}
}
}
This History page works fine the first time when it is called from the NavigationSlider menu. The history page contains two sliding tabs with two fragments. These are displayed the first time and everything works fine.
The problem happens, when they are called the second time or after that.
There is no error shown, the layout is loaded, the sliding tabs are shown, but their fragments are not shown and the sliders malfunction.
What may be the reason for this problem ?
I tried to use a different approach for implementing the sliders in fragments as per this StackOverflow answer. Still the same problem.
Thanks in advance.
replace
pager.setAdapter(new PagerAdapter(getActivity().getSupportFragmentManager()));
with
pager.setAdapter(new PagerAdapter(getActivity().getChildFragmentmanager()));
Reason:
The CHILD FragmentManager is the one that handles Fragments contained within the Fragment that it was added to.
I have the code here with tabs and It works when you select each tab but I cannot swipe to go to next tab.
Each tab has listview which has its own activity.Only thing I want is to add swipe gesture to go to next tab.How do I do that? I really appreciate any help.Thanks in Advance.
public class AndroidTabAndListView extends TabActivity {
// TabSpec Names
private static final String INBOX_SPEC = "Inbox";
private static final String OUTBOX_SPEC = "Outbox";
private static final String PROFILE_SPEC = "Profile";
ViewPager pager;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
pager = (ViewPager) findViewById(R.id.pager);
TabHost tabHost = getTabHost();
// Inbox Tab
TabSpec inboxSpec = tabHost.newTabSpec(INBOX_SPEC);
// Tab Icon
inboxSpec.setIndicator(INBOX_SPEC, getResources().getDrawable(R.drawable.icon_inbox));
Intent inboxIntent = new Intent(this, InboxActivity.class);
// Tab Content
inboxSpec.setContent(inboxIntent);
// Outbox Tab
TabSpec outboxSpec = tabHost.newTabSpec(OUTBOX_SPEC);
outboxSpec.setIndicator(OUTBOX_SPEC, getResources().getDrawable(R.drawable.icon_outbox));
Intent outboxIntent = new Intent(this, OutboxActivity.class);
outboxSpec.setContent(outboxIntent);
// Profile Tab
TabSpec profileSpec = tabHost.newTabSpec(PROFILE_SPEC);
profileSpec.setIndicator(PROFILE_SPEC, getResources().getDrawable(R.drawable.icon_profile));
Intent profileIntent = new Intent(this, ProfileActivity.class);
profileSpec.setContent(profileIntent);
// Adding all TabSpec to TabHost
tabHost.addTab(inboxSpec); // Adding Inbox tab
tabHost.addTab(outboxSpec); // Adding Outbox tab
tabHost.addTab(profileSpec); // Adding Profile tab
}
}
xml
<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="409dp"
android:orientation="vertical" >
<TabWidget
android:id="#android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
</LinearLayout>
</TabHost>
Allright I see that you are not using the ViewPager in the xml. Because I have not tried it the way you are doin it, I recommend it will be a lot easier if you do it like the following examples:
Creating Swipe Views with Tabs
Android Tab Layout with Swipeable Views
Still not useful then you can read this
Hope it Helps you. Cheers :)
Use fragments for inner pages.
Create a class that extends FragmentPagerAdapter for tab buttons.
Example :
activity_main.xml
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
AndroidTabAndListView.java
public class AndroidTabAndListView extends FragmentActivity implements ActionBar.TabListener {
TabSpecNames mAppSectionsPagerAdapter;
ViewPager mViewPager;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Create the adapter that will return a fragment for each of the three primary sections
// of the app.
mAppSectionsPagerAdapter = new TabSpecNames(getSupportFragmentManager());
// Set up the action bar.
final ActionBar actionBar = getActionBar();
// Specify that the Home/Up button should not be enabled, since there is no hierarchical
// parent.
actionBar.setHomeButtonEnabled(false);
// Specify that we will be displaying tabs in the action bar.
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Set up the ViewPager, attaching the adapter and setting up a listener for when the
// user swipes between sections.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mAppSectionsPagerAdapter);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// When swiping between different app sections, select the corresponding tab.
// We can also use ActionBar.Tab#select() to do this if we have a reference to the
// Tab.
actionBar.setSelectedNavigationItem(position);
}
});
// For each of the sections in the app, add a tab to the action bar.
for (int i = 0; i < mAppSectionsPagerAdapter.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(mAppSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
// When the given tab is selected, switch to the corresponding page in the ViewPager.
mViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
public static class TabSpecNames extends FragmentPagerAdapter {
public TabSpecNames(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
switch (i) {
case 0:
return new InboxFragment();
case 1:
return new OutboxFragment();
case 2:
return new ProfileFragment();
default:
break;
}
return null;
}
#Override
public int getCount() {
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
String sections[] = {"Inbox", "Outbox", "Profile"};
return sections[position];
}
}
}
fragment_inbox.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/tv1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Inbox (99)"/>
</LinearLayout>
InboxFragment.java
public class InboxFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.fragment_inbox,
container, false);
return rootView;
}
}
I've been trying to create a simple Horizontal scrolling option.
I have 2 ListFragments, which I would like to scroll between.
I'm getting a "Source Not Found" error when returning the View from onCreateView function.
This is my MainActivity Class:
public class MainActivity extends FragmentActivity implements ActionBar.TabListener {
AppSectionsPagerAdapter mAppSectionsPagerAdapter;
ViewPager mViewPager;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAppSectionsPagerAdapter = new AppSectionsPagerAdapter(getSupportFragmentManager());
final ActionBar actionBar = getActionBar();
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mAppSectionsPagerAdapter);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
for (int i = 0; i < mAppSectionsPagerAdapter.getCount(); i++) {
actionBar.addTab(
actionBar.newTab()
.setText(mAppSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
}
#Override
public void onTabUnselected(ActionBar.Tab tab, android.app.FragmentTransaction fragmentTransaction) {
}
#Override
public void onTabSelected(ActionBar.Tab tab, android.app.FragmentTransaction fragmentTransaction) {
// When the given tab is selected, switch to the corresponding page in the ViewPager.
mViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabReselected(ActionBar.Tab tab, android.app.FragmentTransaction fragmentTransaction) {
}
public static class AppSectionsPagerAdapter extends FragmentPagerAdapter {
public AppSectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
Fragment a;
#Override
public Fragment getItem(int i) {
switch (i) {
case 0:
return new FragmentA();
default:
return new FragmentB();
}
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
return "Section " + (position + 1);
}
}
}
This is one of my ListFragment class (the second is the same but different name & layout file):
public class FragmentA extends ListFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.favorites_layout, container, false);
updateStationsView(0);
return rootView;
}
}
updateStationView is a function that populates the List. removing it did not help, so I figured it's harmless.
The error is thrown right after the:
return rootView;
which returns to the onCreate functions of MainActivity.
When I'm changing the ListFragment to be a simple Fragment it works. I think I'm lacking some knowledge to figure this one out. I really want to use ListFragment...
Can someone please try an help ?
Many thanks for your efforts.
Adding the XML files:
activity_main.xml:
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
favorites_layout.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:id="#+id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
I im quite sure the issue is that your custom layout for the ListFragment does not contain a ListView. These lines of code are causing the error because you need to have a ListView inside your "favourites_layout" .xml file.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.favorites_layout, container, false);
updateStationsView(0);
return rootView;
}
ListFragment has a default layout that consists of a single list view.
However, if you desire, you can customize the fragment layout by
returning your own view hierarchy from onCreateView(LayoutInflater,
ViewGroup, Bundle). To do this, your view hierarchy must contain a
ListView object with the id "#android:id/list" (or list if it's in
code)
So your layout could for example look like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
See here for more:
http://developer.android.com/reference/android/app/ListFragment.html
Hello!
I've been programming for a long time but just started developing for android, which seems to be quite different from c++ to say at least...
Anyway, I'm trying to implement a gui with some tabs, that should be able to change tab on swipe left/right. The tabs are implemented with actionbar (or ActionBarSherlock to be precise), the swiping with ViewPager from the support lib. The individual tabs are fragments (SherlockFragment:s that is). At the bottom there should be a statusbar of some kind just displaying some text.
The problem I'm having is that the tabs are never shown. I see the actionbar on top with logo/title, with a tab list under it. At the bottom of the screen I see the statusbar-text, but nothing else.
If I uncomment the line //context.setContentView(pager); in SwipeBar() constructor, the content of the tabs are shown, but then the statusbar is not shown. (This line feels really wrong to have here anyway but I can't figure out how to get some content in my tabs without it.)
I've tried everything I can think of. I've read everything I could find about it and tried allot of different examples on how to do each functionality by itself. But combining them... I just can't get this to work. I'd really appreciate your help!
My main (activity) class:
Main.java
public class Main extends SherlockFragmentActivity {
private SwipeBar tabs;
#Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tabs = new SwipeBar(this, R.id.pager);
tabs.add(One.class, "one", null);
tabs.add(Two.class, "two", null);
tabs.add(Three.class, "three", null);
}
}
This is my class that implements actionbar/viewpager/fragments:
SwipeBar.java
public class SwipeBar extends FragmentPagerAdapter implements OnPageChangeListener,
TabListener {
private final ActionBar bar;
private final SherlockFragmentActivity ctx;
private final ViewPager pager;
private final ArrayList<TabInfo> tabs;
public SwipeBar(final SherlockFragmentActivity context, final int viewPagerId) {
super(context.getSupportFragmentManager());
bar = context.getSupportActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
pager = new ViewPager(context);
pager.setId(viewPagerId);
pager.setAdapter(this);
pager.setOnPageChangeListener(this);
ctx = context;
// context.setContentView(pager);
tabs = new ArrayList<TabInfo>();
}
public void add(final Class<?> clss, final int tabHeaderStringId, final Bundle args) {
final ActionBar.Tab tab = bar.newTab();
final TabInfo info = new TabInfo(clss, args);
tab.setTag(info);
tab.setText(tabHeaderStringId);
tab.setTabListener(this);
tabs.add(info);
bar.addTab(tab);
notifyDataSetChanged();
}
#Override
public int getCount() {
return tabs.size();
}
#Override
public Fragment getItem(final int pos) {
final TabInfo info = tabs.get(pos);
return Fragment.instantiate(ctx, info.clss().getName(), info.args());
}
public void onPageScrolled(final int arg0, final float arg1, final int arg2) {}
public void onPageScrollStateChanged(final int arg0) {}
public void onPageSelected(final int pos) {
bar.setSelectedNavigationItem(pos);
}
public void onTabReselected(final Tab tab, final FragmentTransaction ft) {}
public void onTabSelected(final Tab tab, final FragmentTransaction ft) {
final TabInfo tag = (TabInfo)tab.getTag();
for(int i = 0; i < tabs.size(); i++)
if(tabs.get(i) == tag) pager.setCurrentItem(i);
}
public void onTabUnselected(final Tab tab, final FragmentTransaction ft) {}
}
The main layout:
Main.xml
<LinearLayout 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:orientation="vertical" >
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0px">
</android.support.v4.view.ViewPager>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#33FF0000"
android:gravity="center"
android:layout_weight="0"
android:text="statusbar">
</TextView>
</LinearLayout>
And the code for the three pages:
One/Two/Three.xml/java
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/one"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="this is tab one" />
</LinearLayout>
public class One extends SherlockFragment {
#Override
public View onCreateView(final LayoutInflater inflater,
final ViewGroup container, final Bundle savedInstanceState) {
return (LinearLayout)inflater.inflate(R.layout.one, container, false);
}
}
Okay, I finally solved it. The above code came from trying to add ViewPager functionality to the tabs I had done. I started over and implemented a regular ViewPager (like in the various examples out there) and then added an ActionBar. The actual fragment content is now in the ViewPager and the ActionBar tabs is empty, but set through the ViewPager callbacks to indicate the current one.
I have still no clue what was wrong with the original attempt though...
I'm trying to set up a ViewPager with a number of layouts with 2 TextViews in each layout. I'm having trouble getting my TextViews to display properly when i run my app. My pager works fine but it's not displaying the Textviews i have in my XML layout.
Here's my code that I have in my PageAdapter
public class MyPageAdapter extends PagerAdapter {
public int getCount() {
return 31;
}
public Object instantiateItem(View collection, int position) {
LayoutInflater inflater = (LayoutInflater) collection.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
int resId = 0;
switch (position) {
case 0:
resId = R.layout.main_menu;
break;
case 1:
resId = R.layout.article1;
break;
case 2:
resId = R.layout.article2;
break;
....
....
View view = inflater.inflate(resId, null);
((ViewPager) collection).addView(view, 0);
return view;
This is what I have for my XML
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" android:background="#drawable/background" android:clickable="true"
android:id="#+id/layout13"
android:weightSum="0">
<TextView
android:id="#+id/textView01"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical|center_horizontal"
android:padding="12dp"
android:text="#string/article13"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#000000" />
<TextView
android:id="#+id/textView02"
android:layout_width="match_parent"
android:layout_height="302dp"
android:gravity="center_vertical|center_horizontal"
android:text="#string/body13"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#000000" />
<android.support.v4.view.ViewPager
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#id/viewPager" >
</android.support.v4.view.ViewPager>
</LinearLayout>
I've tried Moving the around in my XML layout to right underneath my LinearLayout and i get the full screen but all my text disappears. It's probably something simple i'm missing but any help on this would be greatly appreciated!
You only need one ViewPager. My app has 9 fragments and one activity. The viewpager is declared once in main.xml. Here's what the important code looks like:
public class Polling extends SherlockFragmentActivity implements OnMenuItemClickListener {
private ViewPager mViewPager;
private TabsAdapter mTabsAdapter;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mViewPager = new ViewPager(this);
mViewPager.setId(R.id.pager);
setContentView(mViewPager);
//here's the code that makes a tab, adds it to the actionbar, adds a tabadapter, and coordinates the viewpager:
bar = getSupportActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayShowTitleEnabled(false);
bar.setDisplayShowHomeEnabled(false);
mTabsAdapter = new TabsAdapter(this, mViewPager);
mTabsAdapter.addTab(bar.newTab().setText(R.string.login),
LoginFragment.class, null);
mTabsAdapter.addTab(bar.newTab().setText(R.string.economics),
EconFragment.class, null);
So that's my main class. You'll lose I never actually directly employ the entire main.xml: the Content View gets set to the ViewPager rather than a layout. Then, inside my main activity, I have an inner class that handles the ViewPager going left/right, as well as the management of my actionBar tabs. But it doesn't sound like you are using tabs, so this next bit of code may not be that helpful:
public static class TabsAdapter extends FragmentPagerAdapter
implements ActionBar.TabListener, ViewPager.OnPageChangeListener {
private final Context mContext;
private final ActionBar mActionBar;
private final ViewPager mViewPager;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
static final class TabInfo {
private final Class<?> clss;
private final Bundle args;
TabInfo(Class<?> _class, Bundle _args) {
clss = _class;
args = _args;
}
}
public TabsAdapter(SherlockFragmentActivity activity, ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mActionBar = activity.getSupportActionBar();
mViewPager = pager;
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
TabInfo info = new TabInfo(clss, args);
tab.setTag(info);
tab.setTabListener(this);
mTabs.add(info);
mActionBar.addTab(tab);
notifyDataSetChanged();
}
public int getCount() {
return mTabs.size();
}
public SherlockFragment getItem(int position) {
TabInfo info = mTabs.get(position);
return (SherlockFragment)Fragment.instantiate(mContext, info.clss.getName(), info.args);
}
public void onPageSelected(int position) {
mActionBar.setSelectedNavigationItem(position);
}
public void onPageScrollStateChanged(int state) {}
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
mViewPager.setCurrentItem(tab.getPosition());
//Log.v(TAG, "clicked");
Object tag = tab.getTag();
for (int i=0; i<mTabs.size(); i++) {
if (mTabs.get(i) == tag) {
mViewPager.setCurrentItem(i);
}
}
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {}
public void onTabReselected(Tab tab, FragmentTransaction ft) {}
public void onTabReselected(Tab tab, android.app.FragmentTransaction ft) {}
public void onTabUnselected(Tab tab, android.app.FragmentTransaction ft) {}
}
}
I would try placing your ViewPager above the textViews, nested directly beneath the LinearLayout. I'm sorry I can't be of more help than that - my experience with ViewPager has been alongside a TabAdapter/actionBar tabs.
Here's the code to my Pager:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
All of the rest of my interface comes from other tabs, so this is the entirety of my main.xml. Basically I'm posting this to say that I've got my viewpager as the sole child widget inside a linear layout, and it manages the whole screen.