I'm setting up a little application, which requires a tab layout. I've implemented everything with fragments and everything is working very well, the only thing I really cant figure out is the background of the selected tab: here is what I did:
I've started from "tab and pager" ActionBarSherlock's samples. I had put the tabs in an Horizontal scrollview, and created in the drawable folder the following selector called tab_bg_selector :
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Active tab -->
<item android:state_selected="true" android:state_focused="false"
android:state_pressed="false" android:drawable="#drawable/tab_selected" />
<!-- Inactive tab -->
<item android:state_selected="false" android:state_focused="false"
android:state_pressed="false" android:drawable="#drawable/tab_deselected" />
<!-- Pressed tab -->
<item android:state_pressed="true" android:drawable="#android:color/transparent" />
<!-- Selected tab (using d-pad) -->
<item android:state_focused="true" android:state_selected="true"
android:state_pressed="false" android:drawable="#android:color/transparent" />
</selector>
and the tabs are being added in this way
mTabsAdapter.addTab(getTabSpec(STEPS.STEP1_MATERIAL, "firstTab"), FirstTab.class, null);
where mTabsAdapter is a class extending FragmentPagerAdapter (created by the example's developer, below to all there is the code for the sake of completeness) and getTabSpec is
public TabSpec getTabSpec(String tag, String title) {
View tabview;
TabSpec ts;
tabview = createTabView(mTabHost.getContext(), title);
ts = this.mTabHost.newTabSpec(tag).setIndicator(tabview).setContent(new TabContentFactory() {
public View createTabContent(String tag) {
return new TextView(getApplicationContext());
}
});
return ts;
}
and createTabView is
private View createTabView(final Context context, final String text) {
View view = LayoutInflater.from(context).inflate(R.layout.tabs_bg, null);
TextView tv = (TextView) view.findViewById(R.id.tabsText);
tv.setText(text);
return view;
}
R.layout.tabs_bg is
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/tabsLayout" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:background="#drawable/tab_bg_selector"
android:padding="10dip" android:gravity="center" android:orientation="vertical">
<TextView android:id="#+id/tabsText" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Title"
android:textSize="15dip" android:textColor="#drawable/tab_text_selector" />
</LinearLayout>
tab_text_selector is this
this is the class of which mTabAdapter is an instance
/**
* This is a helper class that implements the management of tabs and all
* details of connecting a ViewPager with associated TabHost. It relies on a
* trick. Normally a tab host has a simple API for supplying a View or
* Intent that each tab will show. This is not sufficient for switching
* between pages. So instead we make the content part of the tab host
* 0dp high (it is not shown) and the TabsAdapter supplies its own dummy
* view to show as the tab content. It listens to changes in tabs, and takes
* care of switch to the correct paged in the ViewPager whenever the selected
* tab changes.
*/
public class TabsAdapter extends FragmentPagerAdapter implements TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener {
private final Context mContext;
private final TabHost mTabHost;
private final ViewPager mViewPager;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
private TabInfo mLastTab = null;
final class TabInfo {
public final String tag;
public final Class<?> clss;
public final Bundle args;
public Fragment fragment;
TabInfo(String _tag, Class<?> _class, Bundle _args) {
tag = _tag;
clss = _class;
args = _args;
}
}
class TabFactory implements TabHost.TabContentFactory {
private final Context mContext;
public TabFactory(Context context) {
mContext = context;
}
#Override
public View createTabContent(String tag) {
View v = new View(mContext);
v.setMinimumWidth(0);
v.setMinimumHeight(0);
return v;
}
}
public TabsAdapter(FragmentActivity activity, TabHost tabHost, ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mTabHost = tabHost;
mViewPager = pager;
mTabHost.setOnTabChangedListener(this);
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args) {
tabSpec.setContent(new TabFactory(mContext));
String tag = tabSpec.getTag();
TabInfo info = new TabInfo(tag, clss, args);
info.fragment = getSupportFragmentManager().findFragmentByTag(tag);
mTabs.add(info);
mTabHost.addTab(tabSpec);
notifyDataSetChanged();
}
#Override
public int getCount() {
return mTabs.size();
}
#Override
public Fragment getItem(int position) {
TabInfo info = mTabs.get(position);
return Fragment.instantiate(mContext, info.clss.getName(), info.args);
}
#Override
public void onTabChanged(String tabId) {
int position = mTabHost.getCurrentTab();
mViewPager.setCurrentItem(position);
try {
TabInfo newTab = (TabInfo) mTabs.get(position);// this.mapTabInfo.get(tag);
if (mLastTab != newTab) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
if (mLastTab != null) {
if (mLastTab.fragment != null) {
ft.detach(mLastTab.fragment);
}
}
if (newTab != null) {
if (newTab.fragment == null) {
newTab.fragment = Fragment.instantiate(TabFragment.this, newTab.clss.getName(), newTab.args);
ft.add(android.R.id.tabcontent, newTab.fragment, newTab.tag);
} else {
ft.attach(newTab.fragment);
}
}
mLastTab = newTab;
ft.commit();
getSupportFragmentManager().executePendingTransactions();
}
} catch (Exception e) {
LogHelper.WriteLogError("error in onTabChanged function", e);
}
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
// Unfortunately when TabHost changes the current tab, it kindly
// also takes care of putting focus on it when not in touch mode.
// The jerk.
// This hack tries to prevent this from pulling focus out of our
// ViewPager.
// TabWidget widget = mTabHost.getTabWidget();
// int oldFocusability = widget.getDescendantFocusability();
// widget.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
mTabHost.setCurrentTab(position);
// mTabHost.getTabWidget().focusCurrentTab(position);
// widget.setDescendantFocusability(oldFocusability);
}
#Override
public void onPageScrollStateChanged(int state) {
}
}
Ok, after all this code here is the problem:
the selector for the non selected tabs works fine (except for the textColor which is white instead of being black), but when I select a tab the tab becomes completly black, I i click again on the tab everything is displayed correctly. here is an image to explain better the problem
I really can't figure out what's the problem, I hope someone can helo me
thanks
EDIT: I found the problem: during the initialization of tab layout, i had put all tabs to be focusable in touch mode, because when by code I need to show a tab that is not visible (the tabs can be a lot) using
mTabHost.getTabWidget().focusCurrentTab(position)
which do not work if I do not set tabs to be focusable in touch mode.
I can solve this?
thanks
Related
I am using FragmentTabHost in my app. It is working perfectly well. I have two tabs, which are opened by clicking on the top. Now, I want to add swipe feature in this. I am wondering whether I should use a different approach for the same.
MainActivity:
package com.example.shiza.callhistorycontrol;
import android.os.Bundle;
import android.support.v4.app.FragmentTabHost;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
public class MainActivity extends AppCompatActivity {
private FragmentTabHost mTabHost;
Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Setting up a toolbar for the navigation purpose.
toolbar = (Toolbar)findViewById(R.id.app_bar);
toolbar.setTitle(" Call History Control");
toolbar.setLogo(R.mipmap.ic_launcher);
setSupportActionBar(toolbar);
// The fragments management is done here
mTabHost = (FragmentTabHost)findViewById(android.R.id.tabhost);
mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);
mTabHost.addTab(mTabHost.newTabSpec("simple").setIndicator("HOME"),
Home.class, null);
mTabHost.addTab(mTabHost.newTabSpec("contacts").setIndicator("ABOUT APP"),
Home.class, null);
}
}
main xml:
<android.support.v4.app.FragmentTabHost
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- the app bar customized-->
<include
android:id="#+id/app_bar"
layout="#layout/app_bar"
/>
<TabWidget
android:id="#android:id/tabs"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"/>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0"/>
<FrameLayout
android:id="#+id/realtabcontent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
</LinearLayout>
<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="wrap_content"/>
</android.support.v4.app.FragmentTabHost>
Please provide me any links or any suggestions?
Here is an example that I wrote creates TabHost with swipe feature:
First the main fragment that holds the adapter and add tabs with (two childes fragments).
public class MyFragment extends Fragment
{
private TabHost mTabHost;
private ViewPager mViewPager;
private TabsAdapter mTabsAdapter;
public MyFragment() {
}
#Override
public void onCreate(Bundle instance)
{
super.onCreate(instance);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_main, container, false);
mTabHost = (TabHost) v.findViewById(android.R.id.tabhost);
mTabHost.setup();
mViewPager = (ViewPager) v.findViewById(R.id.pager);
mTabsAdapter = new TabsAdapter(getActivity(), mTabHost, mViewPager);
// Here we load the content for each tab.
mTabsAdapter.addTab(mTabHost.newTabSpec("simple").setIndicator("HOME"), FirstPage.class, null);
mTabsAdapter.addTab(mTabHost.newTabSpec("simple").setIndicator("HOME"), SecondPage.class, null);
return v;
}
#Override
public void onResume() {
super.onResume();
}
public static class TabsAdapter extends FragmentStatePagerAdapter implements TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener
{
private final Context mContext;
private final TabHost mTabHost;
private final ViewPager mViewPager;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
static final class TabInfo
{
private final String tag;
private final Class<?> clss;
private final Bundle args;
TabInfo(String _tag, Class<?> _class, Bundle _args)
{
tag = _tag;
clss = _class;
args = _args;
}
}
static class DummyTabFactory implements TabHost.TabContentFactory
{
private final Context mContext;
public DummyTabFactory(Context context)
{
mContext = context;
}
public View createTabContent(String tag)
{
View v = new View(mContext);
v.setMinimumWidth(0);
v.setMinimumHeight(0);
return v;
}
}
public TabsAdapter(FragmentActivity activity, TabHost tabHost, ViewPager pager)
{
super(activity.getSupportFragmentManager());
mContext = activity;
mTabHost = tabHost;
mViewPager = pager;
mTabHost.setOnTabChangedListener(this);
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args)
{
tabSpec.setContent(new DummyTabFactory(mContext));
String tag = tabSpec.getTag();
TabInfo info = new TabInfo(tag, clss, args);
mTabs.add(info);
mTabHost.addTab(tabSpec);
notifyDataSetChanged();
}
#Override
public int getCount()
{
return mTabs.size();
}
#Override
public Fragment getItem(int position)
{
TabInfo info = mTabs.get(position);
return Fragment.instantiate(mContext, info.clss.getName(), info.args);
}
public void onTabChanged(String tabId)
{
int position = mTabHost.getCurrentTab();
mViewPager.setCurrentItem(position);
}
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
{
}
public void onPageSelected(int position)
{
// Unfortunately when TabHost changes the current tab, it kindly
// also takes care of putting focus on it when not in touch mode.
// The jerk.
// This hack tries to prevent this from pulling focus out of our
// ViewPager.
TabWidget widget = mTabHost.getTabWidget();
int oldFocusability = widget.getDescendantFocusability();
widget.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
mTabHost.setCurrentTab(position);
widget.setDescendantFocusability(oldFocusability);
}
public void onPageScrollStateChanged(int state)
{
}
}
Then create another two fragments that represent each tab and call them:
FirstPage
SecondPage
link those to xml files, call new MyFragment and you are good to go.
So I'm trying to create a layout such that I would have a viewpager w/tabs at the top of the page, with a couple of static buttons at the bottom that do not move when I swipe across tabs. Seem to have hit a roadblock though, my fragments don't load and I lose swiping capability when I implement the following code. I'm new to Actionbarsherlock, not sure what the problem is, would appreciate any help. Thanks!
The java:
public class Main extends SherlockFragmentActivity {
ViewPager mViewPager;
TabsAdapter mTabsAdapter;
TextView tabCenter;
TextView tabText;
Menu menu;
SubMenu subMenu1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mViewPager = new ViewPager(this);
mViewPager.setId(R.id.pager);
ActionBar bar = getSupportActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
mTabsAdapter = new TabsAdapter(this, mViewPager);
mTabsAdapter
.addTab(bar.newTab().setText("Tab 1"), Fragment1.class, null);
mTabsAdapter.addTab(bar.newTab().setText("Tab 2"), Fragment2.class,
null);
mTabsAdapter.addTab(bar.newTab().setText("Tab 3"), Fragment3.class,
null);
}
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();
}
#Override
public int getCount() {
return mTabs.size();
}
#Override
public Fragment getItem(int position) {
TabInfo info = mTabs.get(position);
return Fragment.instantiate(mContext, info.clss.getName(),
info.args);
}
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
}
public void onPageSelected(int position) {
mActionBar.setSelectedNavigationItem(position);
}
public void onPageScrollStateChanged(int state) {
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
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) {
}
}
}
The 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:gravity="center_horizontal"
android:orientation="vertical"
android:padding="4dip" >
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1" >
</android.support.v4.view.ViewPager>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:gravity="center"
android:measureWithLargestChild="true"
android:orientation="horizontal" >
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Example" >
</Button>
</LinearLayout>
</LinearLayout>
Check out the below links. Here defined the ways to implement the functionality which you need.
1) Link 1
2) Link 2
3) Link 3
4) Link 4
5) Link 5
I hope it will help you.
I have the following class (largely taken from the support api samples)
public class MyActivity extends FragmentActivity {
TabHost mTabHost;
TabManager mTabManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_tabs);
mTabHost = (TabHost)findViewById(android.R.id.tabhost);
mTabHost.setup();
mTabManager = new TabManager(this, mTabHost, R.id.realtabcontent);
mTabManager.addTab(mTabHost.newTabSpec("searchandpromoted").setIndicator("Search and\npromoted ads"),
FragmentStackSupport.CountingFragment.class, null);
mTabManager.addTab(mTabHost.newTabSpec("searchengine").setIndicator("Search engine"),
FragmentStackSupport.CursorLoaderListFragment.class, null);
mTabManager.addTab(mTabHost.newTabSpec("manualinput").setIndicator("Manual input"),
FragmentStackSupport.CountingFragment.class, null);
mTabManager.addTab(mTabHost.newTabSpec("sendcartofriend").setIndicator("Send car\nto friend"),
FragmentStackSupport.CountingFragment.class, null);
if (savedInstanceState != null) {
mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab"));
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("tab", mTabHost.getCurrentTabTag());
}
/**
* This is a helper class that implements a generic mechanism for
* associating fragments with the tabs in a tab host. It relies on a
* trick. Normally a tab host has a simple API for supplying a View or
* Intent that each tab will show. This is not sufficient for switching
* between fragments. So instead we make the content part of the tab host
* 0dp high (it is not shown) and the TabManager supplies its own dummy
* view to show as the tab content. It listens to changes in tabs, and takes
* care of switch to the correct fragment shown in a separate content area
* whenever the selected tab changes.
*/
public static class TabManager implements TabHost.OnTabChangeListener {
private final FragmentActivity mActivity;
private final TabHost mTabHost;
private final int mContainerId;
private final HashMap<String, TabInfo> mTabs = new HashMap<String, TabInfo>();
TabInfo mLastTab;
static final class TabInfo {
private final String tag;
private final Class<?> clss;
private final Bundle args;
private Fragment fragment;
TabInfo(String _tag, Class<?> _class, Bundle _args) {
tag = _tag;
clss = _class;
args = _args;
}
}
static class DummyTabFactory implements TabHost.TabContentFactory {
private final Context mContext;
public DummyTabFactory(Context context) {
mContext = context;
}
#Override
public View createTabContent(String tag) {
View v = new View(mContext);
v.setMinimumWidth(0);
v.setMinimumHeight(0);
return v;
}
}
public TabManager(FragmentActivity activity, TabHost tabHost, int containerId) {
mActivity = activity;
mTabHost = tabHost;
mContainerId = containerId;
mTabHost.setOnTabChangedListener(this);
}
public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args) {
tabSpec.setContent(new DummyTabFactory(mActivity));
String tag = tabSpec.getTag();
TabInfo info = new TabInfo(tag, clss, args);
// Check to see if we already have a fragment for this tab, probably
// from a previously saved state. If so, deactivate it, because our
// initial state is that a tab isn't shown.
info.fragment = mActivity.getSupportFragmentManager().findFragmentByTag(tag);
if (info.fragment != null && !info.fragment.isDetached()) {
FragmentTransaction ft = mActivity.getSupportFragmentManager().beginTransaction();
ft.detach(info.fragment);
ft.commit();
}
mTabs.put(tag, info);
mTabHost.addTab(tabSpec);
}
#Override
public void onTabChanged(String tabId) {
TabInfo newTab = mTabs.get(tabId);
if (mLastTab != newTab) {
FragmentTransaction ft = mActivity.getSupportFragmentManager().beginTransaction();
if (mLastTab != null) {
if (mLastTab.fragment != null) {
ft.detach(mLastTab.fragment);
}
}
if (newTab != null) {
if (newTab.fragment == null) {
newTab.fragment = Fragment.instantiate(mActivity, newTab.clss.getName(), newTab.args);
ft.add(mContainerId, newTab.fragment, newTab.tag);
} else {
ft.attach(newTab.fragment);
}
}
mLastTab = newTab;
ft.commit();
mActivity.getSupportFragmentManager().executePendingTransactions();
}
}
}
}
fragment_tabs.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="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TabWidget
android:id="#android:id/tabs"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"/>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0"/>
<FrameLayout
android:id="#+android:id/realtabcontent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
</LinearLayout>
</TabHost>
How to display the text shown on the tabs themselves on multiple lines, e.g.
"Search
and
foo"?
android:lines="5"
or
android:inputType="textMultiLine"in XML could work
Also you can try setSingleLine(false); in the javaCode
I am following this link to do a ViewPager http://blog.stylingandroid.com/archives/537
I managed to get the various pages out. But how do I populate or fill these pages with buttons?
instantiateItem()
This creates the view for a given position. For a
real application we would use a Fragment here, or inflate a layout,
but to keep the example simple we create a TextView, set the text to
the correct value from our titles array, and add it to the ViewPager
I want to have different button functions on different pages. How do I go about doing this? By using different layout? How do I put the layout within the page (is this what you call inflat)?
EDIT:
I have the main.xml which consists of the ViewPager
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:weightSum="1">
<com.viewpagerindicator.TitlePageIndicator
android:id="#+id/indicator"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
I have several other xml which consists of buttons which I want to inflate it into the different pages of the ViewPage. Example of an 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" >
<Button android:layout_width="match_parent" android:text="Button 1" android:onClick="onClick" android:id="#+id/button1" android:layout_height="100dp"></Button>
<Button android:text="Button 2" android:onClick="onClick" android:id="#+id/button2" android:layout_width="match_parent" android:layout_height="100dp"></Button>
<Button android:text="Button 3" android:onClick="onClick" android:id="#+id/button3" android:layout_width="match_parent" android:layout_height="100dp"></Button>
<Button android:text="Button 4" android:onClick="onClick" android:id="#+id/button4" android:layout_width="match_parent" android:layout_height="100dp"></Button>
<Button android:text="Button 5" android:onClick="onClick" android:id="#+id/button5" android:layout_height="match_parent" android:layout_width="match_parent"></Button>
</LinearLayout>
In the ViewPagerAdapter.java, I managed to inflate the various XML into the pages.
#Override
public Object instantiateItem( View pager, int position )
{
//Inflate the correct layout
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//layouts[] is an int[] that points to resources such as R.layout.start_page
View inflatedView = layoutInflater.inflate(layouts[position], null);
((ViewPager)pager).addView(inflatedView,0);
return inflatedView;
}
And this needs to be changed to prevent error.
#Override
public void destroyItem( View pager, int position, Object view )
{
((ViewPager)pager).removeView( (View)view );
}
Now, I have multiple buttons on different pages. How do I programme the ONCLICK function of the different buttons on the different pages? Can this work?
public void onClick(View v) {
switch (v.getId()) {
case R.id.button1:
// do something
break;
case R.id.button2:
// do something
break;
case R.id.button3:
// do something
break;
case R.id.button4:
// do something
break;
case R.id.button5:
// do something
break;
}
}
Here is an example of inflating/programmatically adding views with buttons:
#Override
//Instantiate items based on corresponding layout IDs that were passed in
public Object instantiateItem(View container, int position)
{
//Inflate the correct layout
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//layouts[] is an int[] that points to resources such as R.layout.start_page
View inflatedView = layoutInflater.inflate(layouts[position], null);
((ViewPager)container).addView(inflatedView,0);
//If you can't/don't want to have the above inflated layout include everything up front, you can add them now...
LinearLayout ll = (LinearLayout)inflatedView.findViewById(R.id.linearLayout1);
Button newButton = new Button(context);
newButton.setText(R.string.button_text);
ll.addView(newButton);
return inflatedView;
}
I recently set up a system with a ViewPager. I use actionbar tabs (with compatibility library), a TabAdapter and ViewPager. Each tab is its own fragment and added into the bar via the main activity. Here is some of the key code:
public class Polling extends FragmentActivity {
private ViewPager mViewPager;
private TabsAdapter mTabsAdapter;
private final static String TAG = "21st Polling:";
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mViewPager = new ViewPager(this);
mViewPager.setId(R.id.pager);
setContentView(mViewPager);
final ActionBar bar = getActionBar();
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);
mTabsAdapter.addTab(bar.newTab().setText(R.string.elections),
ElectionsFragment.class, null);
mTabsAdapter.addTab(bar.newTab().setText(R.string.politics),
PoliticsFragment.class, null);
mTabsAdapter.addTab(bar.newTab().setText(R.string.science),
ScienceFragment.class, null);
mTabsAdapter.addTab(bar.newTab().setText(R.string.finance),
FinanceFragment.class, null);
mTabsAdapter.addTab(bar.newTab().setText(R.string.religion),
ReligionFragment.class, null);
mTabsAdapter.addTab(bar.newTab().setText(R.string.military),
MilitaryFragment.class, null);
mTabsAdapter.addTab(bar.newTab().setText(R.string.international),
InternationalFragment.class, null);
}
And the adapter:
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(FragmentActivity activity, ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mActionBar = activity.getActionBar();
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 Fragment getItem(int position) {
TabInfo info = mTabs.get(position);
return Fragment.instantiate(mContext, info.clss.getName(), info.args);
}
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
public void onPageSelected(int position) {
mActionBar.setSelectedNavigationItem(position);
}
public void onPageScrollStateChanged(int state) {
}
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) {}
#Override
public void onTabSelected(Tab tab, android.app.FragmentTransaction ft) {
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, android.app.FragmentTransaction ft) {}
}
And here's a class that makes buttons and widgets on each tab:
public class EconFragment extends SherlockFragment {
Polling activity;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
activity = (Polling)getActivity();
View v = inflater.inflate(R.layout.categoryfragment, container, false);
this.mainLayout = v;
return v;
}
So long as you edit the XML file that is inflated in the above code (categoryfragment.xml), each tab will load whatever you want to put on the page (TextView, Button, etc).
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.