How to transfer data from fragment to fragment through Bundle - java

Below is the adapter code of first fragment , here and sending data to second fragment StoreDetails.
holder.cv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
StoreDetails fragment = new StoreDetails();
Bundle bundle = new Bundle();
bundle.putString("store_id",pojo.getSTORE_ID());
bundle.putString("store_name",pojo.getSTORE_NAME());
bundle.putString("address",pojo.getSTORE_ADDRESS());
// bundle.putString("status",pojo.getSTATUS());
// bundle.putString("teammember",pojo.getSTATUS());
fragment.setArguments(bundle);
FragmentManager manager=fragment.getFragmentManager();
// in below line I am getting error
FragmentTransaction ft = manager.beginTransaction().replace(R.id.container,fragment,"fragment");
ft.addToBackStack("fragment");
ft.commit();
}
});
Below is the StoreDetails fragment
Bundle bundle = getArguments();
mstore_id = bundle.getString("store_id");
mstore_name =bundle.getString("store_name");
mstoreaddress= bundle.getString("address");
mstorestatus = bundle.getString("status");
mteammember = bundle.getString("teammember");
The error I'm receiving is
java.lang.NullPointerException: Attempt to invoke virtual method
'android.app.FragmentTransaction
android.app.FragmentManager.beginTransaction()' on a null object
reference at Adapter.Tab1_Adapter$1.onClick(Tab1_Adapter.java:78)

FragmentManager will be null until it is attached to the activity.
instead of using
FragmentManager manager=fragment.getFragmentManager();
use
getActivity().getFragmentManager() or getActivity().getSupportFragmentManager();

Related

Calling a button in Fragment view from Activity

I want to reach fragment item in Activity method but i get a null pointer error.
Fragment Class
Button button;
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment, container, false);
button= view.findViewById(R.id.button);
return view;
}
public Button getButton(){
return button;
}
MainActivity
FragmentManager fm = getSupportFragmentManager();
Fragment fragment = (Fragment)fm.findFragmentById(R.id.Framelayout);
fragment.getButton().setText("Test");
LOGCAT
java.lang.NullPointerException: Attempt to invoke virtual method
'android.widget.Button com.example.android.fragment.Fragment.getButton()'
on a null object reference
at
com.example.android.MainActivity$1$1.onDataChange(MainActivity.java:141)
For adding the fragment
private void addFragment(FragmentManager manager)
{
YOURFRAGMENT fragment= new YOURFRAGMENT();
FragmentTransaction transaction=manager.beginTransaction();
transaction.add(CONTAINER-ID,fragment,YOURFRAGMENT.class.getSimpleName()).commitNow();
}
for getting the fragment
private void getFragment(FragmentManager manager,String TAG){
YOURFRAGMENT fragment= (YOURFRAGMENT) manager.findFragmentByTag(TAG);
if(fragment!=null){
//access button here
}
}
to get yours
getFragment(fragmentManager, YOURFRAGMENT.class.getSimpleName())k
Add the Fragment using TAG
String TAG="YourTAG";
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.fragment_container, mFragment, TAG)
.commit();
You can invoke a method from your activity like this
Fragment fragment = getSupportFragmentManager().findFragmentByTag(TAG);
if (fragment instanceof YourFragmentClass ) {
fragment.getButton().setText("Test");
}
Hope it helps you.
try with getFragmentManager() instead of getSupportFragmentManager()

Handle onBackPressed in android in fragment

I want to handle onBackPressed in fragment
I use following code in my activity but this return 0
#Override
public void onBackPressed() {
int count = getFragmentManager().getBackStackEntryCount();
Toast.makeText(getBaseContext(), ""+count, Toast.LENGTH_SHORT).show();
if (count == 1) {
super.onBackPressed();
//additional code
} else {
getFragmentManager().popBackStack();
}
}
Just add .addToBackStack(null) in your Activity or Fragment . When you adding or replacing fragment. Like below
getSupportFragmentManager().beginTransaction().replace(R.id.parent_layout, new MyFragment()).addToBackStack(null).commit();
Note:- you don't have to do anything in your onBackPressed() method.
Just app this line when you want to replace any fragment and manage backsack on Fragment.
ClientHome per = new ClientHome();
Bundle bundle = new Bundle();
bundle.putString("usertype", "client");
per.setArguments(bundle);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.slide_from_left, R.anim.slide_to_right);
fragmentTransaction.replace(R.id.content_frame, per, "tag");
fragmentTransaction.addToBackStack("tag");
fragmentTransaction.commit();

Passing data from a adapter to fragment using startActivityForResult within same activity

I want to pass a data from my adapter class to another fragment with the help of startActivityForResult. If I used the below code same activity recreates it i don't want that. How to solve this issue?
Bundle mBundle = new Bundle();
mBundle.putString(Constants.SELECTED_PLOCATION, pLocation);
mBundle.putString(Constants.SELECTED_RLOCATION, rLocation);
mBundle.putString(Constants.SELECTED_FROM, selectedFrom);
mBundle.putString(Constants.FROM_TYPE, fromType);
mBundle.putString(Constants.AREA_TYPE, Constants.AREA);
getActivity().getFragmentManager().popBackStackImmediate();
Intent mIntent = new Intent(getActivity(), AuthorizedCustomerActivity.class);
getActivity().startActivityForResult(mIntent, PICK_LOCATION_REQUEST, mBundle);
Use below code for data transfer from adapter to fragment;
Fragment fragment = new YourFragmentName();
FragmentManager fm = getActivity().getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.content_frame, fragment);
ft.commit();
Bundle mBundle= new Bundle();
mBundle.putString(Constants.SELECTED_PLOCATION, pLocation);
mBundle.putString(Constants.SELECTED_RLOCATION, rLocation);
mBundle.putString(Constants.SELECTED_FROM, selectedFrom);
mBundle.putString(Constants.FROM_TYPE, fromType);
mBundle.putString(Constants.AREA_TYPE, Constants.AREA);
fragment.setArguments(mBundle);

SavedInstanceStateNull between Fragments is null

I have a fragment which shows a list of buttons, each have their own id. When the user clicks the button, I am trying to replace the current fragment with another. Right after I replace the fragment, I a am adding arguments to the bundle. From what I can tell from debug mode, that part is working 100%. However, when we get to the new fragment, the "savedInstanceState" state will always be null.
I have read several posts on this however, I am confused because I am attempting to set the bundle and replace the fragment the same way I did when going from the activity to the first fragment and it is still not working.
MyActivity.java (this is working and all values are being set):
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyFirstFragment fragment = new MyFirstFragment();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frame,fragment);
fragmentTransaction.commit();
Intent i = getIntent();
value = i.getExtras().getString("key");
Bundle bundle = new Bundle();
bundle.putString("key",value);
fragment.setArguments(bundle);
}
MyFirstFragment.java (also working):
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_first, container, false);
final String value = getArguments().getString("key");
myButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
String gid = Integer.toString(v.getId());
MySecondFragment secondfragment = new MySecondFragment();
Bundle secondFragmentBundle = new Bundle();
secondFragmentBundle.putString("key",value);
secondFragmentBundle.putString("id",id);
secondfragment.setArguments(secondFragmentBundle);
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frame,secondfragment);
fragmentTransaction.commit();
}
});
MySecondFragment (getting null for savedInstanceState and all bundle agruments!):
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_second, container, false);
value = getArguments().getString("key");
id = getArguments().getString("id");
}
You cannot set arguments on a Fragment after it is attached to an Activity.
Your issue is caused by confusion about Fragment creation. What you provided in your question is not the correct way to send arguments to another Fragment type.
The de-facto standard way of passing arguments to a Fragment when it is created it to use a static factory method, generally called newInstance(). You should set the arguments this way, and should do so before committing the FragmentTransaction - however, you technically could do it right after committing the transaction with no ill effects. This is because when a Fragment is committed, it isn't immediately attached/created, rather, it is queued on the main thread.
Here is how you would do it:
Write a method in your Fragment class called new instance. Be sure to leave a public default (no arguments) constructor for the system to handle things in the background.
public MyFirstFragment extends Fragment {
public MyFirstFragment(){
//constructor - don't use this to create a new fragment directly
}
public static MyFirstFragment newInstance(String argument1, String argument2) {
// This is where you set the Fragment arguments:
MyFirstFragment instance = new MyFirstFragment();
Bundle arguments = new Bundle();
// add whatever arguments you need to the bundle
arguments.putString("ARGUMENT_1_KEY", argument1);
arguments.putString("ARGUMENT_2_KEY", argument2);
//Set the arguments on the new fragment instance
instance.setArguments(arguments);
return instance;
}
// recover the values in onCreate:
#Override
public void onCreate(Bundle savedInstanceState) {
// an easy way to check if this is a new instance is to null-check the saved state Bundle
if (savedInstanceState == null) {
String argument1 = getArguments().getString("ARGUMENT_1_KEY");
String argument2 = getArguments().getString("ARGUMENT_2_KEY");
} else {
// restore whatever you need from savedInstanceState bundle
}
}
Key point - the arguments are passed into the newInstance() method (these can be whatever you want, as long as the type is allowed). The newInstance() method enforces argument types and also prevents setting them after the fragment is already attached to an activity.
After this, in your Activity.onCreate() method:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String argument1 = "some information";
String argument2 = "other information";
MyFirstFragment fragment = MyFirstFragment.newInstance(argument1, argument2);
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frame,fragment);
fragmentTransaction.commit();
}

Android Studio Failing to Store Arguments as Part of Fragment Bundle

I've been wracking my brain for the greater part of the weekend, trying to solve an issue related to Android Studio. The assignment is to create a list fragment that will update when the user clicks buttons in the overhead bar, but despite my best efforts only one of the fragments actually displays (and it's the same no matter which button the user clicks). I've narrowed it down to the point where I'm fairly certain the problem has to do with the constructor's handling of bundles, but I'm not sure where the error is. Here's the related code:
public static ItemFragment newInstance(String title, int position) {
ItemFragment fragment = new ItemFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1,title);
args.putInt(ARG_PARAM2,position);
fragment.setArguments(args);
return fragment;
}
And later on, the call to getArguments():
public void onCreate(Bundle savedInstanceState) {
setRetainInstance(true);
if (getArguments() != null) {
mTitle=getArguments().getString(ARG_PARAM1);
mPosition=getArguments().getInt(ARG_PARAM2);
getActivity().setTitle(mTitle);
}
if (mPosition == 0) {
setListAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, android.R.id.text1, listItems));
} else if (mPosition == 1) {
setListAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, android.R.id.text1, newGoalItems));
} else if (mPosition == 2) {
setListAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, android.R.id.text1, markProgressItems));
} else if (mPosition == 3) {
setListAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, android.R.id.text1, settingsItems));
}
}
This is the related code in MainActivity:
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_list) {
list=ItemFragment.newInstance("List", 0);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
fragmentTransaction.add(R.id.list_frame, new ItemFragment());
fragmentTransaction.commit();
}
else if (id==R.id.action_newGoal) {
newGoal=ItemFragment.newInstance("New Goal", 1);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
fragmentTransaction.add(R.id.list_frame, new ItemFragment());
fragmentTransaction.commit();
}
else if (id==R.id.action_markProgress) {
markProgress=ItemFragment.newInstance("Mark Progress", 2);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
fragmentTransaction.add(R.id.list_frame, new ItemFragment());
fragmentTransaction.commit();
}
else if (id==R.id.action_settings) {
settings=ItemFragment.newInstance("Settings", 3);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
fragmentTransaction.add(R.id.list_frame, new ItemFragment());
fragmentTransaction.commit();
}
return super.onOptionsItemSelected(item);
}
I know from testing that the code simply crashes through the if statement above. What I don't know is why... It looks to me like there should be some values in getArguments that prevent it from returning null.
Write this piece of code in fragments onCreate method() it will work
if (getArguments() != null) {
mTitle=getArguments().getString(ARG_PARAM1);
mPosition=getArguments().getInt(ARG_PARAM2);
getActivity().setTitle(mTitle);
}
It sounds like you are trying to read the arguments in your Fragment's constructor. The context will not be established yet in the constructor, so you should be reading from the bundle in the onCreate() method.
public static Fragment newInstance(String title, int position) {
Fragment fragment = new ItemFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1,title);
args.putInt(ARG_PARAM2,position);
fragment.setArguments(args);
return fragment;
}
Change this line ItemFragment fragment = new ItemFragment(); to this Fragment fragment = new ItemFragment(); and all your code is perfect.
I finally figured this out! So the issue was that during the process of loading the fragments into the frame (the third section of code), the professor gave us a line of code that instantiated a new fragment instead of using the one that we'd just created a few lines above. I simply replaced
fragmentTransaction.add(R.id.list_frame, new ItemFragment());
with
fragmentTransaction.add(R.id.list_frame, list);
and now everything runs. Thanks for all the help everyone!

Categories