I have implemented in my application tab swiping with ViewPager, Fragments etc. Everything is working fine. But I would like to know which function is run after swiping to next tab? Because I need to refresh some data when user will swipe to next screen.
I have this functions in my activity:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootview = inflater.inflate(R.layout.activity_main_sensors_p, container, false);
return rootview;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
update_data();
display_items();
}
YourFragment extends Fragment {
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (this.isVisible()) {
....
} else {
....
}
}
}
You can try set OnPageChangeListener listener to your ViewPager and do action accrding to the current position in pager adapter:
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
// do action accroding to the viewPager position
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
Related
I have Activity with LastTransactionsFragment, this fragment contains TabLayout with 3 tabs (AllTransactionsFragment , IncomesTransactionsFragment and OutgoesTransactionsFragment). All the tabs shows RecyclerView with list of transactions. User can delete row in each fragments. I need to implement if user delete row in 2nd fragment it also delete it immediately in 1st fragment. For now it delete row in main fragment and in database, but not in others fragments. It changes when i move to other and go back. All fragments look the same:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_all_transactions_list, container, false);
DatabaseHelper databaseHelper = new DatabaseHelper(getContext());
ArrayList<TransactionModel> lastTransactionsList = databaseHelper.getAllTransactionList();
Collections.reverse(lastTransactionsList);
RecyclerView recyclerView = view.findViewById(R.id.rv_allTransactionsList);
adapter = new LastTransactionsAdapter(getContext(), lastTransactionsList, false);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
return view;
}
EDIT
here is short video of the issue: https://streamable.com/398zke
EDIT 2
On Fragment with TabLayout
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
if (position== 0){
IncomesTransactionsListFragment fragment = new IncomesTransactionsListFragment();
fragment.refreshRecyclerView();
} else if (position == 1){
AllTransactionsListFragment allTransactionsListFragment = new AllTransactionsListFragment();
allTransactionsListFragment.refreshRecyclerView();
} else if (position == 2){
AllTransactionsListFragment allTransactionsListFragment = new AllTransactionsListFragment();
allTransactionsListFragment.refreshRecyclerView();
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
and the method in each fragments:
public void refreshRecyclerView(){
adapter.notifyDataSetChanged();
}
EDIT 3
main fragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_last_transactions, container, false);
final ViewPager viewPager = view.findViewById(R.id.vp_allTransactions);
TabLayout tabLayout = view.findViewById(R.id.tl_allTransactions);
adapter = new TransactionsViewPagerAdapter(getChildFragmentManager(), FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT, tabLayout.getTabCount());
viewPager.setAdapter(adapter);
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
if (position == 0){
IncomesTransactionsListFragment fragment = new IncomesTransactionsListFragment();
System.out.println(0);
fragment.refreshRecyclerView();
} else if (position == 1){
AllTransactionsListFragment allTransactionsListFragment = new AllTransactionsListFragment();
System.out.println(1);
allTransactionsListFragment.refreshRecyclerView();
} else if (position == 2){
AllTransactionsListFragment allTransactionsListFragment = new AllTransactionsListFragment();
System.out.println(2);
allTransactionsListFragment.refreshRecyclerView();
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
return view;
}
}
tab fragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_all_transactions_list, container, false);
DatabaseHelper databaseHelper = new DatabaseHelper(getContext());
ArrayList<TransactionModel> lastTransactionsList = databaseHelper.getAllTransactionList();
Collections.reverse(lastTransactionsList);
RecyclerView recyclerView = view.findViewById(R.id.rv_allTransactionsList);
adapter = new LastTransactionsAdapter(getContext(), lastTransactionsList, false);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
return view;
}
public void refreshRecyclerView(){
adapter.notifyDataSetChanged();
}
}
You need to add the addOnPageChangeListener() to update any fragments data from activity. for ex.
pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetpxl) {
}
#Override
public void onPageSelected(int position) {
/*get your fragments instance and write one method in that fragment to refresh the list. call this method from here*/
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
Use this link for reference: https://www.legendblogs.com/blog/how-to-use-tablayout-in-viewpager-with-recyclerview/121810
I am using ViewPager to show 4 fragments but the problem is that on loading first fragment second fragment is also getting called i.e. the onActivityCreate() method of both the fragments is getting called together and on swiping to second fragment third fragment's onActivityCreate() and so on for other fragments and for last fragment no onActivityCreate() is getting called. How to resolve that.
Here are my files:
Purchase Details
public class PurchaseDetails extends AppCompatActivity implements ActionBar.TabListener {
ViewPager viewPager;
ActionBar actionBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_purchase_details);
viewPager=findViewById(R.id.master_purchase_pager);
FragmentManager fm=getSupportFragmentManager();
actionBar = getSupportActionBar();
actionBar.setTitle("Purchase Details");
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
viewPager.setAdapter(new PurchaseFragmentAdapter(fm));
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
ActionBar.Tab tab1 = actionBar.newTab();
tab1.setText("Date Selector");
tab1.setTabListener(this);
ActionBar.Tab tab2 = actionBar.newTab();
tab2.setText("Week");
tab2.setTabListener(this);
ActionBar.Tab tab3 = actionBar.newTab();
tab3.setText("Month");
tab3.setTabListener(this);
ActionBar.Tab tab4 = actionBar.newTab();
tab4.setText("Year");
tab4.setTabListener(this);
actionBar.addTab(tab1);
actionBar.addTab(tab2);
actionBar.addTab(tab3);
actionBar.addTab(tab4);
}
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
}
}
PurchaseFragmentAdapter
public class PurchaseFragmentAdapter extends FragmentPagerAdapter {
public PurchaseFragmentAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
Fragment fragment=null;
if(position==0)
{
fragment= new PurchaseDateSelector();
}
else if(position==1)
{
fragment= new PurchaseWeek();
}
else if(position==2)
{
fragment= new PurchaseMonth();
}
else if(position==3)
{
fragment= new PurchaseYear();
}
return fragment;
}
#Override
public int getCount() {
return 4;
}
}
PurchaseDateSelector
public class PurchaseDateSelector extends Fragment
{
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.purchase_date_selector_fragment,container,false);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Toast.makeText(getActivity(), "Purchase Date Selector", Toast.LENGTH_SHORT).show();
}
}
PurchaseWeek
public class PurchaseWeek extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.purchase_week_fragment,container,false);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Toast.makeText(getActivity(), "Purchase Week", Toast.LENGTH_SHORT).show();
}
}
PurchaseMonth
public class PurchaseMonth extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.purchase_month_fragment,container,false);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Toast.makeText(getActivity(), "Purchase Month", Toast.LENGTH_SHORT).show();
}
}
PurchaseYear
public class PurchaseYear extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.purchase_year_fragment,container,false);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Toast.makeText(getActivity(), "Purchase Year", Toast.LENGTH_SHORT).show();
}
}
The ViewPager doesn’t create all its pages at once. When using a lot of pages this would be horribly slow and even unnecessary if the user would never swipe through all these pages. By default the ViewPager only creates the current page as well as the off-screen pages to the left and right of the current page.
So what is solution of this problem, Is their any?
yeah there is,
mViewPager.setOffscreenPageLimit(int limit);
Parameters : limit – How many pages will be kept offscreen in an idle
state.
ViewPager require a minimum of 1 offscreen pages
If you set value to 0 then you should be getting a warning about this in LogCat, something like:
Requested offscreen page limit 0 too small;
defaulting to1
Its because ViewPager is based on concept of keep ready next page to be loaded. ViewPager can not the page which not exist still.
Thanks to Tech Code Geek
This is how ViewPager has been designed to work. By default the ViewPager only creates the current page as well as the off-screen pages to the left and right of the current page. This is to allow smooth transition between the pages.
You can also set the number of pages that should be retained to either side of the current page in the view hierarchy in an idle state.
Read More
That's the default and expected behavior of view pager, it creates each fragment to its left and right along with the visible fragment for smooth animations, you can't restrict fragment from creation, may be what you can do is restrict the loading content on non-visible fragments using setuserVisibleHint() method
#Override
public void setUserVisibleHint(boolean visible){
if(visible){
//load content
}
}
I have two images. I used ViewPager to display them individually. I want to know which ones is displaying in the screen. Could you help me to solve it? For example, when I scroll the screen, the first image will display and Toast a message such as "This is first image", do same thing for second image. Thanks in advance. This is my code
public class ViewPagerExample extends FragmentActivity{
private MyAdapter mAdapter;
private ViewPager mPager;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mAdapter = new MyAdapter(getSupportFragmentManager());
mPager = (ViewPager) findViewById(R.id.pager);
mPager.setAdapter(mAdapter);
}
public static class MyAdapter extends FragmentPagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return 2;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
{
return new ImageFragment(R.drawable.image1);
}
case 1:
{
return new ImageFragment(R.drawable.image2);
}
default:
return null;
}
}
}
}
and the ImageFragment class
public class ImageFragment extends Fragment {
private final int imageResourceId;
public ImageFragment(int imageResourceId) {
this.imageResourceId = imageResourceId;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e("Test", "hello");
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.image_layout, container, false);
ImageView imageView = (ImageView) view.findViewById(R.id.imageView1);
imageView.setImageResource(imageResourceId);
return view;
}
}
try something like this
mPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int pager_position) {
// show toast here for images
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
You can use these lines of code to detect the image on swipe
ViewPager.SimpleOnPageChangeListener pageChangeListener = new ViewPager.SimpleOnPageChangeListener(){
#Override
public void onPageSelected(int position) {
super.onPageSelected(position);
System.out.println("Positoin is the=="+position);
if(position==0)
{
///on the zero position you can get the image
}
else
{
///on the first position you can get the image
}
}
};
There is a method yourViewpagerObject.getCurrentItem() which returns the position of currently Viewed page of view pager
I am using a viewPager for its swipe abilities to swipe between two Fragments. However I want to refresh the Fragment contents on swipe. The FragmentStatePagerAdapter does a very good job of caching so its hard to get the Fragment to reload. I've tried putting everything in the onResume method but that has no effect.
Here is my code
slideadapter=new ScreenSlidePagerAdapter(this.getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.viewpager);
mViewPager.setOffscreenPageLimit(1);
mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int i, float v, int i2) {
//Not used
Log.v("TAG","onPageScrolled");
}
#Override
public void onPageSelected(int position) {
//Force the fragment to reload its data
Fragment f = slideadapter.getItem(position);
f.onResume();
}
#Override
public void onPageScrollStateChanged(int i) {
//Not used
Log.v("TAG","onPageScrollStateChanged");
}
});
mSlidingTabLayout = (SlidingTabLayout)findViewById(R.id.sliding_tabs);
mViewPager.setAdapter(slideadapter);
mViewPager.setCurrentItem(0);
mSlidingTabLayout.setViewPager(mViewPager);
you can override setUserVisibleHint method in your Fragments
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
doSomething();
}
}
Use the ViewPager.onPageChangeListener:
viewPager.setOnPageChangeListener(new OnPageChangeListener() {
public void onPageScrollStateChanged(int state) {}
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
public void onPageSelected(int position) {
// get fragment by position and do whatever you want to do on fragment selection.
}
});
you can try mViewPager.setOffscreenPageLimit(1); if you want to call the onresume method everytime the fragments becomes visible
Create a BaseFragment class with a method ex. loadData (),where
Viewpager child fragments extends from this BaseFragment and override the loadData () method and do the operation.
viewPager.setOnPageChangeListener(new OnPageChangeListener() {
public void onPageScrollStateChanged(int state) {}
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
public void onPageSelected(int position) {
if (slideadapter.getFragment(position) instanceof BaseFragment) {
((BaseFragment) slideadapter.getFragment (position)).loadData ();
}
}
});
In the SlideAdapter create method called
public Fragment getFragment(int key) {
return mPageReferences.get(key);
}
private final SparseArray<Fragment> mPageReferences = new SparseArray<Fragment>();
//add created fragment refernce to this array
#Override
public Fragment getItem(int position) {
mPageReferences.put(position, fragment);
}
//remove the reference when destroy
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
mPageReferences.remove(position);
}
Hope this will help!
I'm trying to simply play with toasts and check how to show Toasts when I'm switching between fragments. For example I have two fragments in PagerTabStrip as fragment1 and fragment2.
Visiting fragments for the first time makes the toast visible and switching to second fragment makes the toasts visible twice.
Any help would greatly be appreciated!!
summurized code
FragmentOne:
public class FragmentOne extends Fragment {
public static FragmentOne newInstance(int page) {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
page = getArguments().getInt("page", 0);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_group_list, container, false);
return view;
}
#Override
public void onResume() {
Toast.makeText(G.context,"fragment 1", Toast.LENGTH_SHORT).show();
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
Toast.makeText(G.context,"fragment 1", Toast.LENGTH_SHORT).show();
}
}
FragmentTwo:
public class FragmentTwo extends Fragment {
public static FragmentTwo newInstance(int page) {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
page = getArguments().getInt("page", 0);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_group_list, container, false);
return view;
}
#Override
public void onResume() {
Toast.makeText(G.context,"fragment 2", Toast.LENGTH_SHORT).show();
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
Toast.makeText(G.context,"fragment 2", Toast.LENGTH_SHORT).show();
}
}
You should add an OnPageChangeListener for your ViewPager using setOnPageChangeListener().
mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
//show your Toasts here
}
#Override
public void onPageScrollStateChanged(int state) {
}
});