I am having a problem with my fragments overlapping each other. I have an Android ActionBar tab and I am using ActionBarSherlock. When I select other tabs the fragment from the ListFragment is placed on top of my HomeFragment. It is like it is not getting detached properly.
Below is the code for HomeFragment:
public class HomeFragment extends SherlockFragment
implements ActionBar.TabListener {
private View homeView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
homeView = inflater.inflate(R.layout.homefragment, container, false);
return homeView;
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
ft.add(android.R.id.content, this,"apple");
ft.attach(this);
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {}
}
Code for HerbFragment:
public class HerbsFragment extends SherlockListFragment
implements ActionBar.TabListener {
/** An array of items to display in ArrayList */
String apple_versions[] = new String[]{
"Pancreas",
"Blood"
};
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
/** Creating array adapter to set data in listview */
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
getActivity().getBaseContext(),
android.R.layout.simple_list_item_1,
apple_versions);
/** Setting the array adapter to the listview */
setListAdapter(adapter);
View v = inflater.inflate(R.layout.activity_main, container, false);
return super.onCreateView(inflater, container, savedInstanceState);
}
#Override
public void onStart() {
super.onStart();
/** Setting the multiselect choice mode for the listview */
getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
ft.add(android.R.id.content, this,"apple");
ft.attach(this);
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
ft.detach(this);
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {}
}
I think the code in your HerbFragment is missplaced because you should handle the tab stuff in the activity/fragment that has the tabs, not in the tabs. You can handle that in your HomeFragment in two different ways:
-When the user clicks in a tab, replace the current fragment: just change this for a ft.replace (and delete the ft.attach line):
ft.add(android.R.id.content, this,"apple");
ft.attach(this);
-Attach the new fragment and detach the previous: just get a reference from the attached fragment if you know which it is and detach it in the same method you're attaching the new one.
Related
I have a static menu on the left side of my screen in my android application.Whenever I click an item from the left menu a fragment will appear along side it.
One of my items on the left menu is the course. In the course fragment contains a viewpager to watch read or listen to the course. You can navigate to one of these three options by side swipe or clicking the corresponding tab on the title bar. This all works fine.
However if I click another item on the left menu bar and navigate back to the course section, it messes up. The onCreateView() is invoked again and therefore adds the tabs to the title bar again and the viewpager. I tried removing all tabs in the onPause() method and removing all views in the viewpager. The tabs no longer be added again, but the pages on the screen are now blank.
Any help is much appreciated.
Here's the class which extends FragmentPagerAdapter
public class TabsPagerAdapter extends FragmentPagerAdapter {
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
// Top Rated fragment activity
return new WatchCourseFrag();
case 1:
// Games fragment activity
return new ReadCourseFrag();
case 2:
// Movies fragment activity
return new ListenCourseFrag();
}
return null;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 3;
}
}
and here is the tab fragment class:
public class TabFrag2 extends Fragment implements ActionBar.TabListener {
private ViewPager viewPager;
private TabsPagerAdapter mAdapter;
private ActionBar actionBar;
// Tab titles
private String[] tabs = { "Watch", "Read", "Listen" };
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.pager, container, false);
// Initilization
viewPager = (ViewPager) view.findViewById(R.id.pager);
actionBar = ((HomeScreenTablet) getActivity()).getSupportActionBar();
mAdapter = new TabsPagerAdapter(getFragmentManager());
viewPager.setAdapter(mAdapter);
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Adding Tabs
// Adding Tabs
for (String tab_name : tabs) {
actionBar.addTab(actionBar.newTab().setText(tab_name)
.setTabListener(this));
}
/**
* on swiping the viewpager make respective tab selected
* */
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// on changing the page
// make respected tab selected
actionBar.setSelectedNavigationItem(position);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
viewPager.setOffscreenPageLimit(3);
return view;
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
// on tab selected
// show respected fragment view
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
public void onPause() {
super.onPause();
viewPager.removeAllViews();
viewPager.removeAllViewsInLayout();
actionBar.removeAllTabs();
}
}
Found the answer:
Changed "TabsPagerAdapter extends FragmentPagerAdapter" to "TabsPagerAdapter extends FragmentStatePagerAdapter"
At the moment my App has two Fragments in form of two (swipe)tabs.
On one Fragment the user can add information to the database.
On the other Fragment a ListView displays the content of the DB-table.
If the user adds a new DB-Entry and swiped to the second tab, the ListView gets not updated, because I do all the loading in my onCreateView() method.
I already tried using the onResume() method and calling an "update method" of the Fragment from my FragmentActivity (in the onPageSelected() method).
onResume() never gets called.
And i if i call getActivity() from my "update method"(in my fragment) it always returns null, but i need the activity object for my database connection.
My Fragment looks like this:
public class ListFragment extends Fragment implements AdapterView.OnItemLongClickListener, OnRefreshListener{
private ListView listView;
private SpeedsArrayAdapter adapter = null;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View table = inflater.inflate(R.layout.fragment_list, container, false);
listView = (ListView)table.findViewById(R.id.listViewSpeeds);
MySQLiteHelper mSQLHelper = new MySQLiteHelper(getActivity());
List <MichealSpeedBean> mSpeeds = mSQLHelper.getAllSpeedEntries();
adapter = new SpeedsArrayAdapter(getActivity(),
R.layout.list_item, mSpeeds);
listView.setAdapter(adapter);
listView.setOnItemLongClickListener(this);
return table;
}
#Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view, int position, long id) {
MySQLiteHelper mSQLHelper = new MySQLiteHelper(getActivity());
MichealSpeedBean michealSpeedBean = adapter.getItem(position);
mSQLHelper.deleteSpeedById(michealSpeedBean.getObjectId());
adapter.remove(michealSpeedBean);
Toast.makeText(getActivity(),
"Entry deleted " + position, Toast.LENGTH_LONG)
.show();
return false;
}
#Override
public void onRefresh() {
//getActivity Returns null here, if called form FragmentyActivity
}
And my Fragment Activity looks like this:
public class MainActivity extends FragmentActivity {
ViewPager viewPager;
TabPagerAdapter tabAdapter;
ActionBar actionBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tabAdapter = new TabPagerAdapter(getSupportFragmentManager());
viewPager = (ViewPager)findViewById(R.id.pager);
viewPager.setOnPageChangeListener(
new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar = getActionBar();
actionBar.setSelectedNavigationItem(position);
if (position == 1) {
//Here i tried to update my list from outside of my fragment
((OnRefreshListener)tabAdapter.getItem(position)).onRefresh();
}
}
}
);
viewPager.setAdapter(tabAdapter);
actionBar = getActionBar();
//Enable Tabs on Action Bar
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.TabListener tabListener = new ActionBar.TabListener(){
#Override
public void onTabReselected(android.app.ActionBar.Tab tab,
FragmentTransaction ft) {
}
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(android.app.ActionBar.Tab tab,
FragmentTransaction ft) {
}};
//Add New Tab
actionBar.addTab(actionBar.newTab().setText("General").setTabListener(tabListener));
actionBar.addTab(actionBar.newTab().setText("Speed entries").setTabListener(tabListener));
}
So the question is where/ how can i update my table content?
Thank you in advance!
you can use following code:
public class ListFragment extends Fragment
#Override
public void setMenuVisibility(final boolean visible) {
super.setMenuVisibility(visible);
if (getActivity() != null )
{
if (visible) {
// update your list, your fragment is visible now
}
}
}
you can use this:
listview.invalidateViews();
enjoy!
I have actionbar tabs and when a tab is clicked I want to add new button to my fragment.
This is my fragment code where I am adding buttons:
Button btn;
View myView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
int numberOfButtons= getArguments().getInt("someInt",0);
LinearLayout view = new LinearLayout(getActivity());
// Inflate the layout for this fragment
view.setOrientation(LinearLayout.VERTICAL);
view.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
for (int i = 0;i<numberOfButtons;i++)
{
btn = new Button(getActivity());
view.addView(new Button(getActivity()));
}
myView = view;
return myView;
}
This my MainActivity code where I am sending number of buttons to the fragment:
int numberOfButtons=0;
public static FragmentA newInstance(int someInt) {
FragmentA myFragment = new FragmentA();
Bundle args = new Bundle();
args.putInt("someInt", someInt);
myFragment.setArguments(args);
return myFragment;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
for (int i=0;i<10;i++)
{
ActionBar.Tab tab = actionBar.newTab().setText("Tab"+i).setTabListener(new ActionBar.TabListener() {
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
String tabText = (String)tab.getText();
String asd = (String)(tabText.substring(3,tabText.length()));
numberOfButtons = Integer.parseInt(asd);
FragmentA fragmentA = newInstance(numberOfButtons);
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(R.id.mainLayout,fragmentA,"fragA");
transaction.commit();
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
}
});
actionBar.addTab(tab);
}
}
This code adds buttons but there is a problem here. When Tab1 is clicked, one button is added to the fragment. When Tab2 is clicked, two buttons are added to the fragment but the first button that added by Tab1 is not removed. One of the new buttons is placed over it.
Is there any way to reset the fragment layout or remove old items of fragment before adding new ones?
From your code it seems like you're just adding the fragments' instances on top of each other.
The button added by Tab1 is not removed because Tab1 is still there in the background...
Try using the transaction.remove() method to remove the previous fragment before calling transaction.add() to add a new one...
There's also the transaction.replace() method that does both operations at the same time. Perhaps it's also worth a try.
it's a multi tap activity >>
I'm trying to set a layout for each tab but it doesnt work !
it simply shows nothing in both tabs !
Here's the code
public class Game extends Activity {
public static Context appContext;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.game);
//ActionBar gets initiated
ActionBar actionbar = getActionBar();
//Tell the ActionBar we want to use Tabs.
actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
//initiating both tabs and set text to it.
ActionBar.Tab roundTab = actionbar.newTab().setText("Round 55");
ActionBar.Tab scoreTab = actionbar.newTab().setText("Score 55");
//create the two fragments we want to use for display content
Fragment roundFragment = new roundFragment();
Fragment scoreFragment = new scoreFragment();
//set the Tab listener. Now we can listen for clicks.
roundTab.setTabListener(new MyTabsListener(roundFragment));
scoreTab.setTabListener(new MyTabsListener(scoreFragment));
//add the two tabs to the actionbar
actionbar.addTab(roundTab);
actionbar.addTab(scoreTab);
}
class MyTabsListener implements ActionBar.TabListener {
public Fragment fragment;
public MyTabsListener(Fragment fragment) {
this.fragment = fragment;
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
}
public class roundFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.round, container, false);
}
}
public class scoreFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.score, container, false);
}
}
}
Your onTabSelected() is empty. that's why it shows nothing on selection.
Add this code to your onTabSelected() of your MyTabsListener .
public void onTabSelected(Tab tab, FragmentTransaction ft) {
ft.add([id the container /viewgroup in which you have to load your fragment],fragment)
}
It's not the way to do it, and it seems over complicated...for UI with Tabs, I suggest you to use the ViewPagerIndicator library, it's well known, reliable and easy to use.
Is it possible to display tabs without using fragments in android 3.0?I have created actionbar with tabs extending fragments.But without using fragments and by extending activity will i be able to display tabs.I need to achieve that.pls help.I have posted my code also.
Java Code :
public class ActionbarActivity extends Activity {
ActionBar bar;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ActionBar bar = getActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.Tab tabA = bar.newTab().setText("Home");
ActionBar.Tab tabB = bar.newTab().setText("Listings");
ActionBar.Tab tabC = bar.newTab().setText("Remote");
Fragment fragmentA = new ATab();
Fragment fragmentB = new BTab();
Fragment fragmentC = new CTab();
bar.setDisplayShowHomeEnabled(true);
tabA.setTabListener(new MyTabsListener(fragmentA));
tabB.setTabListener(new MyTabsListener(fragmentB));
tabC.setTabListener(new MyTabsListener(fragmentC));
bar.addTab(tabA);
bar.addTab(tabB);
bar.addTab(tabC);
}
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.option, menu);
return true;
}
protected class MyTabsListener implements ActionBar.TabListener {
private Fragment mfragment;
public MyTabsListener(Fragment fragment) {
this.mfragment = fragment;
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
ft.add(R.id.fragment_place, mfragment, null);
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
ft.remove(mfragment);
}
}
}
public class ATab extends Fragment
{
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
return inflater.inflate(R.layout.atab, container, false);
}
}
public class BTab extends Fragment
{
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
return inflater.inflate(R.layout.btab, container, false);
}
}
public class CTab extends Fragment
{
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
return inflater.inflate(R.layout.ctab, container, false);
}
}
xml.code :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<LinearLayout android:layout_height="wrap_content"
android:layout_width="match_parent"
android:id="#+id/fragment_place"></LinearLayout>
</RelativeLayout>
You don't have to use fragments to use tabs and I've successfully done this within one of my apps, just changing content on tab selection.
public class Main extends Activity implements ActionBar.TabListener {
int mDisplayMode;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
mDisplayMode = settings.getInt("displayMode", 0);
ActionBar actionBar = getActionBar();
actionBar.addTab(
actionBar.newTab().setText("Decimal").setTabListener(this)
);
actionBar.addTab(
actionBar.newTab().setText("Hexadecimal").setTabListener(this)
);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionBar.selectTab(actionBar.getTabAt(mDisplayMode));
// Other code
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
mDisplayMode = tab.getPosition();
// do stuff based on new tab selected
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
// do nothing
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// do nothing
}
// ..
}