Implement Listener with ViewPager - android

I have a Main Activity with a Tablayout, which contains 3 Fragments. There's a FAB in the Main Activity that sits on tops of all the Fragments as a I swipe. I need to create an interface, so that when the FAB is clicked, my ViewPager is alerted and performs a certain action. Does anyone know how I could create this listener?
The Listener should just return a boolean indicating that the Fab was clicked.
I added an Interface in my Main Activity but am not sure how to utilize it and connect it to my ViewPagerAdapter Class?
Here is my Main Activity:
public class MainActivity extends AppCompatActivity {
private ViewPager viewPager;
private ArrayList<Fragment> fragments = new ArrayList<>();
private ArrayList<String> titles = new ArrayList<>();
//MY LISTENER....
private static SwitchFragmentsListener switchFragsListener;
public static interface SwitchFragmentsListener{
public void doISwitch(boolean change);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
CollapsingToolbarLayout collapsingToolbarLayout = (CollapsingToolbarLayout)findViewById(R.id.collapsing_toolbar);
setSupportActionBar(toolbar);
fragments.addAll(Arrays.asList(new Tasks(),new Calendar(),new Contacts()));
titles.addAll(Arrays.asList(getResources().getString(R.string.fragment_task_title),
getResources().getString(R.string.fragment_cal_title),getResources().getString(R.string.fragment_contacts_title)));
TabLayout tabLayout = (TabLayout)findViewById(R.id.tabs);
final FloatingActionButton fab = (FloatingActionButton)findViewById(R.id.fab);
fab.hide();
viewPager = (ViewPager)findViewById(R.id.container);
ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager(),fragments,titles);
viewPager.setAdapter(viewPagerAdapter);
viewPager.setCurrentItem(1);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
if (position == 1) {
fab.hide();
}else {
fab.show();
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
tabLayout.setupWithViewPager(viewPager);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
fabAction();
}
});
if (savedInstanceState==null){
if (getSupportActionBar()!=null){
getSupportActionBar().setDisplayShowTitleEnabled(true);
}
}
}
public interface FragChangeListener{
public void doIChange(boolean change);
}
public void fabAction(){
int current = viewPager.getCurrentItem();
switch (current){
case 0:{
//NEED TO IMPLEMENT LISTENER HERE
break;
}
case 2:{
Toast.makeText(this, "IN TAB 3", Toast.LENGTH_LONG).show();
break;
}
}
}}
And My ViewPagerAdapter
public class ViewPagerAdapter extends FragmentPagerAdapter {
ArrayList<Fragment> fragments;
ArrayList<String> titles;
private Fragment mFragmentAtPos0;
private FragmentManager fragManager;
//NEED TO IMPLEMENT THE LISTENER IN THIS CLASS TELLING ME THAT THE BUTTON WAS CLICKED IN MAIN ACTIVITY
public ViewPagerAdapter(FragmentManager fm, ArrayList<Fragment> fragments, ArrayList<String>titles) {
super(fm);
this.fragments = fragments;
this.titles = titles;
fragManager = fm;
}
#Override
public Fragment getItem(int position) {
if (position == 0)
{
mFragmentAtPos0 = new AddContact();
fragManager.beginTransaction().replace(R.id.container,mFragmentAtPos0).commit();
notifyDataSetChanged();
return mFragmentAtPos0;
}else{
return fragments.get(position);
}
}
#Override
public int getCount() {
return fragments.size();
}
#Override
public CharSequence getPageTitle(int position) {
return titles.get(position);
}
#Override
public int getItemPosition(Object object)
{
if (object instanceof Tasks && mFragmentAtPos0 instanceof AddContact)
return POSITION_NONE;
return POSITION_UNCHANGED;
}
}

when the FAB is clicked, my ViewPager is alerted and performs a
certain action
I think you don't need to create listener in this case. You can detect the click FAB and pass it to the adapter directly. In your adapter, just create a method to get the action click of FAB.
In your ViewPagerAdapter, create method
public void clickFAB() {
// your code here
}
and in SwitchFragmentsListener, just call it:
ViewPagerAdapter viewPagerAdapter;
public void fabAction(){
int current = viewPager.getCurrentItem();
switch (current){
case 0:{
//NEED TO IMPLEMENT LISTENER HERE
viewPagerAdapter.clickFAB();
break;
}
case 2:{
Toast.makeText(this, "IN TAB 3", Toast.LENGTH_LONG).show();
break;
}
}
}}

Related

in android how to put exit or close button on tabitems of an android tablayout

I have an android app with TabLayout , I create TabItems and assign them to my TabLayout Dynamically with code in my MainActivity , in one of my Fragments, which is the Fragment for a TabItem , i have a button . what I want is when that button is clicked, its TabItem closes and destroys, how can I achieve that?
extra explanation: bellow is my MainActivity.java Code ( where most of my code for creating dynamic TabItems exists :
public class MainActivity extends AppCompatActivity implements ContactsFragment.CallBacks {
public static List<Fragment> fragments = new ArrayList<>();
public static List<String> fragmentsTitle = new ArrayList<>();
ViewPager viewPager;
TabLayout tabLayout;
public List<Fragment> getFragments() {
return fragments;
}
public List<String> getFragmentsTitle() {
return fragmentsTitle;
}
public void addToFragments(Fragment fragment) {
fragments.add(fragment);
}
public void addToFragmentsTitle(String title) {
fragmentsTitle.add(title);
}
public Fragment getFragmentsWithPosition(int position) {
return fragments.get(position);
}
public String getFragmentsTitleWithPosition(int position) {
return fragmentsTitle.get(position);
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_page_drawer);
this.tabLayout = findViewById(R.id.tab_layout);
this.viewPager = findViewById(R.id.view_pager);
tabLayout.setupWithViewPager(viewPager);
SetUpViewPager(viewPager);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
}
public void SetUpViewPager(ViewPager viewPager) {
MyViewPagerAdapter Adapter = new MyViewPagerAdapter((getSupportFragmentManager()));
Adapter.AddFragmentPage(new SignInFragment(),"ورود");
Adapter.AddFragmentPage(new ContactsFragment(),"ارتباطات");
Adapter.AddFragmentPage(new RegisterFragment(),"ثبت نام");
viewPager.setAdapter(Adapter);
}
#Override
public void send_user_object() {
/* this is the implementation of abstract function defined
in one of my tab , in which it has a button and when
button is clicked i want the tab to be removed . */
}
public class MyViewPagerAdapter extends FragmentPagerAdapter {
public MyViewPagerAdapter(FragmentManager manager) {
super(manager);
}
public void AddFragmentPage(Fragment frag,String title) {
MainActivity.this.addToFragments(frag);
MainActivity.this.addToFragmentsTitle(title);
}
public Fragment getItem(int position) {
return MainActivity.this.getFragmentsWithPosition(position);
}
public CharSequence getPageTitle(int position) {
return MainActivity.this.getFragmentsTitleWithPosition(position);
}
public int getCount() {
List<Fragment> frag = MainActivity.this.getFragments();
return frag.size();
}
}
}
in one of my predefined tabs , i have a listview , when user clickes on an item on the list view , the detail of the item opens in a new tab , then user can see the detail by clicking on that tab . what i want is how user can close ( destroy ) that detail tab about one of items ? ( remember it is creating dynamically )
how can I remove ( close ) the TabItem with Click of a Button in that TabItem Fragment?
Plase help me , thank you beforehand .
It's not a good practice to change horizontal navigation by adding another fragment. If it's not absolutely required by your customer, create a new fragment and just replace the current one like this:
Fragment detailsFragment=new ContactsFragment()
getSupportFragmentManager.beginTransaction()
.addToBackStack("tag")
.replace(R.id.containerName, detailsFragment, "another_tag")
.commit()
At your detailsFragment your close button's clickListener just call getActivity.getSupportFragmentManager.popBackStack()
and it restores previous state.
Hope I could help you.
I solved my problem by :
first ) creating an interface in the UserDetailFragment, which you all know for communication with MainActivity, I had to do that.
but for what did I need communicating with the MainActivity ?
Answer : as you see in my code , my FragmentPagerAdapter class is defined there , and i needed my public List<Fragment> fragments = new ArrayList<>(); and public static List<String> fragmentsTitle = new ArrayList<>(); that i had saved my fragments into them , and also mytabLayout.
Seconde ) i had to define tabLayout.addOnTabSelectedListener(){} with its method OnTabSelected() , i needed that because i get the current index of the tab using addOnTabSelectedListener(){} .
Third ) i defined removeTabPage(int position) in the FragmentPagerAdapter .
Forth ) i created a method as bellow ( which is the implementation of the abstract method of UserDetailFragment interface.
#Override
public void close_tabitem() {
tabLayout.removeTabAt(tabposition_number);
MyViewPagerAdapter Adapter = new MyViewPagerAdapter(getSupportFragmentManager());
Adapter.removeTabPage(tabposition_number);
Adapter.notifyDataSetChanged();
}
and here is my whole code for: MainActivity.Java
public class MainActivity extends AppCompatActivity implements ContactsFragment.CallBacks, UserDetailFragment.DetailCallBacks {
android.support.v7.widget.Toolbar toolbar;
public static List<Fragment> fragments = new ArrayList<>();
public static List<String> fragmentsTitle = new ArrayList<>();
ViewPager viewPager;
TabLayout tabLayout;
int tabposition_number;
public List<Fragment> getFragments() {
return fragments;
}
public List<String> getFragmentsTitle() {
return fragmentsTitle;
}
public void addToFragments(Fragment fragment) {
fragments.add(fragment);
}
public void addToFragmentsTitle(String title) {
fragmentsTitle.add(title);
}
public Fragment getFragmentsWithPosition(int position) {
return fragments.get(position);
}
public String getFragmentsTitleWithPosition(int position) {
return fragmentsTitle.get(position);
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_page_drawer);
this.tabLayout = findViewById(R.id.tab_layout);
this.viewPager = findViewById(R.id.view_pager);
tabLayout.setupWithViewPager(viewPager);
SetUpViewPager(viewPager);
this.toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
NavigationView navigationView = findViewById(R.id.navigation_view);
navigationView.setItemIconTintList(null);
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener(){
#Override
public void onTabSelected(TabLayout.Tab tab) {
tabposition_number = tab.getPosition();
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
}
public void SetUpViewPager(ViewPager viewPager) {
MyViewPagerAdapter Adapter = new MyViewPagerAdapter((getSupportFragmentManager()));
Adapter.AddFragmentPage(new SignInFragment(),"ورود");
Adapter.AddFragmentPage(new ContactsFragment(),"ارتباطات");
Adapter.AddFragmentPage(new RegisterFragment(),"ثبت نام");
viewPager.setAdapter(Adapter);
}
#Override
public void send_user_object(UserObject userObject) {
// tabLayout.removeTabAt(tabposition_number);
// myViewPagerAdapter.remove
}
#Override
public void create_user_detail_tab(UserObject userObject) {
MyViewPagerAdapter Adapter = new MyViewPagerAdapter(getSupportFragmentManager());
UserDetailFragment userDetailFragment = new UserDetailFragment();
Bundle bundle = new Bundle();
bundle.putString("name",userObject.getName());
bundle.putString("family",userObject.getFamily());
bundle.putString("email",userObject.getEmail());
userDetailFragment.setArguments(bundle);
Adapter.AddFragmentPage(userDetailFragment,userObject.getName());
viewPager.setAdapter(Adapter);
}
#Override
public void close_tabitem() {
tabLayout.removeTabAt(tabposition_number);
MyViewPagerAdapter Adapter = new MyViewPagerAdapter(getSupportFragmentManager());
Adapter.removeTabPage(tabposition_number);
Adapter.notifyDataSetChanged();
}
public class MyViewPagerAdapter extends FragmentPagerAdapter {
public MyViewPagerAdapter(FragmentManager manager) {
super(manager);
}
public void removeTabPage(int position) {
fragments.remove(position);
fragmentsTitle.remove(position);
notifyDataSetChanged();
}
public void AddFragmentPage(Fragment frag,String title) {
MainActivity.this.addToFragments(frag);
MainActivity.this.addToFragmentsTitle(title);
}
public Fragment getItem(int position) {
return MainActivity.this.getFragmentsWithPosition(position);
}
public CharSequence getPageTitle(int position) {
return MainActivity.this.getFragmentsTitleWithPosition(position);
}
public int getCount() {
List<Fragment> frag = MainActivity.this.getFragments();
return frag.size();
}
}
}
and here is the UserDetailFragment.Java , which acts as my TabItem :
public class UserDetailFragment extends Fragment {
View view;
DetailCallBacks detailCallBacks;
public UserDetailFragment() {}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.user_detail_fragment,null);
return view;
}
#Override
public void onResume() {
super.onResume();
Button closebtn = view.findViewById(R.id.detail_close_button);
closebtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
detailCallBacks.close_tabitem();
}
});
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
detailCallBacks = (DetailCallBacks)context;
}
public interface DetailCallBacks {
public void close_tabitem();
}
}
Hope It Helps You.
But do remember, you can not use this button. put the button in some other tabitem or in the menu.
or you can use :
TabLayout.Tab tab = tabLayout.getTabAt(2);
tab.select();
to change the tabitem and then fire the event .
enjoy .....

Android - TabLayout - Navigation with RecyclerView Items

I have a Tabbed Activity with 3 Tabs. On each Tab are RecyclerViews with some list items. If you click on an item a new fragment should open and there should appear a Back-Button in the toolbar. My current screen looks like this:
And now I will show you my code. At first MainActivity.java with the TabLayout:
public class MainActivity extends AppCompatActivity {
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
private Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle("Pflege");
setSupportActionBar(toolbar);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
tabLayout.getTabAt(0).setIcon(R.drawable.tab_icon_pflege);
tabLayout.getTabAt(1).setIcon(R.drawable.tab_icon_dokumentation);
tabLayout.getTabAt(2).setIcon(R.drawable.tab_icon_probleme);
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
switch(tab.getPosition()) {
case 0:
mViewPager.setCurrentItem(0);
toolbar.setTitle("Pflege");
break;
case 1:
mViewPager.setCurrentItem(1);
toolbar.setTitle("Daten");
break;
case 2:
mViewPager.setCurrentItem(2);
toolbar.setTitle("Probleme");
break;
default:
mViewPager.setCurrentItem(tab.getPosition());
toolbar.setTitle("Pflege");
break;
}
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch(position){
case 0:
Tab1Pflege tab1 = new Tab1Pflege();
return tab1;
case 1:
Tab2Dokumentation tab2 = new Tab2Dokumentation();
return tab2;
case 2:
Tab3Probleme tab3 = new Tab3Probleme();
return tab3;
default:
return null;
}
}
#Override
public int getCount() {
// Show 3 total pages.
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Pflege";
case 1:
return "Daten";
case 2:
return "Probleme";
}
return null;
}
}
}
Here is the Fragment for the first tab with the RecyclerView:
public class Tab1Pflege extends Fragment {
private RecyclerView recyclerView;
private RecyclerView.Adapter rvAdapter;
private RecyclerView.LayoutManager rvLayoutManager;
private ArrayList<String> listItems;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.tab1_pflege, container, false);
listItems = new ArrayList<>();
listItems.add("Test1");
listItems.add("Test2");
listItems.add("Test3");
recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerView);
rvLayoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(rvLayoutManager);
rvAdapter = new RvAdapter(listItems);
recyclerView.setAdapter(rvAdapter);
return rootView;
}
}
And here is my RecyclerView Adapter:
public class RvAdapter extends RecyclerView.Adapter<RvAdapter.MyViewHolder> {
ArrayList<String> listItems;
public RvAdapter (ArrayList<String> listItems){
this.listItems = listItems;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.rv_item_layout, null);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, final int position) {
holder.itemTitle.setText(listItems.get(position));
holder.itemImage.setImageResource(R.drawable.ic_keyboard_arrow_right);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
System.out.println(listItems.get(position));
}
});
}
#Override
public int getItemCount() {
return listItems.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder{
TextView itemTitle;
ImageView itemImage;
public MyViewHolder(View itemView){
super(itemView);
itemTitle = (TextView) itemView.findViewById(R.id.itemTitle);
itemImage = (ImageView) itemView.findViewById(R.id.itemImage);
}
}
}
In this class is an onClickListener for clicking on a list item. And there I want to open a new fragment for example for Test1. On top of that there should appear a Back-Button in the toolbar to navigate back to the Tab1 Overview with the RecyclerView. But I have no idea how to do that. Can someone help me with it?
In onClick, you can do something like this (to load another fragment)
FragmentTransaction trans = getSupportFragmentManager().beginTransaction();
Fragment fragment = // TODO: initialise your fragment 'fragment'
mFragments.push(fragment);
// Animation, if need it
// trans.setCustomAnimations(R.anim.right_in, R.anim.left_out,
// R.anim.right_out, R.anim.left_in);
// _container is the id of 'fragment' container in the your xml
trans.replace(R.id._container, fragment);
// variable to identify this fragment, and title of the page as well
String name = // TODO: initialise
trans.addToBackStack(name);
trans.commit();
getSupportActionBar().setTitle(name);
and in onCreate of your activity, setup listener for back stack changes.
FragmentManager manager = getSupportFragmentManager();
manager.addOnBackStackChangedListener(mBackStackListener);
and you can change back icon in
private OnBackStackChangedListener mBackStackListener = new OnBackStackChangedListener() {
#Override
public void onBackStackChanged() {
FragmentManager manager = getSupportFragmentManager();
int count = manager.getBackStackEntryCount();
if(count > 0) {
// TODO: Show back icon
} else {
// TODO: Other icon
}
}
};

unable to set the FragmentStatePagerAdapter in ViewPager

I would like to set the object of subclass of FragmentStatePagerAdapter in ViewPager by the method
viewPager.setAdapter(myPagerAdapter);
But i got error as follows
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v4.app.Fragment.setMenuVisibility(boolean)' on a null object reference
at android.support.v4.app.FragmentStatePagerAdapter.instantiateItem(FragmentStatePagerAdapter.java:120)
at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:1006)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1154)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1088)
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1614)
Please help me to fix this issue.
The code snippet is
public class MainActivity extends AppCompatActivity {
Toolbar toolbar;
TabLayout tabLayout;
ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar)findViewById(R.id.toolbar);
toolbar.setTitle("My App");
toolbar.setSubtitle("this is my test");
tabLayout = (TabLayout)findViewById(R.id.tablayout);
tabLayout.addTab(tabLayout.newTab().setText("Left"));
tabLayout.addTab(tabLayout.newTab().setText("Cent"));
tabLayout.addTab(tabLayout.newTab().setText("Right"));
viewPager = (ViewPager)findViewById(R.id.viewpage);
MyPagerAdapter myPagerAdapter = new MyPagerAdapter(
getSupportFragmentManager(),
tabLayout.getTabCount()
);
viewPager.setAdapter(myPagerAdapter);
//viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
}
}
public class MyPagerAdapter extends FragmentStatePagerAdapter {
int tabCount;
public MyPagerAdapter(FragmentManager fm, int tabCount) {
super(fm);
this.tabCount = tabCount;
}
#Override
public Fragment getItem(int position) {
switch (position){
case 1:
Fragment1 fragment1 = new Fragment1();
return fragment1;
case 2:
Fragment2 fragment2 = new Fragment2();
return fragment2;
case 3:
Fragment3 fragment3 = new Fragment3();
return fragment3;
default:
return null;
}
}
#Override
public int getCount() {
return tabCount;
}
}
While you should probably be using tabLayout.setupWithViewPager(viewPager);
Here's the problem
switch (position){
// case 1, 2, 3...
default:
return null; // Here
Did you forget that lists start indexing at position 0? You've returned a null Fragment
Try the following.
MyPagerAdapter.java
public class MyPagerAdapter extends FragmentStatePagerAdapter {
private Context mContext;
private List<Fragment> mFragments = new ArrayList<>();
public FragmentPagerAdapter(Context context, FragmentManager fm) {
super(fm);
this.mContext = context;
}
public void addFragment(Fragment fragment) {
mFragments.add(fragment);
}
#Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
#Override
public int getCount() {
return mFragments.size();
}
}
In your MainActivity,
private void setUpViewPager(ViewPager viewPager) {
adapterViewPager = new MyPagerAdapter(getApplicationContext(), getSupportFragmentManager());
adapterViewPager.addFragment(new AFragment());
viewPager.setAdapter(adapterViewPager);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}
private void setUpTabLayout(TabLayout tabLayout) {
tabLayout.setupWithViewPager(viewPager);
for (int i = 0; i < tabLayout.getTabCount(); i++) {
TabLayout.Tab tab = tabLayout.getTabAt(i);
//set your tab text, image etc here.
}
tabLayout.requestFocus();
}
Then in your onCreate(), just use the methods accordingly. setUpViewPager() follow by setUpTabLayout()

How to prevent Fragment from loading data every time from server when swiping Tabs in TabLayout in android?

I am a newbie with Fragments. I have 5 different Fragmentsin my TabLayout. In each fragment I am loading data from the server.
My problem is as follows:
When the first fragment loads it calls the function and loads data from the server and displays on the RecyclerView.
Then When I swipe to the second tab the server data loads and so on. But when I swipe again to say fragment one the data is loading again from the server and the RecyclerView needs to be set again.
Is there anyway where I can load the server data only once (without saving it to a local database) and set the recyclerview only once so that no matter how many times I swipe the tab the data does not load again? I have referred here but i really didnt understand how to solve my problem.I am posting a snippet of my code.
TabActivity
public class TabActivity extends AppCompatActivity {
ViewPager viewpager;
Toolbar toolbar;
TabLayout tablayout;
ViewPagerAdapter viewPagerAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tab_activity);
initialize();
}
private void initialize() {
viewpager = (ViewPager) findViewById(R.id.viewpager);
toolbar = (Toolbar) findViewById(R.id.toolbar);
tablayout = (TabLayout) findViewById(R.id.tablayout);
setSupportActionBar(toolbar);
viewPagerAdapter=new ViewPagerAdapter(getSupportFragmentManager());
viewpager.setAdapter(viewPagerAdapter);
tablayout.setTabsFromPagerAdapter(viewPagerAdapter);
tablayout.setupWithViewPager(viewpager);
}
}
class ViewPagerAdapter extends FragmentStatePagerAdapter implements ViewPager.OnPageChangeListener {
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:return LocatedEvents.newInstance();
case 1:return QrCodeScanner.newInstance();
case 2:return NewsFeed.newInstance();
case 3:return CreatePoll.newInstance();
case 4:return MyProfile.newInstance();
}
return NewsFeed.newInstance();
}
#Override
public int getCount() {
return 5;
}
#Override
public CharSequence getPageTitle(int position) {
return "Tab " + (position + 1);
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
}
NewsFeed Fragment
public class NewsFeed extends Fragment {
#Nullable
public static NewsFeed newInstance() {
return new NewsFeed();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.newsfeed_fragment, container, false);
load_data();
return view;
}
}
Avoid creating new Fragments every time in
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return LocatedEvents.newInstance();
case 1:
return QrCodeScanner.newInstance();
case 2:
return NewsFeed.newInstance();
case 3:
return CreatePoll.newInstance();
case 4:
return MyProfile.newInstance();
}
return NewsFeed.newInstance();
}
Make an array of fragments and pass it to your Adapter.Something like this
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dashboard);
initFragments();
}
private void initFragments() {
ArrayList < Fragment > fragmentArrayList = new ArrayList < > ();
fragmentArrayList.add(LocatedEvents.newInstance());
fragmentArrayList.add(QrCodeScanner.newInstance());
fragmentArrayList.add(NewsFeed.newInstance());
fragmentArrayList.add(MyProfile.newInstance();
viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager(), fragmentArrayList); viewpager.setAdapter(viewPagerAdapter); tablayout.setTabsFromPagerAdapter(viewPagerAdapter); tablayout.setupWithViewPager(viewpager);
}
And in your adapter change it to
private ArrayList < Fragment > fragments;
public ViewPagerAdapter(FragmentManager fm, ArrayList < Fragment > fragments) {
super(fm);
this.fragments = fragments;
}
#Override
public Fragment getItem(int position) {
return fragments.get(position);
}
#Override
public int getCount() {
return fragments.size();
}

call method from activity in all fragment instance

I have PengaduanHomeActivity.class with 3 tabs using same Fragment PengaduanFragment.class like here :
public class PengaduanHomeActivity extends AppCompatActivity implements AppBarLayout.OnOffsetChangedListener {
....
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.detail_profile_user);
appBarLayout = (AppBarLayout) findViewById(R.id.appBarLayout);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
actionbar = getSupportActionBar();
actionbar.setDisplayHomeAsUpEnabled(true);
actionbar.setHomeButtonEnabled(true);
tabLayout = (TabLayout) findViewById(R.id.tabs);
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setOffscreenPageLimit(7);
mPagerAdapter = new PagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mPagerAdapter);
tabLayout.setupWithViewPager(mViewPager);
appBarLayout.addOnOffsetChangedListener(this);
}
int index = 0;
#Override
public void onOffsetChanged(AppBarLayout appBarLayout, int i) {
index = i;
}
#Override
public boolean dispatchTouchEvent(MotionEvent ev) {
final int action = MotionEventCompat.getActionMasked(ev);
switch (action) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
if (index == 0) {
PengaduanFragment.enableRefreshLayout(true);
} else {
PengaduanFragment.enableRefreshLayout(false);
}
break;
}
return super.dispatchTouchEvent(ev);
}
public class PagerAdapter extends FragmentPagerAdapter {
private final String[] TITLES =
{"News Task", "Task On Progress", "Completed Task"};
private Bundle bundle;
public PagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public CharSequence getPageTitle(int position) {
return TITLES[position];
}
#Override
public int getCount() {
return TITLES.length;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return PengaduanFragment.newInstance("0");
case 1:
return PengaduanFragment.newInstance("1");
case 2:
return PengaduanFragment.newInstance("2");
default:
return null;
}
}
}
in code above, i call method in PengaduanFragment
public static void enableRefreshLayout(boolean b) {
mSwipeRefreshLayout.setEnabled(b);
}
but method just called in last PengaduanFragment with position 2. Other PengaduanFragment with position 0 or 1, not called. So how to Called method enableRefreshLayout in all Fragment ? thaks
You should create an interface that declares the method you want to use:
public interface IMyInterface {
public void myMethod();
}
Then, each fragment you have should implement this method:
public class MyFragment extends Fragment implements IMyInterface {
//Fragment code
public void myMethod() {
//Method code
}
}
Finally, make your adapter have a collection of this interface and loop over it when invoked by the activity
public class MyAdapter extends FragmentPagerAdapter {
//Collection of fragments
Fragment[] fragments;
//Adapter code
public void invokeMe(){
//Loop through each fragment
if (fragment instanceof IMyInterface) {
fragment.myMethod();
}
}
}
You should then be able to call invokeMe and have the adapter delegate to the right fragments the right behaviour. Just be careful of if the fragment instance is still active as per your settings on your ViewPager's current offscreen limit (adjustable by calling setOffscreenPageLimit())

Categories

Resources