In making the swipe tabbed layout as below prior to Android 5.0:
Simply required the code as:
#Override
public void onCreate(Bundle savedInstanceState) {
final ActionBar actionBar = getActionBar();
...
// Specify that tabs should be displayed in the action bar.
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Create a tab listener that is called when the user changes tabs.
ActionBar.TabListener tabListener = new ActionBar.TabListener() {
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
// show the given tab
}
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
// hide the given tab
}
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
// probably ignore this event
}
};
// Add 3 tabs, specifying the tab's text and TabListener
for (int i = 0; i < 3; i++) {
actionBar.addTab(
actionBar.newTab()
.setText("Tab " + (i + 1))
.setTabListener(tabListener));
}
}
But given the methods for navigation on the ActionBar are deprecated, How can I implement this type of view to be compatible withe Android 5.0 and previous versions?
You need to update to Toolbar here is the documentation.
http://android-developers.blogspot.mx/2014/10/appcompat-v21-material-design-for-pre.html
Related
I have the following scenario:
In my main activity, I'm using sliding tabs using viewpager and fragmentpageradapter.
Suppose I have 2 tabs.
In Tab 2, on an event(say button press), I start a new activity using startActivityForResult.
Now, when I get back to Tab 2 from the new activity (in onActionResult), I want Tab 1 to get refreshed.
I'm currently doing it using getActivity.recreate()
Is this good way to do considering performance or is there any other way?
My main activity onCreate code is:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
final ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
// setup action bar for tabs
final ActionBar actionBar = getActionBar();
TabsPagerAdapter mAdapter = new TabsPagerAdapter(getFragmentManager());
viewPager.setAdapter(mAdapter);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionBar.setDisplayShowTitleEnabled(true);
// Create a tab listener that is called when the user changes tabs.
ActionBar.TabListener tabListener = new ActionBar.TabListener() {
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
viewPager.setCurrentItem(tab.getPosition());
}
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
}
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
}
};
ActionBar.Tab tab = actionBar.newTab()
.setText(R.string.tab1)
.setTabListener(tabListener);
actionBar.addTab(tab, 0, false);
tab = actionBar.newTab()
.setText(R.string.tab2)
.setTabListener(tabListener);
actionBar.addTab(tab, 1, true);
// on swiping the viewpager make respective tab selected
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
getActionBar().setSelectedNavigationItem(position);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
}
Why is this code crashing I am doing this exactly according to Google's guidelines but I am getting a null pointer exception on the line
final ActionBar actionBar = getActionBar();
Here is the complete code. I am doing this exactly per Google's dev page which I have linked to here http://developer.android.com/training/implementing-navigation/lateral.html
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
setContentView(R.layout.pager_view);
//TabSetup
tabPagerAdapter = new TabPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(tabPagerAdapter);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
getActionBar().setSelectedNavigationItem(position);
}
});
final ActionBar actionBar = getActionBar();
assert actionBar != null;
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.TabListener tabListener = new ActionBar.TabListener() {
#Override
public void onTabSelected(ActionBar.Tab tab, android.app.FragmentTransaction ft) {
mViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(ActionBar.Tab tab, android.app.FragmentTransaction ft) {
}
#Override
public void onTabReselected(ActionBar.Tab tab, android.app.FragmentTransaction ft) {
}
};
//ADD THE APP'S 3 TABS
actionBar.addTab(actionBar.newTab().setText("News").setTabListener(tabListener));
actionBar.addTab(actionBar.newTab().setText("Surveys").setTabListener(tabListener));
actionBar.addTab(actionBar.newTab().setText("Connect").setTabListener(tabListener));
}
Note that action bar tabs were deprecated with Android 5.0.
Beyond that, you probably are using a theme that does not have a native action bar, such as Theme.AppCompat. If you are using appcompat-v7 with Theme.AppCompat, make sure that you are inheriting from ActionBarActivity and then use getSupportActionBar() instead of getActionBar().
i am currently implementing some swipable tabs into my app, i have got it all working good, the part i am struggling on is changing the icon of the tab when the user swipes.
Basically the tabs update fine when the user swipes and selects the tabs, it updates from selected to non selected, the problem is that it is also changing the actionbar main icon and i was wondering how to stop this and only update the tabs.
Here is the relevant code for the main activity let me know if you need anything else
public class MainActivity extends FragmentActivity implements
ActionBar.TabListener{
private ViewPager viewPager;
private TabsPagerAdapter mAdapter;
private ActionBar actionBar;
// Tab titles
private static final int[] ICONS = new int[] {
R.drawable.ic_tab_n,
R.drawable.ic_tab_f,
R.drawable.ic_tab_h,
R.drawable.ic_tab_n,
R.drawable.ic_tab_p,
};
private static final int[] ICONS_SELECTED = new int[] {
R.drawable.ic_tab_n_selected,
R.drawable.ic_tab_f_selected,
R.drawable.ic_tab_h_selected,
R.drawable.ic_tab_n_selected,
R.drawable.ic_tab_p_selected,
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initilization
viewPager = (ViewPager) findViewById(R.id.pager);
actionBar = getActionBar();
mAdapter = new TabsPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(mAdapter);
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Adding Tabs
// for (String tab_name : tabs) {
// actionBar.addTab(actionBar.newTab().setText(tab_name).setIcon(resources.getDrawable(ICONS[]))
// .setTabListener(this));
// }
for (int i=0; i < tabs.length; i++) {
actionBar.addTab(actionBar.newTab()
.setIcon(ICONS[i])
.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);
actionBar.setIcon(ICONS_SELECTED[position]);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
if (arg0 == ViewPager.SCROLL_STATE_DRAGGING) {
actionBar.setIcon(ICONS[viewPager.getCurrentItem()]);
}
}
});
viewPager.setCurrentItem(2, false);
}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
// on tab selected
// show respected fragment view
viewPager.setCurrentItem(tab.getPosition());
tab.setIcon(ICONS_SELECTED[tab.getPosition()]);
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
tab.setIcon(ICONS[tab.getPosition()]);
}
}
I see this twice in your code, and it seems likely to do exactly what you don't want to happen:
actionBar.setIcon(ICONS_SELECTED[position]);
There is no reason to change the action bar icon, so those lines should be commented out.
Edit: Setting and then resetting the tab icons probably is not going to work either. I recommend changing the code to use a state list drawable for the tab icons, where each of the five tabs gets its own state list drawable as an icon, that will automatically display the corresponding selected or unselected version of its icon, depending on the state of the tab.
Edit: The Android 4 standard clock app is a good example of icons in tabs. The source at the link should be very useful, especially the drawable folder.
I have run into an obstacle when doing my Android application. My issue is that I cannot create an onTabListener for my tabs. I have three tabs with different names. The problem is that they all have the same tab count. In my code I ran this:
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
int n = getActionBar().getTabCount();
Toast.makeText(getApplicationContext(), "You have selected: " + n, Toast.LENGTH_LONG).show();
}
This makes a toast saying the value of the tab (for example: 0, 1, 2, 3), but all of the tabs have the same indicator. I cannot make an onTabListener if I have all my tabs have the same indicator. Here is my full code:
ActionBar.TabListener tabListener = new ActionBar.TabListener() {
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
int n = getActionBar().getTabCount();
Toast.makeText(getApplicationContext(), "You have selected: " + n, Toast.LENGTH_LONG).show();
}
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
// hide the given tab
}
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
// probably ignore this event
}
};
// Add 3 tabs, specifying the tab's text and TabListener
for (int i = 0; i < 3; i++) {
actionBar.addTab(
actionBar.newTab()
.setText(tabTitle[i])
.setTabListener(tabListener));
}
What is the issue? Is there any way I can create an onTabListener using the tab's title? Any help to this problem is greatly appreciated.
all you are doing is getting the number of tabs you have...
you need to do tab.getPosition() to get what one selected
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
int n = tab.getPosition();
Toast.makeText(getApplicationContext(), "You have selected: " + n, Toast.LENGTH_LONG).show();
}
Is my following Action bar Tab implementation method is efficient or not? Because whenever i switch between tabs the Tab content fragments are replaced and load again in frame layout.
I want to add fragments at first time itself and show the fragments smoothly(without reloading) when switch between tabs.
Note: i tried to add all fragments on onCreate method.But the fragments are overlapped with each other and display all fragments in frame layout at same time.
My Code:
public class ManageActivity extends SherlockFragmentActivity implements ActionBar.TabListener {
private Activity mActivity;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_manage);
getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.Tab tab1 = getSupportActionBar().newTab();
tab1.setText("Tab1");
tab1.setTabListener(this);
getSupportActionBar().addTab(tab1);
ActionBar.Tab tab2 = getSupportActionBar().newTab();
tab2.setText("Tab2");
tab2.setTabListener(this);
getSupportActionBar().addTab(tab2);
ActionBar.Tab tab3 = getSupportActionBar().newTab();
tab3.setText("Tab3");
tab3.setTabListener(this);
getSupportActionBar().addTab(tab3);
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
String selectedtab = tab.getText().toString();
if(selectedtab.equalsIgnoreCase("Tab1"))
{
getSupportFragmentManager().beginTransaction().replace(R.id.tabfragment_container, new Tab1Fragment()).commit();
}
else if (selectedtab.equalsIgnoreCase("Tab2")) {
getSupportFragmentManager().beginTransaction().replace(R.id.tabfragment_container, new Tab2Fragment()).commit();
}
else if (selectedtab.equalsIgnoreCase("Tab3")){
getSupportFragmentManager().beginTransaction().replace(R.id.tabfragment_container, new Tab3Fragment()).commit();
}
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
}
activity_manage.xml:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/tabfragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ManageActivity" >
</FrameLayout>
Note: My Tab contents are Listfragments which query data from Sqlite using loader manager.
I use a ViewPager that contains all my fragments. Every time a tab is selected I only switch the position in the Viewpager.
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
int position = adapter.findItemPosition(this.id);
ViewPager viewPager = (YourActivity)getActivity().getViewPager(); // Convenience method
if (viewPager != null) {
viewPager.setCurrentItem(position, this.shouldScroll);
} else {
Log.d(getClass().getSimpleName(), "No pager available");
}
}
To make this code working you need a Viewpager and have to add all tabs into the ViewPager through an instance of PagerAdapter. I use a FragmentPagerAdapter as there are not that many tabs most of the time.
This also enables your user to swipe through the tabs. If the user changes the selected tab through swiping you need to update the selected tab. I use ActionBarSherlock in all of my Apps. Therefore the next Snippet uses a supportActionBar. This code example is a simple listener that can be set on the ViewPager to update tab changes through swiping.
private final class TabPageChangedListener extends ViewPager.SimpleOnPageChangeListener {
#Override
public void onPageSelected(int position) {
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setSelectedNavigationItem(position);
} else {
Log.e(getClass().getSimpleName(),
"No actionbar available to change selected tab.");
}
}
}
There is also the possibility to disable swiping by overwriting the ViewPager and intercepting the swiping touch motions if you do not want the tabs to be swipeable.