Is there a better way to implement a GestureDetetor to all activities instead of having to define a GestureDetector individually?
In my scenario I have 10 activities for which I would like all of them to have the same behavior for Gestures. For example a swipe to the right will end the current activity and take the user back to the main activity.
My options seem to be
Define the GestureDetector in each of my 10 activities
or
Extend Activity and add a GestureDetector there and then extend from my custom activity.
Is there a better way to implement this behavior?
One easy way to do it is setting the GestureDetector in a base class that all activities extend from. This is a typical approach but it creates a new instance each time.
Another way to do it, depending on your target api, is using Application.registerActivityLifecycleCallbacks. You can find more information in the Application class documentation. This is api 14+.
Don't forget to read the docs:
public void registerActivityLifecycleCallbacks (Application.ActivityLifecycleCallbacks callback)
Add a new ComponentCallbacks to the base application of the Context,
which will be called at the same times as the ComponentCallbacks
methods of activities and other components are called. Note that you
must be sure to use unregisterComponentCallbacks(ComponentCallbacks)
when appropriate in the future; this will not be removed for you.
After you do that, just check ActivityLifecycleCallbacks for more information. You've got all the typical onCreate, start, resume, etc callbacks with the corresponding activity as an argument.
Related
While I was coding, I wanted to use findViewById method to find a view that cant access in the current view but can be accessed via the MainActivity. So two options came to my mind. One is creating a static method from that object in the MainActivity class and access the static object. The second method is to create a static object form MainActivity class itself(this) and access the findViewById method by calling the static object. Please answer the method I should use.
And apart from that, it got me thinking that whether an Android developer should come across this type of scenario or whether I have done some improper coding to access findViewById method in MainActivity while I was in a different view.
You can take a look at the code in the below repo.
https://github.com/chrish2015/ExpenseTrackerLatest
Thanks
If you are inside a class that is neither a Context nor an Activity and you need to use a method which exists inside the activity or context, then simply pass the activity as a parameter to that class and take an instance to that activity inside your class.
public class MyAdapter extends ArrayAdapter { // this is not activity
private Activity mActivity; // activity is a member of this class.
public MyAdapter(Activity activity, List<String> data) {
mActivity = activity;
}
public View getView(...) {
// if you need to use findViewById:
View view = mActivity.findViewById(R.id.some_id);
}
}
Don't use any of your two methods.
I might be misunderstanding your first sentence, but just to be sure, are you asking for a way to access a View that exists in the MainActivity, while you're inside of a Fragment?
If that's what you're asking, then yes, as an Android Developer, there will definitely be moments where we come across this scenario. However, the solution is definitely NOT by making your Views or Context static.
This is one of the easiest ways to cause bugs to appear throughout your app, with a very high chance to cause memory leaks too. Here's an Article from Google talking about memory leaks related to keeping a reference to a Context: https://android-developers.googleblog.com/2009/01/avoiding-memory-leaks.html
Rather than your two options, there are better solutions that developers typically use.
First of all, keep in mind that you should NOT be directly accessing any Views from outside of your current layout... meaning, that if you're in a second Activity, you don't directly access Views from the first Activity, or if you're in a Fragment, you don't directly access Views that belong to it's FragmentActivity.
Instead, you let the Activity or Fragment handle it's own Views.
So for example, if you're in another Activity and you want to update some data in the previous Activity, you can take advantage of an Activity's startActivityForResult() and onActivityResult() to obtain the data necessary to update the Activity immediately upon returning to the app.
For Fragments, there's actually a tutorial from the Android Documentation that describes a very good way to communicate between other Fragments: https://developer.android.com/training/basics/fragments/communicating
This method is to use interfaces as a callbacks, so another Fragment or the Activity will be able to receive data and update it's Views within it's own layout.
So for your case, if you're using Fragments and an Activity, you can easily have your fragments and activities communicate to each other in a safer and more reliable way.
Also, make sure you read up more on static and it's effects on your code, especially the side effects on Android components. Do not carelessly use static without considering some of the effects it might cause, because that would cause an endless amount of trouble to your code.
This is a stylistic question more than an actual "how can this be done," but the basic situation is this: I have an Activity MyActivity which contains a MapFragment, as well as a List of Renderers which are my own class that takes care of displaying some data. The Renderers also have ViewPagers which get their content views from yet another class, let's call it ViewPagerTab. Sometimes, something happens in some of these ViewPagerTabs that necessitates the update of the map in the top level Activity. There are, as I see it, a few approaches:
1) Both my Renderers and my ViewPagerTabs contain a reference to the context. If I cast the context as MyActivity I can access its map parameter.
2) By using the reference to the context, I can call getSupportFragmentManager().findFragmentById(R.id.map)).getMap() on it and get the map that way.
3) I can pass the map down from the Activity to the Renderers to the ViewPagerTabs as they are created so the map is accessible in each as a class variable.
4) Use a BroadcastReceiver in my Activity and send a message to it when the map needs updating from my ViewPagerTab.
Have I missed anything? What's the best/cleanest way of doing this?
This lesson may give you some ideas:
Communicating with other Fragments
Basically, the idea is to define an interface in a subunit such as a Fragment, then implement it in the parent Activity. Then, actually call the methods in the interface in the Fragment.
Another alternative is to create a class that extends Application. There, you can "share and declare" a number of non-context specific variables (like a glorified container, but where you don't have to create multiple instances of, or do look ups).
Requires some setup in your manifest but then all your activities can call MyApp app = (MyApp) this.getApplication(); (or in fragments, via the onAttach activity's .getApplication() )
The standard way is to define a listener interface, but I've found this to be cumbersome. Otto is a really nice alternative that you should at least look into before making your decision.
I think this is a bit over my head but what about parcel.I think it wouldn't work because of the dynamic nature of your data however it is one way to communicate between activities.
I am new to Android development. After learning from many tutorials I got many Activities and many Fragments. How can I make a core engine to check what Activity is running and what Fragment is showing on a container?
Assume that I have:
Acivity01, Activity02, ... , Activity10
Fragment01, Fragment02, ... , Fragment10
I want to make a class that filters the Activity where Activity is on runtime and what Fragment is embeded to that activity.
How can I do this?
If I understand you correctly, you may want to store some references within your Application class to an Activity and to Fragment instance(-s), which are currently in foreground (by this I mean that user can instantly interact with Activity/Fragment).
As for Activity
Create some Activity field in your Application class and getter/setter methods for it (e.g., setCurrentActivity(), getCurrentActivity()). Then call setCurrentActivity() from onResume() method for each of your Activity instances. Don't forget to call setCurrentActivity, supplying null reference to ir in order to properly handle a case, when there are no foreground activities, but application is stll working.
As for Fragment
The general idea is similar to the first item, but there can be more than one Fragment instance in foreground state at time. So you need to store something like List, where you add your resumed fragments and remove paused.
You may also want to implement something similar for dialogs, for example. Then use the same strategy. Hope it will help.
I'm implementing fragments in my app. Referring to this documentation,
there is written I should use getActivity() to access activity methods but also (in the next paragraph) I should declare an interface in the fragment and let activity implement it.
Now, the second way is used for callback methods like events, but I can also use getActivity().onSomeEventHappened(), can't I?
Could someone explain me the differences? Because I cannot see differences among them.
There is no difference in the end result if you know that getActivity() will always return the type of Activity you expect.
However using interfaces is a good practice because it decouples your Fragments from a particular implementation of an Activity. So later on in the future if you decide to use your fragments with a different activity, all you have to do is have that activity implement your fragments Interface to be alerted of any fragment events.
You should always strive to have decoupled components if you want an application that is easy to extend without side effects.
You can not always simply call getActivity().onSomeEventHappened(). Just imagine this case: You have two fragments, one with ListView and other which shows image based on listItem selected. In second fragment you cannot just call getActivity().onListItemClicked(), because your activity has no such method, but if activity implements interface and catches those event from the first fragment, then you are able to pass info about event to the second fragment and how the right image.
I want to use my options menu on every activity that I have on my project.
So I've created an OptionsMenuActivity which inherits from Activity.
Each activity I've created inherit from it.
The problem is when creating MyPreferenceActivity which inherits from PreferenceActivity, I cannot use it.
What is the best way doing it ?
If all you are looking to do is find a place to put the onCreateOptionsMenu() and onOptionsItemSelected() methods you can create a separate class with those two methods, make an instance of that class a member of all your activities, and make these two methods 'pass through' methods in your activities, deferring to the member object that now handles the requests.
Your new class does not have to inherit from Activity to do its job. However, the onOptionsItemSelected() method may have to return some indication as to whether it actually handled the request or not so your Activity's method can call 'super.onOptionsItemSelected()' as necessary.