Basically I want to perform setText() feature of TextView class inside , BroadCaseReceiver . But I am not being able to implement this : I don't know
why ( context.findviewById() is not working ) , because findViewById() is part of Activity class and context.toString() is showing the reference of Activity( base activity ) class?
Link to below answer is here: Communicating with Other 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.
Here is an example of Fragment to Activity communication:
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");
}
}
...
}
Now the fragment can deliver messages to the activity by calling the onArticleSelected() method (or other methods in the interface) using the mCallback instance of the OnHeadlineSelectedListener interface.
For example, the following method in the fragment is called when the user clicks on a list item. The fragment uses the callback interface to deliver the event to the parent activity.
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
// Send the event to the host activity
mCallback.onArticleSelected(position);
}
Implement the Interface
In order to receive event callbacks from the fragment, the activity that hosts it must implement the interface defined in the fragment class.
For example, the following activity implements the interface from the above example.
public static class MainActivity extends Activity
implements HeadlinesFragment.OnHeadlineSelectedListener{
...
public void onArticleSelected(int position) {
// The user selected the headline of an article from the HeadlinesFragment
// Do something here to display that article
}
}
Deliver a Message to a Fragment
The host activity can deliver messages to a fragment by capturing the Fragment instance with findFragmentById(), then directly call the fragment's public methods.
For instance, imagine that the activity shown above may contain another fragment that's used to display the item specified by the data returned in the above callback method. In this case, the activity can pass the information received in the callback method to the other fragment that will display the item:
public static class MainActivity extends Activity
implements HeadlinesFragment.OnHeadlineSelectedListener{
...
public void onArticleSelected(int position) {
// The user selected the headline of an article from the HeadlinesFragment
// Do something here to display that article
ArticleFragment articleFrag = (ArticleFragment)
getSupportFragmentManager().findFragmentById(R.id.article_fragment);
if (articleFrag != null) {
// If article frag is available, we're in two-pane layout...
// Call a method in the ArticleFragment to update its content
articleFrag.updateArticleView(position);
} else {
// Otherwise, we're in the one-pane layout and must swap frags...
// Create fragment and give it an argument for the selected article
ArticleFragment newFragment = new ArticleFragment();
Bundle args = new Bundle();
args.putInt(ArticleFragment.ARG_POSITION, position);
newFragment.setArguments(args);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack so the user can navigate back
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
}
}
}
Unless if the BroadcastReceiver is started programmatically inside the context of an Activity e.g. Activity.onCreate(). For an ordinary BroadcastReceiver, it is very odd to access a UI element like TextView from it. You can only work with UI stuff from an Activity. Maybe you should reviewing the solution of which you're trying to apply. Even if you manage to do such a thing, it will have a wrong design.
public class MyReceiver extends BroadcastReceiver {
private MyActivity myActivity;
public MyReceiver(MyActivity myActivity) {
this.myActivity= myActivity;
}
#Override
public void onReceive(Context context, Intent intent) {
Log.d("", "Onrecieve ready to call");
if(this.myActivity!=null)
{
this.myActivity.update();
}
// make update method is in your activity.
// call function of your activity and change UI.
}
}
Related
May someone please elaborate this!
if we have implemented ViewModel to communicate between two fragments then can those fragments by-pass the corresponding activity and communicate directly to the ViewModel? if yes then is it a good practice or not (why and why not)?
You can use interface like this article https://developer.android.com/training/basics/fragments/communicating
Define an Interface
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.
Here is an example of Fragment to Activity communication:
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");
}
}
...
}
Now the fragment can deliver messages to the activity by calling the onArticleSelected() method (or other methods in the interface) using the mCallback instance of the OnHeadlineSelectedListener interface.
For example, the following method in the fragment is called when the user clicks on a list item. The fragment uses the callback interface to deliver the event to the parent activity.
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
// Send the event to the host activity
mCallback.onArticleSelected(position);
}
Implement the Interface
In order to receive event callbacks from the fragment, the activity that hosts it must implement the interface defined in the fragment class.
For example, the following activity implements the interface from the above example.
public static class MainActivity extends Activity
implements HeadlinesFragment.OnHeadlineSelectedListener{
...
public void onArticleSelected(int position) {
// The user selected the headline of an article from the HeadlinesFragment
// Do something here to display that article
}
}
Deliver a Message to a Fragment
The host activity can deliver messages to a fragment by capturing the Fragment instance with findFragmentById(), then directly call the fragment's public methods.
For instance, imagine that the activity shown above may contain another fragment that's used to display the item specified by the data returned in the above callback method. In this case, the activity can pass the information received in the callback method to the other fragment that will display the item:
public static class MainActivity extends Activity
implements HeadlinesFragment.OnHeadlineSelectedListener{
...
public void onArticleSelected(int position) {
// The user selected the headline of an article from the HeadlinesFragment
// Do something here to display that article
ArticleFragment articleFrag = (ArticleFragment)
getSupportFragmentManager().findFragmentById(R.id.article_fragment);
if (articleFrag != null) {
// If article frag is available, we're in two-pane layout...
// Call a method in the ArticleFragment to update its content
articleFrag.updateArticleView(position);
} else {
// Otherwise, we're in the one-pane layout and must swap frags...
// Create fragment and give it an argument for the selected article
ArticleFragment newFragment = new ArticleFragment();
Bundle args = new Bundle();
args.putInt(ArticleFragment.ARG_POSITION, position);
newFragment.setArguments(args);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack so the user can navigate back
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
}
}
}
I want to call the function Ask() of MainActivity from fragment2.
How can I call a function of MainActivity from fragment2?
I want to import results into a page called from fragment2.
Edit:
I already see that discussion, but don't have the solution of my problem.
Make that function static, after that you can access that function in Fragment e.g. MainActivity.Ask();
From fragment to activty:
((YourActivityClassName)getActivity()).yourPublicMethod();
From activity to fragment:
FragmentManager fm = getSupportFragmentManager();
//if you added fragment via layout xml
YourFragmentClass fragment = (YourFragmentClass)fm.findFragmentById(R.id.your_fragment_id);
fragment.yourPublicMethod();
If you added fragment via code and used a tag string when you added your fragment, use findFragmentByTag instead:
YourFragmentClass fragment = (YourFragmentClass)fm.findFragmentByTag("yourTag");
Cheers!
I would recommend you read this documentation.
call to function Ask() of MainActivity from fragment2.
For this you need a create a interface in your fragment2. The below code is an example from the document. You shouldn't ignore the onAttach method in your fragment as well.
public class Fragment2 extends ListFragment {
OnCallActivityListener mCallback;
// Container Activity must implement this interface
public interface OnCallActivityListener {
public void callAskMethod();
}
#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 = (OnCallActivityListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnHeadlineSelectedListener");
}
}
...
}
Now the fragment can deliver messages to the activity by calling the callAskMethod() method (or other methods in the interface) using the mCallback instance of the OnCallActivityListener interface.
For example, the following method in the fragment is called when the user clicks on a list item. The fragment uses the callback interface to deliver the event to the parent activity.
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
// Send the event to the host activity
mCallback.callAskMethod();
}
After that you should implement the interface in your host activity.
public static class MainActivity extends Activity
implements Fragment2.OnCallActivityListener{
...
public void callAskMethod() {
// Do something here
ask();
}
}
So that is it. You have called ask() method from fragment2 fragment.
I want to import results into a page called from fragment2.
The host activity can deliver messages to a fragment by capturing the Fragment instance with findFragmentById(), then directly call the fragment's public methods.
In your `MainActivity you can call send the result to the fragment.
Fragment2 fragment2 = (Fragment2) getSupportFragmentManager().findFragmentById(R.id.article_fragment);
So you have a instance value of the Fragment2 in MainActivity. So you can any public method of the fragment2 from there.
for example
fragment2.doSomething();
That's it.
I call my DialogFragment like so:
If I am in an Activity:
MyDialogFragment dialogfragment = new MyDialogFragment();
dialogfragment.show(getFragmentManager(), "");
If I am already in a Fragment:
MyDialogFragment dialogfragment = new MyDialogFragment();
dialogfragment.show(getActivity().getFragmentManager(), "");
In MyDialogFragment, which inflates an XML and allows the user to input some values to EditTexts and so forth, I want to be able to return those values back to wherever I called the dialog from.
For the sake of the question let's say my dialog class wants to return some private variables String mName and int mValue.
Is there a proper way to do this without knowing where the dialog is being called from (either an Activity or a Fragment)? How do I pass the values back / how do I receive them?
If you want to send data to activity from fragment. You can do that by calling public method of activity by:
((MainActivity)getActivity()).sendData(Object object);
You can't do the same for sending data to a fragment.
As doc says:
All Fragment-to-Fragment communication is done through the associated Activity. Two Fragments should never communicate directly.
What you should do is:
Define an Interface in the fragment.
Implement that Interface in the activity
Deliver data to the activity
then activity will deliver data to some other fragment.
BTW, you can also use this practice to send data to activity (upto point 3).
Reference and example
Defining an interface:
public interface DataListener {
public void onDataReceived(Object obj);
}
inside the fragment:
public class MyFragment extends Fragment {
DataListener callback;
#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 {
callback = (DataListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement DataListener");
}
}
}
Sending data from fragment;
callback.onDataReceived(object); // some object data
Receiving data in activity:
public static class MainActivity extends AppCompatActivity
implements DataListener{
public void onDataReceived(Object object) {
// Do something here with object data
}
}
Now if you want, you can send this data to any other fragment.
Sending data from activity to some other fragment:
AnotherFragment anotherFrag = (AnotherFragment)
getSupportFragmentManager().findFragmentById(R.id.fragment_container);
if (anotherFrag != null) {
anotherFrag.receiveDataInFrag(object);
}else{
// create a new instance of the fragment and pass data to it.
}
Create a callback interface and have pass it into your dialogfragment
interface DialogValuesCallback {
void callThisFunctionWhenUserClicksOnOkInDialog(String passinmName,int passinmValue);
}
You can have your Activity or Fragment implement this interface.
Have a constructor in your MyDialogFragment which accepts the interface and assigns it to an member variable.
MyDialogFragment(DialogValuesCallback activityOrFragmentWhichImplementsThis){
mInterfaceCallbackObjectRef = activityOrFragmentWhichImplementsThis;
}
#Rohit Arya this is what you should know first that fragments needs to declare an interface that must be implemented by every activity that uses that fragment so you can pass data from the fragment to the activity(s)... and must cast the activity displaying the fragment currently into this interface like this in your onAttach method
//#param Listener is the declared interface in your fragment class
public class MyFragment extends Fragment {
Listener mInterface;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mInterface = (Listener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()`
+ " must implement DataListener");
}
}
public interface Listener{
//#param type = data type, cont = variable
public void sendData(type cont, type2 cont2)
;
}
}
make sure the interface declared in your fragment get implemented in your baseActivity then what ever data you pass to the interface using
mInterface.sendData(value, value1);
you can get it in the base activity like
public class baseActivity extends Activity implements MyFragment.Listener{
//#param cont & cont2 are data sent from MyFragment
#Override
public void sendData(type cont, type cont2){
//do what ever with your values here
}
}
got it now?
I have an activity which calls another fragmentA .Now this fragmentA calls another fragmentB .Now I want to transfer data from fragmentB to my activity
check this: Communicating with Other Fragments
Define an Interface (In fragment)
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.
Here is an example of Fragment to Activity communication:
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");
}
}
...
}
Now the fragment can deliver messages to the activity by calling the onArticleSelected() method (or other methods in the interface) using the mCallback instance of the OnHeadlineSelectedListener interface.
For example, the following method in the fragment is called when the user clicks on a list item. The fragment uses the callback interface to deliver the event to the parent activity.
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
// Send the event to the host activity
mCallback.onArticleSelected(position);
}
Implement the Interface (in activity)
In order to receive event callbacks from the fragment, the activity that hosts it must implement the interface defined in the fragment class.
For example, the following activity implements the interface from the above example.
public static class MainActivity extends Activity
implements HeadlinesFragment.OnHeadlineSelectedListener{
...
public void onArticleSelected(int position) {
// The user selected the headline of an article from the HeadlinesFragment
// Do something here to display that article
}
}
PS1: EventBus works for you, but use it carefully if you need, it may make your code harder to read.
PS2: Don't pass an activity instance in Fragment.newInstance() and communicate using it. The activity instance may be destroyed in background. Get activity instance in Fragment.onAttach() like the example, the framework will handle the destroy & recreate & rebind for you.
You can get the Activity instance by overriding onAttach() method
Method: 1
#Override
public void onAttach(Activity activity) {
// TODO Auto-generated method stub
super.onAttach(activity);
this.activity=(ActivityName) activity;
}
and
activity.setdata(yourdata);
or
Method : 2
((ActivityName)getActivity()).setdata(yourdata);
In these ways you need to create a setter method in your activity
It is easiest way to get callback from any fragment to its parent activity .Very well explained by Dev Doc here
You can get the instance of the activity by calling getActivity() in fragmentB and pass the data using an interface.
You could use EventBus if you think that, you will need a similar functionality in different parts of the app and you don't want to write many interfaces for this porpoise.
You could use https://github.com/greenrobot/EventBus
Example:
Add compile 'de.greenrobot:eventbus:2.4.0',
Register on activities
OnCreate -
EventBus.getDefault().register(this);
and OnDestroy-
EventBus.getDefault().unregister(this);
Than add a method with a receiving object parameter and with onEventMainThread name:
public void onEventMainThread(YourObject name) {...}
Now from any Fragament you can call
EventBus.getDefault().post(yourObjectInstance);
And activity will detect it.
Or you could use RxJava to get similar effect -
http://nerds.weddingpartyapp.com/tech/2014/12/24/implementing-an-event-bus-with-rxjava-rxbus/
I have a Class1 extending ListFragment1.
I have a Class2 extending ListFragment2.
I'm currently passing an Intent like this inside OnItemClickListener.
Intent intent = new Intent(getActivity().getApplicationContext(), ListFragment2.class);
intent.putExtra("id", "1");
getActivity().startActivity(intent);
}
However, i get this exception:
java.lang.ClassCastException: com.abc.xyz.Class2 cannot be cast to android.app.Activity
Please help ! :(
First you should know:
You are calling startActivity(intent) and your Intent is pointing to a Fragment.
You cannot pass intents to your Fragment like that since Fragments are not App Components.
Communcation between Fragments should be between the Activity holding them.
Best Solution:
Pass your data from Class1 to your Activity and then send it to Class2, this link provides you exactly this, no more or less code:
http://developer.android.com/training/basics/fragments/communicating.html
It's a must read when you want to communicate between fragments.
Intent must point towards a class extending android.app.Activity which is not a case with your code.
Instead of extending ListFragment2 externally, you can make an inner class extending ListFragment2 and pass the value.
Hope this helps.
Both the fragments must communicate with the activity for communication between each other.The activity acts as a sort of a mediater between the fragement.The flow will look like this:
Fragment1 passes the intent to Activity1 with certain parameters which helps Activity1 to identify that it needs to pass this intent to Fragment2.
Activity1 on receiving the intent, passes this intent to Fragment 2.
How the fragment communicates with activity can be designed in following way mentioned here
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.
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");
}
}
...
}
Now the fragment can deliver messages to the activity by calling the onArticleSelected() method (or other methods in the interface) using the mCallback instance of the OnHeadlineSelectedListener interface.
For example, the following method in the fragment is called when the user clicks on a list item. The fragment uses the callback interface to deliver the event to the parent activity.
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
// Send the event to the host activity
mCallback.onArticleSelected(position);
}
Implement the Interface
In order to receive event callbacks from the fragment, the activity that hosts it must implement the interface defined in the fragment class.
For example, the following activity implements the interface from the above example.
public static class MainActivity extends Activity
implements HeadlinesFragment.OnHeadlineSelectedListener{
...
public void onArticleSelected(int position) {
// The user selected the headline of an article from the HeadlinesFragment
// Do something here to display that article
}
}
Deliver a Message to a Fragment
The host activity can deliver messages to a fragment by capturing the Fragment instance with findFragmentById(), then directly call the fragment's public methods.
For instance, imagine that the activity shown above may contain another fragment that's used to display the item specified by the data returned in the above callback method. In this case, the activity can pass the information received in the callback method to the other fragment that will display the item:
public static class MainActivity extends Activity
implements HeadlinesFragment.OnHeadlineSelectedListener{
...
public void onArticleSelected(int position) {
// The user selected the headline of an article from the HeadlinesFragment
// Do something here to display that article
ArticleFragment articleFrag = (ArticleFragment)
getSupportFragmentManager().findFragmentById(R.id.article_fragment);
if (articleFrag != null) {
// If article frag is available, we're in two-pane layout...
// Call a method in the ArticleFragment to update its content
articleFrag.updateArticleView(position);
} else {
// Otherwise, we're in the one-pane layout and must swap frags...
// Create fragment and give it an argument for the selected article
ArticleFragment newFragment = new ArticleFragment();
Bundle args = new Bundle();
args.putInt(ArticleFragment.ARG_POSITION, position);
newFragment.setArguments(args);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack so the user can navigate back
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
}
}
}
This is one of the way to achieve it, i use constructor to pass the data
FragmentOne.java
int myData=12;
FragmentManager manager = getActivity().getSupportFragmentManager();
Fragment frgObj=FragmentTwo.newInstance(myData);
FragmentTransaction ft = manager.beginTransaction();
ft.replace(R.id.container, frgObj,"FragmentTwo");
ft.addToBackStack(null);
ft.commit();
FragmentTwo.java
int myData;
public static FragmentTwo newInstance(int _myData){
FragmentTwo fragment = new FragmentTwo();
myData=_myData
return fragment;
}
ALSO REFER -- this -- StackOVERFLOW POST