I used below code to passing data from Activity to Fragment.
Fragment Code
public class StoryDetailFragmentInfo extends Fragment {
View view;
TextView txtDescrible;
final static String getData = "abc";
public static StoryDetailFragmentInfo newInstance(String paramater){
Bundle bundle = new Bundle();
bundle.putString(getData,"Message");
StoryDetailFragmentInfo fragmentInfo = new StoryDetailFragmentInfo();
fragmentInfo.setArguments(bundle);
return fragmentInfo;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(getArguments()!=null){
String test = getArguments().getString(getData);
}
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.story_detail_fragment_info_layout, container, false);
txtDescrible = view.findViewById(R.id.txt_describleDetail);
return view;
}
}
MainActivity Code
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.story_detail_layout);
addControls();
loadData();
intentData();
fillDataToView();
}
private void intentData() {
StoryDetailFragmentInfo.newInstance("Hello babe");
}
Problem is getArgument() in my fragment is null and i can't get data What should i do?
Can you help me explain it? Thanks for reading.
If you want to pass data from activity to fragment as initial data, you can send data from activity to ViewPagerAdapter, then pass data from ViewPagerAdapter to fragment in getItem() function.
In Activity:
adapter = new ViewPagerAdapter(getSupportFragmentManager(), this,false));
adapter.setData(data);
In ViewPagerAdapter:
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
MyFragment fragment = new MyFragment();
fragment.setData(data);
return fragment
}
}
If you want to pass data from activity to fragment in real time (like updating data), I recommend to use EventBus. It is a modern and convenient tool to communicate between activity and fragment. Check it at https://github.com/greenrobot/EventBus
Firstly, in the method newInstance of class StoryDetailFragmentInfo, you write these:
bundle.putString(getData,"Message"); while leave paramater alone. So you need change
bundle.putString(getData,"Message");
to
bundle.putString(getData,paramater);
Secondly, you try to get values from arguments from fragment by the key 'AdapterStoryDetailViewPager.idData', but this key is different from the key which you used to save value. So you need to change
String test = getArguments().getString(AdapterStoryDetailViewPager.idData);
to
String test = getArguments().getString(getData);
After these two steps, you would get the right value.
Related
This is the activity class of my project
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tabs_activity);
String LicID = "DATA"
Fragment FragmentDetail = new FragmentDetail();
Bundle data = new Bundle();
data.putString("data",LicID);
FragmentDetail.setArguments(data);
ViewPageAdapter adapter = new ViewPageAdapter(getSupportFragmentManager());
adapter.AddFragment(new FragmentDetail(),"Detail");
viewp.setAdapter(adapter);
tablay.setupWithViewPager(viewp);
}
}
This is my fragmentDetail activity. and it is a tab fragment...
public class FragmentDetail extends Fragment {
public FragmentDetail() {
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.detail_fragment,container,false);
return view;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
String LicID = getArguments().getString ("data");
Toast.makeText(getContext(),""+LicID+" ",Toast.LENGTH_SHORT).show();
}
This code is not work.app crash without any error.... please help. thank you
in tab_activity:
public String LicID = "DATA"
When you want to access this variable from the fragment attached to activity,
in Detail Fragment :
((tab_activity) (getActivity)).LicID
so you don't have to pass arguments to the fragment and use bundle for this. If you need further assistance, please show your logcat
I think the problem is that you set argument to one fragment:
Fragment FragmentDetail = new FragmentDetail();
Bundle data = new Bundle();
data.putString("data",LicID);
FragmentDetail.setArguments(data);
And add to adapter another fragment:
adapter.AddFragment(new FragmentDetail(),"Detail");
Please, try to use the same fragment.
I want to know that is it a good practice to set the objects directly when creating a new Fragment like in the example below or should we always make our object Parcelable and pass through intent?
public class sample extends Fragment {
private Object obj1;
public static sample newInstance(Object obj) {
sample fragment = new sample();
fragment.setObj1(obj);
return fragment;
}
public void setObj1(Object obj1) {
this.obj1 = obj1;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
return super.onCreateView(inflater, container, savedInstanceState);
}
}
In either case, it will be helpful if someone could give me reasons why one is better than the other?
Yes you must use setArguments with a Bundle with all your Parcelables.
Thats because when recreated your Fragment will only have access to it getArguments() and all local variables will be null (or default for primitives).
The way to go is in your newInstance
public static sample newInstance(String obj) {
sample fragment = new sample();
Bundle args = new Bundle();
args.putString(STRING_PARAM_KEY, obj);
fragment.setArguments(args);
return fragment;
}
Then in your onCreateView
obj1 = getArguments().getString(STRING_PARAM_KEY);
Just declare in your class a constant for the key
static final String STRING_PARAM_KEY = "string_param_key";
I am working on an application which needs to retrieve some informations from the user and I am using Fragments to do that. The idea is to have a ListFragment that displays the name of different Fragments that allow the user to give informations, when user click on one name in the ListFragment, the corresponding fragment is displayed in full screen if we are in portrait mode or next the ListFragment in landscape mode.
As basis I used the code explained and given in the following links:
google fragment and Dynamic Layouts using the Fragment Manager.
I "slightly" modified the code of the links above to have two TextView in the Fragment used to retrieved informations. I am trying to retain states for this Fragment. I tried to set setRetainInstance to true but it does not work so I am trying with onSaveInstanceState.
In onSaveInstanceState I put the content of the TextView in a bundle and in onCreateView if savedInstanceState is not null then I retrieve the strings to be displayed in the TextView. I can see in debug mode that everything (seems to) work, after onSaveInstanceState the Bundle has the strings and in onCreateView the strings are correctly retrieved and pass to the TextView with setView but at the end the TextView remain empty.
Why does that happens? How can that happen?
Below the code of my fragment:
public class DataFragment extends AbstractFragment {
private final String TAG = getClass().getSimpleName();
private View mView;
private TextView mFirstNameTextView = null;
private TextView mMailTextView = null;
Bundle mArgs;
public DataFragment(){
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setRetainInstance(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
mView = inflater.inflate(R.layout.data_fragment, container, false);
mFirstNameTextView = (TextView)mView.findViewById(R.id.setting_Firstname);
mMailTextView = (TextView)mView.findViewById(R.id.setting_Mail);
if (savedInstanceState!=null){
String test = savedInstanceState.getString("name");
String retest = savedInstanceState.getString("mail");
mFirstNameTextView.setText(test);
mMailTextView.setText(retest);
}
return mView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public void onDetach() {
super.onDetach();
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
String test = mFirstNameTextView.getText().toString();
String testmail = mMailTextView.getText().toString();
outState.putString("name", mFirstNameTextView.getText().toString());
outState.putString("mail", mMailTextView.getText().toString());
}
#Override
public void onPause() {
super.onPause();
}
#Override
public int getShownIndex() {
int ret = getArguments().getInt("index", 0);
return ret;
}
}
To be complete this Fragment inherit from AbstractFragment. AbstractFragment as mentioned by its name is an abstract class that inherit from Fragment. I use this class because I plan to have several fragments and this class helps me to write less code. For completeness below is the code for the AbstractFragment:
public abstract class AbstractFragment extends Fragment {
public AbstractFragment(){}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setRetainInstance(true);
}
public int getShownIndex(){
int ret = getArguments().getInt("index", 0);
return ret;
}
}
Edit:
Just to be clear, the problem is not to retrieve data, the problem is to display data. I am retrieving the values I stored using onSaveInstanceState but these values are not displayed in TextView. Below a screenshot of my application with a breakpoint on onSaveInstanceState, this screenshot has been taken after I entre the Strings "foo" and "bar" in my TextView and then I rotate the AVD, we can see on the screenshot that strings "foo" and "bar" are inside the savedInstanceState Bundle and the variables test and retest are correctly initialized to "foo" and "bar", but these strings are not displayed in the TextView
You are confusing arguments and savedInstanceState. Go through the developer documents here to know what is savedInstanceState.
Refer arguments bundle rather than savedInstanceState bundle to make it work proper. Refer the following code
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
mView = inflater.inflate(R.layout.data_fragment, container, false);
mFirstNameTextView = (TextView)mView.findViewById(R.id.setting_Firstname);
mMailTextView = (TextView)mView.findViewById(R.id.setting_Mail);
Bundle arguments = getArguments();
if (arguments !=null){
String test = arguments.getString("name");
String retest = arguments.getString("mail");
mFirstNameTextView.setText(test);
mMailTextView.setText(retest);
}
else {
Log.e(DataFragment.class, "Arguments was null, did not load the name and email TextView");
}
return mView;
}
I am creating a app in which i wanna slide images,so for that i will be using view pager.For the image i have created a fragment which will display the images.
Code
public class ImageSwitcher extends BaseFragment {
private ImageView imageView;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.image_switcher_fragment, container, false);
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
initialize();
}
private void initialize() {
imageView = (ImageView) view.findViewById(R.id.image_switcher);
imageView.setBackgroundResource("");
}
Now at this line
imageView.setBackgroundResource("");
the image will come from the int array which i will pass.
My doubt is
How will i pass int values to fragments
Is there any better way to use image switcher
Pass your Integer value from your fragment using Bundle as below:
Fragment fragment = new Fragment();
Bundle bundle = new Bundle();
bundle.putInt("id", id);
fragment.setArguments(bundle);
Access the value in Fragment onCreateView method:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
int m_id=getArguments().getInt("id");
return inflater.inflate(R.layout.fragment, container, false);
}
class MyFragment extends Fragment {
private static final String ARG_BG_RES="ARG_BG_RES";
public Fragment() {}
static public newInstance(String backgroundRes) {
Bundle args = new Bundle();
args.putExtra(ARG_BG_RES, backgroundRes);
Fragment fragment = new Fragment();
fragment.setArguments(args);
return f;
void whereYouNeedIt() {
String backgroundRes = getArguments().getStringExtra(ARG_BG_RES);
...
}
}
From outside:
MyFragment f = MyFragment.newInstance("black");
Don't omit public Fragment() {} it's required by the OS.
You can use bundle to pass values to the fragment or during initializing pass values via a custom constructor
For background resource if you are not changing images based on some logic in code, apply it via XML background and a drawable :-/
I want to pass string value from activity to fragment. For that I'm using bundle for transferring string value.
PUT STRING ACTIVITY
Passing string value :-
Bundle bundle = new Bundle();
bundle.putString("Value", resultp.get(CurrentProjectActivity.VALUE));
Log.d(TAG, "Value ::: " + resultp.get(CurrentProjectActivity.VALUE));
// set Fragmentclass Arguments
AmenetiesFragment fragobj = new AmenetiesFragment();
fragobj.setArguments(bundle);
In log I got "Value" value as well.
GET STRING VALUE IN FRAGMENT (IT IS NOT WORKING).
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.activity_listview, container, false);
Bundle bundle = this.getArguments();
Log.d(TAG, "Value's value:) ::: " + bundle);
String strtext = bundle.getString("Value");
return rootView;
}
In log I'm getting NULL value for BUNDLE. Please help me to resolve this Issue. Thanks in advance.
I advice you to follow this link1 and this . You should use interface. Check here
Bundle bundle = new Bundle();
bundle.putString("edttext", "From Activity");
// set Fragmentclass Arguments
Fragmentclass fragobj = new Fragmentclass();
fragobj.setArguments(bundle);
and in the Frament task
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
String strtext = getArguments().getString("edttext");
return inflater.inflate(R.layout.fragment, container, false);
}
Suppose you want to send String data from Activity to Fragment
In Fragment.java file add the following code,
public static String name= null;
public void setName(String string){
name = string;
}
In MainActivity.java from which you want to send String add the following code,
String stringYouWantToSend;
Fragment fragment = new Fragment();
fragment.setName(stringYouWantToSend);
The savedInstance variable will be empty the first time you run your app,
it only gets filled when the onSaveInstanceState method is called, this usually happens when you rotate the screen, then savedInstance variable will be populated. Try this :
if(savedInstance != null){
Log.d(TAG, "There's is something");
}else{
Log.d(TAG, "Nothing in there");
}
First time in logcat you will see the first message, try turning your device and the message in the else will show.
As #james said, the recommended way is to use interfaces, or have a field class but this increases coupling and destroys the whole point of fragments.
make public first in activity that object you required in fragment.
then you can use like ((ACtivityName)getActivity()).objectName;
i hope it help.this is not best way to pass data into fragment.
there are some other way also.
create constructor of your fragment class and pass it and save in fragment like:
public MyFragment(String data){
this.data = data;
}
also you can use as bundle #james answer.
EDIT:-
First Way
private class MyFeagment extends Fragment {
private String data;
private Object myObject;
public MyFeagment(String data, Object anyObject) {
this.data = data;
this.myObject = myObject;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.i("My Fragment", "data :: " + data + " and myObject :"
+ myObject);
return super.onCreateView(inflater, container, savedInstanceState);
}
}
let's say it is your framgnet.
and put this code in your activity
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(R.id.fragment_container, new MyFeagment("My Data",
"data"));
transaction.commit();
Easiest Approach but not Recommended
You can access activity data from fragment:
Activity:
public class MyActivity extends Activity {
private String myString = "hello";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
...
}
public String getMyData() {
return myString;
}
}
Fragment:
public class MyFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
MyActivity activity = (MyActivity) getActivity();
String myDataFromActivity = activity.getMyData();
return view;
}
}