Dynamically Tabs Android - android

I'm trying to create tabs based on an array returned by the database. However, I'm getting the following error.
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.setVisibility(int)' on a null object reference
The code that I'm using is below, the array subAreas has already 3 values.
public class ExtintorFragment extends Fragment {
private LinearLayout ll;
private TabHost tabs;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ll = (LinearLayout) inflater.inflate(R.layout.fragment_criterios, container, false);
setHasOptionsMenu(true);
tabs = (TabHost) ll.findViewById(R.id.tabHost);
tabs.setup();
String[] subAreas;
EquipamentosSubAreaDbAdapter mDb = new EquipamentosSubAreaDbAdapter(getContext());
mDb.open();
subAreas = mDb.getSubareasEquipamento("Extintores");
mDb.close();
for (int i = 0; i < subAreas.length; i++) {
TabHost.TabSpec spec = tabs.newTabSpec(subAreas[i]);
spec.setIndicator(subAreas[i]);
spec.setContent(new TabHost.TabContentFactory() {
#Override
public View createTabContent(String tag) {
return null;
}
});
tabs.addTab(spec);
}
return ll;
}
#Override
public void onActivityCreated (Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
}
}
Also, could you give me tips to create a listView as TabContent.
Thank you

You can't inflate the view while there are no tabs in said view. It will attempt to set the first tab as what should be shown in the fragment and since you haven't added any tabs to the view, it results in a null pointer.
Try the following code inside onCreateView. Of course, you'll have to parameterize addTab to the values you want.
mTabHost = new FragmentTabHost(getActivity());
mTabHost.setup(getActivity(), getChildFragmentManager(), android.R.id.tabcontent);
mTabHost.addTab(
mTabHost.newTabSpec("Tab 1").setIndicator("Tab 1")
, DefaultContentFragment.class
, null);
mTabHost.addTab(
mTabHost.newTabSpec("Tab 2").setIndicator("Tab 2")
, DefaultContentFragment.class
, null);
mTabHost.addTab(
mTabHost.newTabSpec("Tab 3").setIndicator("Tab 3")
, DefaultContentFragment.class
, null);
return mTabHost;

Related

tabhost inside fragment not loading first time

I have one fragment in which I am setting tabhost widget with three tabs each have fragment.
When ever first time I come to this fragment first tab not loading first child fragment but after click on another tab and return on first tab then it is loading first child fragment.
Also I have little confusion that what will be the third parameter in tabhost.setup() method.It should be the layout of parent fragment which handles tabs or the layout of first child fragment.
Here is my code for parent fragment
public class MyStoreFragment extends Fragment implements TabHost.OnTabChangeListener {
private FragmentTabHost mTabHost;
View rootView;
public MyStoreFragment() {
// Empty constructor required for fragment subclasses
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// rootView = inflater.inflate(R.layout.fragment_my_store,container, false);
// mTabHost = (FragmentTabHost)rootView.findViewById(android.R.id.tabhost);
mTabHost = new FragmentTabHost(getActivity());
// mTabHost.setup(getActivity(), getChildFragmentManager(), android.R.id.tabcontent);
mTabHost.setup(getActivity(), getChildFragmentManager(),R.layout.fragment_my_store);
mTabHost.addTab(mTabHost.newTabSpec("new").setIndicator("NEW"), NewBookFragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("trending").setIndicator("TRENDING"),FragmentTab.class, null);
mTabHost.addTab(mTabHost.newTabSpec("explore").setIndicator("EXPLORE"),FragmentTab.class, null);
mTabHost.setCurrentTab(0);
mTabHost.setOnTabChangedListener(this);
mTabHost.getTabWidget().getChildAt(0).setBackgroundColor(Color.WHITE);
mTabHost.getTabWidget().getChildAt(1).setBackgroundColor(Color.parseColor("#FCF4E7"));
mTabHost.getTabWidget().getChildAt(2).setBackgroundColor(Color.parseColor("#FCF4E7"));
mTabHost.getTabWidget().getChildAt(0)
.setBackgroundColor(Color.parseColor("#DF4426"));
TextView tv1 = (TextView) mTabHost.getTabWidget().getChildAt(0).findViewById(android.R.id.title);
tv1.setTextColor(Color.parseColor("#F6CFC2"));
TextView tv2 = (TextView) mTabHost.getTabWidget().getChildAt(1).findViewById(android.R.id.title);
tv2.setTextColor(Color.parseColor("#E03C20"));
TextView tv3 = (TextView) mTabHost.getTabWidget().getChildAt(2).findViewById(android.R.id.title);
tv3.setTextColor(Color.parseColor("#E03C20"));
// TODO To set height and width properly of tab widget
ViewGroup.LayoutParams params = mTabHost.getTabWidget().getChildAt(0).getLayoutParams();
// params.width = 128;
params.height = 50;
mTabHost.getTabWidget().getChildAt(0).setLayoutParams(params );
mTabHost.getTabWidget().getChildAt(1).setLayoutParams(params );
mTabHost.getTabWidget().getChildAt(2).setLayoutParams(params );
// for (int i = 0; i < mTabHost.getTabWidget().getChildCount(); i++) {
// TextView tv = (TextView) mTabHost.getTabWidget().getChildAt(i).findViewById(android.R.id.title);
// tv.setTextColor(Color.parseColor("#DA4426"));
// }
return mTabHost;
}

How can I switch from the old tabhost to swipe tabs in Android?

I am currentley using the old tabHost to hold a hand full of different fragments as tabs. How can I easily switch this over to the newer swipe tabs?
public class StatisticsTab extends Fragment {
private FragmentTabHost mTabHost;
//Mandatory Constructor
public StatisticsTab() {
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_tabs,container, false);
mTabHost = (FragmentTabHost)rootView.findViewById(android.R.id.tabhost);
mTabHost.setup(getActivity(), getChildFragmentManager(), R.id.realtabcontent);
mTabHost.addTab(mTabHost.newTabSpec("Basic").setIndicator("Basic"),
StatisticsPage.class, null);
mTabHost.addTab(mTabHost.newTabSpec("Brewery").setIndicator("Brewery"),
BreweryStatistics.class, null);
mTabHost.addTab(mTabHost.newTabSpec("Style").setIndicator("Style"),
StyleStatistics.class, null);
mTabHost.addTab(mTabHost.newTabSpec("Taste").setIndicator("Taste"),
TasteStatisticsPage.class, null);
return rootView;
}
}
Try PagerSlidingTabStrip(https://github.com/astuetz/PagerSlidingTabStrip). An interactive indicator to navigate between the different pages of a ViewPager. It works awesome for me.

FragmentTabHost does not have the nested fragments in onTabChanged, why? How can I do?

I'm doing a small app with FragmentTabHost and two nested fragments. I need update the data of nested fragments from the fragment that contains the FragmentTabHost but for any reason I don't have the second fragment (second tab) when I do click in its tab then I get a null pointer exception.
Here it is a test of my code:
TabsTransactionFragment.java, this is the Fragment that contain the FragmentTabHost
public class TabsTransactionFragment extends Fragment implements
OnTabChangeListener{
private static final String TAB_ONE_TAG = "ONE";
private static final String TAB_TWO_TAG = "TW0";
private FragmentTabHost mTabHost;
private ArrayList<Integer> mData;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mData = new ArrayList<Integer>();
for (int i=0; i<10; i++) {
mData.add(i);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_tabs_transations,
container, false);
mTabHost = (FragmentTabHost) view.findViewById(android.R.id.tabhost);
mTabHost.setup(getActivity(), getChildFragmentManager(),
android.R.id.tabcontent);
mTabHost.addTab(
mTabHost.newTabSpec(TAB_ONE_TAG).setIndicator(
"ODD"),
ListDataFragment.class, null);
mTabHost.addTab(
mTabHost.newTabSpec(TAB_TWO_TAG).setIndicator(
"EVEN"),
ListDataFragment.class, null);
mTabHost.setOnTabChangedListener(this);
return mTabHost;
}
#Override
public void onDestroyView() {
super.onDestroyView();
mTabHost = null;
}
private void updateDataChildFragments(String tabName) {
if (mData != null) {
ListDataFragment listOneFragment =
(ListDataFragment) getChildFragmentManager().findFragmentByTag(TAB_ONE_TAG);
ListDataFragment listTwoFragment =
(ListDataFragment) getChildFragmentManager().findFragmentByTag(TAB_TWO_TAG);
if (tabName.equalsIgnoreCase(TAB_ONE_TAG)) {
ArrayList<Integer> odds = new ArrayList<Integer>();
for (int i=0; i<mData.size(); i++) {
if (mData.get(i) % 2 != 0) {
odds.add(mData.get(i));
}
}
listOneFragment.updateData(odds);
} else {
ArrayList<Integer> even = new ArrayList<Integer>();
for (int i=0; i<mData.size(); i++) {
if (mData.get(i) % 2 != 0) {
even.add(mData.get(i));
}
}
// Fragment two is null then crash...
listTwoFragment.updateData(even);
}
}
}
#Override
public void onTabChanged(String tabName) {
updateDataChildFragments(tabName);
}
}
Each tab contains a simple ListFragment like this:
public class ListDataFragment extends ListFragment {
private ArrayAdapter<Integer> mAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mAdapter = new ArrayAdapter<Integer>(getActivity(), android.R.layout.simple_list_item_1);
setListAdapter(mAdapter);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent,
Bundle savedInstanceState) {
return super.onCreateView(inflater, parent, savedInstanceState);
}
public void updateData(ArrayList<Integer> data) {
mAdapter.addAll(data);
mAdapter.notifyDataSetChanged();
}
}
And layout fragment_tabs_transations.xml is the structure of android.support.v4.app.FragmentTabHost with a linearLayout, TabWidget and FrameLayout.
I have tried many things and ways but I haven't got to pass data to the second fragment once I do click... I have tried to created first both fragment and add to FragmentTabHost but I didn't get neither...
I think the problem it is the second fragment it is attached to FragmentTabHost after onTagChanged and that is because I can not find it... But I don't understand this behaviour... :S.
Anybody can help me? Or know any solution to pass data to second Fragment before do click in its tab?
Many thanks!!

FragmentTabHost not creating view inside Fragment in android

I am having an issue getting the view to change on a tabhost - when I select a tab the content stays blank.
From what I can tell, onCreateView is not being called on the child Fragments. onMenuCreate runs fine because the menu changes like it is supposed to.
public class PatientTabFragment extends Fragment {
private FragmentTabHost mTabHost;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mTabHost = new FragmentTabHost(getActivity());
mTabHost.setup(getActivity(), getChildFragmentManager());
mTabHost.addTab(mTabHost.newTabSpec("simple").setIndicator("Info"),
NewPatientFragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("contacts").setIndicator("Notes"),
NoteListFragment.class, null);
return mTabHost;
}
#Override
public void onDestroyView() {
super.onDestroyView();
mTabHost = null;
}
}
according to the docs:
Special TabHost that allows the use of Fragment objects for its tab
content. When placing this in a view hierarchy, after inflating the
hierarchy you must call setup(Context, FragmentManager, int) to
complete the initialization of the tab host.
(emphasis mine)
So I suggest somethong like this:
public class PatientTabFragment extends Fragment {
private FragmentTabHost mTabHost;
private boolean createdTab = false;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mTabHost = new FragmentTabHost(getActivity());
mTabHost.setup(getActivity(), getChildFragmentManager());
mTabHost.addTab(mTabHost.newTabSpec("simple").setIndicator("Info"),
NewPatientFragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("contacts").setIndicator("Notes"),
NoteListFragment.class, null);
return mTabHost;
}
public void onResume(){
if (!createdTab){
createdTab = true;
mTabHost.setup(getActivity(), getActivity().
getSupportedFragmentManager());
}
}
#Override
public void onDestroyView() {
super.onDestroyView();
mTabHost = null;
}
}
Now we can use TabLayout and ViewPager do those things.This is a good guide to use it.Here is my code:
viewPager=(NonSwipeableViewPager)view.findViewById(R.id.circleresdyn_viewpager);
tabLayout=(TabLayout)view.findViewById(R.id.circleresdyn_tablayout);
if (viewPager != null) {
Adapter adapter = new Adapter(((AppCompatActivity)activity).getSupportFragmentManager());
ContentFragment con=new ContentFragment();
con.setArguments(bundleForFramgnet);
MemberFragment memberFragment=new MemberFragment();
memberFragment.setArguments(bundleForFramgnet);
CirResDynTileFragment cirResDynTileFragment=new CirResDynTileFragment();
cirResDynTileFragment.setArguments(bundleForFramgnet);
adapter.addFragment(cirResDynTileFragment, "Tab1");
adapter.addFragment(con, "Tab2");
adapter.addFragment(memberFragment, "Tab3");
viewPager.setAdapter(adapter);
viewPager.setOffscreenPageLimit(3);
tabLayout.setTabGravity(TabLayout.GRAVITY_CENTER);
tabLayout.setupWithViewPager(viewPager);
tabLayout.getTabAt(0).select();
}
Check this peace of code. It may help you:
import android.app.Fragment;
public class Change_password extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.change_password, container,false);
setTabs();
return rootView;
}
private void setTabs() {
try {
addTab("Airlines", R.drawable.tab_home, HomeActivity_bkp.class);
addTab("Advance Search", R.drawable.tab_search,
AdvanceSearchAcitivty.class);
addTab("Booking", R.drawable.tab_home, Booking.class);
addTab("Settings", R.drawable.tab_search, SettingAcitivty.class);
} catch (Exception e) {
Toast.makeText(getApplicationContext(), e.toString(),
Toast.LENGTH_LONG).show();
// TODO: handle exception
}
}
private void addTab(String labelId, int drawableId, Class<?> c) {
TabHost tabHost = getTabHost();
Intent intent = new Intent(this, c);
TabHost.TabSpec spec = tabHost.newTabSpec("tab" + labelId);
View tabIndicator = LayoutInflater.from(this).inflate(
R.layout.tab_indicator, getTabWidget(), false);
TextView title = (TextView) tabIndicator.findViewById(R.id.title);
title.setText(labelId);
ImageView icon = (ImageView) tabIndicator.findViewById(R.id.icon);
icon.setImageResource(drawableId);
spec.setIndicator(tabIndicator);
spec.setContent(intent);
tabHost.addTab(spec);
}

Android: Can't load tab. Says child already has a parent

I have the following FragmentActivity:
public class TabsActivity extends FragmentActivity {
private FragmentTabHost mTabHost;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tabs);
mTabHost = (FragmentTabHost)findViewById(android.R.id.tabhost);
mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);
mTabHost.addTab(mTabHost.newTabSpec("Home").setIndicator("Home", getResources().getDrawable(R.drawable.hometab)),HomeTab.class, null);
mTabHost.addTab(mTabHost.newTabSpec("Explore").setIndicator("Explore", getResources().getDrawable(R.drawable.exploretab)),ExploreTab.class, null);
mTabHost.addTab(mTabHost.newTabSpec("Info").setIndicator("Info", getResources().getDrawable(R.drawable.infotab)),InfoTab.class, null);
mTabHost.addTab(mTabHost.newTabSpec("Social").setIndicator("Social", getResources().getDrawable(R.drawable.socialtab)),SocialTab.class, null);
mTabHost.addTab(mTabHost.newTabSpec("Contact").setIndicator("Contact", getResources().getDrawable(R.drawable.contacttab)),ContactTab.class, null);
TabWidget tabWidget = mTabHost.getTabWidget();
tabWidget.setStripEnabled(false);
for(int i=0; i < tabWidget.getChildCount(); i++){
tabWidget.getChildAt(i).setBackgroundResource(R.drawable.tab_bg);
TextView tv = (TextView)tabWidget.getChildAt(i).findViewById(android.R.id.title);
tv.setTextColor(this.getResources().getColor(R.color.white));
}
mTabHost.setOnTabChangedListener(new OnTabChangeListener() {
#Override
public void onTabChanged(String tabId) {
Log.d("PAUL",tabId);
if(tabId=="Home"){
finish();
}
TabWidget tw = mTabHost.getTabWidget();
for(int i=0; i < tw.getChildCount(); i++){
TextView tabText = (TextView)tw.getChildAt(i).findViewById(android.R.id.title);
if(tabText.getText()==tabId){
tabText.setTextColor(TabsActivity.this.getResources().getColor(R.color.tcmgreen));
} else {
tabText.setTextColor(TabsActivity.this.getResources().getColor(R.color.white));
}
}
}
});
Intent intent = getIntent();
String tag = intent.getStringExtra("tab");
Log.d("DEBUG",tag);
mTabHost.setCurrentTabByTag(tag);
}
}
When the user taps the 'Explore' tab I get the following error: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first. Here is my ExploreTab class:
public class ExploreTab extends Fragment {
private ArrayList<Level> levels;
private TCMSQLiteHelper sqliteHelper;
#Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
sqliteHelper = new TCMSQLiteHelper(this.getActivity());
levels = sqliteHelper.getAllLevels();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.d("DEBUG","Explore Created");
View v = inflater.inflate(R.layout.explorelist, container);
return v;
}
}
This doesn't make any sense to me because I don't see where there could be a problem of a view already being loaded. What am I missing here?
In onCreateView(), you should be passing in a third parameter, false. This third parameter specifies whether the layout should attached itself to the ViewGroup container.
From the Fragments documentation:
In this case, this is false because the system is already inserting the inflated layout into the container—passing true would create a redundant view group in the final layout.
Thus your code should be:
View v = inflater.inflate(R.layout.explorelist, container, false);

Categories

Resources