In My application, I have used the ViewPager. Like,
(say main.xml)
you can use this method to update your views
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
// Fetch data or something...
}
}
I faced the same issue - getItem() method was called twice. I don't know about your purposes of using that method by mine was to trigger changes in a hosting activity when new slide appears.
Well, first of all getItem() is not a right method to get event of appearing new slide.
I used ViewPager.OnPageChangeListener listener on ViewPager itself for this purpose. Here is what I did:
In Activity that holds slide fragments:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.signature_wizard_activity);
// Instantiate a ViewPager and a PagerAdapter.
mPager = (ViewPager) findViewById(R.id.pager);
mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
mPager.setAdapter(mPagerAdapter);
mPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
onSlideChanged(position); // change color of the dots
}
@Override
public void onPageSelected(int position) {}
@Override
public void onPageScrollStateChanged(int state) {}
});
}
onPageScrolled() is called every time your slide appears, as a parameter it gets current position of the slide that is shown. Nice thing is that it is called including the first time it appears, not just when slide was changed.
When it can be used? For example if you have some wizard activity with ViewPager where you slide fragments with some hints, you probable would like to have a bar with grey dots below the slider that would represent the number of slides in total, and one of the dots will be different color representing the current slide. In this case ViewPager.OnPageChangeListener and method onPageScrolled() will be the best option.
Or if you have buttons PREV. and NEXT which change slides and you want to disable PREV. button on the first slide and disable NEXT button on the last slide. Here is how you do it inside onPageScrolled() method:
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if(position == 0){
prevBtn.setTextColor(ContextCompat.getColor(SignatureWizardActivity.this, R.color.main_grey_500));
prevBtn.setEnabled(false);
}else{
prevBtn.setTextColor(ContextCompat.getColor(SignatureWizardActivity.this, R.color.main_blue));
prevBtn.setEnabled(true);
}
if(position == NUM_PAGES -1){
nextBtn.setTextColor(ContextCompat.getColor(SignatureWizardActivity.this, R.color.main_grey_500));
nextBtn.setEnabled(false);
}else{
nextBtn.setTextColor(ContextCompat.getColor(SignatureWizardActivity.this, R.color.main_blue));
nextBtn.setEnabled(true);
}
}
where NUM_PAGES is a constant with total number of slides
The FragmentPagerAdapter
instantiates 2 Fragments
on start, for index 0 and for index 1. If you want to get data from the Fragment
which is on the screen, you can use setOnPageChangeListener
for the Pager
to get current position. Then have SparseArray
with WeakReference
to your fragments. Update that array in the getItem
call. When onPageSelected
gets called use that position to get reference to right Fragment
and update User
data.
Initialization of array:
private SparseArray<WeakReference<MyFragment>> mFragments = new SparseArray<WeakReference<MyFragment>>(3);
My Problem is getItem() method is called twice on First time
This is not the problem, this is default feature of FragmentPagerAdapter
. Its good for you to swipe from this page to the next one and previous one.
the view displayed in the emulator is 0th index, but got 1st Index value in the FragmentActivity
I got the same issue, and I know why. This because you used same Fragment in View Pager
.
How to fix this is separate Fragments by using different Fragment
.
in getItem method i wrote this..
@Override
public Fragment getItem(int index) {
EditFragment frag = new EditFragment();
Bundle args = new Bundle();
args.putSerializable("currentItem", itemsList.get(index));
frag.setArguments(args);
return (frag);
}
here itemsList.get(index) is the model class object which i will use in EditFragment class. here is that.
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View result = inflater.inflate(R.layout.pager_fragment_layout, container, false);
image = (ImageView)result.findViewById(R.id.pager_image);
text = (TextView)result.findViewById(R.id.pager_item_desc);
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getActivity()).build();
ImageLoader.getInstance().init(config);
imLoader = ImageLoader.getInstance();
****NOTE
final SwapItems itemList = (SwapItems) getArguments().getSerializable("currentItem");
imagePath = itemList.getPaths().get(0);
imLoader.displayImage(imagePath,image);
text.setText(itemList.getItemDescription());
image.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Fragment fragment = new ItemImagesFragment();
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Bundle bundle = new Bundle();
bundle.putSerializable("val", itemList);
fragment.setArguments(bundle);
fragmentTransaction.replace(R.id.content_frame, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
});
return result;
}
NOTE: here i am getting swapitems model object from previous getItem method is 'final'. this solves my issue. Earlier i was initialized the same object with static as modifier.
hope yours will also clear