ViewPager calling multiple times -- Android - android

I am doing graph using onDraw() method. I have four different Fragments which contains different graphs. I used ViewPager to show the graph in swipe model.
When I call viewPager.getCount() it's getting called multiple times. Later I found that the onDraw() method was calling each time I touched the screen or when I swipe the fragment. I really wondered why the Fragment is called several times while using ViewPager. I didn't get any proper solution for this, can anyone guide me how to restrict multiple calling of getCount() or calling Fragment when doing a swipe.

Try this,
Add a mViewPager.setOnPageChangeListener(mPageLitsener);
And
define as,
private ViewPager.OnPageChangeListener mPageLitsener = new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
switch (position) {
case 0:
((FirstFragment)mViewPagerAdapter.getItem(0)).onUpdate();
break;
case 1:
((SecondFragment)mViewPagerAdapter.getItem(1)).onUpdate();
break;
case 2:
((ThirdFragment)mViewPagerAdapter.getItem(2)).onUpdate();
break;
default:
((FirstFragment)mViewPagerAdapter.getItem(0)).onUpdate();
break;
}
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {}
#Override
public void onPageScrollStateChanged(int arg0) {}
};
Then call a public method inside of Fragment (i.e, onUpdate()), and define that as what you need.

Related

Android studio - tabbed activity how to reset fragment to default view?

I have one fragment where are three (default) images and when user click on them, they will change to another. But when i swipe to another fragment and back to fragment with images there are not default ones as on the start. When I swipe two times so I will pass to another fragment (distance from original with images is 2 fragments) images are resetted to default. I was trying to implement setOffscreenPageLimit() from ViewPager and set it to 1, but minimum "length" when views in fragments are resetted is 2. How can I change that images to default manually after swipe action? Thank you.
Edit: I think that issue why onResume() is not working here: Fragment onResume not called
but i dont know what that means :/ I have three classes FragmentController.class, PagerAdapter.class and class of specific fragment for example FirstFragment.class. I don't know how connect these classes together.
Check that you create the fragments in the getItem() method of the adapter and do not hold any reference to that fragments (only WeakReferences if necessary), otherwise the fragments could not be destroyed.
EDIT:
The first fragment is unloaded only when you are in the third one because setOffscreenPageLimit is at least 1 so a viewpager allways loads the fragments that are at both sides of the selected one.
What you could do is to update your adapter with this code to provide a getFragment(position) method:
private HashMap<Integer, WeakReference<Fragment>> fragmentReferences = new HashMap<>();
#Override
public Fragment getItem(int position) {
Fragment fragment;
switch (position) {
case 0:
fragment = FirstFragment.newInstance();
break;
// etc
}
fragmentReferences.put(position, new WeakReference<>(fragment));
return fragment;
}
public Fragment getFragment(int position) {
WeakReference<Fragment> ref = fragmentReferences.get(position);
return ref == null ? null : ref.get();
}
After then you can get the selected fragment and call the method you want from the first fragment when a page is selected:
viewPager.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageSelected(int currentPage) {
if (currentPage == 0) {
Fragment firstFragment = adapter.getFragment(0);
if (firstFragment != null) {
// This method resets the images of the first fragment
((FirstFragment) firstFragment).reset();
}
}
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// Do nothing
}
#Override
public void onPageScrollStateChanged(int state) {
// Do nothing
}
});

Android: ViewPager + Fragments: modify fragment view when "onPageScrolled"

Well, I think the title is quite self explanatory. I have a ViewPager in my HomeActivity, the ViewPager contains 5 fragments at the moment.
When one of the fragments is visible by calling ViewPager's onPageScrolled I want to modify some views inside the current displayed fragment according to some conditions in the HomeActiviy.
After some research, it seems like I cannot find a good way to communicate in the direction HomeActivity --> Fragments inside ViewPager.
I have easily solved the communication in the direction Fragments in ViewPager --> HomeActivity using an Interfacebut this trick seems to not be working on the other direction.
I can access each time the current displayed fragment using a method on my FragmentStatePagerAdapter
public Fragment getActiveFragment(int position){
return myFragmentsList.get(position);
}
However, by doing that, I would have to cast each Fragment into its class MyFragment1 MyFragment2 MyFragment3....
Any easy clean way to achieve that?. Here is the relevant portion of the code:
mPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if (currentStatus == 1){
Fragment activeFrag = mPagerAdapter.getActiveFragment(mPager.getCurrentItem());
//here I would like to modify one of the 5 fragments
}
#Override
public void onPageSelected(int position) {}
#Override
public void onPageScrollStateChanged(int state) {}
});
Define an interface,
interface FragmentListenerInterface {
public void onFragmentSelected();
}
Implement this interface in all of your fragments. change the communication between fragment and viewpager. write a method to return fragmentlistenerinterface instead of fragment.
public FragmentListenerInterface getActiveFragment(int position){
return (FragmentListenerInterface) myFragmentsList.get(position);
}
After this just say, in your code
public void onPageSelected(int position) {
mViewPager.getActiveFragment(position).onFragmentSelected();
}
And implement onFragmentSelected() in every fragment.

android viewpager inside another viewpager

I'm trying to have a viewpager with few views (let's say 5?) and in one of the views (let's say 3rd view?) I have to put another viewpager so after searching for a while, I've come up with some questions which I couldn't get the exact answer for my situtation.
How is it possible to implement a viewpager inside a fragment of another viewpager?
If it's possible to do the above task, how's the touch function will be handled for viewpagers ? Isn't changing views for the inner viewpager gonna affect the outer one?
I don't really need a code kinda solution but more like a concept kinda solution, so I'm not asking for anyone to do my coding, but I've been quiet away from android and I rather to hear the new concepts from the pros.
thanks in advance.
Edit:
Ok I managed to do it at some point but another problem I'm facing now.
here is the call to the fragment which contains my viewpager:
Fragment fragment = new Fragment();
switch(position)
{
case 0: fragment = new CalendarFragment();break;
case 1: fragment = new DummySectionFragment();
Bundle args = new Bundle();
args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, 2);
fragment.setArguments(args);break;
}
return fragment;
and this is the oncreate of calendarFragment class:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View cal = inflater.inflate(R.layout.calendar, container, false);
viewPager = (ViewPager) cal.findViewById(R.id.calendar_pager);
viewPager.setOnTouchListener( new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN && v instanceof ViewGroup) {
((ViewGroup) v).requestDisallowInterceptTouchEvent(true);
}
return false;
}
});
viewPager.setAdapter(createCalendarAdaptor());
viewPager.setCurrentItem(MONTHS_LIMIT / 2);
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int arg0) {
//updateResetButtonState();
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
});
return cal;
}
and I get the calendar in the first fragment and it works just fine and I can easily scroll to next page, and then I can easily move back to the first page, but when I move to 3rd page and then I go back to first page which is my other viewpager it cause an error:
java.lang.IllegalStateException: Recursive entry to executePendingTransactions
I'm not quiet sure why is it happening, I've done some searching and it appears it's because I'm using a viewpager inside a fragment...
Any help would be appreciated.

FragmentStatePageAdapter Doesn't Pause Fragments

I'm using a FragmentStatePageAdapter (android.support.v4) and I have setOffscreenPageLimit set to 2, so it creates and stores Fragments 2 ahead and 2 behind of the currently displayed Fragment.
Problem:
When the off-screen Fragments are created, they are also immediately started and resumed even though they haven't been painted to the screen yet. (!)
When the current page is changed and the corresponding Fragment is swiped off screen, it isn't paused or stopped. (!)
I've tried logging the behavior of all the callbacks in FSPA and its super class - setPrimaryItem comes the closest to being usable but appears to be called for all sorts of reasons, not just when the fragment is displayed.
How can you detect that one of your Fragments is no longer displayed, or returning to the display?
You could use a listener.
mPager.setOnPageChangeListener(new OnPageChangeListener(){
#Override
public void onPageScrollStateChanged(int arg0) {
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageSelected(int position) {
if(mPageSelectedListener!=null){
mPageSelectedListener.pageSelected(position);
}
}
});
Where PageSelectedListener is defined by you like so
public interface PageSelectedListener{
public void pageSelected(int position);
};
public void setPageSelectedListener(PageSelectedListener l){
mPageSelectedListener = l;
}
And use it like this in your fragment
if(getActivity() instanceof MyActivity
((MyActivity)getActivity()).setPageSelectedListener(new PageSelectedListener(){
#Override
public void pageSelected(int position) {
if(position==MyAdapter.MY_PAGE){
// do something with currently viewed page...like resume it
} else {
// do something with any other page..like pause it
}
}
});
}

How to insert own activity on the ViewPager?

I want to create ViewPager with this tutorial:
ViewPager example
But i don't know how can I use my own activity on First layout or Second layout.
This is function which change layout:
private void setTab(){
_mViewPager.setOnPageChangeListener(new OnPageChangeListener(){
#Override
public void onPageScrollStateChanged(int position) {}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {}
#Override
public void onPageSelected(int position) {
// TODO Auto-generated method stub
switch(position){
case 0:
findViewById(R.id.first_tab).setVisibility(View.VISIBLE);
findViewById(R.id.second_tab).setVisibility(View.INVISIBLE);
break;
case 1:
findViewById(R.id.first_tab).setVisibility(View.INVISIBLE);
findViewById(R.id.second_tab).setVisibility(View.VISIBLE);
break;
}
}
});
}
I want to create ViewPager with this tutorial: ViewPager example
That is not an especially good sample. Please consider using PagerTitleStrip, PagerTabStrip (both in the Android Support package, along with ViewPager) or one of the classes from ViewPagerIndicator.
But i don't know how can I use my own activity on First layout or Second layout.
ViewPager does not hold activities. It holds views, optionally managed by fragments. The concept of having activities inside of other activities is not recommended and is officially deprecated.

Categories

Resources