ViewPager not getting updated using FragmentStatePagerAdapter

纵然是瞬间 提交于 2019-12-05 07:24:14

You could use the following PagerFragment base class for your fragments and implement the onVisible method as needed:

public abstract class PagerFragment extends Fragment {

private boolean mCalled = false;
private boolean mWasVisible = false;
private boolean mIsResumed = false;
private boolean mIsPaused = false;

protected void onVisible() {
    mCalled = true;
}

protected void onHide() {
    mCalled = true;
}

/**
 * {@inheritDoc}
 * 
 * @see android.app.Fragment#onAttach(android.app.Activity)
 */
@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
}

/**
 * {@inheritDoc}
 * 
 * @see android.app.Fragment#onDetach()
 */
@Override
public void onDetach() {
    super.onDetach();
}

/**
 * {@inheritDoc}
 * 
 * @see android.app.Fragment#onResume()
 */
@Override
public void onResume() {
    super.onResume();
    mIsPaused = false;
    mIsResumed = true;
    setUserVisibleHint(getUserVisibleHint());
}

/**
 * {@inheritDoc}
 * 
 * @see android.app.Fragment#onPause()
 */
@Override
public void onPause() {
    mIsPaused = true;
    mIsResumed = false;
    setUserVisibleHint(getUserVisibleHint());
    super.onPause();
}

/**
 * {@inheritDoc}
 * 
 * @see android.app.Fragment#setUserVisibleHint(boolean)
 */
@Override
public void setUserVisibleHint(boolean visible) {
    super.setUserVisibleHint(visible);

    mCalled = false;
    if (mIsResumed) {
        if (visible) {
            performVisible();
            mWasVisible = visible;
        } else {
            performHide();
            mWasVisible = visible;
        }
    } else if (mIsPaused && mWasVisible) {
        performHide();
        mWasVisible = visible;
    }

}

private void performVisible() {
    onVisible();
    if (!mCalled) {
        throw new SuperNotCalledException("PagerFragment " + this + " did not call through to super.onVisible()");
    }
}

private void performHide() {
    onHide();
    if (!mCalled) {
        throw new SuperNotCalledException("PagerFragment " + this + " did not call through to super.onHide()");
    }
}

}

Or you simply preload the Data on Fragment A and notify the Adapter when the data was loaded and then change the pages. It is always possible to add and remove Fragments dynamically from a ViewPager. So you may also try to delete the fragment with the old data and create a new one afterwards.

You haven't shown the critical part, i.e. MyTabActivity.navigateFragment().

I believe you are trying to reuse existing instance of Fragment B, and pass new data by Fragment.setArguments()

setArguments has no use after Fragment is created

either

  1. create new instance of Fragment B every time and replace the existing one, or
  2. pass the new data using custom functions in the fragment

I would suggest method 1, because by doing this, your data is kept even if Activity recreation, e.g. screen rotation. For method 2, you need extra work to handle Activity recreate.

If I understand you correctly, you can try using the onPageSelected and depending on position update your fragments on which page is selected.

        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        @Override
        public void onPageSelected(int position) {

        //use this to run when your fragment is visible

        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    });

As you might know you are loading the image in a background process. i.e using volley library.

your adapter.notifyDataSetChanged() is being called even before the process is finished. But as you told when you call it on the button click it works, then solution is simple.

Call your adapter.notifyDataSetChanged() after the background process is completed.

i.e inside :-

  @Override
      public void onResponse(ImageContainer response, boolean result) {
        // TODO Auto-generated method stub

        if (response.getBitmap() != null) {

            ivProductImage.setImageBitmap(response.getBitmap());
            pBar.setVisibility(View.GONE);
            adapter.notifyDataSetChanged();
        }
    }
});

When you are using FragmentStatePagerAdapter, getItem() is called just once, so initially you have the correct image, but then it stays the same.

You should reload your data using a callback interface. So when the one of items in your Fragment A is selected, you reload data in your Fragment B. For this you will need to add

public void reloadData() {
//relaod your data here
}

Then create a callback interface in Fragment A like this

public interface itemSelectedListener {
    void onItemSelected(View view, int position)
}

Implement this interface in activity that holds both fragments

in

onItemSelected() {
    MyFragmentB myFragmentB = ...//get your fragment
    myFragmentB.reloadData();
}

Finally I've solved the answer. Fragment B was getting saved in navigateFragment, it has been prevented by the following line and it worked.

    if (mCurrentFragment != null) {
        if (mCurrentFragment instanceof GetProducts)
            saveFragmentState(mCurrentFragment.getClass().getName(), mCurrentFragment);
    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!