How to Update Fragment ViewPager
My approach to update fragments within the viewpager is to use the setTag()
method for any instantiated view in the instantiateItem()
method. So when you want to change the data or invalidate the view that you need, you can call the findViewWithTag()
method on the ViewPager
to retrieve the previously instantiated view and modify/use it as you want without having to delete/create a new view each time you want to update some value.
Imagine for example that you have 100 pages with 100 TextView
s and you only want to update one value periodically. With the approaches explained before, this means you are removing and instantiating 100 TextView
s on each update. It does not make sense…
You can see complete code here
In my adapter
import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import android.view.ViewGroup; import com.thedeveloperworldisyours.refreshcurrentfragment.fragments.FirstFragment; import com.thedeveloperworldisyours.refreshcurrentfragment.fragments.SecondFragment; import com.thedeveloperworldisyours.refreshcurrentfragment.fragments.ThirdFragment; import java.util.HashMap; import java.util.Map; /** * Created by javierg on 09/01/2017. */ public class MyPagerAdapter extends FragmentPagerAdapter { private static int NUM_ITEMS = 3; private Map<Integer, String> mFragmentTags; private FragmentManager mFragmentManager; public MyPagerAdapter(FragmentManager fragmentManager) { super(fragmentManager); mFragmentManager = fragmentManager; mFragmentTags = new HashMap<Integer, String>(); } // Returns total number of pages @Override public int getCount() { return NUM_ITEMS; } // Returns the fragment to display for that page @Override public Fragment getItem(int position) { switch (position) { case 0: return FirstFragment.newInstance(); case 1: return SecondFragment.newInstance(); case 2: return ThirdFragment.newInstance(); default: return null; } } // Returns the page title for the top indicator @Override public CharSequence getPageTitle(int position) { return "Page " + position; } @Override public Object instantiateItem(ViewGroup container, int position) { Object object = super.instantiateItem(container, position); if (object instanceof Fragment) { Fragment fragment = (Fragment) object; String tag = fragment.getTag(); mFragmentTags.put(position, tag); } return object; } public Fragment getFragment(int position) { Fragment fragment = null; String tag = mFragmentTags.get(position); if (tag != null) { fragment = mFragmentManager.findFragmentByTag(tag); } return fragment; } }
And now in my activity:
import android.support.v4.app.Fragment; import android.support.v4.view.ViewPager; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import com.thedeveloperworldisyours.refreshcurrentfragment.adapter.MyPagerAdapter; public class MainActivity extends AppCompatActivity implements ViewPager.OnPageChangeListener{ MyPagerAdapter mAdapterViewPager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ViewPager viewPager = (ViewPager) findViewById(R.id.activity_main_view_pager); mAdapterViewPager = new MyPagerAdapter(getSupportFragmentManager()); viewPager.setAdapter(mAdapterViewPager); viewPager.addOnPageChangeListener(this); } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { Fragment fragment = mAdapterViewPager.getFragment(position); if (fragment != null) { fragment.onResume(); } } @Override public void onPageScrollStateChanged(int state) { } }
Finally in your fragment, something like that:
import android.animation.Animator; import android.content.Context; import android.os.Bundle; import android.support.v4.app.Fragment; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewAnimationUtils; import android.view.ViewGroup; import android.widget.RelativeLayout; import com.thedeveloperworldisyours.refreshcurrentfragment.R; public class FirstFragment extends Fragment { RelativeLayout mView; Context mContext; public FirstFragment() { // Required empty public constructor } /** * Use this factory method to create a new instance of * this fragment using the provided parameters. * * @return A new instance of fragment FirstFragment. */ // TODO: Rename and change types and number of parameters public static FirstFragment newInstance() { return new FirstFragment(); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View view = inflater.inflate(R.layout.fragment_first, container, false); mView = (RelativeLayout) view.findViewById(R.id.fragment_first_view); return view; } @Override public void onResume() { super.onResume(); onAnimationStart(); } @Override public void onAttach(Context context) { super.onAttach(context); mContext = context; } public void onAnimationStart() { Log.d("FirstFragment","onAnimationStart()"); // get the center for the clipping circle int cx = (mView.getRight()); int cy = (mView.getBottom()); // get the final radius for the clipping circle int finalRadius = Math.max(mView.getWidth(), mView.getHeight()); // create the animator for this view (the start radius is zero) Animator anim = ViewAnimationUtils.createCircularReveal(mView, cx, cy, 0, finalRadius); anim.setDuration(1000); // make the view visible and start the animation mView.setVisibility(View.VISIBLE); anim.start(); } }
You can see complete code here