I've tried to implement PagerSlidingTabStrip to my app but it just isn't working. I did everything that is done in the sample but it isn't working. The tab indicator just isn't moving as it is supposed to and the app isn't crashing. Basically nothing is happening. I have no idea what is wrong.
MainActivity code
public class MainActivity extends FragmentActivity implements TabListener {
ActionBar aBar;
ViewPager vPager;
PagerAdapter pAdapter;
PagerSlidingTabStrip slidingTabStrip;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Action Bar
aBar = getActionBar();
aBar.setTitle("Beautiful Voice Recorder");
aBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Variables
slidingTabStrip = (PagerSlidingTabStrip) findViewById(R.id.slidingTabs);
vPager = (ViewPager) findViewById(R.id.pager);
pAdapter = new PagerAdapter(getSupportFragmentManager());
// Tabs
vPager.setAdapter(pAdapter);
slidingTabStrip.setViewPager(vPager);
aBar.addTab(aBar.newTab().setText("Record").setTabListener(this));
aBar.addTab(aBar.newTab().setText("Library").setTabListener(this));
vPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
LibraryFragment listViewFragment = (LibraryFragment)pAdapter.instantiateItem(vPager, 1);
RecordFragment recordFragment = (RecordFragment)pAdapter.instantiateItem(vPager, 0);
listViewFragment.updateComponents();
// Pause mp if it's playing and tabs are switched just in case
if (listViewFragment.mp.isPlaying())
{
listViewFragment.mp.pause();
listViewFragment.playPause.setBackgroundResource(R.drawable.play_button_selector);
}
if (recordFragment.isRecording)
{
recordFragment.stopRecording();
}
aBar.setSelectedNavigationItem(position);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
vPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
}
class PagerAdapter extends FragmentPagerAdapter{
String[] pageTitles = { "Record", "Library" };
public PagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int arg0) {
Fragment fragment = new Fragment();
if (arg0 == 0)
{
fragment = new RecordFragment();
}
if (arg0 == 1)
{
fragment = new LibraryFragment();
}
return fragment;
}
#Override
public int getCount() {
return pageTitles.length;
}
#Override
public CharSequence getPageTitle(int position) {
return pageTitles[position];
}
}
XML
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.astuetz.PagerSlidingTabStrip
android:id="#+id/slidingTabs"
android:layout_width="match_parent"
android:layout_height="48dip" />
<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="match_parent" />
</RelativeLayout>
Does anyone have any idea why my code is not working?
I think you didn't locate ViewPager even if it's RelativeLayout.
so try this code that i'm using. I hope it will be helpful for you.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.astuetz.PagerSlidingTabStrip
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="48dip"
/>
<com.flitto.app.widgets.MainViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/tabs"
tools:context=".MainTabActivity"/>
</RelativeLayout>
I found where the problem was lying after I took a deeper look at the sample code. The problem was the fact that I still had the previous ActionBar tabs left in the code and those were overlapping the PagerSlidingTabStrip tabs so that I didn't see them.
All I had to do was to remove every reference to ActionBar tabs and it worked!
Related
EDIT The latest design libraries fixed this issue
compile 'com.android.support:design:+'
I am working with the TabLayout in two instances, PagerAdapter and FragmentStatePagerAdapter. In both cases the tab indicator bounces, when swiped between pages. The tab indicator doesn't bounce when clicking tab's to change pages.
I am not sure if it is an error on my part, it is a known issue, or part of the guidelines. If you need more code, or the other example I will post it.
FragmentStatePagerAdapter
mViewPager.setAdapter(new FragmentStatePagerAdapter(getSupportFragmentManager()) {
#Override
public Fragment getItem(int position) {
LogMeal log = mLogMealAdapter.getItem(position);
return MealViewFragment.newInstance(log.getId());
}
#Override
public CharSequence getPageTitle(int position) { // Tab text
LogMeal logMeal1 = mLogMealAdapter.getItem(position);
String s;
if (logMeal1.getMealName().toString().trim().length() > 12) {
s = logMeal1.getMealName().substring(0, 12) + "..";
} else {
s = logMeal1.getMealName();
}
return s;
}
#Override
public int getCount() {
return mLogMealAdapter.getCount();
}
});
tabs.setTabTextColors(Color.parseColor("#80ffffff"), Color.parseColor("#ffffff"));
if (mLogMealAdapter.getCount() == 1) {
tabs.setTabMode(TabLayout.MODE_FIXED);
} else {
tabs.setTabMode(TabLayout.MODE_SCROLLABLE);
}
tabs.setupWithViewPager(mViewPager);
mViewPager.setCurrentItem(position);
XML
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar_meal_view"
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="#color/primary"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_below="#+id/toolbar_meal_view"
android:background="#color/primary"
android:theme="#style/ToolbarTheme"/>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/tabs"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_below="#+id/tabs"
android:background="#drawable/toolbar_shadow"/>
</RelativeLayout>
I had a similar problem recently.
My workaround:
1) Change tabs.setupWithViewPager(mViewPager); for
\\ use own OnPageChangeListener
mViewPager.addOnPageChangeListener(new MyPageScrollListener(mTabLayout));
\\ Manually add tabs, for example:
mTabLayout.addTab(mTabLayout.newTab().setText(mViewPager.getAdapter().getPageTitle(0)));
mTabLayout.addTab(mTabLayout.newTab().setText(mViewPager.getAdapter().getPageTitle(1)));
\\ use own OnTabSelectedListener
mTabLayout.setOnTabSelectedListener(new MyOnTabSelectedListener());
2) Add implementation for custom listeners
private class MyPageScrollListener implements ViewPager.OnPageChangeListener {
private TabLayout mTabLayout;
public MyPageScrollListener(TabLayout tabLayout) {
this.mTabLayout = tabLayout;
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
if(mTabLayout != null) {
mTabLayout.getTabAt(position).select();
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
}
private class MyOnTabSelectedListener implements TabLayout.OnTabSelectedListener {
#Override
public void onTabSelected(TabLayout.Tab tab) {
int position = tab.getPosition();
if (mViewPager.getCurrentItem() != position) {
mViewPager.setCurrentItem(position, true);
}
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
}
I hope it helps.
It is a bug on design support library 22.2.0
Maybe it will be fixed.
https://code.google.com/p/android/issues/detail?id=175073
The indicator "bouncing" bug has been fixed in version 22.2.1 and superior.
Just update your build.gradle:
dependencies {
//...
compile 'com.android.support:design:22.2.1'
}
I have a main Activity with a navigation drawer and I'm trying to realize a layout like Play Music App with tabs.
The MainActivity has a FrameLayout like a container:
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
and I want to put inside the #+id/container a Fragment with Tabs.
How's the best way to do this?
I thought I can create a MyFragment which extends Fragment and implements TabListener.
The associated layout could be like
<?xml version="1.0" encoding="utf-8"?>
<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="match_parent" >
</android.support.v4.view.ViewPager>
But then how can I proceed?
Try following the following steps:
First, create your activity and extend FragmentActivity and implement TabListener
Secondly, create your TabsPagerAdapter
Thirdly, create your fragment (or fragments if more than one is needed).
You can then set the adapter in your activity after requesting navigation mode to tabs.
Code Sample
public class SampleActivity extends FragmentActivity implements ActionBar.TabListener {
private ViewPager viewPager;
private ActionBar actionBar;
private TabsPagerAdapter mAdapter;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_ACTION_BAR);
setContentView(R.layout.gd_pager);
getActionBar().setDisplayHomeAsUpEnabled(true);
viewPager = (ViewPager) findViewById(R.id.pager);
actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
String [] tabs = new String[]{"Tab1", "Tab2", "Tab3", "Tab3"};
for(String tab : tabs)
{
actionBar.addTab(actionBar.newTab()
.setText(tab)
.setTabListener(this));
}
mAdapter = new TabsPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(mAdapter);
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft)
{
viewPager.setCurrentItem(tab.getPosition());
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener()
{
#Override
public void onPageSelected(int position)
{
actionBar.setSelectedNavigationItem(position);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2)
{
}
#Override
public void onPageScrollStateChanged(int arg0)
{
}
});
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
}
}
I am fairly new to android programming but what I am trying to do seems fairly simple though. I have this setup with 4 different tabs in the action bar, the first should display a Fragment with the Google maps API and the others some other stuff i haven't done yet. Following some tutorials online I managed to get the functionality I wanted for the tabs and get the map to appear.
The app is working fine when changing from the initial tab with the map (tab 1) to any other, but when trying to come back it crashes. Weirdly enough when the map fragment is in one of the tabs it makes the second tab crash as well on some transitions, in the image bellow the transitions shown as blue arrows work fine, while the ones with yellow arrows make the app crash.
http://imageshack.com/a/img839/4796/kf7w.png
If I change the first tab fragment for one of the others all the transitions work fine again, therefore I think the problem must indeed be with the map fragment.
My code is as follows:
MainActivity.java
public class MainActivity extends FragmentActivity implements ActionBar.TabListener {
private ViewPager viewPager;
private TabsPagerAdapter mAdapter;
private ActionBar actionBar;
private String[] tabs = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.pager);
actionBar = getActionBar();
mAdapter = new TabsPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(mAdapter);
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
tabs = getResources().getStringArray(R.array.tab_names);
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) {
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
}
TabsPagerAdapter.java
public class TabsPagerAdapter extends FragmentPagerAdapter {
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int index) {
switch (index){
case 0:
return new GoogleMapsFragment();
case 1:
return new SampleFragment();
case 2:
return new ContactFragment();
case 3:
return new WhoFragment();
default:
Log.e("switch", "default");
}
return null;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 4;
}
}
GoogleMapsFragment.java
public class GoogleMapsFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.activity_map, container, false);
return rootView;
}
#Override
public void onDestroyView() {
super.onDestroyView();
Fragment f = (Fragment) getFragmentManager().findFragmentById(R.id.map);
if (f != null) {
getFragmentManager().beginTransaction().remove(f).commit();
}
}
}
And the xml files:
activity_main.xml
<RelativeLayout 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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity"
android:background="#ffff0000"
android:id="#+id/mainLayout"
android:tag="#+id/mainLayoutTag" >
<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="match_parent"
android:tag="pagerTag">
</android.support.v4.view.ViewPager>
</RelativeLayout>
activity_map.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="#+id/mapLayout"
android:tag="mapLayoutTag" >
<fragment android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.google.android.gms.maps.MapFragment"
android:tag="gMaps"/>
</RelativeLayout>
The other java classes are pretty much empty and the other xml files only contain the default RelativeLayout.
Any suggestion as to what I could do to fix this?
Thanks for your time reading all of that :)
EDIT:
Forgot to put the crash error:
02-10 23:42:01.723: E/AndroidRuntime(7221): Caused by:
java.lang.IllegalArgumentException: Binary XML file line #9:
Duplicate id 0x7f05000a, tag gMaps, or parent id 0x7f050009 with another
fragment for com.google.android.gms.maps.MapFragment
Well managed to solve this only by switching the position of the super call in the onDestroy() function. It seems I needed to first destroy or unassign the fragment from its parent to make it work. Heres the new onDestroy() code if anyone is still having the same problem:
#Override
public void onDestroyView() {
userMarker.remove();
Fragment f = (Fragment) getFragmentManager().findFragmentById(R.id.map);
if (f != null) {
getFragmentManager().beginTransaction().remove(f).commit();
}
super.onDestroyView();
}
After loads of search, finally I found this tutorial : Using an Android MapView inside of a Fragment
and it works awesome !!! hopefully it helps your guys !
I can't seem to update the ui in one of my fragments, I'm not sure why. I have a main activity which should send some json to the fragment and update the UI with the data from the JSON object. I'm sending the json over successfully and I can log the data in the Fragment which I have sent over. I am just not able to update the textbox value in the UI.
In my mainactivity
MainPageFragment myFragment = new MainPageFragment();
SectionsPagerAdapter mSectionsPagerAdapter;
ViewPager mViewPager;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//Create adapter that will return a fragment for each section of app
mSectionsPagerAdapter = new SectionsPagerAdapter(getFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
}
#Override
public void onSuccess(JSONObject user) {
//This seems to be all I need
myFragment.grabJSON(user);
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle (int position) {
return titles[position];
}
#Override
public Fragment getItem(int position) {
if (position == 1) {
return new PreferenceFragment() {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.layout.settings_preferances);
}
};
}
else {
return myFragment;
}
}
}
In my MainFragment.java
public void grabJSON(JSONObject object){
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
TextView usernameTextView = (TextView) getView().findViewById(R.id.usernameview);
CharSequence val = usernameTextView.getText();
Log.d("value", val.toString());
usernameTextView.setText("NEW TEXT");//Set the Text
val = usernameTextView.getText();
Log.d("value", val.toString());
}
});
}
The fact that it sends the json is irrelevant, according to the log, my value of the textbox is changing but the actual UI is not changing.
I'm adding here the xml for the mainactivity
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<android.support.v4.view.PagerTabStrip
android:id="#+id/pager_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:textColor="#fff"/>
<FrameLayout
android:id="#+id/fragment_placeholder"
android:layout_width="fill_parent"
android:layout_height="fill_parent" ></FrameLayout>
</android.support.v4.view.ViewPager>
This has been updated with correct code, turns out I was defining the fragment twice
Thank you all,
Tom
Your fragment is getting added twice.
It's added via the layout XML file, and then you do a fragment transaction to add it aw well. Adding fragments via layout doesn't work as well as it should, so you should put in a placeholder view and then add the fragment via the fragment manager. That should clear everything up.
I'm guessing you dont add the fragment in the activity?
FragmentManager fragmentManager = getFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
MainPageFragment fragment = new MainPageFragment ();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
I am using a ViewPager to swipe between 4 tabs. I'd love to align the tabs where the current tab is in the aligned middle and there is one tab (if available) on far right, and one on far left.
I know you can do some tricky stuff like that with some of the Third party libraries (for example, by Jake Wharton). But can I have this control with the native ViewPager? (I am also using Support Library v4.)
At the very least, my question is, can I define how many tabs show up on the screen? I have 4, and would like 3 at any given time.
Here is my layout
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TabWidget
android:id="#android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:orientation="horizontal" />
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0" />
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
The normal view of a tabbed app has three tabs on the top, and you are allowed to swipe through them. If you have more tabs in your viewpager, you can scroll through as many as you like.
The implementation would be similar to this:
public class MainActivity extends FragmentActivity implements ActionBar.TabListener {
private ViewPager ViewPager;
private TabsPagerAdapter SectionsPagerAdapter;
private ActionBar actionBar;
private String[] tabs = { "Event Details", "Line-up", "Donations", "Concert"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initialisation
ViewPager = (ViewPager) findViewById(R.id.pager);
actionBar = getActionBar();
SectionsPagerAdapter = new TabsPagerAdapter(getSupportFragmentManager());
ViewPager.setAdapter(SectionsPagerAdapter);
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Adding Tabs
for (String tab_name : tabs) {
actionBar.addTab(actionBar.newTab().setText(tab_name).setTabListener(this));
}
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) {
}
});
}
#Override
public void onTabReselected(Tab tab, android.app.FragmentTransaction ft) {
}
#Override
public void onTabSelected(Tab tab, android.app.FragmentTransaction ft) {
ViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(Tab tab, android.app.FragmentTransaction ft) {
}
}
Hope this helps :)