Unfortunately when I attempt to switch between tabs, I get an error similar to this person's (FragmentTransaction.replace() not working), where the list of text from my first tab appears in the background of every other fragment. I did follow the recommendation to use a FrameLayout with a container, so that I could simply add or delete the relevant fragments when the tab was switched (which was also recommended here Fragment duplication on Fragment Transaction). I am attempting to use @Niek's TabListener solution from Switching fragments within tab, yet the problem still persists.
All help will be most appreciated, thank you so much for your time.
From my MainActivity:
//Making an Action Bar
ActionBar actionbar = getSupportActionBar();
actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionbar.setTitle("MyApp");
//Creating the Tabs
ActionBar.Tab Frag1Tab = actionbar.newTab().setText("BlackList");
ActionBar.Tab Frag2Tab = actionbar.newTab().setText("TreeMenu");
ActionBar.Tab Frag3Tab = actionbar.newTab().setText("Map");
ActionBar.Tab Frag4Tab = actionbar.newTab().setText("Help");
//Fragments (Underlying Classes for Each Class)
Fragment1 = new BlackistFragment();
Fragment2 = new TreeMenuFragment();
Fragment3 = new Fragment_3();
Fragment4 = new Fragment_4();
//Adding Tab Listeners
//new TabListener<StationsFragment>(this, "stations", StationsFragment.class)
Frag1Tab.setTabListener(new TabListener<BlackistFragment>(this, "frag1", BlackistFragment.class));
Frag2Tab.setTabListener(new TabListener<TreeMenuFragment>(this, "frag2", TreeMenuFragment.class));
Frag3Tab.setTabListener(new TabListener<Fragment_3>(this, "frag3", Fragment_3.class));
Frag4Tab.setTabListener(new TabListener<Fragment_4>(this, "frag4", Fragment_4.class));
//Adding Tabs to Action Bar
actionbar.addTab(Frag1Tab);
actionbar.addTab(Frag2Tab);
actionbar.addTab(Frag3Tab);
actionbar.addTab(Frag4Tab);
The Tab Listener...
public class TabListener<T extends SherlockFragment> implements com.actionbarsherlock.app.ActionBar.TabListener {
private final SherlockFragmentActivity mActivity;
private final String mTag;
private final Class<T> mClass;
private SherlockFragment mFragment;
public TabListener(SherlockFragmentActivity activity, String tag, Class<T> class1) {
mActivity = activity;
mTag = tag;
mClass = class1;
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
SherlockFragment preInitializedFragment = (SherlockFragment) mActivity.getSupportFragmentManager().findFragmentByTag(mTag);
if (preInitializedFragment == null) {
mFragment = (SherlockFragment) SherlockFragment.instantiate(mActivity, mClass.getName());
ft.add(R.id.fragment_container, mFragment, mTag);
} else {
ft.attach(preInitializedFragment);
}
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
SherlockFragment preInitializedFragment = (SherlockFragment) mActivity.getSupportFragmentManager().findFragmentByTag(mTag);
if (preInitializedFragment != null) {
ft.detach(preInitializedFragment);
} else if (mFragment != null) {
ft.detach(mFragment);
}
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// User selected the already selected tab. Usually do nothing.
}
}
The onCreateView from my BlackistFragment Tab (the one that appears in all other tabs..). Note that it extends SherlockFragment
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
view = inflater.inflate(R.layout.blacklist, container, false);
ListView listView = (ListView) view.findViewById(R.id.listview);
//Making BlackList
TreeSet<BlacklistWord> theSet = MainActivity.getInstance().datasource.GetAllWords();
ArrayList<String> list = new ArrayList<String>();
for(BlacklistWord i :theSet){
System.out.println(i.getWord());
list.add(i.getWord());
}
Collections.sort(list);
adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, list);
listView.setAdapter(adapter);
((BaseAdapter) listView.getAdapter()).notifyDataSetChanged();
((ViewGroup) listView.getParent()).removeView(listView);
container.addView(listView);
return view;
}
My second Fragment class...
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
MainActivity.getInstance().invalidateOptionsMenu();
view = inflater.inflate(R.layout.treemenu, container, false);
//Auto-Complete
AutoCompleteTextView autoView = (AutoCompleteTextView) view.findViewById(R.id.edit_message);
String[] itemOptions = getResources().getStringArray(R.array.edit_message);
ArrayAdapter<String> theAdapter =
new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, itemOptions);
autoView.setAdapter(theAdapter);
((BaseAdapter) autoView.getAdapter()).notifyDataSetChanged();
// ((ViewGroup) autoView.getParent()).removeView(autoView);
Button b = (Button) view.findViewById(R.id.post_blacklist_button);
b.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
AutoCompleteTextView editText=(AutoCompleteTextView) view.findViewById(R.id.edit_message);
String blackListItem = editText.getText().toString();
editText.setText("");
MainActivity.getInstance().postBlackListItem(blackListItem);
//refreshes the rest
MainActivity.getInstance().invalidateOptionsMenu();
}
});
initViews(view);
if(view != null) { return view; }
((ViewGroup) autoView.getParent()).removeView(autoView);
container.addView(autoView);
MainActivity.getInstance().invalidateOptionsMenu();
return view;
}
I think it will be easier to show you how I have it implemented than to modify your code. Then you can easily adapt it to your use case.
Edit: I have changed some variables to match your program.
Here is the class implementing TabListener:
public class CustomTabListener implements TabListener {
private Fragment fragment;
public CustomTabListener(Fragment frag){
fragment = frag;
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
ft.replace(R.id.fragment_container, fragment);
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
ft.remove(fragment);
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
//Tab Reselected....
}
}
Then you can add tabs like so...
private void addTabs() {
ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionBar.setTitle("MyApp");
actionBar.addTab(actionBar.newTab()
.setText("BlackList")
.setTabListener(new CustomTabListener(Fragment1)));
actionBar.addTab(actionBar.newTab()
.setText("TreeMenu")
.setTabListener(new CustomTabListener(Fragment2)));
actionBar.addTab(actionBar.newTab()
.setText("Map")
.setTabListener(new CustomTabListener(Fragment3)));
actionBar.addTab(actionBar.newTab()
.setText("Help")
.setTabListener(new CustomTabListener(Fragment4)));
}
All you have to do is pass it the fragment.