I have a problem with pass data from activity to fragment, it says null pointer exception, but my data is not null.
This is my activity :
#Override
public void onResponse(Call call, Response response) throws IOException {
dataj = response.body().string();
System.out.println(dataj);
Bundle bundle = new Bundle();
bundle.putString("datak", dataj);
FragmentUtama fu = new FragmentUtama();
fu.setArguments(bundle);
Intent load = new Intent(LoginActivity.this, MainActivity.class);
load.putExtra("datajs", dataj);
startActivity(load);
finish();
}
and this is my fragment :
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
// Inflate the layout for this fragment
String datas = getArguments().getString("datak");
System.out.println(datas);
return inflater.inflate(R.layout.fragment_utama, container, false);
}
Thanks for your help.
You don't pass data to fragment via Intents. Arguments are passed by setting them to the fragment instance before calling Fragment transaction commit.
SomeFragment f = new SomeFragment ();
// Supply data input as an argument.
Bundle args = new Bundle();
args.putInt("some_key", value);
f.setArguments(args);
then you read it in your fragment.
NOTE: setArguments can only be called before the Fragment is attached to the Activity. So if fragment is already attached, it will not transfer any data to the fragment.
Bundle args = getArguments();
int value = args.getInt("some_key", 0);
you may try this,
use findFragmentByTag it will help you to find fragment and send data over it.
FragmentUtama fu =(FragmentUtama)getSupportFragmentManager().findFragmentByTag(FragmentUtama.class.getSimpleName())
Bundle bundle = new Bundle();
bundle.putString("datak", dataj);
fu.setArguments(bundle);
or
you can have one setter method in fragment and set data from activity to fragment
from Activity.
fu.setData(dataj);
In fragment
String data;
public void setData(String data)
{
this.data=data;
}
use data using getter method of fragment
public String getData()
{
return data;
}
You need to pass the data to MainActivity using extras of an intent and then using setArguments to pass it to the fragment that belongs to this activity when replacing/adding that fragment to its container.
Related
Hi I'm learning now about Fragments and I have some doubts.
V1:
So the correct way to create a new Fragment should be with "newInstance" instead of a constructor and would be something like this:
Fragment fragment = MyFragment.newInstance(variable);
And the code on the class "MyFragment" should be this:
private static final String ARG_PARAM1 = "param1";
private int variable;
public MyFragment() {
//Empty constructor
}
New instance will receive the param and will put them on a Bundle and set the argument for the class
public static mi_fragment newInstance(Int param1) {
MyFragment fragment = new MyFragment();
Bundle args = new Bundle();
args.putInt(ARG_PARAM1, param1);
fragment.setArguments(args);
return fragment;
}
Then after setting it the method onCreate will pick up the argument:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
variable = getArguments().getInt(ARG_PARAM1);
}
V2:
But I still can't see the problem with using the constructor and setting the arguments programatically:
Bundle bundle = new Bundle();
bundle.putInt("key", variable);
Fragment fragment = new MyFragment();
fragment.setArguments(bundle);
Then I pick up the argument on the method onCreate:
public void onCreate(#Nullable Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Bundle bundle = this.getArguments();
if(bundle!=null){
variable = getArguments().getInt("key");
}
}
So I decided to search on the internet about this and I found a good answer but I still can't seem to understand it or when you could use it.
the way to pass stuff to your Fragment so that they are available after a Fragment is recreated by Android is to pass a bundle to the setArguments method.
This Bundle will be available even if the Fragment is somehow recreated by Android.
So my conclusion is that you keep the bundle alive and using the newInstance could make you return to the last fragment for example. But probably I'm wrong so I need help.
Question: What's the main difference between both and how do you benefit from newInstance ? An example.
I am trying to get bundle extras from activity 1 to fragment of activity 2 but getargument() always returns as null.
//Using this to get string in fragment
String value = getArguments().getString("abc");
//activity1 code that i used to get the extras
Bundle bundle = new Bundle();
bundle.putString("abc", townextra);
UserFragment myFrag = new UserFragment();
myFrag.setArguments(bundle);
There is a problem with logic of passing data.
Correct way would be: Pass data from Activity1 to Activity2, and then from Activity2 to Fragment.
all fixed. I added a new function on my activity 2 to create fragment. instead of doing it in oncreat. it all works fine, thanks
Your Activity
Bundle bundle = new Bundle();
bundle.putString("params", "Your String data");
// set MyFragment Arguments
MyFragment myObj = new MyFragment();
myObj.setArguments(bundle);
The Fragment.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam = getArguments().getString("params");
}
}
But will be better if you show the code how you pass data between activities and then use my answer.
And please add your fragment code.
Below is a snapshot of the activity code. I want to send the lists to separate fragments. The first one works fine, however in stepsFragment.setArguments(stepsBundle); setArguments isn't recognized. thank you.
//
// Send the ingredients array list in Parcelable to the Ingredients Fragment
//
private void sendArrayToIngredientsFragment() {
//Pack Data in a bundle(call the bundle "ingredientsBundle" to differentiate it from the "stepsBundle"
Bundle ingredientsBundle = new Bundle();
ingredientsBundle.putParcelable("Recipes", recipes);
//Pass Over the bundle to the Ingredients Fragment
IngredientsFragment ingredientsFragment = new IngredientsFragment();
ingredientsFragment.setArguments(ingredientsBundle);
getSupportFragmentManager().beginTransaction().replace(R.id.ingredients_fragment_container, ingredientsFragment).commit();
}
/*
Send the steps array list in Parcelable to the Steps Fragment
*/
private void sendArrayToStepsFragment() {
//Pack Data in a bundle(call the bundle "stepsBundle" to differentiate it from the "ingredientsBundle"
Bundle stepsBundle = new Bundle();
stepsBundle.putParcelable("Recipes", recipes);
//Pass Over the bundle to the Steps Fragment
StepsFragment stepsFragment = new StepsFragment();
stepsFragment.setArguments(stepsBundle);
getSupportFragmentManager().beginTransaction().replace(R.id.steps_fragment_container, stepsFragment).commit();
}
}
Take sure, your fragment classes both extends from Fragment class. If that so, there must be method setArguments()
I am working on Fragments, I would like to know whether it is possible to pass data from a fragment A to a fragment B directly, without forwarding the data to their attached Activity.
Use Bundle to send String:
//Put the value
YourNewFragment ldf = new YourNewFragment ();
Bundle args = new Bundle();
args.putString("YourKey", "YourValue");
ldf.setArguments(args);
//Inflate the fragment
getFragmentManager().beginTransaction().add(R.id.container, ldf).commit();
In onCreateView of the new Fragment:
//Retrieve the value
String value = getArguments().getString("YourKey");
There are number of ways you can do that. One of them is by sending data in arguments like this:
private int data;
private static String PARAM_MY = "param";
public static MyFragment newInstance(int data) {
MyFragment fragment = new MyFragment ();
Bundle args = new Bundle();
args.putInt(PARAM_MY , data);
fragment.setArguments(args);
return fragment;
}
and you can retreive it onCreate() :
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
data = getArguments().getInt(PARAM_MY);
}
}
Other way is to use Interfaces.
I don't think so. Every fragment is attached to an activity, there's no direct connection between two fragments, unless they are connected to the same activity. If you want to communicate between fragments, you'll have to define interfaces insides fragment and make the attached activity implement the interfaces. In the attached activity you have the two fragments instances, so you can pass (using the activity) data between fragments. It's strictly recommended by best practices, take a look at documentation for details:
https://developer.android.com/training/basics/fragments/communicating.html
If the activity is the same you can keep the data in the activity.
Activity
public class MyActivity extends Activity {
private MyObject myObject = new MyObject();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
...
}
public MyObject getMyObject() {
return myObject;
}
}
Fragment
public class MyFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
MyActivity activity = (MyActivity) getActivity();
MyObject myObjectFromActivity = activity.getMyObject();
return view;
}
}
The main question would be what are you trying to achieve and what sort of data are you trying to pass?
One of the apps I wrote for work used the Main Activity to hold all the controllers so they could easily be accessed from any view, or framgment, or associated controller. A good example would be a data-controller holding all shared app data.
Are you looking to pass strings and ints, or more complex objects?
There are number of ways to achieve this
1 : Using Bundle
Link 1 - Explains How to transfer data using bundle and other methods
2 : Using Activities & Fragment
Link 2 - With help of activites ,interface and fragments
3: Using Shared Preferences
Shared Preferences Link
I've two activity "Name_Status" and "Main_activity".
In Main_activity , i've fragments . i wanna send a string value from Name_Status activity to one of Main_activity fragment.
Below is the method of Name_Status activity:
#Override
public void onClick(View v) {
if (v.getId() == R.id.ok_change_name)
{
name = name_change.getText().toString();
System.out.println(name);
Log.d("entered", "entred");
MainActivity obj=new MainActivity();
Log.d("obj created", "obj created");
obj.changeMainName(name);
Log.d("obj.changename", "obj.changename");
}
}
By using this method i'm first sending data to the Main_activity and from there sending data to fragment as below.
Below is the code of Main_activity:
public void changeMainName(String s) {
FragActivity1 obj = (FragActivity1) getSupportFragmentManager().findFragmentById(R.id.person_profile); obj.changeName(s);
}
Now from here I'm sending string value to fragment class and there I'm only setting the string to the textview like below:
public void changeName(String s)
{
Log.d("changename entry" ,"changename netry");
System.out.println(s);
System.out.println(name_field.getText().toString());
name_field.setText(s);
System.out.println(name_field.getText());
}
I'm getting
NullPointerException at obj.changeMainName(name);
You gonna have to do some relay. For instance you have activity A which has no Fragment and Activity B which has a fragment. On Android framework you can first pass data to From Activity A to B and From Activity B you can pass data to its Fragment following the view Hierarchy.
In Activity A. do the following
Intent intent = new Intent(this, ActivityB.class);
intent.putExtra("key", "value");
startActivity(intent);
Now inside Activity B, get data from activity A
String stringValue= getIntent().getStringExtra("key");
Then pass that data your Fragment as an argument before to start Frag
Bundle bundle = new Bundle();
bundle.putString("key", stringValue);
ActivityBFrag fragment = new ActivityBFrag();
fragment.setArguments(bundle);
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(container, fragment, tag);
transaction.addToBackStack(tag);
transaction.commit();
Then inside your Fragment class. get data like below whenever you wanna access your data, can be inside onCreate, OnActivityCreated etc.
public void getArguments(){
Bundle bundle = getArguments();
if(bundle != null){
String stringValue = bundle.get("key");
}
}
Send data to second activity by Intent bundle. Then get the data in second activity by getIntent().getExtras() and then pass the data to fragment.