Viewpager with Toolbar - android

I have a bar which includes menu. Im using viewbar and i need to show my bar every single page.
So thats why i created my bar in MainActivity and viewpager_layout.xml
If i use same fragment layout every page its working well but when i try change layout its suck. Here my code.
MainActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.viewpager_layout);
ViewPager vpPager = (ViewPager) findViewById(R.id.viewPager);
adapterViewPager = new viewPagerAdapter(getSupportFragmentManager());
vpPager.setAdapter(adapterViewPager);
vpPager.setCurrentItem(0);
getBottomBar();
// Attach the page change listener inside the activity
vpPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
// This method will be invoked when a new page becomes selected.
#Override
public void onPageSelected(int position) {
Toast.makeText(MainActivity.this,
"Seçilen sayfa: " + position, Toast.LENGTH_SHORT).show();
if (position == 0)
{
bottomNavigationBar.selectTab(0);
}
if (position == 1)
{
bottomNavigationBar.selectTab(1);
}
}
// This method will be invoked when the current page is scrolled
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// Code goes here
}
// Called when the scroll state changes:
// SCROLL_STATE_IDLE, SCROLL_STATE_DRAGGING, SCROLL_STATE_SETTLING
#Override
public void onPageScrollStateChanged(int state) {
// Code goes here
}
});
}
BottomNavigationBar bottomNavigationBar;
private void getBottomBar() {
bottomNavigationBar = (BottomNavigationBar) findViewById(R.id.bottom_navigation_bar);
bottomNavigationBar
.addItem(new BottomNavigationItem(R.drawable.home, "Anasayfa"))
.addItem(new BottomNavigationItem(R.drawable.group, "Gruplar"))
.addItem(new BottomNavigationItem(R.drawable.counter, "Votloc"))
.addItem(new BottomNavigationItem(R.drawable.date, "Profil"))
.addItem(new BottomNavigationItem(R.drawable.password, "Daha Fazla"))
.initialise();
bottomNavigationBar.setTabSelectedListener(new BottomNavigationBar.OnTabSelectedListener(){
#Override
public void onTabSelected(int position) {
}
#Override
public void onTabUnselected(int position) {
}
#Override
public void onTabReselected(int position) {
}
});
bottomNavigationBar
.setMode(BottomNavigationBar.MODE_FIXED);
bottomNavigationBar
.setBackgroundStyle(BottomNavigationBar.BACKGROUND_STYLE_RIPPLE);
bottomNavigationBar
.setActiveColor(R.color.colorPrimary)
.setInActiveColor("#FFFFFF")
.setBarBackgroundColor("#FF1717");
}
viewpager_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.ashokvarma.bottomnavigation.BottomNavigationBar
android:layout_gravity="bottom"
android:id="#+id/bottom_navigation_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<android.support.v4.view.ViewPager
android:id="#+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
What should I do for use my bar every single page.
Am I have to create bar in every fragments ?

I realized it was because I used <include> to add the ListView to my fragment from another layout resource file.
After that I created a new layout file and I just included my ListView directly into the new layout file. Then I used this new layout file for myMainFragment.java file and finally my ViewPager works well.

Related

how to change tablayout indicator color by index in android?

I have a ViewPager2 in my activity and TabLayout attached to this viewpager2 as below:
<com.google.android.material.tabs.TabLayout
android:id="#+id/tab_layout"
android:layout_width="match_parent"
app:tabIndicatorColor="#color/colorPrimary"
app:tabMode="fixed"
android:layout_height="2dp" />
<androidx.viewpager2.widget.ViewPager2
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/vpager"/>
I have attached the TabLayout to ViewPager as below
new TabLayoutMediator(tabLayout, vpager,
new TabLayoutMediator.TabConfigurationStrategy() {
#Override public void onConfigureTab(#NonNull TabLayout.Tab tab, int position) {
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
}).attach();
My target is to keep the indicator color selected in previous tab seeing by the user, so if the user go to next tab, the previous one must be coloring as the selected, like the images below
The images show the first indicator is selected and keep it selected when going to the next fragment, so it can be like a progress bar.
I choose to set the indicator color programmatically by index, how?
The TabLayout indicator color functionality is limited the current selected tab of the TabLayout; so it affects only the current tab; not any other tab.
Instead, you can use a ProgressBar for that and set the progress whenever the ViewPager changes the page:
Layout
<ProgressBar
android:id="#+id/progress_bar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<androidx.viewpager2.widget.ViewPager2
android:id="#+id/intro_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Behavior
ProgressBar progressBar = findViewById(R.id.progress_bar);
progressBar.max = pageCount // Change pageCount to the number of pages in your ViewPager2
mViewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
progressBar.setProgress(position + 1);
}
#Override
public void onPageSelected(int position) {
progressBar.setProgress(position + 1);
}
});

How to disable the transition of fragments?

I am building a quiz app with three questions and therefore I have 6 Fragments but I would like to disable the default transition from one fragment to another, how can I achieve this? I already disabled that you can swipe between the fragments, you have to click a button to get to the next fragment, but there is still somehow a swiping transition after clicking the button. I searched for this but there was never an answer that would fit my problem. Here is one fragment example:
public class FragmentQuestion1 extends Fragment {
private Button btnNavFrag1;
private EditText editText;
private ProgressBar m_bar;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_question_1, container, false);
btnNavFrag1 = view.findViewById(R.id.btn_question1);
editText = view.findViewById(R.id.edit_text_question_1);
editText.addTextChangedListener(new NumberTextWatcher(editText));
m_bar = view.findViewById(R.id.progress_bar_question_1);
btnNavFrag1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
((GameActivity)getActivity()).setViewPager(2);
}
});
return view;
}
// Method that is used so the countdown starts when the user gets to this fragment
#Override
public void setMenuVisibility(final boolean visible) {
super.setMenuVisibility(visible);
if (visible) {
startCountdownTimer();
}
}
// Countdown 17 seconds
int i = 0;
private void startCountdownTimer() {
m_bar.setProgress(i);
final int totalMsecs = 17 * 1000; // 17 seconds in milli seconds
int callInterval = 100;
/** CountDownTimer */
new CountDownTimer(totalMsecs, callInterval) {
public void onTick(long millisUntilFinished) {
int secondsRemaining = (int) millisUntilFinished / 1000;
float fraction = millisUntilFinished / (float) totalMsecs;
// progress bar is based on scale of 1 to 100;
m_bar.setProgress((int) (fraction * 100));
}
public void onFinish() {
}
}.start();
}
Because you are using a viewPager, you could use a library like this which lets you add a transformer (some sort of effect) to the viewPager when going to the next fragment. I'd recommend the ZoomOutTranformer for your use-case. If the transition is not what you expect you can always extend from that class and override the transition so it's more to your liking.
ViewPagerTransformers are native, so you don't need to use a library. Just create a class, implement the PageTransformer interface and override the method transformPage.
In your layout xml define a tablayout and a FrameLayout like this:
..................your xml code...............
.............................................................
<com.google.android.material.tabs.TabLayout
android:id="#+id/simpleTabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabBackground="#color/colorPrimary"
app:tabIndicatorColor="#0080FF"
app:tabSelectedTextColor="#050505"
app:tabTextColor="#color/colorAccent">
<com.google.android.material.tabs.TabItem
android:id="#+id/abcd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Item 1" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="item 2" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="item 3" />
</com.google.android.material.tabs.TabLayout>
<FrameLayout
android:id="#+id/simpleFrameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
This layout is defined for three tabs. You can make it for more tabs by adding more tabs if you like.
Then define the fragments for each tab. In this case:
item_one_fragment:
<?xml version="1.0" encoding="utf-8"?>
<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"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context="your.activity.context">
......................................
............................................
fragments xml
.............................
,.....................................
</RelativeLayout>
Similarly item 2 and item 3 fragment layouts.
Then define the fragments in java:
public class FirstItemFragment extends Fragment {
public ListView CallListView;
public FirstFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.item_one_fragment, container, false);
// Inflate the layout for this fragment
return view;
}
}
Simiarly second and third fragment.
Then in your Main Activity:
FrameLayout simpleFrameLayout = (FrameLayout) findViewById(R.id.simpleFrameLayout);
TabLayout tabLayout = (TabLayout) findViewById(R.id.simpleTabLayout);
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.simpleFrameLayout, new FirstItemFragment());
ft.commit();
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
// get the current selected tab's position and replace the fragment accordingly
Fragment fragment = null;
switch (tab.getPosition()) {
case 0:
fragment = new FirstItemFragment();
break;
case 1:
fragment = new SecondItemFragment();
break;
case 2:
fragment = new ThirdItemFragment();
break;
}
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.simpleFrameLayout, fragment)
.addToBackStack(null)
//Commit the transaction.
.commit();
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
Now when you run your activity you will have three tabs and when you click on any one you will go to the respective fragment without any swipe

FAB animation with viewpager/tabslider

I'm trying to find way to achieve such effect https://material-design.storage.googleapis.com/publish/material_v_4/material_ext_publish/0B6Okdz75tqQsVlhxNGJCNTEzNFU/components-buttons-fab-behavior_04_xhdpi_009.webm
I'm using android.support.v4.view.ViewPager
I appreciate any hints and help
First, you need to have the layout with the floating action button anchored to the ViewPager:
<android.support.design.widget.CoordinatorLayout
android:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="#+id/action_bar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"/>
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/white"
app:tabGravity="center"
app:tabIndicatorColor="?attr/colorAccent"
app:tabMode="scrollable"
app:tabSelectedTextColor="?attr/colorAccent"
app:tabTextColor="#android:color/black" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
app:layout_anchor="#id/viewpager"
app:layout_anchorGravity="bottom|right|end"
android:layout_width="56dp"
android:layout_height="56dp"
android:src="#drawable/ic_add_white"
app:borderWidth="#dimen/fab_border_width"
app:fabSize="normal" />
</android.support.design.widget.CoordinatorLayout>
Now that you have the FAB anchored to the ViewPager (note: I've tried this on a fragment that is a tab in the viewpager; it does not seem to behave properly), add an OnPageChangeListener to your ViewPager like so:
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
switch (position) {
case INDEX_OF_TAB_WITH_FAB:
fab.show();
break;
default:
fab.hide();
break;
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
The animations for the "pop" and the "shrink" upon switching tabs are handled automatically for you with the new version of the Support Library.
Here is another solution. The problem for me with other ones is that giving the control of the FAB to the activity that contains the ViewPager makes thing difficult to code.
I need lots of controls on the FAB by the Fragments to easily change the FAB icon and set specific listeners on it.
Roughly, the steps are:
Declares one FAB in the main activity that contains the ViewPager, and not in the fragments (it is a mandatory step that I wanted to avoid, but the magic comes after; doing otherwise makes things difficult for a good animation)
In each fragment to be displayed in the ViewPager, I create a method where I can pass a FAB, like public void shareFab(FloatingActionButton sharedFab); inside this method, each fragment will set the FAB icon and add the needed listeners
I set up a ViewPager.OnPageChangeListener listener on the ViewPager that will trigger animations and calls my shareFab methods.
So each time a fragment is displayed, the containing activity will give to the displayed fragment the reference of the FAB. The fragment then reset/recycle the FAB to suit its needs.
Here is an example:
The fragments to display
public void Fragment1 extends Fragment {
private FloatingActionButton mSharedFab;
#Override
public void onDestroy() {
super.onDestroy();
mSharedFab = null; // To avoid keeping/leaking the reference of the FAB
}
public void shareFab(FloatingActionButton fab) {
if (fab == null) { // When the FAB is shared to another Fragment
if (mSharedFab != null) {
mSharedFab.setOnClickListener(null);
}
mSharedFab = null;
}
else {
mSharedFab = fab;
mSharedFab.setImageResource(R.drawable.ic_search);
mSharedFab.setOnClickListener((fabView) -> {
// Your code
});
}
}
}
The container activity
public class ActivityMain extends AppCompatActivity {
FloatingActionButton mSharedFab;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSharedFab = (FloatingActionButton) findViewById(R.id.shared_fab);
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
Fragment1 fragment1 = new Fragment1();
Fragment2 fragment2 = new Fragment2();
adapter.addFragment(fragment1, "Fragment1");
adapter.addFragment(fragment2, "Fragment2");
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
viewPager.setAdapter(adapter);
fragment1.shareFab(mSharedFab); // To init the FAB
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { }
#Override
public void onPageSelected(int position) { }
#Override
public void onPageScrollStateChanged(int state) {
switch (state) {
case ViewPager.SCROLL_STATE_DRAGGING:
mSharedFab.hide(); // Hide animation
break;
case ViewPager.SCROLL_STATE_IDLE:
switch (viewPager.getCurrentItem()) {
case 0:
fragment2.shareFab(null); // Remove FAB from fragment
fragment1.shareFab(mSharedFab); // Share FAB to new displayed fragment
break;
case 1:
default:
fragment1.shareFab(null); // Remove FAB from fragment
fragment2.shareFab(mSharedFab); // Share FAB to new displayed fragment
break;
}
mSharedFab.show(); // Show animation
break;
}
}
});
}
}
... and the classical layout of the main activity
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
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:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"
app:tabGravity="fill"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/shared_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/fab_margin" />
</android.support.design.widget.CoordinatorLayout>
The pros are:
animation like the one described in the Material Design guidelines!
full control of the FAB by each fragments
The cons are:
since the FAB can be shared to another fragments, the reference of the FAB should be checked each time to be sure it is not null
declaration of the FAB at the level of the ViewPager, a little cumbersome
For good animation of hide and show use this :
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
switch (state){
case ViewPager.SCROLL_STATE_IDLE:
fab.show();
break;
case ViewPager.SCROLL_STATE_DRAGGING:
case ViewPager.SCROLL_STATE_SETTLING:
fab.hide();
break;
}
}
});
The solution that I discovered was:
My fragments that are shown within my ViewPager implement an Interface (in my case FloatingActionButtonFragment). This interface requires that the fragment have a method handleFABClick(View).
My ViewPager change listener then looks like below:
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
switch (state) {
case ViewPager.SCROLL_STATE_SETTLING:
displayFloatingActionButtonIfNeeded(viewPager.getCurrentItem());
break;
case ViewPager.SCROLL_STATE_IDLE:
displayFloatingActionButtonIfNeeded(viewPager.getCurrentItem());
break;
default:
mFloatingActionButton.hide();
}
}
});
private void displayFloatingActionButtonIfNeeded(int position) {
if (mFragmentStatePagerAdapter.getItem(position) instanceof FloatingActionButtonFragment) {
final FloatingActionButtonFragment floatingActionButtonFragment = (FloatingActionButtonFragment) mFragmentStatePagerAdapter.getItem(position);
mFloatingActionButton.show();
mFloatingActionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
floatingActionButtonFragment.handleFABClick(v);
}
});
}
}
This makes the FAB 'hide' when the user is changing views, but then triggers the show method when the view state is either idle (it has settled) or is settling (I needed to do both as it didn't feel right only using idle).
I recently found much better solution that i am satisfied with. FAB hide method can also have a parameter - listener which is triggered when the button is hidden (show method also have this). The only drawback is that you have to implement viewpager and tablayout changes manually.
#Override
public void onPageSelected(int position) {
onToolbarTitleChanged(adapter.getPageTitle(position).toString());
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(final TabLayout.Tab tab) {
fab.hide(new FloatingActionButton.OnVisibilityChangedListener() { // Hide FAB
#Override
public void onHidden(FloatingActionButton fab) {
fab.show(); // After FAB is hidden show it again
}
});
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
If you want to show FAB only on specific tabs, you can change the onTabSelected method to:
#Override
public void onTabSelected(TabLayout.Tab tab) {
if (tab.getPosition() == 2) {
createButton.hide();
}
viewPager.setCurrentItem(tab.getPosition());
}
For my problem, I did not want to show floating action button on first Tab; in order to achieve this I added
android:visibility="invisible"
in floating action bar.
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="#dimen/fab_margin"
android:visibility="invisible"
app:srcCompat="#android:drawable/ic_input_add" />
And I have added ViewpagerListner in my activity as suggested by #chantell
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
switch (position) {
case 0:
addFloatingActionBt.hide();
break;
default:
addFloatingActionBt.show();
break;
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
});

PagerSlidingTabStrip isn't working, but my code seems OK to me

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!

Google Maps MapFragment causing the app to crash

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 !

Categories

Resources