How to pass data from Activity to already created Fragment? - android

Lately i've been stuck! I have one Activity (not my MainActivity, I mean, it is not where I created this Fragment), and I need to pass some data. I've already tried to pass using Bundle, using getter, but the same issue appears: "Attempt to invoke virtual method {...} on a null object." at the line where I call the Bundle in the Fragment. I am new at this, so I'm sorry if this is a simple question and I didn't understand. Below the relevant parts of my code:
On Activity (not the main activity):
public void save(){
myGoal = spinnerGoals.getSelectedItem().toString();
Bundle bundle = new Bundle();
bundle.putString("goal", myGoal);
GoalFragment goalFragment = new GoalFragment();
goalFragment.setArguments(bundle);
}
On Fragment (where I want to put this 'goal')
private TextView goal;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate( R.layout.fragment_goal, container, false);
goal = view.findViewById(R.id.myGoalText);
Bundle bundle = getArguments();
if (bundle != null) {
final String myGoal = bundle.getString("goal");
goal.setText(myGoal);
}
return view;
}
On MainActivity (where I created the Fragments):
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BottomNavigationView bottomNav = findViewById(R.id.bottom_navigation);
bottomNav.setOnNavigationItemSelectedListener(navListener);
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new HomeFragment() )
.commit();
}
private BottomNavigationView.OnNavigationItemSelectedListener navListener =
new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Fragment selectedFragment = null;
switch (item.getItemId()) {
case R.id.nav_home:
selectedFragment = new HomeFragment();
break;
case R.id.nav_goal:
selectedFragment = new GoalFragment();
break;
case R.id.nav_info:
selectedFragment = new InfoFragment();
break;
}
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, selectedFragment)
.commit();
return true;
}
};
Please, I've lost much time trying to solve this by myself hahaha. If anyone can help me, i'd appreciate that!

Create a method in Fragment which you want to receive data, then invoke the method in Activity.
Write this code in Activity :
Bundle bundle = new Bundle();
bundle.putString("goal", myGoal);
fragmentObj.sendData(bundle);
write code in Fragment:
public void sendData(Bundle bundle){
String myGoal = bundle.getString("goal");
}

If the Activity(not main activity) was created from your fragment, you could use
startActivityForResult()
method to receive data after the activity is ended, read about it more here
If that is not the case, you need to persist (in storage) the data using Preferences or Room Database

Related

how to send data from activity to fragment with bottom navigation

Hi everyone can help me pls
I want send data from activity to fragment but I using bottom navigation
I using Intent to send data from activity 1 to activity 2 (activity 2 have bottom navigation)
I want to send data to Home_Fragment what should I Used ?
BottomNavigationView bottomNav = findViewById(R.id.top_navigation);
bottomNav.setOnNavigationItemSelectedListener(navListener);
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
new Home_Fragment()).commit();
}
private BottomNavigationView.OnNavigationItemSelectedListener navListener =
new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
Fragment selectedItem = null;
switch (menuItem.getItemId()){
case R.id.navigation_home:
selectedItem = new Home_Fragment();
break;
case R.id.navigation_project:
selectedItem = new Project_Fragment();
break;
case R.id.navigation_persons:
selectedItem = new Persons_Fragment();
break;
case R.id.navigation_accounts:
selectedItem = new Accounts_Fragment();
break;
case R.id.navigation_other:
selectedItem = new Others_Fragment();
break;
}
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
selectedItem).commit();
return true;
}
};
just initialize your fragment from itself and pass any data inside initialize method.
so by example if we want to pass a String value to fragmen we should make it like this inside fragment :
public static YourFrament getInstance(String example) {
YourFrament fragment = new YourFrament();
Bundle bundle = new Bundle();
bundle.putString("key", example);
fragment.setArguments(bundle);
return fragment;
}
and to get data you should receive it from onCreate method inside fragment like this :
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null)
String value = getArguments().getString("key");
}
so from activity we should call fragment like this :
case R.id.navigation_accounts:
selectedItem = YourFrament.getInstance("string example");
break;
Assuming you want to pass the data when you initialize the fragment, you could try and create a Bundle object, add your data to the bundle.
Then initialize your fragments using a static newInstance(Bundle args) passing in your bundle.
So basically your fragments would look something like this.
public class HomeFragment extends Fragment{
public static Fragment newInstance(Bundle args){
// get your data and do whatever
return new HomeFragment(); }
Then in your onNavigationItemSelected() method
case R.id.navigation_home:
Bundle bundle = new Bundle();
bundle.putInt(AGE, 22); // put whatever data you want to pass to the fragment.
selectedItem = HomeFragment.newInstance(bundle)
break;

getting menu press item and passing it to recycler view to set variable

I have a navigation drawer set up with different categories. I also have a recycler view that gets the post from firestore (already segregrated in categories) and loads and displays them. my issue is that I want it so when the user presses on that menu item it loads the posts from that category in firestore and displays them. I have attempted to use bundles but have not figured out how to successfully get it to load
adapter:
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_categories, container, false);
blog_list = new ArrayList<>();
blog_list_view = view.findViewById(R.id.blog_list_view);
// blogRecyclerAdapter = new BlogRecyclerAdapter(blog_list);
blogRecyclerAdapter = new BlogRecyclerAdapter(getContext(),blog_list);
blog_list_view.setLayoutManager(new LinearLayoutManager(getActivity()));
blog_list_view.setAdapter(blogRecyclerAdapter);
firebaseFirestore = FirebaseFirestore.getInstance();
firebaseFirestore.collection("politics").addSnapshotListener(new EventListener<QuerySnapshot>() {
#Override
public void onEvent(#javax.annotation.Nullable QuerySnapshot queryDocumentSnapshots, #javax.annotation.Nullable FirebaseFirestoreException e) {
for(DocumentChange doc: queryDocumentSnapshots.getDocumentChanges())
if (doc.getType() == DocumentChange.Type.ADDED) {
BlogPost blogPost = doc.getDocument().toObject(BlogPost.class);
blog_list.add(blogPost);
blogRecyclerAdapter.notifyDataSetChanged();
}
}
});
return view;
}
}
you can see here where it says "politics" is where i need to get the proper menu item to load
navigation drawer:
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.nav_home:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
new HomeFragment()).commit();
break;
case R.id.nav_profile:
Intent profileIntent = new Intent(MainActivity.this, user_profile.class);
startActivity(profileIntent);
break;
case R.id.nav_settings:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
new SettingsFragment()).commit();
break;
case R.id.nav_sign_out:
Toast.makeText(this, "SIGNED OUT TEST", Toast.LENGTH_SHORT).show();
FirebaseAuth.getInstance().signOut();
sendToStart();
break;
case R.id.nav_new_post:
Intent postIntent = new Intent(MainActivity.this, NewPost.class);
startActivity(postIntent);
break;
case R.id.nav_politics:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
new CategoriesFragment()).commit();
break;
the adapter works fine i just cant figure out how to pass the data to the adapter to load the specif category based on what menu item was selected
First, inside your onNavigationItemSelected, add the info to your CategoriesFragment via a bundle:
case R.id.nav_politics:
CategoriesFragment fragment = new CategoriesFragment();
Bundle args = new Bundle();
args.putString("collection", "politics");
fragment.setArguments(args);
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, fragment)
.commit();
break;
Next, inside your fragment's onCreate or onStart (not sure about onCreateView) get the string from the bundle:
Bundle bundle = this.getArguments();
if (bundle != null) {
String collection = bundle.getString("collection", "");
}
You can then use it for your Firestore collection.
A future improvement would be extracting politics to a static variable. Another (if passing different values for collection) would be making a helper function you can just pass the collection value to so multiple nav items can use it without code duplication.

Saving values when closing app or switching fragments

I am new to Android and have an integer weekNumber that needs to be kept when closing the app. My idea was to set the value in the activity that handled the fragments that need to use the value, and always get the value from there with a getter, but the weekNumber keeps resetting when I close the app or switch fragments, even though I use SharedPreferences. I load the saved data in onCreate of the activity, and save the data in onPause. Maybe this is wrong. Why does this happen? I would appreciate any help and would love to learn more!
Here is my MainActivity that handles Fragments:
public class MainActivity extends AppCompatActivity {
private int weekNumber;
private static final String SHARED_PREFS = "sharedPrefs";
private static final String WEEK_NUMBER = "weekNumber";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BottomNavigationView bottomNavigationView = findViewById(R.id.bottomNavigation);
bottomNavigationView.setOnNavigationItemSelectedListener(navListener);
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,new HomeFragment()).commit();
loadData();
}
private BottomNavigationView.OnNavigationItemSelectedListener navListener =
new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Fragment selectedFragment = null;
switch (item.getItemId()) {
case R.id.nav_home:
selectedFragment = new HomeFragment();
break;
case R.id.nav_add:
selectedFragment = new CalculatorFragment();
break;
case R.id.nav_settings:
selectedFragment = new SettingsFragment();
break;
}
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,selectedFragment).commit();
return true;
}
};
#Override
protected void onPause() {
super.onPause();
saveData();
}
public void saveData() {
SharedPreferences sharedPreferences = getSharedPreferences(SHARED_PREFS,MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putInt(WEEK_NUMBER,weekNumber);
}
public void loadData() {
SharedPreferences sharedPreferences = getSharedPreferences(SHARED_PREFS,MODE_PRIVATE);
weekNumber = sharedPreferences.getInt(WEEK_NUMBER,1);
}
public int getWeekNumber() {
return weekNumber;
}
public void setWeekNumber(int weekNumber) {
this.weekNumber = weekNumber;
}
One of the Fragments:
public class HomeFragment extends Fragment {
View rootView;
private TextView[] textViews;
MainActivity mainActivity = new MainActivity();
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_home,container,false);
textViews = new TextView[16];
for(int i=0; i<textViews.length; i++) {
{
String buttonID = "textView" + (i+1);
int resID = getResources().getIdentifier(buttonID, "id", getActivity().getPackageName());
textViews[i] = ((TextView) rootView.findViewById(resID));
}
}
setWeekText();
textViews[9].setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(getActivity(),ActivityDay1.class));
}
});
Button buttonNextWeek = rootView.findViewById(R.id.buttonNextWeek);
buttonNextWeek.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mainActivity.setWeekNumber(mainActivity.getWeekNumber()+1);
setWeekText();
}
});
return rootView;
}
private void setWeekText() {
textViews[8].setText(String.valueOf(mainActivity.getWeekNumber()));
}
Call editor.apply(); at the end of your saveData function in order to actually save the value in the SharedPreferences.
Also, you can't call MainActivity mainActivity = new MainActivity(); in the fragment. Set it with mainActivity = getActivity(); in onCreateView or directly in your onClick listeners.
Why? What you have creates a new instance of MainActivity inside the fragment rather than referring to the one on which you have set the data you need.
Also, if you keep the current design, it's probably safer to call loadData in your Activity onCreate before you create the fragment that is going to try to access the data.
Perhaps a better option would be to just use the shared preferences in the fragment directly though.
A couple of things.
You need to make sure data is actually being saved. Add editor.commit()in your saveData()
You should do the saving in onSaveInstance and restoring in onSaveInstance since this is what android will call when the system kill your activity on cases such as low memory

How do you pass an intent from activity to a fragment that is already opened

This is the answer that I got from other topic and applied it to my codes:
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);
}
These are the codes that I applied, it is not working somehow. The fragment is already opened at the start.
public void onInfoWindowClick(Marker marker) {
if (tag.equals("Click to show all routes in this point")) {
Bundle bundle = new Bundle();
bundle.putString("route1", "Divisoria - San Juan");
// set Fragmentclass Arguments
hideShowFragment fragobj = new hideShowFragment();
fragobj.setArguments(bundle);
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
Fragment intersectionFragment = manager.findFragmentById(R.id.fragmentContainer2);
ft.setCustomAnimations(R.anim.fade_in, R.anim.fade_out);
ft.add(R.id.fragmentContainer2, fragobj);
ft.show(intersectionFragment);
ft.commit();
}
}
The codes in my onCreateView method:
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_hide_show, container, false);
if (!routes.equals(none)) {
routes = getArguments().getString("route1");
} else {
routes = "Food";
}
return view;
}
What I want to happen is that the fragment will always update to what marker Tag that I click on the map. In other words, pass the string to the fragment (that is opened) and update it.
I do not want to use startActivityForResult because I can't move around the map if I don't use fragments. Is there a way to send result from activity to fragment that is already opened and running? If none, then how can I make the fragment not running from the start (using supportFragmentManager)? I only know is to hide it
If you have running Fragment and want to pass some data to it, you should create some way to communicate. For that purposes, you can use Observer pattern.
First of all create interface inside Activity if you want to pass data to Fragment:
public interface OnInfoClickedListener {
void onInfoClicked(String info);
}
Implement this interface inside Fragment:
#Override
public void onInfoClicked(String info) {
infoTextView.setText(info);
}
Now, inside your Activity, create variable to store this interface implementation:
private OnInfoClickedListener listener;
And when instantiating Fragment, save instance of it to variable:
InfoFragment fragment = InfoFragment.newInstance();
listener = fragment;
And when needed just provide data through this interface:
listener.onInfoClicked("Info - " + UUID.randomUUID());

Launch fragment map with address to search

Im having a issue I dont know how to resolve.
I have a fragment with a editText and a button.
The button launches a fragment map like this:
public void onClick(View view) {
//Fragment fragment = null;
switch (view.getId()) {
case R.id.SearchButton:
Home activity = (Home) getActivity();
if(activity != null)activity.openMapFragment();
break;
}
and the function openMapFragment():
public void openMapFragment(){
Fragment fragment = new gMapFragment();
replaceFragment(fragment);
}
How would i do to send the text inserted on editText field as a address to look for on map fragment?
You should use bundle to pass data to a fragment :
public void openMapFragment(String args){
Fragment fragment = new gMapFragment();
Bundle bundle = new Bundle();
bundle.putString("foo", args);
fragment.setArguments(bundle);
replaceFragment(fragment);
}
And to retrieve data :
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//...
String foo = getArguments() != null ? getArguments().getString("foo") : "";
//...
}

Categories

Resources