I have a little problem with my tabs, I have a Fragment extended class which has a Tabhost. In the tabs I want to show another fragments and at the same time use the ViewPager to change from one fragment to another.
My problem is that the tabhost is not showing anything, but if I do a println of the content that is suposse to be showing I get the correct information.
I don't know what else to do.
Here is my code for the class with the tabhost:
public class PerfilEstructuraFragment extends Fragment implements TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener {
private ImageView imvFotoPerfil;
private static Context cd;
private static Resources res;
private TabHost mTabHost;
private ViewPager mViewPager;
private HashMap<String, TabInfo> mapTabInfo = new HashMap<String, PerfilEstructuraFragment.TabInfo>();
private PagerAdapter mPagerAdapter;
/**
*
* #author
* Maintains extrinsic info of a tab's construct
*/
private class TabInfo {
private String tag;
private Class<?> clss;
private Bundle args;
private Fragment fragment;
TabInfo(String tag, Class<?> clazz, Bundle args) {
this.tag = tag;
this.clss = clazz;
this.args = args;
}
}
/**
* A simple factory that returns dummy views to the Tabhost
* #author
*/
class TabFactory implements TabContentFactory {
private final Context mContext;
/**
* #param context
*/
public TabFactory(Context context) {
mContext = context;
}
/** (non-Javadoc)
* #see android.widget.TabHost.TabContentFactory#createTabContent(java.lang.String)
*/
public View createTabContent(String tag) {
View v = new View(mContext);
v.setMinimumWidth(0);
v.setMinimumHeight(0);
return v;
}
}
/** (non-Javadoc)
* #see android.support.v4.app.FragmentActivity#onCreate(android.os.Bundle)
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Inflate the layout
setContentView(R.layout.activity_perfil_estructura);
// Initialise the TabHost
this.initialiseTabHost(savedInstanceState);
if (savedInstanceState != null) {
mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab")); //set the tab as per the saved state
}
// Intialise ViewPager
this.intialiseViewPager();
}*/
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.activity_perfil_estructura, container, false);
cd = getActivity();
res = getResources();
// Restore preferences
SharedPreferences settings = cd.getSharedPreferences(Config.getPreferencias(), 0);
String idUsuario = settings.getString(Config.getIdVisitante(), null);
//Si el identificador del usuario en nulo eso significara que no estamos visitanto el perfil de nadie, ergo, estamos visitando el nuestro
//Si por algun motivo no ha podido conseguir a ID del usuario, no cargamos nada
if(idUsuario==null){
return rootView;
}
imvFotoPerfil = (ImageView) rootView.findViewById(R.id.imvFotoPerfil);
imvFotoPerfil.setTag(Amigo.dummyFriends().get(Integer.parseInt(idUsuario)).getFotoPerfil());
DownloadImageTask img = new DownloadImageTask();
img.descargarImagen(imvFotoPerfil);
this.initialiseTabHost(savedInstanceState, rootView);
if (savedInstanceState != null) {
mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab")); //set the tab as per the saved state
}
else{
mTabHost.setCurrentTab(0);
}
// Intialise ViewPager
this.intialiseViewPager(rootView);
return rootView;
}
/** (non-Javadoc)
* #see android.support.v4.app.FragmentActivity#onSaveInstanceState(android.os.Bundle)
protected void onSaveInstanceState(Bundle outState) {
outState.putString("tab", mTabHost.getCurrentTabTag()); //save the tab selected
super.onSaveInstanceState(outState);
}*/
/**
* Initialise ViewPager
*/
private void intialiseViewPager(View rootView) {
List<Fragment> fragments = new Vector<Fragment>();
fragments.add(Fragment.instantiate(cd, PerfilInformacionFragment.class.getName()));
fragments.add(Fragment.instantiate(cd, PerfilInformacionFragment.class.getName()));
fragments.add(Fragment.instantiate(cd, PerfilInformacionFragment.class.getName()));
fragments.add(Fragment.instantiate(cd, PefilListaAlbumesFragment.class.getName()));
fragments.add(Fragment.instantiate(cd, PerfilInformacionFragment.class.getName()));
this.mPagerAdapter = new PagerAdapter(super.getFragmentManager(), fragments);
//this.mPagerAdapter = new PagerAdapter(super.getSupportFragmentManager(), fragments);
//
this.mViewPager = (ViewPager)rootView.findViewById(R.id.viewpager);
this.mViewPager.setAdapter(this.mPagerAdapter);
this.mViewPager.setOnPageChangeListener(this);
}
/**
* Initialise the Tab Host
*/
private void initialiseTabHost(Bundle args, View rootView) {
mTabHost = (TabHost)rootView.findViewById(android.R.id.tabhost);
/*LocalActivityManager mLocalActivityManager = new LocalActivityManager((Activity) cd, false);
mLocalActivityManager.dispatchCreate(args);
mTabHost.setup(mLocalActivityManager);
*/
mTabHost.setup();
TabInfo tabInfo = null;
PerfilEstructuraFragment.AddTab(this, this.mTabHost,
this.mTabHost.newTabSpec("Tab1").setIndicator(res.getText(R.string.tab_infomacionGeneral)),
( tabInfo = new TabInfo("Tab1", PerfilInformacionFragment.class, args)));
this.mapTabInfo.put(tabInfo.tag, tabInfo);
PerfilEstructuraFragment.AddTab(this, this.mTabHost,
this.mTabHost.newTabSpec("Tab2").setIndicator(res.getText(R.string.tab_actividades), res.getDrawable(R.drawable.ic_user_perfil)),
( tabInfo = new TabInfo("Tab2", PerfilInformacionFragment.class, args)));
this.mapTabInfo.put(tabInfo.tag, tabInfo);
PerfilEstructuraFragment.AddTab(this, this.mTabHost,
this.mTabHost.newTabSpec("Tab3").setIndicator(res.getText(R.string.tab_amigos), res.getDrawable(R.drawable.ic_user_perfil)),
( tabInfo = new TabInfo("Tab3", PerfilInformacionFragment.class, args)));
this.mapTabInfo.put(tabInfo.tag, tabInfo);
PerfilEstructuraFragment.AddTab(this, this.mTabHost,
this.mTabHost.newTabSpec("Tab4").setIndicator(res.getText(R.string.tab_album), res.getDrawable(R.drawable.ic_user_perfil)),
( tabInfo = new TabInfo("Tab4", PefilListaAlbumesFragment.class, args)));
this.mapTabInfo.put(tabInfo.tag, tabInfo);
PerfilEstructuraFragment.AddTab(this, this.mTabHost,
this.mTabHost.newTabSpec("Tab5").setIndicator(res.getText(R.string.tab_tablon), res.getDrawable(R.drawable.ic_user_perfil)),
( tabInfo = new TabInfo("Tab5", PerfilInformacionFragment.class, args)));
this.mapTabInfo.put(tabInfo.tag, tabInfo);
//PerfilEstructuraFragment.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab3").setIndicator("Tab 3"), ( tabInfo = new TabInfo("Tab3", Tab3Fragment.class, args)));
//this.mapTabInfo.put(tabInfo.tag, tabInfo);
// Default to first tab
//this.onTabChanged("Tab1");
//
mTabHost.setOnTabChangedListener(this);
}
/**
* Add Tab content to the Tabhost
* #param activity
* #param tabHost
* #param tabSpec
* #param clss
* #param args
*/
private static void AddTab(PerfilEstructuraFragment activity, TabHost tabHost, TabHost.TabSpec tabSpec, TabInfo tabInfo) {
// Attach a Tab view factory to the spec
tabSpec.setContent(activity.new TabFactory(cd));
tabHost.addTab(tabSpec);
}
/** (non-Javadoc)
* #see android.widget.TabHost.OnTabChangeListener#onTabChanged(java.lang.String)
*/
public void onTabChanged(String tag) {
//TabInfo newTab = this.mapTabInfo.get(tag);
int pos = this.mTabHost.getCurrentTab();
this.mViewPager.setCurrentItem(pos);
}
/* (non-Javadoc)
* #see android.support.v4.view.ViewPager.OnPageChangeListener#onPageScrolled(int, float, int)
*/
#Override
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* #see android.support.v4.view.ViewPager.OnPageChangeListener#onPageSelected(int)
*/
#Override
public void onPageSelected(int position) {
System.out.println(position);
this.mTabHost.setCurrentTab(position);
}
/* (non-Javadoc)
* #see android.support.v4.view.ViewPager.OnPageChangeListener#onPageScrollStateChanged(int)
*/
#Override
public void onPageScrollStateChanged(int state) {
// TODO Auto-generated method stub
}
}
And here is the XML I use:
<?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"
android:background="#93EC83" >
<RelativeLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="100dp"
android:gravity="center" >
<ImageView
android:id="#+id/imvFotoPerfil"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="#drawable/backgroundcolor"
android:contentDescription="#string/estruc_icono"
android:scaleType="centerCrop" />
</RelativeLayout>
<TabHost
android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<HorizontalScrollView
android:id="#+id/horizontalScrollView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#476644" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TabWidget
android:id="#android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</TabWidget>
</LinearLayout>
</HorizontalScrollView>
<FrameLayout
android:id="#android:id/tabcontent"
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="0dp"
android:layout_weight="1" />
</LinearLayout>
</TabHost>
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.
I am Trying to add a TabHost Inside a Fragment like in example, getting NullPointerException when calling
mTabHost.setup()
what can be the problem ? code below
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.tabs_layout,container,false);
mTabHost = (FragmentTabHost)rootView.findViewById(android.R.id.tabhost);
mTabHost.setup(getActivity(), getChildFragmentManager(), R.id.tabcontent);
mTabHost.addTab(mTabHost.newTabSpec("fragmentb").setIndicator("tab1"),
Fragment1.class, null);
mTabHost.addTab(mTabHost.newTabSpec("fragmentc").setIndicator("tab2"),
Fragment2.class, null);
return rootView;
}
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">
<FrameLayout
android:id="#+id/tabcontent"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
</android.support.v4.app.FragmentTabHost>
This following code is an example I use:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mView = inflater.inflate(R.layout.fragment_tab_destaques, container, false);
mTabHost = (TabHost) mView.findViewById(android.R.id.tabhost);
initialiseTabHost();
return mView;
}
private void initialiseTabHost() {
mTabHost.setup();
String title = "TITLE";
addTab(getActivity(), this.mTabHost, this.mTabHost.newTabSpec(title).setIndicator(title));
Typeface tf = Typeface.createFromAsset(getActivity().getAssets(),
"fonts/Roboto-Bold.ttf");
for (int i = 0; i < mTabHost.getTabWidget().getChildCount(); i++) {
TextView tv = (TextView) mTabHost.getTabWidget().getChildAt(i).findViewById(android.R.id.title);
tv.setTextAppearance(getActivity(), android.R.style.TextAppearance_Medium);
tv.setTextColor(Color.WHITE);
tv.setTypeface(tf);
mTabHost.getTabWidget().getChildAt(i).setBackgroundResource(R.drawable.selector_actionbar);
}
mTabHost.setOnTabChangedListener(this);
}
private static void addTab(Activity activity, TabHost tabHost, TabHost.TabSpec tabSpec) {
tabSpec.setContent(new InicialTabFactory(activity));
tabHost.addTab(tabSpec);
}
My fragment_tab_destaques.xml
<?xml version="1.0" encoding="utf-8"?>
<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">
<TabHost
android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<HorizontalScrollView
android:id="#+id/horizontalScrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
android:scrollbars="none"
android:background="#color/BlueViolet">
<TabWidget
android:id="#android:id/tabs"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundStacked="#color/white"
android:weightSum="2" />
</HorizontalScrollView>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0" />
</LinearLayout>
</TabHost>
</LinearLayout>
EDIT
InicialTabFactory.java:
public class InicialTabFactory implements TabHost.TabContentFactory {
private final Context mContext;
public InicialTabFactory(Context context) {
mContext = context;
}
#Override
public View createTabContent(String s) {
View v = new View(mContext);
v.setMinimumWidth(0);
v.setMinimumHeight(0);
return v;
}
}
Solve your issue + a beautiful Material Design HERE
I have used Tab with viewPager inside fragment. This is my code :-
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_dashboard_tab, container, false);
mViewPager = (ViewPager) rootView.findViewById(R.id.pager);
mViewPager.setAdapter(new TabPageAdapter(getChildFragmentManager(), getActivity()));
tabHost = (TabHost) rootView.findViewById(android.R.id.tabhost);
tabHost.setup();
mViewPager.setOnPageChangeListener(this);
for (int i = 0; i < tabSpec.length; i++) {
tabHost.addTab(tabHost.newTabSpec(tabSpec[i]).setIndicator(tabTitle[i]).setContent(mFactory));
}
tabHost.setOnTabChangedListener(new TabHost.OnTabChangeListener() {
#Override
public void onTabChanged(String tabId) {
if (tabId.equals("Tab_1")) {
mViewPager.setCurrentItem(0);
} else if (tabId.equals("Tab_2")) {
mViewPager.setCurrentItem(1);
} else if (tabId.equals("Tab_3")) {
mViewPager.setCurrentItem(2);
} else if (tabId.equals("Tab_4")) {
mViewPager.setCurrentItem(3);
}
}
});
return rootView;
}
This is the layout file :-
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TabWidget
android:id="#android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="0dp" />
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
</LinearLayout>
</TabHost>
Hope this helps you :)
my simple working example
Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Resources res = getResources(); // Resource object to get Drawables
TabHost tabHost = getTabHost(); // The activity TabHost
TabHost.TabSpec spec; // Reusable TabSpec for each tab
Intent intent; // Reusable Intent for each tab
// Create an Intent to launch an Activity for the tab (to be reused)
intent = new Intent().setClass(this, ArtistsActivity.class);
// Initialize a TabSpec for each tab and add it to the TabHost
spec = tabHost.newTabSpec("artists").setIndicator("Artists",
res.getDrawable(R.drawable.ic_tab_artists))
.setContent(intent);
tabHost.addTab(spec);
// Do the same for the other tabs
intent = new Intent().setClass(this, AlbumsActivity.class);
spec = tabHost.newTabSpec("albums").setIndicator("Albums",
res.getDrawable(R.drawable.ic_tab_albums))
.setContent(intent);
tabHost.addTab(spec);
intent = new Intent().setClass(this, SongsActivity.class);
spec = tabHost.newTabSpec("songs").setIndicator("Songs",
res.getDrawable(R.drawable.ic_tab_songs))
.setContent(intent);
tabHost.addTab(spec);
tabHost.setCurrentTab(2);
}
<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:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dp">
<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:padding="5dp" />
</LinearLayout>
</TabHost>
Try this..
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
tabHost = new FragmentTabHost(getActivity());
tabHost.setup(getActivity(), getChildFragmentManager(), R.layout.fragment_home);
Bundle arg1 = new Bundle();
arg1.putInt("Arg for Frag1", 1);
tabHost.addTab(tabHost.newTabSpec("Tab1").setIndicator("tab1"),
Tab1Fragment.class, arg1);
Bundle arg2 = new Bundle();
arg2.putInt("Arg for Frag2", 2);
tabHost.addTab(tabHost.newTabSpec("Tab2").setIndicator("tab2"),
Tab2Fragment.class, arg2);
Bundle arg3 = new Bundle();
arg3.putInt("Arg for Frag3", 3);
tabHost.addTab(tabHost.newTabSpec("Tab3").setIndicator("tab3"),
Tab3Fragment.class, arg3);
return tabHost;
}
[SOLVED] This is the solution that I want. There is a main fragment and its inside there are tabs. Solution is here
And the code is here for possible future broken link:
package com.example.android.apis.app;
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.apis.app;
import java.util.ArrayList;
import com.example.android.apis.R;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TabHost;
/**
* Sample fragment that contains tabs of other fragments.
*/
public class FragmentTabsFragment extends Fragment {
TabManager mTabManager;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mTabManager = new TabManager(getActivity(), getChildFragmentManager(),
R.id.realtabcontent);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_tabs_fragment, container, false);
TabHost host = mTabManager.handleCreateView(v);
mTabManager.addTab(host.newTabSpec("result").setIndicator("Result"),
FragmentReceiveResult.ReceiveResultFragment.class, null);
mTabManager.addTab(host.newTabSpec("contacts").setIndicator("Contacts"),
LoaderCursor.CursorLoaderListFragment.class, null);
mTabManager.addTab(host.newTabSpec("apps").setIndicator("Apps"),
LoaderCustom.AppListFragment.class, null);
mTabManager.addTab(host.newTabSpec("throttle").setIndicator("Throttle"),
LoaderThrottle.ThrottledLoaderListFragment.class, null);
return v;
}
#Override
public void onViewStateRestored(Bundle savedInstanceState) {
super.onViewStateRestored(savedInstanceState);
mTabManager.handleViewStateRestored(savedInstanceState);
}
#Override
public void onDestroyView() {
super.onDestroyView();
mTabManager.handleDestroyView();
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mTabManager.handleSaveInstanceState(outState);
}
/**
* This is a helper class that implements a generic mechanism for
* associating fragments with the tabs in a tab host. DO NOT USE THIS.
* If you want tabs in a fragment, use the support v13 library's
* FragmentTabHost class, which takes care of all of this for you (in
* a simpler way even).
*/
public static class TabManager implements TabHost.OnTabChangeListener {
private final Context mContext;
private final FragmentManager mManager;
private final int mContainerId;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
private TabHost mTabHost;
private TabInfo mLastTab;
private boolean mInitialized;
private String mCurrentTabTag;
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(Context context, FragmentManager manager, int containerId) {
mContext = context;
mManager = manager;
mContainerId = containerId;
}
public TabHost handleCreateView(View root) {
if (mTabHost != null) {
throw new IllegalStateException("TabHost already set");
}
mTabHost = (TabHost)root.findViewById(android.R.id.tabhost);
mTabHost.setup();
mTabHost.setOnTabChangedListener(this);
return mTabHost;
}
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);
}
public void handleViewStateRestored(Bundle savedInstanceState) {
if (savedInstanceState != null) {
mCurrentTabTag = savedInstanceState.getString("tab");
}
mTabHost.setCurrentTabByTag(mCurrentTabTag);
String currentTab = mTabHost.getCurrentTabTag();
// Go through all tabs and make sure their fragments match
// the correct state.
FragmentTransaction ft = null;
for (int i=0; i<mTabs.size(); i++) {
TabInfo tab = mTabs.get(i);
tab.fragment = mManager.findFragmentByTag(tab.tag);
if (tab.fragment != null && !tab.fragment.isDetached()) {
if (tab.tag.equals(currentTab)) {
// The fragment for this tab is already there and
// active, and it is what we really want to have
// as the current tab. Nothing to do.
mLastTab = tab;
} else {
// This fragment was restored in the active state,
// but is not the current tab. Deactivate it.
if (ft == null) {
ft = mManager.beginTransaction();
}
ft.detach(tab.fragment);
}
}
}
// We are now ready to go. Make sure we are switched to the
// correct tab.
mInitialized = true;
ft = doTabChanged(currentTab, ft);
if (ft != null) {
ft.commit();
mManager.executePendingTransactions();
}
}
public void handleDestroyView() {
mCurrentTabTag = mTabHost.getCurrentTabTag();
mTabHost = null;
mTabs.clear();
mInitialized = false;
}
public void handleSaveInstanceState(Bundle outState) {
outState.putString("tab", mTabHost != null
? mTabHost.getCurrentTabTag() : mCurrentTabTag);
}
#Override
public void onTabChanged(String tabId) {
if (!mInitialized) {
return;
}
FragmentTransaction ft = doTabChanged(tabId, null);
if (ft != null) {
ft.commit();
}
}
private FragmentTransaction doTabChanged(String tabId, FragmentTransaction ft) {
TabInfo newTab = null;
for (int i=0; i<mTabs.size(); i++) {
TabInfo tab = mTabs.get(i);
if (tab.tag.equals(tabId)) {
newTab = tab;
}
}
if (newTab == null) {
throw new IllegalStateException("No tab known for tag " + tabId);
}
if (mLastTab != newTab) {
if (ft == null) {
ft = mManager.beginTransaction();
}
if (mLastTab != null) {
if (mLastTab.fragment != null) {
ft.detach(mLastTab.fragment);
}
}
if (newTab != null) {
if (newTab.fragment == null) {
newTab.fragment = Fragment.instantiate(mContext,
newTab.clss.getName(), newTab.args);
ft.add(mContainerId, newTab.fragment, newTab.tag);
} else {
ft.attach(newTab.fragment);
}
}
mLastTab = newTab;
}
return ft;
}
}
}
I am working on FragmentTabs. When I try to show the following layout in one of the tabs, I don't see the button on the screen. I can see the button if I don't use tabs.The activity's layout is as follows:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:padding="4dip"
android:gravity="center_horizontal"
android:layout_width="match_parent" android:layout_height="match_parent">
<FrameLayout
android:id="#+id/simple_fragment"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1">
</FrameLayout>
<Button android:id="#+id/new_fragment"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0"
android:text="New fragment">
<requestFocus />
</Button>
</LinearLayout>
The FragmentTabs code is as follows:
package com.example.tabswithfragments;
import java.util.HashMap;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.view.View;
import android.widget.TabHost;
import android.widget.TabHost.TabContentFactory;
/**
* #author mwho
*
*/
public class TabsFragmentActivity extends FragmentActivity implements
TabHost.OnTabChangeListener {
private TabHost mTabHost;
private HashMap<String, TabInfo> mapTabInfo = new HashMap<String, TabInfo>();
private TabInfo mLastTab = null;
private class TabInfo {
private String tag;
private Class<? extends Fragment> clss;
private Bundle args;
private Fragment fragment;
TabInfo(String tag, Class<? extends Fragment> clazz, Bundle args) {
this.tag = tag;
this.clss = clazz;
this.args = args;
}
}
class TabFactory implements TabContentFactory {
private final Context mContext;
/**
* #param context
*/
public TabFactory(Context context) {
mContext = context;
}
/**
* (non-Javadoc)
*
* #see android.widget.TabHost.TabContentFactory#createTabContent(java.lang.String)
*/
public View createTabContent(String tag) {
View v = new View(mContext);
v.setMinimumWidth(0);
v.setMinimumHeight(0);
return v;
}
}
/**
* (non-Javadoc)
*
* #see android.support.v4.app.FragmentActivity#onCreate(android.os.Bundle)
*/
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Step 1: Inflate layout
setContentView(R.layout.tabs_layout);
// Step 2: Setup TabHost
initialiseTabHost(savedInstanceState);
if (savedInstanceState != null) {
mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab")); // set the
// tab
// as
// per
// the
// saved
// state
}
}
/**
* (non-Javadoc)
*
* #see android.support.v4.app.FragmentActivity#onSaveInstanceState(android.os.Bundle)
*/
protected void onSaveInstanceState(Bundle outState) {
outState.putString("tab", mTabHost.getCurrentTabTag()); // save the tab
// selected
super.onSaveInstanceState(outState);
}
/**
* Step 2: Setup TabHost
*/
private void initialiseTabHost(Bundle args) {
mTabHost = (TabHost) findViewById(android.R.id.tabhost);
mTabHost.setup();
TabInfo tabInfo = null;
TabsFragmentActivity.addTab(this, this.mTabHost, this.mTabHost
.newTabSpec("Tab1").setIndicator("Tab 1"),
(tabInfo = new TabInfo("Tab1",
MainActivity.CountingFragment.class, args)));
this.mapTabInfo.put(tabInfo.tag, tabInfo);
TabsFragmentActivity
.addTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab2")
.setIndicator("Tab 2"), (tabInfo = new TabInfo("Tab2",
ListActivity.FavList.class, args)));
this.mapTabInfo.put(tabInfo.tag, tabInfo);
// Default to first tab
this.onTabChanged("Tab1");
//
mTabHost.setOnTabChangedListener(this);
}
/**
* #param activity
* #param tabHost
* #param tabSpec
* #param clss
* #param args
*/
private static void addTab(TabsFragmentActivity activity, TabHost tabHost,
TabHost.TabSpec tabSpec, TabInfo tabInfo) {
// Attach a Tab view factory to the spec
tabSpec.setContent(activity.new TabFactory(activity));
String tag = tabSpec.getTag();
// 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.
tabInfo.fragment = activity.getSupportFragmentManager()
.findFragmentByTag(tag);
if (tabInfo.fragment != null && !tabInfo.fragment.isDetached()) {
FragmentTransaction ft = activity.getSupportFragmentManager()
.beginTransaction();
ft.detach(tabInfo.fragment);
ft.commit();
activity.getSupportFragmentManager().executePendingTransactions();
}
tabHost.addTab(tabSpec);
}
/**
* (non-Javadoc)
*
* #see android.widget.TabHost.OnTabChangeListener#onTabChanged(java.lang.String)
*/
public void onTabChanged(String tag) {
TabInfo newTab = (TabInfo) this.mapTabInfo.get(tag);
if (mLastTab != newTab) {
FragmentTransaction ft = this.getSupportFragmentManager()
.beginTransaction();
if (mLastTab != null) {
if (mLastTab.fragment != null) {
ft.detach(mLastTab.fragment);
}
}
if (newTab != null) {
if (newTab.fragment == null) {
newTab.fragment = Fragment.instantiate(this,
newTab.clss.getName(), newTab.args);
ft.add(R.id.realtabcontent, newTab.fragment, newTab.tag);
} else {
ft.attach(newTab.fragment);
}
}
mLastTab = newTab;
ft.commit();
this.getSupportFragmentManager().executePendingTransactions();
}
}
}
Counting fragment class is as follows:
package com.example.tabswithfragments;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends FragmentActivity {
int mStackLevel = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_stack);
// Watch for button clicks.
Button button = (Button)findViewById(R.id.new_fragment);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
addFragmentToStack();
}
});
if (savedInstanceState == null) {
// Do first time initialization -- add initial fragment.
Fragment newFragment = CountingFragment.newInstance(mStackLevel);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.simple_fragment, newFragment).commit();
} else {
mStackLevel = savedInstanceState.getInt("level");
}
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("level", mStackLevel);
}
void addFragmentToStack() {
mStackLevel++;
// Instantiate a new fragment.
Fragment newFragment = CountingFragment.newInstance(mStackLevel);
// Add the fragment to the activity, pushing this transaction
// on to the back stack.
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.simple_fragment, newFragment);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.addToBackStack(null);
ft.commit();
}
public static class CountingFragment extends Fragment {
int mNum;
/**
* Create a new instance of CountingFragment, providing "num"
* as an argument.
*/
static CountingFragment newInstance(int num) {
CountingFragment f = new CountingFragment();
// Supply num input as an argument.
Bundle args = new Bundle();
args.putInt("num", num);
f.setArguments(args);
return f;
}
/**
* When creating, retrieve this instance's number from its arguments.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mNum = getArguments() != null ? getArguments().getInt("num") : 1;
}
/**
* The Fragment's UI is just a simple text view showing its
* instance number.
*/
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.hello_world, container, false);
View tv = v.findViewById(R.id.text);
((TextView)tv).setText("Fragment #" + mNum);
tv.setBackgroundDrawable(getResources().getDrawable(android.R.drawable.gallery_thumb));
return v;
}
}
}
Can someone help me please.
Why you use android:layout_weight="0"? I don't think it is a good practice. In LinearLayout, android:layout_weight is use to divide layout into pieces and the number means how many pieces it will take. For example, if you use two android:layout_weight="1", then each of the subview will be hold 50%(1/(1+1)) of the whole layout. However, in your case, you use 1:0, which means 1 will contains whole layout and 0 gets nothing. So the 0 part will not show at all. I think you should use RelativeLayout instead of LinearLayout in your case.
layout_weight for your button should not be zero.
In the main activity layout just use this code, the reason why I remove the button view is that we can create another layout that we can put the button there. Just imagine that the simple_fragment in the main.xml will be replaced or another xml or view will be added to it using the with_button.xml
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:padding="4dip"
android:gravity="center_horizontal"
android:layout_width="match_parent" android:layout_height="match_parent">
<FrameLayout
android:id="#+id/simple_fragment"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1">
</FrameLayout>
</LinearLayout>
hello_world.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">
<!--Other Views -->
<Button android:id="#+id/new_fragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:text="New fragment">
</Button>
</LinearLayout >
CountingFragment Fragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.hello_world, container, false);
View tv = v.findViewById(R.id.text);
((TextView)tv).setText("Fragment #" + mNum);
tv.setBackgroundDrawable(getResources().getDrawable(android.R.drawable.gallery_thumb));
Button btn = (Button)v.findViewById(R.id.new_fragment);
btn.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Log.d("Button","Clicked");
}});
return v;
}
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
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