I have two ListFragments which needs to share some code. This was very basic by just creating a abstract fragment extending ListFragment and then let my two fragments both extend my abstract fragment.
However, now I need a third fragment to use the code from my abstract fragment. However, this third fragment is not a ListFragment but a GridFragment.
Is there a good way to solve this problem?
As java won't support multiple inheritance either seperate your generic code in to Fragment Super class or make static methods.
or
Simply write a FragmentUtil class.
I would suggest you put your shared code in class that dont extends any Fragments. In your fragments classes you make calls to your SharedCode.class .
Related
public class MainActivity extends fragment
public class MainActivity extends Activity
The issue I have is that I need to extend Fragment to be able to use the 'pager_title_strip' but to use a list view that can read json, it also needs to be extended.
How can I extend both within the same class?
You can't, a class can only extend one other class.
It can however implement multiple interfaces, maybe that can help you in your design.
Abstractly spoken, multiple inheritance is not the only answer to such design problems, and in Java it was excluded by designers of Java (Gosling et.al.) because they saw it as inherently unsafe. Still in Java 8 multiple inheritance is only allowed for behaviour (see interface inheritance and new "default" methods), but not in state.
Alternatively, you can also think about composition or delegate patterns. From Joshua Bloch we know his recommendation "Favor composition for inheritance". I think this should be possible in your case.
There is FragmentActivity or ActionBarActivity class which may solve your problem!
http://developer.android.com/reference/android/support/v4/app/FragmentActivity.html
The issue I have is that I need to extend Fragment to be able to use the 'pager_title_strip'
There is no requirement to use fragments at all with a ViewPager, let alone with a PagerTitleStrip or PagerTabStrip.
so saying that does this mean you aren't able to use a listview box that reads json and the pager title strip at the same time?
It is perfectly possible to "use a listview box that reads json and the pager title strip at the same time". However, you will need to create more than one Java class, in all likelihood, such as an Activity and a Fragment.
There are methods and attributes I would like to share across activities. E.g.
public class BaseActivity extends Activity
would be the parent for another activity
public class MainActivity extends BaseActivity
BUT if the child activity is a e.g. ListActivity this is not possible, right? Do I need a base class for ListActivity, too? This would be redundant code.
I could transform the ListActivity to an Activity, but this would be more code then necessary.
Any suggestions?
Yes, you're right. As java does not support multiple inheritance, a class can only have one base class.
But you can work via delegation instead of inheritance: Put your methods into a separate class (which does NOT inherit Activity) and use instances of it in your activities. Then you can reduce the redundant code (creating and holding the instance) to a minimum.
See also:
http://sourcemaking.com/refactoring/replace-inheritance-with-delegation
How do I implement multiple inheritence in Java
For the ListActivity case I would create a BaseListActivity that extends from BaseActivity. The BaseListActivity would contain a getListView() that returns the ListView if you really-really need it, a protected method setAdapter() that receives an Adapter/ListAdapter. You could also create some protected methods for enabling to show the empty view, to enable this behavior and to return the ids for your empty view and ListView. By default these should point to android.R.id.list/android.R.id.empty. But you can override that in your child activity.
In the end it's a matter of OOP and not that much of Android specific. If you check the implementation of ListActivity you'll see how simple it is to make your own BaseListActivity implementation. In the end it's more important to have a consistent and robust class hierarchy.
I am using my Activities this way, and I'm really happy I'm doing it. Of course you have to make some changes (like the ListActivity you mentioned in your question), but it has more advantages then disadvantages in my opinion.
In my app I don't have to worry about sending Analytics data every time I create a new Activity, and I also don't have to worry about setting up BroadcastReceivers I need in every class, I just made my BaseActivity abstract and have an abstract function what I call every time my BaseActivity gets a broadcast.
if you want to share some methods the best way it to impelement an interface or make an abstract class for baseactivty.
As others have pointed out, you need to use composition, since multiple inheritance is not possible in Java. This answer to a related question explains how to do this in the case of Android Activities.
The question doesn't really make sense, but this should help explain it better.
I'm currently using the IOIO, and it works like this:
public class MainActivity extends CustomIOIOActivity {}
From there I can call classes I've made in CustomIOIOActivity, which extends Activity.
The problem I'm running into now is that I have to inherit classes different from just Activity. For example, FragmentActivity.
Is there a way for me to create a custom IOIO activity which I can use for when I extend Activity and FragmentActivity? I don't want to have to make two essentially identical classes, which is what I am doing right now--seems silly. I'm not very familiar with Java, perhaps this is easy to do.
In Java you can't inherit class from more than one superclass. In order to achive your purpose, I would advise you to move all common logic to another class(IOIOHolder, for example), which would take an Activity parameter in constructor. Later you can create two different classes extending Activity and FragmentActivity, each containing an exemplar of IOIOHolder and using it for it's own tasks. By using this approach you can write IOIO code once and use it in any activity you want.
I want to display the same options menu on all of my application's activities. I created a generic Activity that implements the menu, and all my further activies extend it.
The problem: when I need to extend other specific activities, like ListActivity and MapActivity, I can't figure out how to extend the generic activity and add the List or Map behaviour to the new class. To deal with the issue I had to create three different generic activities, each extending Activity, ListActivity and MapActivity.
I've tried creating an abstract activity but it doesn't work, I would need to extend two classes at the same time. I could try interfaces but since I can't implement methods, I would have to paste the menu implementation all over the second-level classes, right?
You can't do this. Java doesn't allow multiple inheritance.
When I need this kind of behavior and it depends on the Activity lifecycle I just replicate it two abstract classes:
AbstractActivity
AbstractMapActivity
You can also read more about multiple inheritance:
Multiple Inheritance in Java
Simulate multiple inheritance in Java
I wish to have a single class which all of my Activity classes extend. I have ListActivities, Activities, MapActivities, TabActivities, etc in my App.
I have many of these different activities in my app, ~12 activities. I want each of them to have the methods which are in the parent class.
Right now, i have created 4 parent activity classes which are extended from a certain activity depending on their type(ListActivity, Activity, MapActivity, TabActivity)
I am creating a lot of redundant code - each of the 4 parent activities has almost identical code, in exception for what class activity it extends.
Here is an example that may clarify what my problem is:
I have an Activity: MenuScreen which extends BaseListActivity
BaseListActivity extends ListActivity
BaseListActivity contains methods and fields which i want all my activities to have access to
I have another Activity: HomeScreen which extends BaseActivity
BaseActivity extends Activity
BaseActivity contains the same methods and fields which are in my other Base[<type>]Activity classes(such as BaseListActivity)
these methods/fields are copy-pasted to all my Base[<type>]Activity, and seems awfully redundant to me.
Can i create a master activity class which all types of Activity classes can use as its parent? if not, am i stuck with copy and pasting this code and feeling gross/dirty about it?
Can i create a master activity class which all types of Activity classes can use as its parent?
No, sorry.
if not, am i stuck with copy and pasting this code and feeling gross/dirty about it?
First, you do not need ListActivity or TabActivity. You do not need ListActivity for a ListView; you do not need TabActivity for a TabHost. That knocks things down to two base classes: Activity and MapActivity. Unfortunately, you do need to extend MapActivity to use MapView.
For that, you can use composition to minimize redundancy. Rather than your "methods and fields which i want all my activities to have access to" being implemented on the activity, implement them on some other object, and have BaseActivity and BaseMapActivity hold onto an instance of that object. You will still need some amount of duplicate code (e.g., for lifecycle methods like onStop()), but more stuff can be located in a single class.
Yes, you can make a master class, that has all the redundant code. Although the problem is, that you use ListActivities, TabActivites and so on, which are only convenience classes (they extends the Activity class and do some chores for you, but not that much).
I'd just ditch them, make a class named BaseActivity that extends the Activity class, and has all the redundant code parts. Then, all your activites should extends BaseActivity.