Send a string value from Activity to Fragment in Android - java

I need to pass a String from an Activity to a fragment but nothing seems to work for me.
I found this answer on stackoverflow
From Activity you send data with intent as:
Bundle bundle = new Bundle(); bundle.putString("edttext", "From
Activity"); // set Fragmentclass Arguments Fragmentclass fragobj = new
Fragmentclass(); fragobj.setArguments(bundle);
and in Fragment onCreateView method:
#Override public View onCreateView(LayoutInflater inflater, ViewGroup
container,
Bundle savedInstanceState) {
String strtext = getArguments().getString("edttext");
return inflater.inflate(R.layout.fragment, container, false); }
But this doesn't work for me. When I click the button nothing happens.
Is it maybe because the fragment is already created? In my app: ToDoFragment> Activity(pass data to:>ToDoFragment
Here is my code but I don't thing it will provide more info:
Activity.java (inside OnClickListener of a button)
String datePassed = mDate.getText().toString();
String toDoPassed = mEditText.getText().toString();
Bundle bundle=new Bundle();
bundle.putString("key1", datePassed);
//set Fragmentclass Arguments
ToDoFragment myToDoFragment=new ToDoFragment();
myToDoFragment.setArguments(bundle);
ToDoFragment.java (inside oncreateview)
Bundle bundle = this.getArguments();
if (bundle != null) {
mToDoInfo = getActivity().getIntent().getStringExtra(key1);

If I understood correct, then you are not doing it wrong, but you are doing this in wrong scenario. This is on assumption that your fragment is already inflated & you are starting new Activity from it & want the data back as result from it. so what you need is something like this,
inside your ToDoFragment where I believe you are starting activity, do this instead:
startActivityForResult(new Intent(getActivity(), MyActivity.class), 1001);
& override onActivityResult method like:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 1001 && resultCode == Activity.RESULT_OK) {
String myData = data.getStringExtra("my_key");
}
}
& now inside onClick of your MyActivity,
Intent intent = new Intent();
intent.putExtra("my_key", "my_data");
setResult(RESULT_OK, intent);
finish();
this should invoke onActivityResult of fragment where we wrote code to get data.

Yes this is because the fragment is already created. Create a method in your fragment class and call it from inside the onClick method of your activity.

Let me make it Easy for you!
ToDoFragment myToDoFragment=new ToDoFragment(datePassed); //easy right?
and in your ToDoFragment class make a constructor with String as input!

You can simply follow this pattern to pass the values from activity to fragment
ToDoFragment.java
public class ToDoFragment extends Fragment {
String date;
public static Fragment newInstance(String date) {
ToDoFragment fragment = new ToDoFragment();
fragment.date = date;
return ToDoFragment;
}
}
In your activity's onclick
String toDoPassed = mEditText.getText().toString();
ToDoFragment myToDoFragment = ToDoFragment.newInstance(toDoPassed);

Related

how to invoke an Activity(Java Class ) method from Fragment?

how can i call or invoke Regular Activity class method from a fragment.
I have tried to invoke Registration class method activityFunction from fragment like below and it returns null pointer exception. below is the entire fragment class and any help would be highly appreciated. i have googled around and it has been mentioned that i have to manually assign fragment to activity and then call the method , but i sort of couldnt find a way to do that .
Any help would be highly appreciated. Below in the code i was trying to call activity method from fragment on clicking a button.
Registration media = new Registration();
media.activityFunction();
public class fragment_login extends Fragment {
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
public fragment_login() {
// Required empty public constructor
}
public static fragment_login newInstance(String param1, String param2) {
fragment_login fragment = new fragment_login();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_login, container, false);
login = v.findViewById(R.id.et_email);
password = v.findViewById(R.id.et_password);
send = v.findViewById(R.id.btn_login);
return v;
}
// thats where i am trying to call clas method from fragment
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
send.setOnClickListener(new View.OnClickListener() {
Registration media = new Registration();
media.activityFunction();
}
});
}
You can use Local Broadcast Receiver to send the event from fragment to activity and do the work that you want to do from fragment. For Example
Fragment.java
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context);
Intent localIntent = new Intent(“CUSTOM_ACTION”);
intent.putExtra("key", "value");
localBroadcastManager.sendBroadcast(localIntent);
Activity.java
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive( Context context, Intent intent ) {
String data = intent.getStringExtra(“key”);
Log.d( “Received data : “, data);
}
};
register broadcast receiver in activity in onResume() and unregister in onStop().
register using below code
IntentFilter filter = new IntentFilter("CUSTOM_ACTION");
registerReceiver(receiver, filter);
unregister using below code:
localBroadcastManager.unregisterReceiver(receiver);
Note: Don't forget to use the same action as declared while sending broadcast.
You can call activity method like this, if fragment is loaded in that activity
((MainActivity)getActivity()).abcMethod();

how to pass a value using intents and bundle

I am trying to pass a value from my Activity to my Fragment but the Bundle is always null.
Activity
CallLogsFragment callLogfrag = new CallLogsFragment();
Intent intent = new Intent(this, DeviceUsageActivity.class);
Bundle bundle = new Bundle();
bundle.putInt("key", callgroup);
callLogfrag.setArguments(bundle);
this.startActivity(intent);
Fragment which is meant to retrieve value from Activity
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
bundle = this.getArguments();
if (bundle != null) {
int myInt = bundle.getInt("key", 0);
}
View view = inflater.inflate(R.layout.fragment_call_logs, container, false);
load(view);
setupList(view);
return view;
}
try this one
// send value from activity to fragment
CallLogsFragment callLogfrag = new CallLogsFragment();
Bundle bundle = new Bundle();
bundle.putInt("key", "4");
callLogfrag.setArguments(bundle);
// call fragment from activity
getSupportFragmentManager().beginTransaction().replace(R.id.containar, callLogfrag).commit();
// get value in fragment
if (getArguments() != null) {
int status = getArguments().getInt("key");
If I am clear with your question!! You are trying to send data from one activity to the fragment in Another activity.
Then you need to first send data in Intent that starts second activity. Then get the data from intent and set your data to fragment as argument and add the fragment to the parent activity.
//here you go, from first activity
Intent intent = new Intent(this, DeviceUsageActivity.class);
Bundle bundle = new Bundle();
bundle.putInt("key", callgroup);
intent.putExtra("yourdata",bundle);
//start your activity - parent activity of your fragment
this.startActivity(intent);
//then get your data in DeviceUsageActivity in onCreate()
Bundle yourdata = null;
if(getIntent().getExtras() != null) {
yourdata = getIntent().getBundleExtra("yourdata");
}
//Then sent data to fragment
CallLogsFragment callLogfrag = new CallLogsFragment();
callLogfrag.setArguments(yourdata);
// add fragment to parent activity
getSupportFragmentManager().beginTransaction().replace(R.id.containar, callLogfrag).commit();
//rest you know - get bundle argument in fragmet
From Activity to store data
Intent i = new Intent(getApplicationContext(), NewActivity.class);
i.putExtra("key","value");
startActivity(i);
To retrieve data back to fragment,use Context as getActivity if needed only in fragments
Bundle extras = getIntent().getExtras();
if (extras != null) {
String value = extras.getString("key");
//The key argument here must match that used in the other activity
}

Adding button on ActivityResult when using fragments Android

I am making an app, that will have FragmentsActivity and after clicking on Floating Action Button making a simple button on the screen. How I should implement something like that. Now I have got this:
at main.java
#Override
public View onCreateView(final LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.monday_act, container, false);
RelativeLayout rl = (RelativeLayout) rootView.findViewById(R.id.rel);
rl.addView(new DayView(this.getContext(), getArguments().getInt(ARG_SECTION_NUMBER)));
FloatingActionButton fab = (FloatingActionButton) getActivity().findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent addClass = new Intent(getActivity(), AddClass.class);
startActivityForResult(addClass, 1);
}
});
return rootView;
}
and the onActivityResult:
#SuppressLint("SetTextI18n")
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1)if (resultCode == RESULT_OK) {
final Button lesson = new Button(this.getActivity());
lesson.setText("Button");
lesson.setBackgroundColor(getResources().getColor(R.color.green));
lesson.setTextColor(getResources().getColor(R.color.red));
lesson.setX(100);
lesson.setY(100);
lesson.setWidth(100);
lesson.setHeight(150);
lesson.setTextSize(100);
RelativeLayout(this.getActivity());
rl.addView(lesson);
}
}
Both functions are in public static class PlaceholderFragment extends Fragment {
You don't use onActivityResult() between Activity and Fragment
you use it between two Activities
A activity will command another activity to do some work on some data passed to it or a request is made to the other activity to fetch something or do something and return the result.
after the work is done the worker Activity finishes it self and returns the result to the activity which started it.
And the activity who issues the work will have onActivityResult() it updated the UI depending on the result it gets

Sending string to Activity and then to a Fragment of Activity

I am having some trouble with my simple app. The app starts in the MainActivity where you can press a camera icon. This opens an implicit intent for taking a photo. When the photo is taken, another activity DisplayImageActivity is opened. This activity consists of two fragments: one that holds an ImageView for displaying the photo and another one that holds some TextViews that displays some information about the photo (filename, size, location etc.). I use a ViewPager for having horizontal swipe capabilities.
Now to the problem. I should note that this is not a consistent problem. Sometimes the app crashes, sometimes it works just fine. The problem lies in getting the image path from the onActivityResult in MainActivity to the two fragments so I can get the image and info. Here is my onActivityResult method:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 42 && resultCode == RESULT_OK) {
Log.d(TAG, "MainActivity onActivityResult method called.");
Intent intentShowPicture = new Intent(this, DisplayImageActivity.class);
intentShowPicture.putExtra(PICTURE_KEY, imgPath);
startActivity(intentShowPicture);
}
}
So I just put the image path I get from taking the picture in the bundle and start the DisplayImageActivity. Then in my DisplayImageActivity, I do this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_image);
Log.d(MainActivity.TAG, "DisplayImageActivity onCreate called.");
imgPath = getIntent().getExtras().getString(MainActivity.PICTURE_KEY);
mAdapter = new FragmentAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mAdapter);
Then I have a method that just return the straing imgPath:
public String getImgPath() {
return imgPath;
}
Then inside the fragment (PictureFragment) I try to retrieve the imgPath like this:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
DisplayImageActivity activity = (DisplayImageActivity) getActivity();
imgPath = activity.getImgPath();
But as I mentioned earlier, sometimes the getImgPath method just returns null and the app crashes when I try to retrieve the photo. But sometimes it works fine. I am kinda lost as to why this is. Is it because the fragment is sometimes constructed before the imgPath variable is assigned in the DisplayImageActivity, so the variable is just null?
I am kinda new to android, so this might not be the best approach. I just did it from the top of my head. Any ideas why this is happening?
If you want to pass data from an Activity to a Fragment, you could use this approach:
In the Activity:
Bundle bundle = new Bundle();
String imgPath = "path/to/my/image";
bundle.putString("imgPath", imgPath );
PictureFragment frag = new PictureFragment();
frag.setArguments(bundle);
transaction.replace(R.id.fragment_single, frag);
transaction.commit();
Fragment:
Reading the value in fragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
String myValue = this.getArguments().getString("imgPath");
...
...
...
}
For more information, take a look at this question How to pass a variable from Activity to Fragment, and pass it back?

Fragment Arguments are null

I am trying to send data from one fragment to another, I am using bundle for that. But, whenever, I try to get any information from that bundle in the second fragment, I get an error message saying that I am trying to get a null object. I have set the arguments of the second fragment before I create it, and I have also add information to the bundle before sending it. I could not find out what is the problem. Here is the interface code in the main fragment which should open the details fragment,
public interface ListClickHandler {
public void onlistElementClicked ( Bundle args); //we'll have to override it in the parent activity.
}//end interface.
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
mCallback = (ListClickHandler) activity;
}//end try
catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement ListClickHandler interface");
}//end catch
}
Also, I create the bundle in two places, once in the main fragment, which contains a list, if any item is clicked the bundle is created, info is added to the bundle, and that bundle is passed to the method inside the interface as the following,
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_todo_list, container, false);
mSimpleCursorAdapter=new SimpleCursorAdapter(getActivity(),R.layout.notes_row,null, from, to,0);
getLoaderManager().initLoader(LOADER_ID, null, this); //once this is done onCreateLoader will be called.
ListView listView = (ListView) rootView.findViewById(R.id.notes_list); //findViewById must be called using the rootView because we are inside a fragment.
listView.setAdapter(mSimpleCursorAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
Cursor cursor = mSimpleCursorAdapter.getCursor();
if (cursor != null && cursor.moveToPosition(position)) {
String category= cursor.getString(1);
String summary= cursor.getString(2);
String description=cursor.getString(3);
long id= cursor.getLong(cursor.getColumnIndex(NotesContract.NotesTable._ID));
int locationId= cursor.getInt(cursor.getColumnIndex(NotesContract.NotesTable.COLUMN_LOCATION));
String [] retrievedData= {category, summary, description};
if (getActivity().findViewById (R.id.fragment_container)!=null){
//two pane layout:
Bundle args = new Bundle();
args.putStringArray("data",retrievedData);
/*args.putInt("update", 1);*/
args.putLong("id", id);
args.putInt("locationId", locationId);
mCallback.onlistElementClicked(args );/*this is available in the parent activity*/
}
else {
// one pane layout:
Intent intent = new Intent(getActivity(), NotesDetails.class);
intent.putExtra(Intent.EXTRA_TEXT, retrievedData);
/*intent.putExtra("update", 1); */ //to indicate that the query should be update not insert.
intent.putExtra("id", id);
intent.putExtra("locationId", locationId); //whether it is 0 or 1
startActivity(intent);
}
}//end outer cursor if.
}
});
return rootView;
}
The second place where I create and call the bundle is in the main activity (which contains the main fragment) when some items of the options menu are selected as the following,
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {//open the settings activity to enable the user to change the settings.
//open settings activity via intent here.
startActivity(new Intent (this, Settings.class));
return true;
}
if (id==R.id.text_note){ //open the details activity where the user can enter their notes and save it.
if (twoPane) {
args.putBoolean("location", false);
mCallBack.onlistElementClicked(args);
}
else {
Intent intent = new Intent(this, NotesDetails.class);
startActivity(intent);
return true; //this line is necessary
}
}//end if
if (id==R.id.location_note)
{
if (twoPane) {
args.putBoolean("location", true);
mCallBack.onlistElementClicked(args);
}
else {
//prepare intent here:
Intent intent = new Intent(this, NotesDetails.class);
intent.putExtra("location", true);
startActivity(intent);
}
}
return super.onOptionsItemSelected(item);
}
This is how I override onlistElementClicked in the main activity,
#Override
public void onlistElementClicked(Bundle args) {
DetailsFragment detailsFragment = new DetailsFragment();
detailsFragment.setArguments(args);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, detailsFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
}//end interface method.
And this is how I get the information inside the arguments of the details fragment (The fragment that should be opened from the main fragment).
Bundle args=this.getArguments();
After that I use args to get any information in the bundle, but I am getting the error which I mentioned previously.
Can any one please help me? I've checked several solutions on the web and nothing worked for me.
Thank you.
You should assign the value of Bundle like this:
public void onCreate(Bundle savedInstance){
super.onCreate(savedInstance);
youtBandGlobalMember = getArguments();
}
Bundle args=this.getArguments();
actually, I didn't call it in any method, it is called in the body of fragment class, and its value is assigned to a global variable. Is that wrong?
It's too early. Member variables are initialized when the object is constructed and that is before you can call setArguments() on the fragment object.
Postpone the getArguments() call to one of the on...() lifecycle callbacks in the fragment.

Categories