call method from fragment to Activity - android

hello i have activity and i call many fragment based on my application business i need to call method from fragment in activity i searched in the internet but i cannot find the solution
this is my fragment :
public class HomeFragment extends Fragment implements View.OnClickListener {
public HomeFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
Log.d("onCreate", "onCreateViewHF");
view = inflater.inflate(R.layout.new_fragment_home, container, false);
}
/// this method i need to call in Activity
public void addUserLineInfoFragment() {
userLineInfoFragment = new UserLineInfoFragment();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.replace(R.id.user_info_fragment_container, userLineInfoFragment).commit();
Log.d("HOMMETEST","HOMMMME");
}

Call method of Activity from fragment
((YourActivityName)getActivity()).addUserLineInfoFragment();
Call method of fragment from Activity
1. Create Interface
public interface OnButtonListener
{
void onButtonClick();
}
2. Init in Activity
protected OnButtonListener onActionButtonListener;
public void setOnButtonListener(OnButtonListener actionButtonListener)
{
this.onActionButtonListener = actionButtonListener;
}
3. In Activity, click event when this action need to perform
this.onActionButtonListener.onButtonClick();
4. Implement listener(OnButtonListener) in Fragment
#Override
public void onButtonClick(){}
5. In fragment onCreateView
((YourActivityName) getActivity()).setOnButtonListener(this);

Just call the method of Fragment by creating the object of it.
HomeFragment homeFragment = new HomeFragment();
homeFragment.addUserLineInfoFragment();

You can Broadcast Intent from the Fragment to activity after you get the bundle
#Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
Intent intent = new Intent("key_to_identify_the_broadcast");
Bundle bundle = new Bundle();
bundle.putString("edttext", json.toString());
intent.putExtra("bundle_key_for_intent", bundle);
context.sendBroadcast(intent);
}
and then you can receive the bundle in your Activity by using the BroadcastReceiver class
private final BroadcastReceiver mHandleMessageReceiver = new
BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle =
intent.getExtras().getBundle("bundle_key_for_intent");
if(bundle!=null){
String edttext = bundle.getString("edttext");
}
//you can call any of your methods for using this bundle for your use case
}
};
in onCreate() of your Activity you need to register the broadcast receiver first otherwise this broadcast receiver will not be triggered
IntentFilter filter = new IntentFilter("key_to_identify_the_broadcast");
getActivity().getApplicationContext().
registerReceiver(mHandleMessageReceiver, filter);
Finally you can unregister the receiver to avoid any exceptions
#Override
public void onDestroy() {
try {
getActivity().getApplicationContext().
unregisterReceiver(mHandleMessageReceiver);
} catch (Exception e) {
Log.e("UnRegister Error", "> " + e.getMessage());
}
super.onDestroy();
}
You can create separate broadcast receivers in all of your fragments and use the same broadcast to broadcast the data to your Activity. You can also use different keys for different fragments and then broadcast using particular key for particular fragment.

Your solution is pretty simple, find the fragment instance assuming you have already added it, and call your method as follow:
HomeFragment homeFragment = (HomeFragment)getSupportFragmentManager().findFragmentByTag("myFragmentTag");
if(homeFragment != null) //check for null
homeFragment.addUserLineInfoFragment();

Related

How to Synchronize Data Between Viewpager Fragments

With the following code I can click a button to send a string from one fragment (Fragment A) into a MainActivity. How would I retrieve the string from the MainActivity and display it on a fragment B all in one go? I would like the fragments to act synchronized; to have Fragment B update itself as soon as I click the button in Fragment A. I can't seem to find anything in SO on this.
Interface:
public interface OnDataListener {
public void onDataReceived(String data);
}
Fragment A data listener:
OnDataListener mOnDataListener;
#Override
public void onAttach(Context context) {
try{
mOnDataListener = (OnDataListener) context;
Log.d(TAG, "onAttach was called" + context);
}catch (ClassCastException e){
Log.e(TAG, "onAttach: ClassCastException: " + e.getMessage() );
}
super.onAttach(context);
}
Button logic in Fragment A's onCreateView:
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String newTextString = editTextView.getText().toString();
mOnDataListener.onDataReceived(newTextString);
}
});
MainActivity data receiver
public class MainActivity extends AppCompatActivity implements OnDataListener {
#Override
public void onDataReceived(String data) {
Log.e(TAG, "MainActivity received this string " + data );
}
}
Solution 1: Using Callbacks
//this will work if your fragment instance is active so check viewpager offscreenpage limit
(You can also use solution 3 mentioned by Farid Haq, which do the same by doing work of activity itself)
Here, Activity implements callback OnDataUpdateListener
interface OnDataUpdateListener{
void passDataToFragmentB(String data)
}
Activity code:
Fragment instanceFragmentB;
// intialise it somewhere in your activity
// or get from viewpager adapter
#Override
void passDataToFragmentB(String data){
instanceFragmentB.onDataChange(data)
}
Fragment A code:
OnDataUpdateListener mOnDataUpdateListener;
onAttach(Activity activity){
mOnDataUpdateListener= (OnDataUpdateListener) activity
}
onViewCreated(){
somebutton.onClick{
mOnDataUpdateListener.passDataToFragmentB("someString")
}
}
Fragment B code:
onDataChange(String data){
//do your work with update data passed from fragment A
}
Solution 2: Using EventBus or RxBus
//this will work if your fragment instance is active so check viewpager offscreenpage limit
Using event or rxbus, post new updated value on bus and make destination fragment observing that same value type.
Fragment A:
onViewCreated(){
somebutton.onClick{
EventBus.post("your data")
}
}
Fragment B:
#Subsribe
void onDataChange(String data){
//do your work with update data passed from fragment A
}
Solution 3: Using ViewModel.
Take viewmodel with context of activity in all fragment and Wrap String with LiveData.
Whenever, string data is changed, just post new data on String Livedata object.
All fragment observing that livedata will get updated value.
Solution 1
In your MainActivity
#Override
public void onDataReceived(String data) {
Log.e(TAG, "MainActivity received this string " + data );
Bundle bundle = new Bundle();
bundle.putString("edttext", data);
FragmentB fragment = new FragmentB();
fragment.setArguments(bundle);
// Fragment Transaction method goes here
}
In your FragmentB Retrieve Data
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
String strtext = getArguments().getString("edttext");
return inflater.inflate(R.layout.fragment, container, false);
}
Solution 2
You can put callback data to your global variable and use it at fragment transaction at the time of onClickListerner.
Solution 3
A) Create method in your FragmentB
public void changeText (String data) {
textview.setText(data)
}
B) And Pass Value From MainActivity
#Override
public void onDataReceived (String data) {
myInterface.CallBack("Callbacked when onCreate method Created" + data);
Log.d("Tiggered", "respond: ");
FragmentManager manager = getFragmentManager();
FragmentB fragmentB = (FragmentB) manager.findFragmentById(R.id.id_fragmentB);
fragmentB.changeText(data);
}

Sending data to the container activity

I have this issue of sending some data back and forth between a fragment and its container activity, I succeeded in doing it. What puzzles me is sending my data from the fragment to the activity, at first I implemented OnResume(), OnStop() and sent the data through an intent and that created an infinite loop so I removed them. Then I did setRetainInstance(true) and it worked and gave me the wanted behavior.
My Question is How my data are really being sent and where in the fragment lifecycle ?
The Right approach is to use Interfaces. Don't use onStop or setRetainInstance()
See this. It will solve you problem.
Pass data from fragment to actvity
You can also achieve this by using Interface, using an EventBus like LocalBroadcastManager, or starting a new Activity with an Intent and some form of flag passed into its extras Bundle or something else.
Here is an example about using Interface:
1. Add function sendDataToActivity() into the interface (EventListener).
//EventListener.java
public interface EventListener {
public void sendDataToActivity(String data);
}
2. Implement this functions in your MainActivity.
// MainActivity.java
public class MainActivity extends AppCompatActivity implements EventListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public void sendDataToActivity(String data) {
Log.i("MainActivity", "sendDataToActivity: " + data);
}
}
3. Create the listener in MyFragment and attach it to the Activity.
4. Finally, call function using listener.sendDataToActivity("Hello World!").
// MyFragment.java
public class MyFragment extends Fragment {
private EventListener listener;
#Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
if(activity instanceof EventListener) {
listener = (EventListener)activity;
} else {
// Throw an error!
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_my, container, false);
// Send data
listener.sendDataToActivity("Hello World!");
return view;
}
#Override
public void onDetach() {
super.onDetach();
listener = null;
}
}
Hope this will help~

System services not available to Activities before onCreate(), but no properties instantiated

I am trying to create a service which checks if the device has an active internet connection and reports it. I have absolutely no clue what's wrong with my code.
I know this question has been asked many times, but most answers, like this, state
that one cannot create an activity using the new keyword (see this post);
that properties which are instantiated also are the cause of the problem (see this post).
Now as far as I know, I avoided forementioned causes. This is my simplified code:
MyActivity
public MyActivity extends SuperActivity {
// No properties are instantiated
// No onCreate(Bundle) method
}
SuperActivity
public SuperActivity extends Activity {
ApplicationManager appMgr;
UIManager uiMgr;
// No properties are instantiated, only declared
#Override
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
this.appMgr = new ApplicationManager(this);
this.appMgr.getUIManager().init();
}
}
ApplicationManager
public ApplicationManager {
// No properties are instantiated
SuperActivity activity;
Thread serviceThread;
UIManager uiMgr;
ApplicationManager(SuperActivity activity) {
this.activity = activity;
this.uiMgr = new UIManager(this);
}
void initService() {
this.serviceThread = new Thread(new Runnable() {
#Override
public void run() {
Intent intent = new Intent(getActivity(), ConnectionService.class);
intent.putExtra("CONTEXT", getActivity());
intent.putExtra("ALLOW_MOBILE_CONNECTION", true);
getActivity().startService(intent);
}
});
}
void startService() {
this.serviceThread.start();
}
UIManager getUIManager() {
return this.uiMgr;
}
SuperActivity getActivity() {
return this.activity;
}
}
UIManager
public class UIManager {
// No properties are instantiated
void init() {
getApplicationManager().initService();
getApplicationManager().startService(); // <-- FIRST MARKER,
// see below
}
}
ConnectionService
public class ConnectionService {
#Override
protected Bundle onHandleIntent(Intent intent) {
Bundle params = intent.getExtras();
Bundle bundle = new Bundle();
Context cntxt = (Context) params.getSerializable("CONTEXT");
try {
boolean wifi =
NetworkUtils.hasWifiCon(cntxt); // <-- SECOND MARKER,
// see below
...
}
catch (SocketException exc) { ... }
return bundle;
}
}
The error occurs on the line denoted by SECOND MARKER, which gets the system connection service and checks for wifi. This is the service which is not allowed to be called before onCreate().
Furthermore, if I remove or comment the line denoted by FIRST MARKER, the error is gone, but also, of course, the service is not started.
What could be the problem?
You cannot pass around a Context by serializing it in a bundle.
In an IntentService which I assume your ConnectionService is, just use this for a valid Context.

Displaying data from an Intent in a fragment

I have an activity that receives intents and then should display contents of the intents in a nested fragment. My code is the same as the Implement Effective Navigation tutorial which is here with a few modifications detailed below
As in the example the fragments are nested in the main activity with
public static class DummySectionFragment extends Fragment {
....
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_section_dummy, container, false);
...
public void updateFragUI() {
if(rootView!=null){
((TextView) rootView.findViewById(R.id.example)).setText(mData.getSomething());
}
I am having difficulties getting an instance of a fragment so that I can update the UI after the MainActivity receives an intent. The code to receive the intent and update the fragment is
public class uiReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
mData = getIntent().getParcelableExtra(ExampleService.EXAMPLE_INTENT);
updateUI(mData);
}
}
public void updateUI() {
DummySectionFragment dummyFrag = (DummySectionFragment)
getSupportFragmentManager().findFragmentById(dummyFragId);
if(dummyFrag==null) {
Log.v(TAG,"Dummy frag is null");
} else {
if(dummyFrag.isVisible()) {
Log.v(TAG,"Dummy frag is visable ");
dummyFrag.updateFragUI();
} else {
Log.v(TAG,"Dummy frag is not visable");
}
}
}
I have tried a number of approaches playing with the variable dummyFragId but I always find dummyFrag is always null. So far I've tried:
Experimenting with tags and ids in the XML code for the fragment. i.e. dummFragId is written as R.id.dummy_fragment_id (or Tag) with a corresponding property in <FrameLayout ...
Getting the fragment tag from the fragment transaction, but this is not done explicitly in the effective navigation code i.e.
getting the fragment id using dummyFragId = dummySectionFragment.getId() i.e.
#Override
public Fragment getItem(int i) {
switch (i) {
case 0:
// The first section of the app is the most interesting -- it offers
// a launchpad into the other demonstrations in this example application.
return new LaunchpadSectionFragment();
case 1:
Fragment dummySectionFragment = new DummySectionFragment();
Bundle args = new Bundle();
args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, i + 1);
dummySectionFragment.setArguments(args);
return dummySectionFragment;
Registering a receiver in the fragment. (The receiver is an external class that I cannot update the UI from)
I am open minded to the solution, I just want to know the best way of displaying information from an intent in a fragment.
I think I've found a good solution by creating a register method in the fragment. There is no relevant code in the activity, it's all in the fragment. Hope this helps someone.
public static class DummySectionFragment extends Fragment {
public void updateFragUI() {
Log.v(TAG, "updateFragUI received");
((TextView) getView().findViewById(R.id.example_field))
.setText(Double.toString(mData.getSomething()));
}
private IntentFilter filter = new IntentFilter(
TransmittingService.STATE_UPDATE);
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
mData = intent
.getParcelableExtra(TransmittingService.STATE_VALUES);
updateFragUI();
}
};
#Override
public void onResume() {
super.onResume();
Log.v(TAG, "registering Receiver");
getActivity().registerReceiver(mReceiver, filter);
}
#Override
public void onPause() {
super.onPause();
Log.v(TAG, "unregistering receiver");
getActivity().unregisterReceiver(mReceiver);
}
...
}

How to pass data between fragments

Im trying to pass data between two fragmens in my program. Its just a simple string that is stored in the List. The List is made public in fragments A, and when the user clicks on a list item, I need it to show up in fragment B. The content provider only seems to support ID's, so that will not work. Any suggestions?
Why don't you use a Bundle. From your first fragment, here's how to set it up:
Fragment fragment = new Fragment();
Bundle bundle = new Bundle();
bundle.putInt(key, value);
fragment.setArguments(bundle);
Then in your second Fragment, retrieve the data using:
Bundle bundle = this.getArguments();
int myInt = bundle.getInt(key, defaultValue);
Bundle has put methods for lots of data types. Please see http://developer.android.com/reference/android/os/Bundle.html
If you use Roboguice you can use the EventManager in Roboguice to pass data around without using the Activity as an interface. This is quite clean IMO.
If you're not using Roboguice you can use Otto too as a event bus: http://square.github.com/otto/
Update 20150909: You can also use Green Robot Event Bus or even RxJava now too. Depends on your use case.
From the Fragment documentation:
Often you will want one Fragment to communicate with another, for example to change the content based on a user event. All Fragment-to-Fragment communication is done through the associated Activity. Two Fragments should never communicate directly.
So I suggest you have look on the basic fragment training docs in the documentation. They're pretty comprehensive with an example and a walk-through guide.
So lets say you have Activity AB that controls Frag A and Fragment B.
Inside Fragment A you need an interface that Activity AB can implement.
In the sample android code, they have:
private Callbacks mCallbacks = sDummyCallbacks;
/*A callback interface that all activities containing this fragment must implement. This mechanism allows activities to be notified of item selections.
*/
public interface Callbacks {
/*Callback for when an item has been selected. */
public void onItemSelected(String id);
}
/*A dummy implementation of the {#link Callbacks} interface that does nothing. Used only when this fragment is not attached to an activity. */
private static Callbacks sDummyCallbacks = new Callbacks() {
#Override
public void onItemSelected(String id) {
}
};
The Callback interface is put inside one of your Fragments (let’s say Fragment A). I think the purpose of this Callbacks interface is like a nested class inside Frag A which any Activity can implement. So if Fragment A was a TV, the CallBacks is the TV Remote (interface) that allows Fragment A to be used by Activity AB. I may be wrong about the detail because I'm a noob but I did get my program to work perfectly on all screen sizes and this is what I used.
So inside Fragment A, we have:
(I took this from Android’s Sample programs)
#Override
public void onListItemClick(ListView listView, View view, int position, long id) {
super.onListItemClick(listView, view, position, id);
// Notify the active callbacks interface (the activity, if the
// fragment is attached to one) that an item has been selected.
mCallbacks.onItemSelected(DummyContent.ITEMS.get(position).id);
//mCallbacks.onItemSelected( PUT YOUR SHIT HERE. int, String, etc.);
//mCallbacks.onItemSelected (Object);
}
And inside Activity AB we override the onItemSelected method:
public class AB extends FragmentActivity implements ItemListFragment.Callbacks {
//...
#Override
//public void onItemSelected (CATCH YOUR SHIT HERE) {
//public void onItemSelected (Object obj) {
public void onItemSelected(String id) {
//Pass Data to Fragment B. For example:
Bundle arguments = new Bundle();
arguments.putString(“FragmentB_package”, id);
FragmentB fragment = new FragmentB();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction().replace(R.id.item_detail_container, fragment).commit();
}
So inside Activity AB, you basically throwing everything into a Bundle and passing it to B. If u are not sure how to use a Bundle, look the class up.
I am basically going by the sample code that Android provided. The one with the DummyContent stuff. When you make a new Android Application Package, it's the one titled MasterDetailFlow.
1- The first way is define an interface
public interface OnMessage{
void sendMessage(int fragmentId, String message);
}
public interface OnReceive{
void onReceive(String message);
}
2- In you activity implement OnMessage interface
public class MyActivity implements OnMessage {
...
#Override
public void sendMessage(int fragmentId, String message){
Fragment fragment = getSupportFragmentManager().findFragmentById(fragmentId);
((OnReceive) fragment).sendMessage();
}
}
3- In your fragment implement OnReceive interface
public class MyFragment implements OnReceive{
...
#Override
public void onReceive(String message){
myTextView.setText("Received message:" + message);
}
}
This is the boilerplate version of handling message passing between fragments.
Another way of handing data passage between fragments are by using an event bus.
1- Register/unregister to an event bus
#Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
#Override
public void onStop() {
EventBus.getDefault().unregister(this);
super.onStop();
}
2- Define an event class
public class Message{
public final String message;
public Message(String message){
this.message = message;
}
}
3- Post this event in anywhere in your application
EventBus.getDefault().post(new Message("hello world"));
4- Subscribe to that event to receive it in your Fragment
#Subscribe(threadMode = ThreadMode.MAIN)
public void onMessage(Message event){
mytextview.setText(event.message);
}
For more details, use cases, and an example project about the event bus pattern.
IN my case i had to send the data backwards from FragmentB->FragmentA hence Intents was not an option as the fragment would already be initialised All though all of the above answers sounds good it takes a lot of boiler plate code to implement, so i went with a much simpler approach of using LocalBroadcastManager, it exactly does the above said but without alll the nasty boilerplate code. An example is shared below.
In Sending Fragment(Fragment B)
public class FragmentB {
private void sendMessage() {
Intent intent = new Intent("custom-event-name");
intent.putExtra("message", "your message");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
}
And in the Message to be Received Fragment(FRAGMENT A)
public class FragmentA {
#Override
public void onCreate(Bundle savedInstanceState) {
...
// Register receiver
LocalBroadcastManager.getInstance(this).registerReceiver(receiver,
new IntentFilter("custom-event-name"));
}
// This will be called whenever an Intent with an action named "custom-event-name" is broadcasted.
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String message = intent.getStringExtra("message");
}
};
}
Hope it helps someone
That depends on how the fragment is structured. If you can have some of the methods on the Fragment Class B static and also the target TextView object static, you can call the method directly on Fragment Class A. This is better than a listener as the method is performed instantaneously, and we don't need to have an additional task that performs listening throughout the activity. See example below:
Fragment_class_B.setmyText(String yourstring);
On Fragment B you can have the method defined as:
public static void setmyText(final String string) {
myTextView.setText(string);
}
Just don't forget to have myTextView set as static on Fragment B, and properly import the Fragment B class on Fragment A.
Just did the procedure on my project recently and it worked. Hope that helped.
you can read this doc .this concept is well explained here http://developer.android.com/training/basics/fragments/communicating.html
I'm working on a similar project and I guess my code may help in the above situation
Here is the overview of what i'm doing
My project Has two fragments Called "FragmentA" and "FragmentB"
-FragmentA Contains one list View,when you click an item in FragmentA It's INDEX is passed to FragmentB using Communicator interface
The design pattern is totally based on the concept of java interfaces that says
"interface reference variables can refer to a subclass object"
Let MainActivity implement the interface provided by fragmentA(otherwise we can't make interface reference variable to point to MainActivity)
In the below code communicator object is made to refer to MainActivity's object by using "setCommunicator(Communicatot c)" method present in fragmentA.
I'm triggering respond() method of interface from FrgamentA using the MainActivity's reference.
Interface communcator is defined inside fragmentA, this is to provide least access previlage to communicator interface.
below is my complete working code
FragmentA.java
public class FragmentA extends Fragment implements OnItemClickListener {
ListView list;
Communicator communicater;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
return inflater.inflate(R.layout.fragmenta, container,false);
}
public void setCommunicator(Communicator c){
communicater=c;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
communicater=(Communicator) getActivity();
list = (ListView) getActivity().findViewById(R.id.lvModularListView);
ArrayAdapter<?> adapter = ArrayAdapter.createFromResource(getActivity(),
R.array.items, android.R.layout.simple_list_item_1);
list.setAdapter(adapter);
list.setOnItemClickListener(this);
}
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int index, long arg3) {
communicater.respond(index);
}
public interface Communicator{
public void respond(int index);
}
}
fragmentB.java
public class FragmentA extends Fragment implements OnItemClickListener {
ListView list;
Communicator communicater;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
return inflater.inflate(R.layout.fragmenta, container,false);
}
public void setCommunicator(Communicator c){
communicater=c;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
communicater=(Communicator) getActivity();
list = (ListView) getActivity().findViewById(R.id.lvModularListView);
ArrayAdapter<?> adapter = ArrayAdapter.createFromResource(getActivity(),
R.array.items, android.R.layout.simple_list_item_1);
list.setAdapter(adapter);
list.setOnItemClickListener(this);
}
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int index, long arg3) {
communicater.respond(index);
}
public interface Communicator{
public void respond(int index);
}
}
MainActivity.java
public class MainActivity extends Activity implements FragmentA.Communicator {
FragmentManager manager=getFragmentManager();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentA fragA=(FragmentA) manager.findFragmentById(R.id.fragmenta);
fragA.setCommunicator(this);
}
#Override
public void respond(int i) {
// TODO Auto-generated method stub
FragmentB FragB=(FragmentB) manager.findFragmentById(R.id.fragmentb);
FragB.changetext(i);
}
}
Basically Implement the interface to communicate between Activity and fragment.
1) Main activty
public class MainActivity extends Activity implements SendFragment.StartCommunication
{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public void setComm(String msg) {
// TODO Auto-generated method stub
DisplayFragment mDisplayFragment = (DisplayFragment)getFragmentManager().findFragmentById(R.id.fragment2);
if(mDisplayFragment != null && mDisplayFragment.isInLayout())
{
mDisplayFragment.setText(msg);
}
else
{
Toast.makeText(this, "Error Sending Message", Toast.LENGTH_SHORT).show();
}
}
}
2) sender fragment (fragment-to-Activity)
public class SendFragment extends Fragment
{
StartCommunication mStartCommunicationListner;
String msg = "hi";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View mView = (View) inflater.inflate(R.layout.send_fragment, container);
final EditText mEditText = (EditText)mView.findViewById(R.id.editText1);
Button mButton = (Button) mView.findViewById(R.id.button1);
mButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
msg = mEditText.getText().toString();
sendMessage();
}
});
return mView;
}
interface StartCommunication
{
public void setComm(String msg);
}
#Override
public void onAttach(Activity activity) {
// TODO Auto-generated method stub
super.onAttach(activity);
if(activity instanceof StartCommunication)
{
mStartCommunicationListner = (StartCommunication)activity;
}
else
throw new ClassCastException();
}
public void sendMessage()
{
mStartCommunicationListner.setComm(msg);
}
}
3) receiver fragment (Activity-to-fragment)
public class DisplayFragment extends Fragment
{
View mView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
mView = (View) inflater.inflate(R.layout.display_frgmt_layout, container);
return mView;
}
void setText(String msg)
{
TextView mTextView = (TextView) mView.findViewById(R.id.textView1);
mTextView.setText(msg);
}
}
I used this link for the same solution, I hope somebody will find it usefull.
Very simple and basic example.
http://infobloggall.com/2014/06/22/communication-between-activity-and-fragments/
getParentFragmentManager().setFragmentResultListener is the 2020 way of doing this. Your only limitation is to use a bundle to pass the data. Check out the docs for more info and examples.
Some other ways
Call to getActivity() and cast it to the shared activity between your fragments, then use it as a bridge to pass the data. This solution is highly not recommended because of the cupelling it requires between the activity and the fragments, but it used to be the popular way of doing this back in the KitKat days...
Use callbacks. Any events mechanism will do. This would be a Java vanilla solution. The benefit over FragmentManager is that it's not limited to Bundles. The downside, however, is that you may run into edge cases bugs where you mess up the activity life cycle and get exceptions like IllegalStateException when the fragment manager is in the middle of saving state or the activity were destroyed. Also, it does not support cross-processing communication.
Fragment class A
public class CountryListFragment extends ListFragment{
/** List of countries to be displayed in the ListFragment */
ListFragmentItemClickListener ifaceItemClickListener;
/** An interface for defining the callback method */
public interface ListFragmentItemClickListener {
/** This method will be invoked when an item in the ListFragment is clicked */
void onListFragmentItemClick(int position);
}
/** A callback function, executed when this fragment is attached to an activity */
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try{
/** This statement ensures that the hosting activity implements ListFragmentItemClickListener */
ifaceItemClickListener = (ListFragmentItemClickListener) activity;
}catch(Exception e){
Toast.makeText(activity.getBaseContext(), "Exception",Toast.LENGTH_SHORT).show();
}
}
Fragment Class B
public class CountryDetailsFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
/** Inflating the layout country_details_fragment_layout to the view object v */
View v = inflater.inflate(R.layout.country_details_fragment_layout, null);
/** Getting the textview object of the layout to set the details */
TextView tv = (TextView) v.findViewById(R.id.country_details);
/** Getting the bundle object passed from MainActivity ( in Landscape mode ) or from
* CountryDetailsActivity ( in Portrait Mode )
* */
Bundle b = getArguments();
/** Getting the clicked item's position and setting corresponding details in the textview of the detailed fragment */
tv.setText("Details of " + Country.name[b.getInt("position")]);
return v;
}
}
Main Activity class for passing data between fragments
public class MainActivity extends Activity implements ListFragmentItemClickListener {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
/** This method will be executed when the user clicks on an item in the listview */
#Override
public void onListFragmentItemClick(int position) {
/** Getting the orientation ( Landscape or Portrait ) of the screen */
int orientation = getResources().getConfiguration().orientation;
/** Landscape Mode */
if(orientation == Configuration.ORIENTATION_LANDSCAPE ){
/** Getting the fragment manager for fragment related operations */
FragmentManager fragmentManager = getFragmentManager();
/** Getting the fragmenttransaction object, which can be used to add, remove or replace a fragment */
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
/** Getting the existing detailed fragment object, if it already exists.
* The fragment object is retrieved by its tag name *
*/
Fragment prevFrag = fragmentManager.findFragmentByTag("in.wptrafficanalyzer.country.details");
/** Remove the existing detailed fragment object if it exists */
if(prevFrag!=null)
fragmentTransaction.remove(prevFrag);
/** Instantiating the fragment CountryDetailsFragment */
CountryDetailsFragment fragment = new CountryDetailsFragment();
/** Creating a bundle object to pass the data(the clicked item's position) from the activity to the fragment */
Bundle b = new Bundle();
/** Setting the data to the bundle object */
b.putInt("position", position);
/** Setting the bundle object to the fragment */
fragment.setArguments(b);
/** Adding the fragment to the fragment transaction */
fragmentTransaction.add(R.id.detail_fragment_container, fragment,"in.wptrafficanalyzer.country.details");
/** Adding this transaction to backstack */
fragmentTransaction.addToBackStack(null);
/** Making this transaction in effect */
fragmentTransaction.commit();
}else{ /** Portrait Mode or Square mode */
/** Creating an intent object to start the CountryDetailsActivity */
Intent intent = new Intent("in.wptrafficanalyzer.CountryDetailsActivity");
/** Setting data ( the clicked item's position ) to this intent */
intent.putExtra("position", position);
/** Starting the activity by passing the implicit intent */
startActivity(intent);
}
}
}
Detailde acitivity class
public class CountryDetailsActivity extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/** Setting the layout for this activity */
setContentView(R.layout.country_details_activity_layout);
/** Getting the fragment manager for fragment related operations */
FragmentManager fragmentManager = getFragmentManager();
/** Getting the fragmenttransaction object, which can be used to add, remove or replace a fragment */
FragmentTransaction fragmentTransacton = fragmentManager.beginTransaction();
/** Instantiating the fragment CountryDetailsFragment */
CountryDetailsFragment detailsFragment = new CountryDetailsFragment();
/** Creating a bundle object to pass the data(the clicked item's position) from the activity to the fragment */
Bundle b = new Bundle();
/** Setting the data to the bundle object from the Intent*/
b.putInt("position", getIntent().getIntExtra("position", 0));
/** Setting the bundle object to the fragment */
detailsFragment.setArguments(b);
/** Adding the fragment to the fragment transaction */
fragmentTransacton.add(R.id.country_details_fragment_container, detailsFragment);
/** Making this transaction in effect */
fragmentTransacton.commit();
}
}
Array Of Contries
public class Country {
/** Array of countries used to display in CountryListFragment */
static String name[] = new String[] {
"India",
"Pakistan",
"Sri Lanka",
"China",
"Bangladesh",
"Nepal",
"Afghanistan",
"North Korea",
"South Korea",
"Japan",
"Bhutan"
};
}
For More Details visit this link [http://wptrafficanalyzer.in/blog/itemclick-handler-for-listfragment-in-android/]. There are full example ..
Basically here we are dealing with communication between Fragments. Communication between fragments can never be directly possible. It involves activity under the context of which both the fragments are created.
You need to create an interface in the sending fragment and implement the interface in the activity which will reprieve the message and transfer to the receiving fragment.

Categories

Resources