How to pass string from one Fragment to another? [duplicate] - java

This question already has answers here:
How to pass values between Fragments
(18 answers)
Closed 7 years ago.
I want to pass a string call custID from one fragement to anopther. but I don't know how to pass it. Below is my code:
class TabsAdapter extends FragmentPagerAdapter {
public TabsAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return 2;
}
#Override
public Fragment getItem(int i) {
switch(i) {
case 0: return MaterialUpConceptFakePage.newInstance();
case 1: return MaterialUpConceptFakePage.newInstance();
}
return null;
}
#Override
public CharSequence getPageTitle(int position) {
switch(position) {
case 0: return "Tab 1";
case 1: return "Tab 2";
}
return "";
}
}
Can someone help me on this?

Bundle bundle=new Bundle();
bundle.putString("ID", "value");
MyFragment obj=new MyFragment ();
obj.setArguments(bundle);

well you can use bundle as below -
Fragment fragment = new Fragment();
Bundle bundle = new Bundle();
bundle.putInt(key, value);
fragment.setArguments(bundle);
getFragmentManager()
.beginTransaction()
.replace(R.id.body, fragment, null)
.commit();
and then inside onCreateView() you can receive as below -
Bundle args = getArguments();
int myInt = bundle.getInt(key, defaultValue);

User Bundle to pass any value from one Fragment to another. This is how you can pass string from one Fragment to another.
Put the value
SecondFragment secondFragment = new SecondFragment ();
Bundle args = new Bundle();
args.putString("MyKey", "MyValue");
secondFragment.setArguments(args);
Load the second fragment
getFragmentManager().beginTransaction().add(R.id.container, secondFragment).commit();
In onCreateView of the second Fragment:
//Retrieve the value
String value = getArguments().getString("MyKey");

While a simple Bundle like other answers works, I can already see you use the newInstance so I will show you an example while still using newInstance to make the code easier to maintain in the future.
In your fragment where you want the String to be add this code
public static YourFragmentName newInstance(String str) {
YourFragmentName fragment = new YourFragmentName ();
Bundle args = new Bundle();
args.putSerializable("customer_id", str);
fragment.setArguments(args);
return fragment;
}
Then looking at your code instead of
MaterialUpConceptFakePage.newInstance()
you should have
MaterialUpConceptFakePage.newInstance(customerid)
Then inside your onCreateView
String customer_id = (String) getArguments().get("customer_id");

SharedPreference is a good way for passing data between activities or fragment. You can send any data int,boolean, string int etc.
SharedPreferences preference;
//Initialize preference
preference = getActivity().getSharedPreferences("STATE",MODE_PRIVATE);
// it uses key-value pairs
// put string data to preference
preference.edit().putString("Your_String_Data", "anything").commit();
//use this to get that value in any fragment.
preference = getActivity().getSharedPreferences("STATE",
Context.MODE_PRIVATE);
String data = preference.getString("Your_String_Data",null);

Related

How do I stop my transaction between Fragments?

I have recently just learnt how to use a fragment manager to send data between two fragments as shown in the codes below:
My First fragment that I am sending the data from:
history_fragment fragment = history_fragment.newInstance(InputValue1, InputValue2, InputValue3, InputValue4);
getFragmentManager().beginTransaction().replace(R.id.nav_host_fragment, fragment).commit();
The Fragment that is receiving the data:
public static history_fragment newInstance(String InputValue1, String InputValue2, String InputValue3, String InputValue4) {
history_fragment fragment = new history_fragment();
Bundle args = new Bundle();
args.putInt("Value1", Integer.parseInt(InputValue1));
args.putInt("Value2", Integer.parseInt(InputValue2));
args.putInt("Value3", Integer.parseInt(InputValue3));
args.putInt("Value4", Integer.parseInt(InputValue4));
fragment.setArguments(args);
return fragment;
}
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView value1 = view.findViewById(R.id.Value1);
if ( getArguments() != null) {
Value1 = getArguments().getInt("Value1");
}
value1.setText(String.valueOf(Value1));
}
My code is not fully complete but the main problem am I trying to solve is that whenever I go back to my first fragment, the application crashes. I know that the problem is due to the transaction ".replace()", but how should I stop the transaction before returning back to the first fragment?

java.lang.RuntimeException: Unable to start activity ComponentInfo, Unable to instantiate fragment, could not find Fragment constructor

Please see all the four pictures, first 3 pictures has error screen, the last one has Fragment constructor.
https://i.stack.imgur.com/lbodG.png
https://i.stack.imgur.com/nysfG.png
https://i.stack.imgur.com/AHYCR.png
https://i.stack.imgur.com/telPC.png
You must have a default constructor for Fragment.
public class Tab1Fragment extends Fragment{
public Tab1Fragment(){
}
...
}
If you want to pass data to your fragment you must do that by setArguments(), not by passing it through constructor, not good practice.
Instead try something like this:
public class Tab1Fragment extends Fragment{
private static final String ARG_URL = "url";
public Tab1Fragment(){
}
public static Tab1Fragment newInstance(String url) {
Tab1Fragment fragment = new Tab1Fragment();
Bundle args = new Bundle();
args.putString(ARG_URL, url);
fragment.setArguments(args);
return fragment;
}
}
And to get url value in fragment use
getArguments().getString(ARG_URL);
Now use newInstance method to get fragment instance.
Tab1Fragment.newInstance("your url");
As #Mangal mentioned, a Fragment must have a default (no argument) constructor. To pass data to a new fragment, use a static function, like this
public static MyFragment newInstance(String someData) {
MyFragment fragment = new MyFragment ();
Bundle args = new Bundle();
args.putString("someData", someData);
fragment.setArguments(args);
return fragment;
}
and retrieve the data like this
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Bundle args = getArguments();
String someData = "";
if( args != null ) {
someData = args.getString("someData", "");
}
}
Then, instead of calling
new MyFragment(data);
in the code where you create the Fragment, you would instead call
MyFragment.getInstance(data);

Communication between one fragment to another [duplicate]

This question already has answers here:
How to pass data between fragments
(13 answers)
Closed 6 years ago.
I am new to fragments. I added two edit texts in first fragment and I want to send that edittext data to second fragment.
I am using a bundle, but its printing null in second fragment.
Can anyone tell me how to send data to other fragment?
First fragment
nextt.setOnClickListener(new Button.OnClickListener() {
#Override
public void onClick(View _view) {
int viewId = _view.getId();
FragmentTransaction ft;
switch (viewId) {
case R.id.Button1:
FragmentManager fm = getFragmentManager();
ft = fm.beginTransaction();
SecondFrag secondFrag = new SecondFrag();
Bundle bundle = new Bundle();
bundle.putInt("deviceInst",viewId);
secondFrag.setArguments(bundle);
ft.replace(R.id.total_frame_content, secondFrag);
ft.addToBackStack(null);
ft.commit();
break;
}
}
});
In second fragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.second_new, container, false);
String value = getArguments().getString("deviceInst");
System.out.println("TTTT"+ value);
In your first fragment you pass an int as an argument.
bundle.putInt("deviceInst",viewId);
And then, in your second fragment you try to get that argument by using
getArguments().getString("deviceInst")
which will fail, so to get the argument you pass you need to use getArguments().getInt("deviceInst")
For encapsulating the needed data, a good tip is to have a static newInstance() method in your fragments that requires data.
Here's a post about it.
https://plus.google.com/+AndroidDevelopers/posts/bCD7Zvd945d
You need to change like
int value = getArguments().getInt("deviceInst");
instead of
String value = getArguments().getString("deviceInst");
You will need to make the following changes in your code.
bundle.putString("deviceInst",editText.getText().toString());
Then in your second fragment you can get that argument by using
getArguments().getString("deviceInst")
Here editText is the instance of the edit text in the first fragment.
As you have passed int in the bundle, you need to use getInt() in your receiver fragment.
For example:
SecondFrag secondFrag = new SecondFrag();
Bundle bundle = new Bundle();
bundle.putInt("deviceInst",viewId);
secondFrag.setArguments(bundle);
getFragmentManager().beginTransaction().add(R.id.total_frame_content, secondFrag).commit();
In receiver fragment
String value = getArguments().getInt("deviceInst");

setText to Fragment from within Activity

I am trying in vain to simply take a value from FormActivity and use it to fill a EditText in a Fragment. I have to wait for activity to retrieve the value from a remote server and populate the local SQLite table with it, this means no solution I have tried from within the fragment has worked (null error because it hasn't been populated that early).
I need help.
Relevant section of FormActivity.java
public void DrawText() {
// Fetching user details from sqlite
HashMap<String, String> user = db.getUserDetails();
if (user.size() != 0) {
Log.e(TAG, "string surname: " + surname);
// Displaying the user details on the fragment
FirstFragment f1 = new FirstFragment();
//put info into a bundle to pass to fragments
Bundle drawbundle = new Bundle();
drawbundle.putString("surname", surname);
f1.setArguments(drawbundle);
FragmentManager FM = getSupportFragmentManager();
FragmentTransaction FT = FM.beginTransaction();
FT.add(R.id.something, f1);
FT.commit();
}else{
Log.e(TAG, "table was empty");
}
}
private class MyPagerAdapter extends FragmentPagerAdapter {
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int pos) {
switch(pos) {
case 0: return FirstFragment.newInstance("#string/form_instruct");
case 1: return SecondFragment.newInstance("SecondFragment, Instance 1");
case 2: return ThirdFragment.newInstance("ThirdFragment, Instance 1");
case 3: return FourthFragment.newInstance("FourthFragment, Instance 1");
//case 4: return FifthFragment.newInstance("ThirdFragment, Instance 3");
default: return FirstFragment.newInstance("FirstFragment, Default");
}
}
Obviously, id.something is not correct, I do not know how to get the id. I read I can use a tag, but my attempt at that did not work. I tried the following:
FirstFragment fragA = (FirstFragment) getSupportFragmentManager().findFragmentByTag("fragA");
Here is my FirstFragment.java
public class FirstFragment extends android.support.v4.app.Fragment {
//create variables & Logcat tag
private static final String TAG = FirstFragment.class.getSimpleName();
private EditText inputTitle;
private EditText inputName;
private EditText inputSurname;
//private SQLiteHandler db;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_first, container, false);
TextView tv = (TextView) v.findViewById(R.id.tvFragFirst);
tv.setText(getArguments().getString("msg"));
inputSurname = (EditText) getActivity().findViewById(R.id.surnameText);
inputSurname.setText(getArguments().getString("surname"));
return v;
}
public static FirstFragment newInstance(String text) {
FirstFragment f = new FirstFragment();
Bundle b = new Bundle();
b.putString("msg", text);
f.setArguments(b);
return f;
}
I'm going around in circles with this, can anyone please help?
if you are using a ContentProvider you could use a ContentObserver to get notified when your table is filled up, and when onChange is invoked, you can update the TextView. If you are not using a ContentProvider, yo could use the LocalBroadcastManger and a BroadcastReceiver to achieve the same thing
Create interface implement your fragment with it after fragment creation access your activity and save your interface reference in activity, after your operation will complete access your method from activity using saved interface reference and update your fragment.
Second option add your fragment with tag and using this fragment manager find your fragment by tag than you have the reference of your fragment than simply call your method inside your activity

android disable fragment 0 in fragmentpager

I'd like to be able to not allow switching to one of my 3 fragments in my custom FragmentPagerAdapter when certain conditions are met. Unfortunately I failed to find any help.
I'd prefer to not remove and re-add the fragment (item 0), as this criterium can change inside the FragmentActivity any time and I'd need the fragment to be able to receive and handle messages.
Any suggestions? Please ask if something's unclear.
Edit: Sharing some code
Main activity:
#Override
protected void onResume() {
super.onResume();
...
_sectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager(), this, cardnumber, pin);
_viewPager = (ViewPager) findViewById(R.id.pager);
_viewPager.setAdapter(_sectionsPagerAdapter);
_viewPager.setOnPageChangeListener(_sectionsPagerAdapter);
_viewPager.setCurrentItem(1);
_viewPager.setOffscreenPageLimit(2);
This seems a bit rude, but it works
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
Bundle args = new Bundle();
switch (position) {
case CUSTOMER_DETAILS_PAGE:
// fragment = _fragments.get(TRLIST_PAGE);
fragment = new UserDetailFragment();
args.putString("TAG", "details");
break;
case BALANCE_PAGE:
// fragment = _fragments.get(BALANCE_PAGE);
fragment = new BalanceFragment();
args.putString("TAG", "balance");
break;
case TRLIST_PAGE:
// fragment = _fragments.get(TRLIST_PAGE);
fragment = new TrListFragment();
args.putString("TAG", "trlist");
break;
default:
break;
}
_listeners.put(position, (MyTabSelectedListener) fragment);
// fragment = (Fragment) _listeners.get(position);
args.putString("cardnumber", _cardnumber);
args.putString("pin", _pin);
fragment.setArguments(args);
return fragment;
}
I want to limit access to the CUSTOMER_DETAILS_PAGE when it would be empty anyway.
After reading corsair992-s answer here https://stackoverflow.com/a/23967701/3153792 and looking at the CWAC-Pager source code here https://github.com/commonsguy/cwac-pager I managed to find what I was looking for.
The key was to change the getItemPosition function (which I didn't even use before) to get the TAG argument (set in getItem) from the fragments and identify them that way:
#Override
public int getItemPosition(Object item) {
Fragment fragment = (Fragment) item;
String title = fragment.getArguments().getString("TAG");
int position = tabs.indexOf(title);
if (position >= 0) {
return position;
} else {
return POSITION_NONE;
}
First I define tags for each tab and a list to hold them in order of appearance:
public static final String CUSTOMER_DETAILS_PAGE = "detail";
public static final String BALANCE_PAGE = "balance";
public static final String TRLIST_PAGE = "trlist";
List<String> tabs = new ArrayList<String>();
Afterwards, I add them in the constructor in the original order:
tabs.add(CUSTOMER_DETAILS_PAGE);
tabs.add(BALANCE_PAGE);
tabs.add(TRLIST_PAGE);
When I need to hide a tab, I just remove it from the list and notify the adapter:
public void disableUserDetail() {
tabs.remove(tabs.indexOf(CUSTOMER_DETAILS_PAGE));
notifyDataSetChanged();
}
My fragment specifically goes to the left side (the beginning) but it would be easy to change:
public void enableUserDetail() {
tabs.add(0, CUSTOMER_DETAILS_PAGE);
notifyDataSetChanged();
}
I had to change getItem and getPageTitle to use the tabs list and TAG constants as identifier (which I also include as arguments for getItemPosition):
#Override
public Fragment getItem(int position) {
String id = tabs.get(position);
Fragment fragment = null;
Bundle args = new Bundle();
if (id.equals(CUSTOMER_DETAILS_PAGE)) {
fragment = new UserDetailFragment();
args.putString("TAG", CUSTOMER_DETAILS_PAGE);
...
#Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
String id = tabs.get(position);
if (id.equals(CUSTOMER_DETAILS_PAGE)) {
return _ctx.getString(R.string.title_section1).toUpperCase(l);
...

Categories