using bundle to pass data between fragment to another fragment example - android

I have 3 sherlockListFragments in my app. Every fragment has some editTexts and the last fragment has a button which when it's pressed all data in the first and second fragments should be accessed and stored.
I used bundle to send data between fragments. with the simple following example,
This is the code of my first fragment :
public class PersonalDataFragment extends SherlockListFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragmet_personal_data, container, false);
return v;
}
#Override
public void onCreate(Bundle savedInstanceState) {
PersonalDataFragment fragment = new PersonalDataFragment();
Bundle bundle = new Bundle();
bundle.putString("y", "koko"); //any string to be sent
fragment.setArguments(bundle);
super.onCreate(savedInstanceState);
}
}
and this is the code of the fragment that receives the text :
public class WorkExpRefFragment extends SherlockListFragment {
String myInt;
#Override
public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_workexp_ref, container, false);
final EditText t = (EditText) view.findViewById(R.id.editText5);
final Button generate = (Button)view.findViewById(R.id.button2);
generate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
t.setText(myInt + "sadfigha");
}
});
return view;
}
#Override
public void onCreate(Bundle savedInstanceState) {
Bundle bundle = this.getArguments();
if(getArguments()!=null) {
myInt = getArguments().getString("y");
}
super.onCreate(savedInstanceState);
}
}
Now I have a null in the third fragment, what should i do ?
Thanks in advance

It's normal that your code fails. In the first fragment all you do is create a new instance of PersonalDataFragment and you pass it a Bundle with the data. The problem is although fragment holds the data in the Bundle, the fragment itself is not the one used by the app(isn't even attached to the Activity). You also set the Bundle on a PersonalDataFragment instance but you try to access the data in a WorkExpRefFragment which will obvious not work as the two fragments don't have a direct connection.
One simply solution for what you want to do is to let the Activity "save" the data for your fragments as the Activity is available for all fragments. First create two methods in the Activity holding the three fragments:
public void saveData(int id, Bundle data) {
// based on the id you'll know which fragment is trying to save data(see below)
// the Bundle will hold the data
}
public Bundle getSavedData() {
// here you'll save the data previously retrieved from the fragments and
// return it in a Bundle
}
Then your fragments will save their data like this:
public class PersonalDataFragment extends SherlockListFragment {
// this will identify the PersonalDataFragment fragment when trying to save data
public void static int id PERSONAL_ID = 1;
//...
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle bundle = new Bundle();
bundle.putString("y", "koko"); //any string to be sent
YourActivity activity = (YourActivity) getActivity();
activity.saveData(PERSONAL_ID, bundle);
}
}
To retrieve the data in the WorkExpRefFragment fragment:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
YourActivity activity = (YourActivity) getActivity();
Bundle savedData = activity.getSavedData();
}
Depending on how you used those fragments this solution might not work. Also, keep in mind that the Bundle you pass like above will not be retained for a configuration change.

Related

How we get the previous data of fragment in android?

In my application Main_Activity contain four fragments. In one fragment (called mobile_fragment) whenever i click the button in fragment it will move to another activity, in that i need to get the one value and need to send that data to that fragment(mobile_fragment).
what i done is:
whenever i click the button in fragment i moved to activity and get the value and that value sent to main_Activity, after that in mobile fragment i accessed that variable (static declaration of variable in main_activity).
Now my problem is after getting the value in mobile_fragment, i already entered values in remaining edit text widgets are cleared (no text). how i get previously entered values?
please any one help me.
fragment
public class Mobile_Fragment extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
// TODO Auto-generated method stub
if (container == null) {
return null;
}
browseplans.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), BrowsePlans_Activity.class);
startActivity(intent);
}}
BrowseplansActivty:
Intent intent=new Intent(BrowsePlans_Activity.this,MainActivity.class);
intent.putExtra("Amount",amount);
startActivity(intent);
Main_Activity:
public class MainActivity extends FragmentActivity implements OnClickListener {
public static String TAG = "Main First Frag";
public static String contact_number, prepaid_amt;
Fragment fragment;
FragmentManager frgManager;
FragmentTransaction ft;
Bundle b = new Bundle();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
initUI();
bindEvents();// now this is my changed one
Intent in=getIntent();
prepaid_amt=in.getStringExtra("Amount");
Log.v("TAG+AMOUNT",""+prepaid_amt);
}
}
To pass data from your fragment to the Activity you are starting, pass it through Intent Extras.
To return data from the Activity back to the fragment, call setResult with a result code and an intent that, again, holds data set with extras. Retrieve that data in the onActivityResult override of your fragment.
To save information in a fragment when it is detached and then re-attached, use the override onSaveInstanceState and then extract data from that state in onCreate and/or onCreateView overrides.

Getting value from Fragment into mainActivity

I have a MainActivity. It's layout contains a fragmentContainer and an actionBar. Then I have 2 different fragments containing various EditTexts.All of them have Ids. I populate the fragmentContainer with the fragments when user clicks a button in actionBar. Everything works perfectly.
Now...the app, is supposed to collect the contents of all EditTexts from both fragments when I push a button (in the menu of the actionBar). But it does not work. It crashes when I try to access the EditTexts directly from the activity. I understand that I should create a public method inside the code of the fragments that will return the values I am interested in. But I seem to be doing something wrong because the method is not accessible from the main (TabActivity)
Here is my code:
public class TabActivity extends Activity {
ActionBar.Tab tab_alocare, tab_merc;
Fragment fragmentTab1 = new aloc_fragment();
Fragment fragmentTab2 = new merc_fragment();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tab); // this layout contains the fragmentContainer
...// here I do some actionBar stuff
}
...
}
An example of one of the fragments is bellow:
public class aloc_fragment extends Fragment {
EditText mEditText;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_aloc, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mEditText = (EditText) getView().findViewById(R.id.edaloc);
}
public String getMyText() {
String rez = "";
if (mEditText.getText()!=null) {
rez = mEditText.getText().toString();
}
return rez;
}
}
Now... if inside the Activity code I want to access the edaloc EditText using findViewById, it crashes the app with nullException. So I then tried to access the public method of the fragment so that it would return me the value that I need. But "getMyText" method is not accessible from the TabActivity.
So, this code does not work:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.save:
Fragment alocfragment = (Fragment) getFragmentManager().findFragmentByTag("aloc");
String s = alocfragment.getMyText(); // this is not compiling at all
I am clearly doing something wrong.
Please advise.
Thank you
There are lots of mistakes in your code, You have neither declared nor initialize the fragments at proper place. Also, you are trying to create another instance of fragment in onOptionsItemSelected which is wrong, you need to use same instance of fragment there to access your functions with values. I hope you know how to add and inflate fragment. See my comments and code changes.
Try with this -
public class TabActivity extends Activity {
ActionBar.Tab tab_alocare, tab_merc;
//Declare fragments here
Fragment fragmentTab1;
Fragment fragmentTab2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tab); // this layout contains the fragmentContainer
//Initialize here
fragmentTab1 = new aloc_fragment();
fragmentTab2 = new merc_fragment();
//inflate/add fragments here to the activity
...// here do your actionBar stuff
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.save:
//Now, use same instance of fragment to access your function
String s = fragmentTab1.getMyText();
}
}
public class aloc_fragment extends Fragment {
EditText mEditText;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_aloc,
container, false);
//hold edittext here in the variable
mEditText = (EditText) view.findViewById(R.id.edaloc);
return view;
}
public String getMyText() {
String rez = "";
if (mEditText.getText()!=null) {
rez = mEditText.getText().toString();
}
return rez;
}
}
Also, must to go through Fragment tutorial on Android Developer Fragment Link Link 2, Using Fragments

Android buttons' onClickLIstener() only works once when the Activity begins, not when returning from Fragment transaction

Any time the main Activity is started or restarted (i.e. by pressing the home button on my action bar), all of the buttons (which reside in a fragment in this main activity) work correctly. However, if I press one of the buttons, then press the back button, the home fragment and its buttons reappears but none of the button callbacks work. The button images continue to change appearance when pressed, as always.
The callbacks are assigned in the onCreateView method of the home fragment, as follows:
public class HomeFragment extends SherlockFragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Button button = (Button) v.findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Log.d(TAG, "Button!");
mActivity.getSupportFragmentManager().beginTransaction()
.replace(R.id.contFragMain, new SomeFragment())
.addToBackStack(null)
.commit();
}
});
}
Here is the superclass of Fragments I launch with the buttons:
public abstract class RouteListFragment extends SherlockFragment {
private static final String TAG = RouteListFragment.class.getName();
private Activity mActivity; // parent activity
RouteListAdapter mAdapter;
ListView mListViewRouteList;
public RouteListFragment() {
super();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mActivity = getActivity();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Bundle bndl = getArguments(); // data passed should contain search term
View v = inflater.inflate(R.layout.fragment_route_list, container, false);
mListViewRouteList = (ListView) v.findViewById(R.id.listViewRouteList);
addRoutesToList(); //Populates the list with data via an async DB call
return v;
}
You shouldn't be stashing the Activity reference; the Activity is probably getting recreated at some point (depends on how your flow is), but you should either reassign the reference in onAttach (Activity activity), or just call getActivity() to get the currently Activity you're attached to.
So mActivity.getSupportFragmentManager()...
should instead be
getActivity().getSupportFragmentManager()...
EDIT: Wait, maybe that's not right. What is v in onCreateView()? You're not creating any UI in this Fragment? You should be using onViewCreated() to get a reference to the views in the created hierarchy.

Make AsyncTask inside fragment run after FragmentTransaction.commit()

I have a FragmentTransaction in the activity, and I want the AsyncTask to run in the fragment after fragmentTransaction.commit(). How do I make AsyncTask run after commit? Because AsyncTask runs 2 times before and after the commit. Can anyone help?
*note: AsyncTask run with String of the activities that I sent using FragmentTransaction
Activity :
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menudisplay);
Bundle extras = getIntent().getExtras();
language = extras.getString("language");
lang_id = extras.getInt("id");
MyListFragment mylist = new MyListFragment();
FragmentTransaction fragmentTrans = getFragmentManager()
.beginTransaction();
mylist.language = language;
fragmentTrans.add(mylist, "language");
fragmentTrans.commit();
Log.d("tes", "data loaded");
}
Fragment :
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_menulist_overview, container,
false);
System.out.println("tes="+language+" sama ini = "+asdf);
onActivityCreated(inflater, container, savedInstanceState);
return view;
}
public void onActivityCreated(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
run();
}
public void run(){
Log.d("Test","How many called?");
if(language != null)
new loadcat().execute();
}
I didn't get the note you wrote but you can run the AsyncTask after you have .commit() the transaction simple by creating a public method inside of the fragment that executed you desired AsyncTask and to call it from the Activity at the desired point in code.
So for example if you crate this method inside the Fragment:
public void executeAsyncTask(String language, int lang_id)
{
...
asyncTask.execute(language, lang_id);
}
And in Activity, you can call this method:
...
fragmentTrans.commit();
Log.d("tes", "data loaded");
mylist.executeAsyncTask(language,lang_id);
As far as I know, commit execution callback is not exposed(or maybe even doesn't exist).
So the question is - when do you want to execute your AsyncTask?
If you want it to be executed once at the fragment creation, your code is right, except you should remove your explicit onActivityCreated() call from onCreateView like this:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_menulist_overview, container,
false);
System.out.println("tes="+language+" sama ini = "+asdf);
onActivityCreated(inflater, container, savedInstanceState); // REMOVE THIS LINE
return view;
}
onActivityCreated is a callback. Calling it explicitly cause double execution of your task

Fragment setRetainInstance not works (Android support lib) [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Android fragments setRetainInstance(true) not works (Android support library)
I wrote a simple test project, but I cant understand why I always receive savedInstanceState = null in lifecycle methods onCreate, onCreateView and onActivityCreated. I change the screen orientation, see the log, but state not saved.
Tell me please where is my mistake.
Thanks.
The code of fragment class is:
public class TestFragment extends Fragment {
private String state = "1";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (savedInstanceState != null) {
//never works
state = savedInstanceState.getString("state");
}
//always prints 1
Toast.makeText(getActivity(), state, Toast.LENGTH_SHORT).show();
return inflater.inflate(R.layout.fragment_layout, container, false);
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("state", "2");
Log.e("", "saved 2");
}
}
EDIT
When i try to use setRetainInstance i have no result again((( I change a state to 2 using btn1, but after changing orientation i see 1 when pressing on btn2. Help please(
public class TestFragment extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
setRetainInstance(true);
super.onCreate(savedInstanceState);
}
private String state = "1";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_layout, container, false);
//button for changing state
((Button)view.findViewById(R.id.button1)).setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
state = "2";
}
});
//button for showing state
((Button)view.findViewById(R.id.button2)).setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
Toast.makeText(getActivity(), state, Toast.LENGTH_SHORT).show();
}
});
return view;
}
}
I have seen the same issue. But you can save the instate state in an other way, thanks to the method setRetainInstance(true), all your class data are saved automatically.
#Override
public void onCreate(Bundle savedInstanceState) {
setRetainInstance(true);
super.onCreate(savedInstanceState);
}
EDIT
Try to also add these params when you declare your activities :
<activity
android:name="MyActivity"
android:configChanges="orientation|keyboardHidden|screenSize" />

Categories

Resources