Extend Activity and ActivityGroup - android

I'm writing an application in which i have a set of code which i want to be available in all of my Activities and ActivityGroups. However, to achieve this, I have extended my activities as:
//custom Activity
public abstract class BaseActivity extends Activity
//custom ActivityGroup
public abstract class BaseActivityGroup extends ActivityGroup
//implemented activities in my app
public class PickUser extends BaseActivity
//and
public class Home extends BaseActivityGroup
Now the thing is, whatever the custom code i write in BaseActivity, I have to write the same in BaseActivityGroup too (as in current implementation). This is prone to code-sync problems and i believe not a good technique.
So, how can i make my extensions in such a way that I only write custom code in BaseActivity and my BaseActivityGroup extends ActivityGroup - which is conceived from BaseActivity class?
If i observe how android does this, so the ActivityGroup in android extends Activity class. And I also want to write my custom ActivityGroup class (known as BaseActivityGroup) that actually extends BaseActivity (which is an extended Activity).
Any ideas/suggestions?

First of all ActivityGroups are bad and should not be used. They are deprecated and it is preferred to use a single activity with multiple fragments.
If you must use an activitygroup you are probably best of by implementing a delegate pattern.
Create a delegate that handles all the common methods such as onCreate, onResume and use that in the bases. In this example I save a reference to the activity in the delegate. This circular referencing might not be the pretties. An alternative is to pass on the activity to the methods in the delegate.
public class ActivityDelegate() {
private Activity mActivity;
public ActivityDelegate(final Activity activity) {
mActivity = activity;
}
public void onCreate(final Bundle savedInstanceState) {
// Do stuff.
}
}
public abstract class BaseActivity extends Activity {
private ActivityDelegate mDelegate = new ActivityDelegate(this);
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDelegate.onCreate(savedInstanceState);
}
...
}
public abstract class BaseActivityGroup extends ActivityGroup {
private ActivityDelegate mDelegate = new ActivityDelegate(this);
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDelegate.onCreate(savedInstanceState);
}
...
}

Add an extra final class, called Base.
This one will only contain methods to be called by the other Base classes, such as for instance:
public static boolean createOptionsMenu(final Menu menu,
final MenuInflater inflater) {
inflater.inflate(R.menu.main_menu, menu);
return true;
}
Then, in your BaseActivity and BaseActivityGroup classes, you would call:
#Override
public final boolean onCreateOptionsMenu(final Menu menu) {
return Base.createOptionsMenu(menu, getMenuInflater());
}
Hope it helps!

Just Extend everything to BaseActivity including BaseGroupActivity as everything is a child of Activity in android

you can put your login in a separate file under a method. now call the same method from both BaseActivity and BaseActivityGroup if you need activity instance in file . pass context through constructor

Related

Is it okay to extend to MainActivity from a JavaScriptInterface to avoid non-static errors?

I have one activity with a webview in it.
When the user interacts with the webview, it does this through the JavaScriptInterface so both the app and webview can interact with each other.
I believe the class is by default static, so I've found not too much can be done without it extending MainActivity.
public class JSInterface extends MainActivity {
private MainActivity mainActivity;
JSInterface(Context context, MainActivity mActivity) {
mainActivity = mActivity;
}
#JavascriptInterface
public void someMethod() {
mainActivityMethod(webViewData);
}
// other methods
}
In my MainActivity I have:
WebView webView = findViewById(R.id.webView);
JSInterface JSInterface = new JSInterface(this, this);
//other methods called by JSInterface, e.g.
#Override
public void mainActivityMethod(String webViewData) {
// do something with data
}
So I've found by extending to MainActivity from JSInterface, I can call normal (non-static) methods from MainActivity which is very much a necessity.
If I don't extend it to MainActivity, it seems to be a static class and I get this error when trying to call MainActivity methods or reference anything not static:
Non-static method someMethod() cannot be referenced from a static context.
It works as it is, but I feel like this isn't the best way to go about it.
Am I right?
What would be the 'best' way to do this? Or other ways, as best is subjective.
I feel like this isn't the best way to go about it
Never create a subclass of Activity unless you are going to start it with startActivity().
What would be the 'best' way to do this?
One option is simple composition, getting rid of the improper inheritance:
public class JSInterface {
private MainActivity mainActivity;
JSInterface(MainActivity mActivity) {
mainActivity = mActivity;
}
#JavascriptInterface
public void someMethod() {
mainActivity.something(webViewData);
}
// other methods
}
Another is a nested class. In this sample activity, Locater is a nested class inside of my GeoWebOne activity, and therefore Locater can call methods and access fields in GeoWebOne. The simple composition approach is a better answer, though a nested class will work.

Let Fragments use the Same Method

I have two fragments (each a tab in a sliding tab activity) in my application. The two fragments have some methods which now are identical, I thought that I could abstract out those methods to follow the DRY (don't repeat yourself) principle. Is there any recommended way of doing this?
Is a util class with static methods a good way? Or should I create an abstract class "MyAbstractFragment" which has those methods and let the fragments extend this class?
For example.
public class MyCustomFragment extends Fragment {
protected LinearLayout linearLayout;
protected MyAdapter adapter;
//more common fields
void addButtonToFragmentView(final String btnText) {
final Button btn = new Button(getContext());
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
linearLayout.removeView(btn);
}
});
btn.setText(btnText);
linearLayout.addView(btn);
}
void upDateAdapterList(List<String> list){
//....
adapter.updateList(list);
}
}
Than my fragments could extend this class and set the properties and use the methods. But I also see that I as well could make a static util class just for the methods, like addButtonToFragmentView(final String btnText, Context context, final LinearLayout linearLayout) and upDateAdapterList(List<String> list, MyAdapter adapter)
Or is there a preferred way of doing this?
Yes, you can use abstract class like below:
public abstract class BaseFragment extends Fragment {
#Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
public Context getContext() {
return this.getActivity().getApplicationContext();
}
protected abstract void addButtonToFragmentView(final String btnText);
protected abstract void upDateAdapterList(List<String> list){
}
then extends your new fragment with this base class.
code taken from:
https://github.com/spirosoik/AndroidArchitecturePadawans/blob/master/presentation/src/main/java/com/architecture/padawans/views/common/BaseFragment.java
We should try to follow composition over inheritance. May be you can have a dedicated UIFactory class which deals with dynamic creation of views, then you move your addButtonToFragmentView method to the UI factory and make if more generic.
void addButtonToView(final String btnText, final Context, final View parentView);
As far as upDateAdapterList is concerned you can create a BaseListFragment and move it there, so whoever is interested in using a fragment with List can extend this Fragment. Hence this follows Single Responsibility Principle.

Get & Set Value of my Activity from a fragment - Android

I would like know how can I get and set a value of my activity from my fragment?? is that possible?
below is my activity and the attribute 'myStation' is the value I want get and set from my fragment.
public class MyActivity extends Activity
implements NavigationDrawerFragment.NavigationDrawerCallbacks {
public static Station myStation;
In my fragment I can execute 'getActivity()' but I really don't know if I can do that. if I'm wrong, what is the correct process?¿
Thanks.
If the fragment is only used in that activity, then you can simply cast the activity. Otherwise you'll have to verify that it is the correct activity perhaps using instance of.
Let's look at the simpler case:
public class MyActivity extends Activity {
private boolean myFlag;
public boolean getMyFlag() {
return myFlag;
}
public void setMyFlag(boolean myFlag) {
this.myFlag = myFlag;
}
And here would be the fragment to adjust the flag.
public class MyUniqueFragment extends Fragment {
public void updateActivityFlag(boolean myFlag) {
MyActivity myActivity = (MyActivity) getActivity();
myActivity.setMyFlag(myFlag);
}
}

Use a container for Android activities

I want to know if Android support the possibility to make a container with some static components and just include my activities in it.
I have a sliding menu with some onClickListener events and I don't want to set these events for each activity.
If I understood you correctly, you have some functionality that is common to several Activities, and you don't want to repeat the same code in all of them. Instead, you want to do that in one place.
One way to achieve this is to create a superclass activity, place your common code in that activity, and then extend it with your other activities. For example,
public class BaseActivity extends Activity implements OnClickListener {
private Button button;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
button = (Button) findViewById(R.id.my_button);
button.setOnClickListener(this);
}
...
#Override
public void onClick(View view) {
int id = view.getId();
switch(id) {
case R.id.my_button:
// perform action
break;
}
}
}
Then you extend it as
public class Activity1 extends BaseActivity {
/...
}
public class Activity2 extends BaseActivity {
/...
}
public class Activity3 extends BaseActivity {
/...
}
I am not exactly sure I understand your question, can you perhaps elaborate some more? maybe even post some sample code that you are using currently.
From what I can tell you should be able to achieve what you want by making your own CustomActivity
public class CustomActivity extends Activity {
//put your slidingmenu stuff here
}
Then inside all of the other Activities where you want to use that shared piece do it like this:
public class AnotherActivity extends CustomActivity {
//...
}
with extends CustomActivity instead of the usual extends Activity
This is how i solved the problem:
First thing i did is creating my main class wich will host common code.
for example :
public abstract class main extends activity(){
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getLayoutResourceId());
// Your common code here
}
protected abstract int getLayoutResourceId();
}
Then all what you need is to extend this class in your activity:
public class HelloActivity extends main{
#Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_hello);
super.onCreate(savedInstanceState);
//make sure to put setcontentview before super.oncreate
}
#Override
protected int getLayoutResourceId() {
return R.layout.activity_hello;
}
}
All the activities needs to be registered in the Manifest. For the common things, e.g. Slide menu, you can use Fragment for the slide menu.

roboguice replace Activity with own implementation

Is there a way to replace the default Activity class with own implementation extending from this class using roboguice?
For instance an activity like this:
public class MyActivity extends Activity
{...}
would replace the default Activity class and would become the base activity for all other derived activities.
Yes. The easiest way is to have your base activity extend from RoboActivity.
Eg.
class MyBaseActivity extends RoboActivity { ... }
And then have all of your activities extend from MyBaseActivity.
However, if for some reason you don't wish to extend from RoboActivity, you can easily add injection to your own activities by doing the following:
class MyBaseActivity extends Activity {
public void onCreate(Bundle b) {
super.onCreate(b);
RoboGuice.getInjector(this).injectMembersWithoutViews(this);
}
public void onContentChanged() {
super.onContentChanged();
RoboGuice.getInjector(this).injectViewMembers(this);
}
}
Take a look at RoboActivity's source for more details. As long as you don't need events, the changes required are quite simple.

Categories

Resources