April G April G - 4 months ago 22
Android Question

Pass a value from Main Activity to tab fragments

I need to pass a value from my

MainActivity
to my Tab
Fragments
so I can use that value accordingly. Any help will be greatly appreciated. Thanks in advance.

MAIN ACTIVITY:

//Value from Login Activity. The value I need to pass
Intent intent = getIntent();
String username = intent.getStringExtra("username");

//Menu on my Drawer
mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
mDrawerLayout.closeDrawers();

if (menuItem.getItemId() == R.id.nav_request) {
FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.containerView,new RequestFragment()).commit();
}

if (menuItem.getItemId() == R.id.nav_requisitions) {
FragmentTransaction xfragmentTransaction = mFragmentManager.beginTransaction();
xfragmentTransaction.replace(R.id.containerView,new RequisitionsFragment()).commit();
}
return false;
}

});


The 3 Tabs belong to
RequisitionsFragment()
. That is where I need to pass the username value.

This is my
RequisitionsFragment()
:

public class RequisitionsFragment extends Fragment {

public static TabLayout tabLayout;
public static ViewPager viewPager;
public static int int_items = 3 ;

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View x = inflater.inflate(R.layout.tab_layout,null);
tabLayout = (TabLayout) x.findViewById(R.id.tabs);
viewPager = (ViewPager) x.findViewById(R.id.viewpager);
viewPager.setAdapter(new MyAdapter(getChildFragmentManager()));
tabLayout.post(new Runnable() {
@Override
public void run() {
tabLayout.setupWithViewPager(viewPager);
}
});
return x;
}


class MyAdapter extends FragmentPagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position)
{
switch (position){
case 0 : return new PendingFragment();
case 1 : return new ApprovedFragment();
case 2 : return new CompletedFragment();
}
return null;
}

@Override
public int getCount() {
return int_items;
}

@Override
public CharSequence getPageTitle(int position) {

switch (position){
case 0 :
return "Pending";
case 1 :
return "Approved";
case 2 :
return "Completed";
}
return null;
}
}
}


And here's the part of
PendingFragment()
where I need to use the value:

public class PendingFragment extends Fragment {
.....
......
private void sendRequest(){

StringRequest stringRequest = new StringRequest(Request.Method.POST, JSON_URL,
new Response.Listener<String>()
{
@Override
public void onResponse(String response) {
showJSON(response);
}
},
new Response.ErrorListener()
{
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(PendingFragment.this.getActivity(),error.getMessage(),Toast.LENGTH_LONG).show();
}
}
) {
@Override
protected Map<String, String> getParams()
{
Map<String, String> params = new HashMap<>();
params.put("username", username);
return params;
}
};
RequestQueue queue = Volley.newRequestQueue(PendingFragment.this.getActivity());
queue.add(stringRequest);
}

Answer

You are instantiating RequisitionsFragment through a call to new RequisitionsFragment(). Instead of doing this, use the newInstance() method pattern. Something like this:

In your RequisitionsFragment, declare this method:

public static RequisitionsFragment newInstance(String username) {
    RequisitionsFragment fragment = new RequisitionsFragment();
    Bundle args = new Bundle();
    args.putString("USERNAME", username);
    fragment.setArguments(args);
    return fragment;
}

And in your MainActivity, call this method thus:

 fragmentTransaction.replace(R.id.containerView, RequestFragment.newInstance(username)).commit();

After this, when you need to access the arguments inside the fragment, call

String username = getArguments().getString("USERNAME");

That should do it. Let me know if this helps.

EDIT

Make these changes to your RequisitionsFragment:

public class RequisitionsFragment extends Fragment {

public static TabLayout tabLayout;
public static ViewPager viewPager;
public static int int_items = 3 ;
String username;

public RequisitionsFragment() {
    // Required empty public constructor
}

public static RequisitionsFragment newInstance(String username) {
    RequisitionsFragment fragment = new RequisitionsFragment();
    Bundle args = new Bundle();
    args.putString("USERNAME", username);
    fragment.setArguments(args);
    return fragment;
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View x =  inflater.inflate(R.layout.tab_layout,null);
    tabLayout = (TabLayout) x.findViewById(R.id.tabs);
    viewPager = (ViewPager) x.findViewById(R.id.viewpager);
    viewPager.setAdapter(new MyAdapter(getChildFragmentManager()));
    tabLayout.post(new Runnable() {
        @Override
        public void run() {
            tabLayout.setupWithViewPager(viewPager);
        }
    });
    username = getArguments().getString("USERNAME");
    return x;
}


class MyAdapter extends FragmentPagerAdapter {
    public MyAdapter(FragmentManager fm) {
        super(fm);
    }
    @Override
    public Fragment getItem(int position)
    {
        switch (position){
            case 0 : return PendingFragment.newInstance(username);
            case 1 : return new ApprovedFragment();
            case 2 : return new CompletedFragment();
        }
        return null;
    }

    @Override
    public int getCount() {
        return int_items;
    }

    @Override
    public CharSequence getPageTitle(int position) {

        switch (position){
            case 0 :
                return "Pending";
            case 1 :
                return "Approved";
            case 2 :
                return "Completed";
        }
        return null;
    }
}
}

Then write a newInstance() method inside your PendingFragment as well:

public class PendingFragment extends Fragment {

String username;

public PendingFragment(){
    //Required empty constructor
}

public static PendingFragment newInstance(String username) {
    PendingFragment fragment = new PendingFragment();
    Bundle args = new Bundle();
    args.putString("USERNAME", username);
    fragment.setArguments(args);
    return fragment;
}
.....//Initialize username inside onCreateView like this:
//username = getArguments().getString("USERNAME");
......    
private void sendRequest(){

        StringRequest stringRequest = new StringRequest(Request.Method.POST, JSON_URL,
                new Response.Listener<String>()
                {
                    @Override
                    public void onResponse(String response) {
                        showJSON(response);
                    }
                },
                new Response.ErrorListener()
                {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Toast.makeText(PendingFragment.this.getActivity(),error.getMessage(),Toast.LENGTH_LONG).show();
                    }
                }
        ) {
            @Override
            protected Map<String, String> getParams()
            {
                Map<String, String> params = new HashMap<>();
                params.put("username", username);
                return params;
            }
        };
        RequestQueue queue = Volley.newRequestQueue(PendingFragment.this.getActivity());
        queue.add(stringRequest);
    }

Let me know if this helps.