Using Otto Event Bus to Communicate b/w Activity and Fragment.
Otto Event Bus is an Android Library that helps developers to communicate between Android Activity and Fragment and vice-versa.
Lets see a simple implementation of this.
Here I will pass a simple string from Activity to Fragment and Vice-versa.
Gradle
dependencies { compile 'com.squareup:otto:1.3.8' }
Layout
Activity layout
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#cfcfcf"> <RelativeLayout android:id="@+id/activityLayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@android:color/white"> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Activity" android:textStyle="bold"/> <TextView android:id="@+id/message" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/title"/> <EditText android:id="@+id/activityData" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/message" android:hint="pass data"/> <Button android:id="@+id/sendMessageToFragment" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/activityData" android:layout_centerHorizontal="true" android:onClick="sendMessageToFragment" android:text="Send Message To Fragment"/> </RelativeLayout> <LinearLayout android:id="@+id/fragmentContainer" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentEnd="true" android:layout_alignParentRight="true" android:layout_below="@+id/activityLayout" android:orientation="vertical"> </LinearLayout> </RelativeLayout>
Fragment Layout
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@android:color/white"> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Fragment" android:textStyle="bold"/> <TextView android:id="@+id/message" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/title"/> <EditText android:id="@+id/editText" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/message" android:hint="Pass Data"/> <Button android:id="@+id/submit" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/editText" android:layout_centerHorizontal="true" android:text="Send message to Activity"/> </RelativeLayout>
Register and unregister for events
Event registration is done via the @Subcribe annotation on a public single parameter method. The method parameter is the event key, i.e., if such an data type is send via the Otto event bus the method is called.
Event receivers must register via the register method of the Bus class.
/* subscribe for string messages */ @Subscribe public void getMessage(String s) { } Example /* subscribe for DemoData messages */ @Subscribe public void getMessage(DemoData data) { Toast.makeText(getActivity(), data.getMessage(), Toast.LENGTH_LONG).show(); } // You could do this in onStart... OttoBus.getBus().register(this); // Also don't forget to unregister OttoBus.getBus().unregister(this);
How to send messages
OttoBus.getBus().post(new DemoData().getMessage());
Receive the last Event
Sometimes new components, like a dynamically created fragment, should receive event data during their creation. If this case component can register as producer for such event data with the @Produce annotation.
Event receivers must register via the register method of the Bus class.
@Produce public String produceEvent() { return "Just Started"; }
Implementation
Instantiate Otto Library
import com.squareup.otto.Bus; public class OttoBus { private static Bus sBus; public static Bus getBus() { if (sBus == null) sBus = new Bus(); return sBus; } }
Events Class
public class Events { public static class FragmentActivityMessage { private String message; public FragmentActivityMessage(String message) { this.message = message; } public String getMessage() { return message; } } public static class ActivityFragmentMessage { private String message; public ActivityFragmentMessage(String message) { this.message = message; } public String getMessage() { return message; } } }
Activity
package otto_library_android.coderzheaven.com.ottolibraryandroiddemo; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.EditText; import android.widget.TextView; import com.squareup.otto.Subscribe; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); addFragment(); } @Override protected void onStart() { super.onStart(); OttoBus.getBus().register(this); } private void addFragment() { getSupportFragmentManager().beginTransaction().add(R.id.fragmentContainer, new DemoFragment()).commit(); } public void sendMessageToFragment(View view) { EditText etMessage = findViewById(R.id.activityData); OttoBus.getBus().post(String.valueOf(etMessage.getText())); } @Subscribe public void getMessage(Events.ActivityFragmentMessage message) { TextView messageView = findViewById(R.id.message); messageView.setText(message.getMessage()); } @Override protected void onStop() { super.onStop(); OttoBus.getBus().unregister(this); } }
Fragment
package otto_library_android.coderzheaven.com.ottolibraryandroiddemo; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import com.squareup.otto.Subscribe; public class DemoFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.demo_fragment, container, false); } @Override public void onStart() { super.onStart(); OttoBus.getBus().register(this); } @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); setClickListener(view); } public void setClickListener(final View view) { Button btnSubmit = (Button) view.findViewById(R.id.submit); btnSubmit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { sendMessageToActivity(); } }); } private void sendMessageToActivity() { EditText etMessage = getView().findViewById(R.id.editText); OttoBus.getBus().post(etMessage.getText().toString()); } @Subscribe public void getMessage(Events.FragmentActivityMessage message) { TextView messageView = getView().findViewById(R.id.message); messageView.setText(message.getMessage()); } @Override public void onStop() { super.onStop(); OttoBus.getBus().unregister(this); } }
Source Code
You can download the source code from here.