i have a created a fragment and can't find what is the use of Interface class in this Fragment...i google it but can't find the right documentation?
Thank you for your concern!
public class SongListFragment extends Fragment {
public SongListFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
songIds = getArguments().getIntArray(SONG_IDS);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
//what's the use?
public interface OnFragmentInteractionListener {
public void onSongSelected(int songId);
}
}
OnFragmentInteractionListener could be use to communicate between fragments
To allow a Fragment to communicate up to its Activity, you can define
an interface in the Fragment class and implement it within the
Activity. The Fragment captures the interface implementation during
its onAttach() lifecycle method and can then call the Interface
methods in order to communicate with the Activity.
Find another SO example here
An interface is a reference type in Java. It is similar to class. It is a collection of abstract methods. A class implements an interface, thereby inheriting the abstract methods of the interface.
Along with abstract methods, an interface may also contain constants, default methods, static methods, and nested types. Method bodies exist only for default methods and static methods.
Writing an interface is similar to writing a class. But a class describes the attributes and behaviors of an object. And an interface contains behaviors that a class implements.
Unless the class that implements the interface is abstract, all the methods of the interface need to be defined in the class.
You might have a brief idea over here Feel free to ask if any confusion rises! :)
So in your particular case your Activity must implement that interface OnFragmentInteractionListener otherwise the fragments which are attached in the Activity cannot communicate with each other. Your activity should look like
public class YourActivity extends Activity implements OnFragmentInteractionListener
Then in your Activity you implement the method onSongSelected(int songId)
You might get help from here. Hope this helps!
#Tahmid Rahman explains what an interface is in there answer.
In this specific case the interface should be implemented in the Activity that your fragment is attaching to. That will allow the fragment to call onSongSelected() on the activity. Then the activity can in turn properly handle the users requested action.
Without the interface, there would not be a well defined way for the fragment to tell its parent activity that the user had clicked on a song.
Interface is used to communicate between fragment and activity or between multiple fragments when an event occurs.
See the Documentation
in your case:
public static class MainActivity extends Activity
implements SongListFragment.OnFragmentInteractionListener{
...
public void onSongSelected(int songId) { //this method must be implemented
// The user selected the song from the list in SongListFragment
// Do something here to display that song..in your activity
}
}
you can implement the interface in your activity and write the onSongSelected method with the song id passed as parameter.
So basically it is used to pass selected song list information to other activity or fragment when a selection occurs
Related
I seem to be stuck with a problem with an object communicating with my activity class. The object is a view object with an onClick method that when called I would like it to notify my activity class so that it can perform said action. Below is some example code of my situation (assume all conventional setup operations have already been made):
public class MainActivity extends AppCompatActivity{
//...other global methods and objects
//Does not have access to instantiated Entry object(s)
public void entryObjectWasClicked(){
//perform said action
}
}
public class Entry extends View implements View.OnClickListener{
//...other global methods and objects
//Does not have access to the MainActivity object
#Override
public void onClick(View v){
//send a message to the MainActivity to
//somehow call the entryObjectWasClicked() method
}
}
The only way (off the top of my head) that I could think about dealing with this problem is by creating a static method in MainActivity and then calling it from an anonymous MainActivity object in the onClick method of Entry. The problem with the static method approach is that any subsequent method/object/primitive usages in the static method force those methods/objects/primitives to be static. This defeats the purpose of then being able to have two different instances of the MainActivity object.
After some looking I came across using Broadcast messages, specifically using the LocalBroadcastManager to send an intent to the activity. This code example works for my model, but I want to know: is this the best way for me to go about sending messages to my MainActivity from my Entry object?
If there is a more effective way of doing all this, what would it be?
You're overcomplicating things. Don't override onClick for this. Instead, have your activity call setOnClickHandler on your view, which sets a callback that's called when the view is clicked. Then use the default implementation.
Since you extend view, i guess you want to use it inside a layout. That means you may want to create a Listener for that. Example:
public class Entry extends View implements View.OnClickListener{
private OnClickListener listener;
public void setListener(OnClickListener listener) {
this.listener = listener;
}
#Override
public void onClick(){
if (this.listener != null) this.listener.onClick(this);
}
}
How you can inflate your layout in your Activity and access your custom view.
public class MainActivity extends AppCompatActivity{
public void onCreate( ...) {
Entry entry = findViewById(R.id.entry);
entry.setListener(new OnClickListener(...));
}
}
I don't actually have a question, just want to ask you to explain me this code
public class HeadlinesFragment extends ListFragment {
OnHeadlineSelectedListener mCallback;
// Container Activity must implement this interface
public interface OnHeadlineSelectedListener {
public void onArticleSelected(int position);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
mCallback = (OnHeadlineSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnHeadlineSelectedListener");
}
}
...
}
is this about a class object which implements interface's method ?
even if it is, please explain it
thanks
The code creates interface OnHeadlineSelectedListener and requires that any activity to which the fragment is attached must implement this interface. (OnHeadlineSelectedListener) activity tries to cast an activity to that interface, i.e. checks whether the activity implements it. If it does not, ClassCastException is thrown.
First, when you want to communicate between your activity and a fragment, for instance; if you have an application that lets users selected a headline and then open a details for it, you can use an interface as you show above.
Interface definition
An interface is a contract that whoever implements it must respect/adhere to. Just like any other contract in real life.
Now, in your Fragment, when you are ready to notify your activity of something - considering they implemented the interface for exactly this reason (to be notified), you ensure to cast the interface to your activity and throw a ClassCastException to let the class know that it must implement the interface.
Type
When you cast an interface to the activity, it implies that when an activity implements an interface, it becomes of that type (interface type).
Subscriber/Publisher Design Pattern
If you think about it, this sounds like the popular Subscriber/Publisher design pattern.
How?
The Fragment is the publisher in this case.
The activity is the subscriber here
So, in essence, in order to obey the rules of a contract, the activity MUST implement the interface that helps the two classes communicate!
I hope this helps.
By the way, this sounds and looks really similar to my demo application currently published on PlayStore.
At school we're now learning on how to make fragments more universal by using interfaces.
This technique is still kinda abstract and I don't really know when/how to use it.
Can anybody point me to some resources on how to use that technique (Could it be called interface callbacks?)
All help is very appreciated!
The callback approach, as you would call it, is as simple as Listener interface found in many parts of Java or Android. You may check the Observer pattern if you want to learn about a very general description. But if you already understand how to work with Listener, you will easily get the point about callbacks.
NOTE: Do not mix it with Callback term - these are not the same.
Suppose we have Activity MyActivity and Fragment MyFragment. We want to post some data from Fragment to Activity. Then let us create an interface within MyFragment:
public class MyFragment extends Fragment{
private PostDataCallback mCallback;//our Activity will implement this
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
mCallback = (PostDataCallback) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnHeadlineSelectedListener");
}
}
public interface PostDataCallback{
public void onPostData(Object data);
}
/*
we trigger this method when we calculated
data or something like that and want to post it*/
public void onSomeEvent(Object data){
mCallback.onPostData(data);
}
}
Our MyActivity will look like this:
public class MyActivity extends Activity implements MyFragment.PostDataCallback{
private Object data;
#Override
protected void onCreate(Bundle savedInstanceState){
getFragmentManager().beginTransaction().add(R.id.some_container_id, new MyFragment(), "my fragment");
}
#Override
public void onPostData(Object data){
this.data = data;
//some operations
}
}
So, MyFragment knows nothing about the implementation of it's callback. But it knows, that it can call the method onPostData(Object o) on the instance of PostDataCallback, which is held in the variable mCallback.
Thus, when MyFragment triggers it's mCallback.onPostData(data), MyActivity get's the result.
Exactly the same approach would work if we wanted to send message from MyActivity to MyFragment, but we would do it do it vice versa: the trigger method, callback interface definition and instance would reside in MyActivity, and MyFragment would implement the interface.
Here are steps:
Download sample data from http://developer.android.com/training/basics/fragments/index.html(given in right side) and also look at url to how to add fragments from xml or dynamically to performing fragment transaction operations..
Then would recommend you to go through with fragment guide..http://developer.android.com/guide/components/fragments.html
Once you understand complete life cycle and its fragment callback methods then would be easy to understand example given by Google as sample.
To defining interface in fragment to calling interface or passing callback to activity..
Let’s say you have two fragments which shows list as article titles and article details.
In your article list extends fragment list public class Fragment1 extends ListFragment
Set your list view using list adapter in oncreateview method.
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, Array);
setListAdapter(adapter);
Now we need to display article details when user click on article, so we need to pass position to activity to it can call back corresponding article details to show in fragment2.
So when user click on article, system call onListItemClick callback method.
public void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Call interface here and pass article position
Define interface and pass position in method which activity will override.
public interface OnArticleSelectedListener {
public void onArticleSelected(int position);
}
In on attach method instantiates an instance of interface by casting the Activity, If the activity has not implemented the interface, then the fragment throws a ClassCastException. On success.
Override interface method to display article details by passing position as bundle data to Fragment2.
Hope it will help you to understand sample code.
You can simple create new Android Application project in eclipse.
Then create Android Object (Fragment) with callback methods. This will give you an idea for interfaces.
And then the same you can apply for activity to fragment.
The use of this tutorial is very clear to me however I am using the Actionbar.tablistner interface. How can I pass variables(strings) from fragment to fragment using this interface?
public class MainActivity extends FragmentActivity implements ActionBar.TabListener
{
}
Create an interface with a method which accepts any variable (e.g. String). Something like this:
public interface TabClickedListener {
public void passParam(String var);
}
Implement this interface in your Activity. From the Actionbar.tablistener onTabSelected() method call the above interface method (on the activity instance you have) passing whatever value you would like. Once you receive this value in your Activity you can pass this to a different Fragment.
I have multiple fragments in one activity that should be able to pass data inbetween them. I have used tutorials to implement callbacks. My MainActivity is the outer class in which my fragment classes are. Furthermore I have a FragmentPagerAdapter that handles the fragment transitions.
Well the thing is, Eclipse wont let me implement my callback interface, that is included in one of the Fragments, for my MainActivity outer class.
This is the structure of my code:
public class MainActivity extends FragmentActivity **implements ConnectionFragment.dataCallback**{
//compiler error here:"ConnectionFragment cannot be resolved to a type"
//when i leave this out i get runtime error: "MainActivity java must
//implement dataCallback"
...
public class SectionsPagerAdapter extends FragmentPagerAdapter implements ConnectionFragment.dataCallback{
#Override
public void updateLog(View v, String line) {
DataFragment dataFrag = (DataFragment)getSupportFragmentManager().findFragmentByTag(DataFragment.class.getName());
if (dataFrag != null){
dataFrag.updateLog(v,line);
}
}
...
}
public static class ConnectionFragment extends Fragment {
...
public interface dataCallback{
public void updateLog(View v, String line);
}
dataCallback mCallback;
private static dataCallback dummyCallback=new dataCallback(){
#Override
public void updateLog(View v, String line){
}
};
#Override
public void onAttach(Activity activity){
super.onAttach(activity);
try {
mCallback = (dataCallback)activity;
} catch (ClassCastException e){
throw new ClassCastException(activity.toString() + " must implement dataCallback");
}
}
}
public static class DataFragment extends Fragment implements ConnectionFragment.dataCallback{
public void updateLog(View v,String line){
TextView logTextView=(TextView)v.findViewById(R.id.log_view);
logTextView.append("\n"+line);
}
...
}
public static class GraphFragment extends Fragment {
...
}
}
ConnectionFragment should be able to send data to DataFragment.
I appreciate your help!
You can't implement an inner-interface or extend an inner-class. Simply move ConnectionFragment to its own file.
This is because at compile time, these inner classes are dependent on the parent class - and NEVER the other way around. As proof, if you look at the compiled .class files, these inner-Objects are compiled as MainActivity$ConnectionFragment.class or something there-abouts. If, however, ConnectionFragment is compiled into its own file (ConnectionFragment.cass), then MainActivity.class can depend on it, and Eclipse will automatically handle the build-order.
Fragments should never directly interact with each other since this creates undesired coupling.
Your fragment should call the interface method implemented by the Activity to communicate with the Activity, then the Activity can communicate/relay that interaction with the other fragment.
It's seem that you can't use an interface before you declare it.