Android how to send data from Activity to Fragment? - android

I want to pass data from my Activity to a Fragment. I have no idea how to do it. I've seen many solutions but no one of them did really work.
I just want to pass a simple String to the Fragment.
I have tried it this way:
public class PhotoActivty extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_photo);
if (null == savedInstanceState) {
Bundle bundle = new Bundle();
String myMessage = "Stackoverflow is cool!";
bundle.putString("message", myMessage );
BasicFragment fragInfo = new BasicFragment();
fragInfo.setArguments(bundle);
android.app.FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.photo_frame, fragInfo);
transaction.commit();
}
}
}
What is the error there? I call it this way:
String myValue = this.getArguments().getString("message");
In the onCreateView in the Fragment

I usually use a static factory pattern:
public class MyFragment extends Fragment {
public static MyFragment newInstance(int index) {
MyFragment f = new MyFragment();
Bundle args = new Bundle();
args.putInt("index", index);
f.setArguments(args);
return f;
}
}
When you create the fragment in your Activity:
Fragment MyFragment = MyFragment.newInstance(5);
Alex Lockwood has a good rundown on why this is a preferred design pattern:
http://www.androiddesignpatterns.com/2012/05/using-newinstance-to-instantiate.html

Bundle bundle = new Bundle();
String myMessage = "Stackoverflow is cool!";
bundle.putString("message", myMessage );
Fragment fragInfo = new BasicFragment();
fragInfo.setArguments(bundle);
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.photo_frame, fragInfo);
transaction.commit();
try this inside your if

from activity:
Bundle bundleObject = new Bundle();
bundleObject.putString("data", " Send From Activity");
/*set Fragmentclass Arguments*/
Fragment fragmentobject = new Fragment();
fragmentobject .setArguments(bundleObject );
From Fragment You receive this way:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
String stringText = getArguments().getString("data");
return inflater.inflate(R.layout.fragment, container, false);

Not sure if this is the real cause of the problem, but you have to use getSupportFragmentManager() instead of getFragmentManager() inside AppCompatActivity. Also, classes such as Fragment and FragmentTransaction should come from support.v4 package.

Remove if (null == savedInstanceState) in your activity. If savedInstanceStatenull == null then BasicFragment will not replace your FrameLayout for R.id.photo_frame.

Related

Share information between fragments

I need to share information between fragments. I know that I can use sharedpreferences but I think that is not optimized.
This is the parent fragment code:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view= inflater.inflate(R.layout.fragment_blank, container, false);
....
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.replace(R.id.eventos_pager, new BlankFragment2());
ft.commit();
....
return view;
}
This fragment call BlankFragment2 and BlankFragment1 need to sends information to BlankFragment2
I can share information to BlankFragment2 by the BlankFragment2's constructor. It is not allowed.
In Android you pass values to Fragments via bundles.
Using AndroidStudio File > New > Fragment > Fragment (Blank) will generate something like this.
public class MTFragment extends Fragment {
private String mParam1;
public static MTFragment newInstance(String param1) {
MTFragment fragment = new MTFragment();
Bundle args = new Bundle();
args.putString("value", param1);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString("value");
}
}
}
From your code:
MTFragment mFragment = MTFragment.newInstance("Hello");
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.replace(R.id.eventos_pager, mFragment);
ft.commit();

OnCreateView not called again after replacing with the same fragment

I am using a drop-down menu with the different items in the toolbar. In the activity, I am adding the fragment as soon as the menu item is clicked. The fragment OnCreateview gets called and the data is fetched from the API. The logic for the fetching of data remains same for all menu items but only the API endpoint differs. So I am trying to pass the Bundle with API endpoint name and using the same fragment for all the items. But the problem is OnCreateView gets called only first time and the request is made only for first fragment transaction even if I am replacing the same fragment for different item click.
Activity.java
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
switch (i) {
case 0: //Clients
Bundle bundle1 = new Bundle();
bundle1.putString("hash-key","item1");
ReportCategoryFragment rp1 = new ReportCategoryFragment();
rp1.setArguments(bundle1);
replaceFragment(rp1,false,R.id.container);
break;
case 1:
Bundle bundle2 = new Bundle();
bundle2.putString("hash-key","item2");
ReportCategoryFragment rp2 = new ReportCategoryFragment();
rp2.setArguments(bundle2);
replaceFragment(rp2,false,R.id.container);
break;
}
}
ReportCategoryFragment
#Nullable
#Override
public View onCreateView(LayoutInflater inflater,
#Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_runreport, container, false);
setHasOptionsMenu(true);
ButterKnife.bind(this, rootView);
presenter.attachView(this);
reportType = getArguments().getString("hash-key");
Log.v("hashkey",reportType);
presenter.fetchCategories(reportType, false, true);
return rootView;
}
replaceFragment Function
public void replaceFragment(Fragment fragment, boolean addToBackStack, int containerId) {
invalidateOptionsMenu();
String backStateName = fragment.getClass().getName();
boolean fragmentPopped = getSupportFragmentManager().popBackStackImmediate(backStateName,
0);
if (!fragmentPopped && getSupportFragmentManager().findFragmentByTag(backStateName) ==
null) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(containerId, fragment, backStateName);
if (addToBackStack) {
transaction.addToBackStack(backStateName);
}
transaction.commit();
}
}
EDIT: FragmentnewInstance method
public static ReportCategoryFragment newInstance() {
ReportCategoryFragment fragment = new ReportCategoryFragment();
Bundle bundle = new Bundle();
fragment.setArguments(bundle);
return fragment;
}
Simple solution is to use Broadcast Receiver
Declare this in your fragment class
BroadcastReceiver broadCastNewMessage = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//extract our message from intent
String msg_for_me = intent.getStringExtra("some_msg");
}
};
Now in onCreate() of fragment register this
registerReceiver(this.broadCastNewMessage, new IntentFilter("update_fragment"));
And in onDestroyView()
unregisterReceiver(broadCastNewMessage);
Now Call this method from the service class where u want to update the activity from your menu selection
Intent intent = new Intent("update_fragment");
intent.putExtra("some_msg", message);
sendBroadcast(intent);
Try using static method in fragment to create new instance of the fragment.
public static Fragment newInstance()
{
MyFragment myFragment = new MyFragment();
return myFragment;
}

putExtra from activity then getExtra in fragment

i tried to put and get extra from activity to fragment . but something is wrong! anybody have idea? my case is diffrent because i wanna do it in fragment
myActivity :
if(email.matches(users.user1)&&password.matches(users.pass1)){
Intent intent = new Intent(LoginActivity.this,MainActivity.class);
Intent i = new Intent(LoginActivity.this,ProfileFragment.class);
i.putExtra("pn", users.pn1);
i.putExtra("name", users.name1);
i.putExtra("family", users.family1);
i.putExtra("rank", users.rank1);
startActivity(intent);
finish();
}
myfragment
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_profile2, container, false);
final TextView pn =getActivity().findViewById(R.id.pn);
final TextView name =getActivity().findViewById(R.id.name);
final TextView family =getActivity().findViewById(R.id.family);
final TextView user =getActivity().findViewById(R.id.user);
final TextView rank =getActivity().findViewById(R.id.rank);
String pnget = getActivity().getIntent().getStringExtra("pn");
String nameget = getActivity().getIntent().getStringExtra("name");
String familyget = getActivity().getIntent().getStringExtra("family");
String userget = getActivity().getIntent().getStringExtra("user");
String rankget = getActivity().getIntent().getStringExtra("rank");
pn.setText(pnget);
name.setText(nameget);
family.setText(familyget);
user.setText(userget);
rank.setText(rankget);
}
Hi . i tried to put and get extra from activity to fragment . but something is wrong! anybody have idea?
You start an intent call intent. But the intent have data is i, and it have't started yet.
You can use setArgument and getArgument to send and receive data from activity to fragment or from fragment to fragment:
In YourReceiveFragment:
public static Fragment newInstance(String data1, String data2, ...) {
Fragment f = new YourReceiveFragment();
Bundle bundle = new Bundle();
bundle.putString(DATA_RECEIVE1, data1);
bundle.putString(DATA_RECEIVE2, data2);
f.setArguments(bundle);
return f;
}
In your activity: Just call it:
Fragment f = YourReceiveFragment.newInstance(yourString1, yourString2);
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.add(R.id.main_container, f).commit();
Then in YourReceiveFragment:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null){
String dataReceive1 = getArguments().getString(DATA_RECEIVE1);
String dataReceive2 = getArguments().getString(DATA_RECEIVE2);
}
}
In case you want to send data from an activity to a fragment in another activity, use interface or an easier way is just pass the data to the activity which contains fragment and from that, send data to fragment.
You can't create a Fragment with startActivity. You need to create the fragment with bundle like this:
ProfileFragment fragment = new ProfileFragment();
Bundle args = new Bundle();
args.putString("name", users.name1);
args.putString("family", users.family1);
fragment.setArguments(args);
// then tell the FragmentManager to attach the fragment
// to the activity
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.your_placeholder, fragment);
ft.commit();
Then in your onCreateView get them with:
String name = getArguments().getString("name", "");
String family = getArguments().getString("family", "");
Please remember that you need to move the return code to the last of onCreateView method and change your code to something like this:
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_profile2, container, false);
TextView pn =view.findViewById(R.id.pn);
...
return view;
}
You can send data with the bundle, that is recommended
To Pass Data from Activity
fragment = new YourFragment();
if (fragment != null) {
FragmentManager fragmentManager = getFragmentManager();
Bundle bundle = new Bundle();
bundle.putString("key", "value");
fragment.setArguments(bundle);
fragmentManager.beginTransaction().replace(R.id.container, fragment).commit();
}
To receive data from Fragment
String var = getArguments().getString("value");

Passing data by using bundle between tablayout

I am using Bundle to passing data from my First TabFragment but it prompts out with the NullPointerException. Error is occur when getArguments() in list_fragments2 in second tab
MainActivity Fragment
list_fragment2 fragment = new list_fragment2();
Bundle b = new Bundle();
b.putString("test","text");
fragment.setArguments(b);
Toast.makeText(this, "" + b, Toast.LENGTH_SHORT).show();
SecondActivity Fragment
public class list_fragment2 extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View h = inflater.inflate(R.layout.tab2, container, false);
TextView textView = (TextView) h.findViewById(R.id.textView);
Bundle bundle=getArguments();
//your string
if(bundle != null) {
String test = bundle.getString("test");
textView.setText(test);
}
return h;
}
}
Do you actually load your second fragment?
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
list_fragment2 fragment = new list_fragment2();
Bundle b = new Bundle();
b.putString("test","text");
fragment.setArguments(b);
fragmentTransaction.replace(placeholder, fragment);
fragmentTransaction.commit();
I think you can create your instance of list_fragment2 code within list_fragment2. Maybe your codes recreated list_fragment2 many times.
public static list_fragment2 createInstance() {
list_fragment2 fragment = new list_fragment2();
Bundle bundle = new Bundle();
bundle .putString("test","text");
fragment.setArguments(bundle);
return fragment;
}

Communication between fragment in Navigation Drawer

I am trying to send data from Fragment A to Fragment B of NAVIGATION Drawer on Button click.I tried with bundle and intent but both of them are not working.
In Fragment A I have editText and button when I click the data is passed to another fragment.
In Fragment B there is textView where editText data is going to show but I am not getting a way to communicate between fragment in Navigation Drawer
When lauching Fragment from first fragment
Bundle bundle = new Bundle();
bundle.putString("key", YOUR_EDITVIEW_TEXT);
Fragment fragment = new SECONDFragment();
if (arguments != null) {
fragment.setArguments(arguments);
}
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction ft = fragmentManager.beginTransaction();
ft.replace(R.id.container, fragment);
ft.addToBackStack("");
ft.commit();
And in SecondFragment
private String mData;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mData = getArguments().getString("key");
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.YourLayout, container, false);
TextView text = (TextView) rootView.findViewById(R.id.yourTextView);
text.setText(mData);
return rootView;
}
Let your Activity to do the communication.
Take a public static variable in your MainActivity from where you're controlling the Fragment replaces of the navigation drawer. When you click the button in FragmentA store the value in the EditText to the public static variable of your MainActivity. Then when FragmentB is loaded check if the public static value is null or not. If not null place the value of that variable to your desired position.
This is not an elegant way for passing values between fragments, but in your case it'll work just fine.
If you're looking for how to pass values from one fragment to another, try something like this.
// To pass some value from FragmentA
FragmentB mFragmentB = new FragmentB();
Bundle args = new Bundle();
args.putString("VALUE", value);
mFragmentB.setArguments(args);
And from your FragmentB use the code to get the values passed.
Bundle args = getArguments();
int value = args.getString("VALUE");
1- create Application Class
public class MyApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
mInstance = this;
}
private static MyApplication mInstance;
public static synchronized MyApplication getInstance() {
return mInstance;
}
String mytext;
public String getMytext() {
return mytext;
}
public void setMytext(String mytext) {
this.mytext = mytext;
}
}
2- app name tag in manifast
<application
android:name=".MyApplication"
.......
3- from first Fragment
MyApplication.getInstance().setMytext("your text here");
4- from other Fragment
String text=MyApplication.getInstance().getMytext();
//Put the value
YourNewFragment ldf = new YourNewFragment ();
Bundle args = new Bundle();
args.putString("KEY", "VALUE");
ldf.setArguments(args);
//Inflate the fragment
getFragmentManager().beginTransaction().add(R.id.container, ldf).commit();
In onCreateView of the new Fragment:
//Retrieve the value
String value = getArguments().getString("KEY");

Categories

Resources