I have a launcher Activity A which calls to an Activity B. B has multiple fragments. Now what I want is to be able to kill B from one of those fragments. I used getActivity().finish() but it would just kill the fragment.
How do I kill the activity/exit app from a fragment?
There is a way discussed in docs: http://developer.android.com/training/basics/fragments/communicating.html
Make Fragment define an interface which the Activity implements. Then make call to the Activity and then let the Activity to finish(or something else).
public class MyActivity extends Activity
implements MyFragment.MyListener {
public void onMyCancel() {
finish();
}
}
public class MyFragment extends Fragment {
private MyListener callback;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
callback= (MyListener) activity;
}
public interface MyListener {
public void onMyCancel();
}
public void btnCancel(View v) {
callback.onMyCancel();
}
}
you can only call finish() in your activity B , this would close your current activity.
if you want to close your app you can simply use:
System.exit(0);
this will kill whole application process.
Related
As the title says, I want to get the reference of currently visible activity or you can say activity which is at the top of backstack from a class, I don't want to send activity reference to that class, because I am using that class from many activities and if I do, I have to pass activity reference from every activity which is a long process.
I already have seen many answers which are typecasting context reference to activity but it is not working.
If anyone has the idea of how to do that in a short way, then please share.
I don't know what you mean by "long process".
Normally, if the Activity is delegating work to another class, it needs to pass itself as a reference so that the delegate knows how to call back the Activity to report progress, etc. This is standard Android stuff. AsyncTask works like this (as an example).
However, if all you want to do is display a Dialog, then you can, instead, start an Activity that looks like a Dialog. This is also a pretty common Android solution. There are themes that you can apply to an Activity that make it look just like a Dialog.
I have found a way via we can do this, In your application class add: registerActivityLifecycleCallbacks(this will listen to all activity lifecycle methods), like this:
public class MyApplication extends Application {
public static Activity currentActivity=null;
#Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
#Override
public void onActivityCreated(#NonNull Activity activity, #Nullable Bundle bundle) {
}
#Override
public void onActivityStarted(#NonNull Activity activity) {
currentActivity=activity;
}
#Override
public void onActivityResumed(#NonNull Activity activity) {
}
#Override
public void onActivityPaused(#NonNull Activity activity) {
}
#Override
public void onActivityStopped(#NonNull Activity activity) {
}
#Override
public void onActivitySaveInstanceState(#NonNull Activity activity, #NonNull Bundle bundle) {
}
#Override
public void onActivityDestroyed(#NonNull Activity activity) {
}
});
}
}
And then use it like:
if (MyApplication.currentActivity!=null){
// your code here
}
Don't forget to add your application class to manifest:
<application
android:name=".MyApplication"
.../>
I think this question may simple but I didn't find any solution for this,
I there any way in Android that if any one of an activity calls onPause() I need to show Toast message or any notification kind of thing need to show. Generally I want to get notified when activity calls onPause() but I need it in one place since I may have some 15 activity I don't want to add it in all the activity.
ex:If I have activity when any one of the activity calls onPause I need to get notified but that notification code should be in one place and we should not add any line of code onPause() Is it possible to do this.
Thanks.
Create a baseActivity, which has for example :
open class BaseActivity : AppCompatActivity() {
override fun onPause() {
super.onPause()
Toast.makeText(this, "notified", Toast.LENGTH_SHORT).show()
}
}
Then you can extends this in your activities and handle the on pause call in BaseActivity
If your minSdkVersion >= 14, you can use Application.ActivityLifecycleCallbacks: ActivityLifecycleCallbacks
You have to define a custom Application class and you can register for this callbacks afterwards:
public class MyApplication extends Application {
private class LifecycleCallbacks implements Application.ActivityLifecycleCallbacks {
#Override
public void onActivityCreated(final Activity activity, final Bundle savedInstanceState) {
//nothing to do
}
#Override
public void onActivityDestroyed(final Activity activity) {
//nothing to do
}
#Override
public void onActivityPaused(final Activity activity) {
// TODO Do your stuff, e.g. show toast.
}
#Override
public void onActivityResumed(final Activity activity) {
//nothing to do
}
#Override
public void onActivitySaveInstanceState(final Activity activity, final Bundle outState) {
//nothing to do
}
#Override
public void onActivityStarted(final Activity activity) {
}
#Override
public void onActivityStopped(final Activity activity) {
}
}
private final LifecycleCallbacks callbacks;
public void onCreate() {
super.onCreate();
callbacks = new LifecycleCallbacks();
application.registerActivityLifecycleCallbacks(callbacks);
}
}
Create a BaseActivity which contain all the methods you want to use in all other activities.
Then extend every activity with BaseActivity to call onPause() method.
Please please don't minus my question i confused when googling.
I used Android Tab Layout with Swipeable Views in my code for when user pressed setting button on an activity.
now I need send message from TopRatedFragment.java that extends from fragment to the activity that call the mainActivity of "Android Tab Layout with Swipeable Views".
You can do this by implementing a call back
create an interface first
public interface CommunicationInterface {
public void onSuccess();
public void onFailed();
}
then in your activity implement the interface
public class YourActivity extends ActionBarActivity implements CommunicationInterface {
//default functions
#Override
public void onSuccess() {
//stuff you want to do in the acivity
}
#Override
public void onFailed() {
//stuff you want to do in the acivity
}
}
Now in the fragment
public class yourfragment extends Fragment {
CommunicationInterface callback;
//stuffs that usually come in yor fragment and like OncreateView etc
#Override
public void onActivityCreated(#Nullable Bundle outState) {
super.onActivityCreated(outState);
//after all the stuff you want to do in your fragment then implement //call back function to communicate with the activity
callback= (CommunicationInterface) getActivity();
callback.onSuccess();//according to your purpose use where ever you like
callback.onFailed();//according to your purpose use where ever you like
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
callback= (CommunicationInterface) activity;
}
}
Take a close look on this reference:
Creating event callbacks to the activity
The android docs recommend using this pattern of having the parent activity implement an interface of the fragment (Basically calling methods on it)
class MyFragment extends Fragment {
interface Listener {
public void onSomeEvent();
}
private void somethingHappeninInTheFragment() {
// let the activity know
((Listener) getActivity()).onSomeEVent();
}
}
class MyActivity extends Activity implements MyFragment.Listener {
// etc
#Override
public void onSomeEvent() {
// handle the message from the fragment
}
}
Explained with a more concrete example here: http://developer.android.com/guide/components/fragments.html#EventCallbacks
Here's the solution:
Step 1 : From your fragment.
Intent i = new Intent(getActivity(), YourActivity.class);
i.putExtra("key", "Your value1");
i.putExtra("key2", "Your value2");
i.putExtra("key3", "Your value3");
getActivity().startActivity(i);
Step 2 : In your Activity where you want the result
Intent getResults = getIntent();
String firstValue = getResults.getStringExtra("key1");
String secondValue = getResults.getStringExtra("key2");
String thirdValue = getResults.getStringExtra("key3");
Use those values your needs are.
Hope this helps.. :)
For Fragment-Activity communication, this is the suggested way of doing it, by using a listener.
In my case I have two fragments and a button at each and I would like them to do the exact same thing when pressed.
Should I create a separate listener class that the Activity implements and then instantiate a listener in each fragment or there is a better design that I am not aware of?
EDIT
I am sorry, I probably didn't communicate that properly. I am not looking for communication between fragments. I have a Fragment A with a buttonA and a Fragment B with a buttonB. When I click on buttonA, there is a listener in my Activity and method doSomething() is called. Now I want buttonB calling doSomething() too. Should I A) create a second listener and have the activity implement that too, B) create one separate listener class and use this one for both or C) a better choice ??
For communication between fragment to frament or activity to fragment communication via events. There are few alternatives are there e.g. this otto eventbus I know. and the tutorial about this can be found Here or just google it.
As from the documentation :
Two Fragments should never communicate directly.
So you best follow the pattern explained in the article and communicate thru the activity on which the fragments are attached.
When a listener is called from fragment A then get the fragment B from the fragmentManger
YourFragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_b);
fragment.doSomething();
I'm using this pattern and it works well for me:
public class Fragment1 extends Fragment {
FragmentListener mCallback;
public interface FragmentListener {
public void onAction1();
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity instanceof FragmentListener) {
mCallback = (FragmentListener) activity;
}
}
public void onAction2() {
// do your stuff...
}
}
public class Fragment2 extends Fragment {
FragmentListener mCallback;
public interface FragmentListener {
public void onAction2();
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity instanceof FragmentListener) {
mCallback = (FragmentListener) activity;
}
}
public void onAction1() {
// do your stuff...
}
}
public class MainActivity implements Fragment1.FragmentListener, Fragment2.FragmentListener {
private Fragment1 fragment1;
private Fragment2 fragment2;
/**
* Listening to events from first fragment and forwarding to second fragment
*/
#Override
public void onAction1() {
fragment2.onAction1();
}
/**
* Listening to events from second fragment and forwarding to first fragment
*/
#Override
public void onAction2() {
fragment1.onAction2();
}
}
The Activity listens to "events" from the fragments and if needed forward it to the other fragment(s).
Is there a way to register for an activity's events? I'm specifically interested in the onStart / onStop events, and I don't want to add special operations in the activity for that.
One way to get events from the lifecycle of other activities is to register your class as an Application.ActivityLifecycleCallbacks with the main Application instance and filter events for the Activity you're interested in.
This is a short example (you may want to register the callbacks from another method/class other than MainActivity.onCreate or you'll miss that message ;) and you may have a dependency there that you don't want)
On the activity you want to spy:
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Register a spy for this activity
getApplication().registerActivityLifecycleCallbacks(new ActivitySpy(this));
}
}
Then the Spy code looks something like:
public class ActivitySpy implements ActivityLifecycleCallbacks {
private final Activity mActivity;
public ActivitySpy(Activity activity) {
mActivity = activity;
}
#Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
if (mActivity == activity)
Log.i("SPY", "Activity Created");
}
#Override
public void onActivityDestroyed(Activity activity) {
if (mActivity == activity)
Log.i("SPY", "Activity Destroyed");
}
// (...) Other overrides
}
You can also register the spy from another place if you have a reference to the Activity you want to follow.
I hope this helps :)
EDIT: I forgot to mention, this will only work on API Level 14 and above...