Best practise for displaying multiple controls which require an extended class? - java

If I want to display a MapView inside my Activity I would have to extend my Class from MapActivity. If I want to display a Tabbed interface I would have to extend my Class from TabActivity. Similar is the case with some other controls which require user class to extend from a specific class.
Let's say inside my Activity I want to display both a MapView for displaying Google Map and a TabView to display some other data. I can't do it directly because Java doesn't support multiple inheritance. My question is how can I achieve this scenario? How can I display multiple controls inside my activity where each require your class to extend from a specific class. Is it possible first of all? If yes, what are the best practises to achieve this scenario?
Update I want to achieve this
I am using Map and Tab for sake of an example. I would like to know how you can tackle this scenario in general?

In this case it's simple: You can use the MapActivity within the TabActivity (it's designed to manage activities as tabs).
As general approach I always prefer to use views and nest them in an activity. I never use such things like ListActivity. They should make things easier but often look like a bad design decision to me. I never faced the fact that I had to combine two activities (expect TabActivity).
You can take a look at this question. It seems that activities never meant to be used that way. I think the situation which you describe is the reason why fragments where introduced.

You could build it via object composition. Initially I am not sure how to get the Activity started and add it to the layout, but then I found out about LocalActivityManager which allow you to embed other Activity as your view. Note that this class is deprecated since API Level 11. In any case here are the steps to embed other Activity that require extension as a View:
Create a LocalActivityManager to enable creation of Activity within Activity
Start the activity that you want to embed and get the View via getDecorView()
Add the View in your layout
The following is my test code that I tried within my Activity
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Create local activity manager so that I could start my activity
LocalActivityManager localActivityManager = new LocalActivityManager(this, true);
// dispatch the onCreate from this manager
localActivityManager.dispatchCreate(savedInstanceState);
// layout to hold the activity, optionally this could be set through XML file
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
this.addContentView(layout, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.FILL_PARENT));
// start the activity which is in this example is an extension of a TabActivity
Intent tabIntent = new Intent(this, DummyTabActivity.class);
Window tabWindow = localActivityManager.startActivity("tabView", tabIntent);
View tabView = tabWindow.getDecorView();
// start the activity that extends MapActivity
Intent mapIntent = new Intent(this, DummyMapView.class);
Window mapViewWindow = localActivityManager.startActivity("mapView", mapIntent);
View mapView = mapViewWindow.getDecorView();
// dispatch resume to the Activities
localActivityManager.dispatchResume();
// add to the tabView, optionally you could use other layout as well
layout.addView(tabView);
// add to the mapView, optionally you could use other layout as well
layout.addView(mapView);
}
My limited experiments show that object composition via the above method will achieve what you are trying to do. Having said that, I am not sure how common this approach is. Without your question, I wouldn't probably look for the above method, but your use case is interesting and might be applicable for future use. I will look into Fragment and see if I could do the same with it and update my answer if it is applicable.

Related

Difference between creating a class and extending fragment and just creating a fragment

I am relatively new at Android. I am taking a program on college and I am on my third semester. When we first started looking at fragments in the course, we always created them by right clicking the java folder and directly making a blank fragment. this would create the java file and the xml layout. then we would with help of the fragment manager, replace the content of the activity with the new fragment.
I thought this was the only way of doing it so far, but this week I've started to take a look at the developers course android offers on their website, and looking at the Creating a Fragment section, I learned that you can also just create a class and make it extend Fragment. Then, add an actual xml fragment tag to your layout and link your fragment to this xml.
My concerns about this are:
1) Is both ways doing the same process?
2) Is one of them better than the other?
3) Is there a moment when I'll prefer doing one or the other?
There is no difference. Directly using the "Create a fragment" option is just a convenience option that does the following:
Create a new class that extends from Fragment
Create a new layout for your new custom fragment class
Automatically set this layout as the contentView of your fragment (in the onCreate method)
As a bonus, add some sample code for you to get started
You could do all these steps manually as well.

Why implement the onClickListener instead of just setting the onClick attribute to a defined method in the Activity class?

I understand professionals use the former to tailor the onClick method to their exact specification, but cant I just use the onClick attribute and specify the same desired actions within a method.
i.e. [In xml file:] onClick="doSomething" & then
[in MainActivity.java:]
public void doSomething(View view){
//define and start intent
//Show a toast, etc
}
Why not just use the latter option? Thanks
Why not just use the latter option?
Go right ahead.
On bigger projects, it is unlikely that the activity will be managing the button directly:
You might be using fragments, in which case the fragment is more likely to manage the button than is the activity
You might be using MVP, MVVM, MVI, etc. GUI architectures, in which case some other "presenter" object is more likely to manage the button than is the activity
You might be using the data binding framework, in which case you might still be using android:onClick in a layout resource, but directing the event to something other than the activity (e.g., a fragment, a presenter)
And so on
Yes you can do so,both are doing the same thing but using the onClickListener is a better choice ,you can set the listener when you want that button to be active thus your Button and Activity are in cooordinaton.
If you use onClick in your xml file ,it will always call that method doesn't matter what is happening in your activity.

Can one class in android studio handle several different in layout and purpose XML layouts

Currently when I make a new layout I create a new class that handles that layout and then make a method to communicate with a class that the layout might communicate with, but can I use one class for everything. Like if I make a game can 1 class handle the Main Menu layout from which by pressing buttons you will be able to go to Options, High Scores and New Game. Can I do everything on a class ?
It's not a normal class that handles the layout. In Android, a class when extends an Activity or Fragment, it becomes one of the component of Android.
An Activity can render multiple layouts using setContentView() method. You can call this method with different layout as you click on different buttons.
BUT, this is a bad approach. To keep the same activity and change layouts, use Fragments. Fragments are part of an Activity that can have their own life cycle and can be attached or detached from Activity dynamically. They are mostly used for layouts for multiple sized devices. Read more about fragments here.
Here is tutorial of how to use Fragment in Android: https://www.raywenderlich.com/117838/introduction-to-android-fragments-tutorial

When is Activity.onBackPressed called in Android? (in relation to other callback functions)

When is Activity.onBackPressed called in my Android application? I'm not looking for the obvious answer of when the user presses the back button. I wan't the answer in relation to other "callback" functions.
Is is possible to be called during the execution of another function within the Activity class?
What is the case if I have my Activity class implement some typical interfaces used for your typical game? For example GLSurfaceView.Rendered? I'm having the feeling onBackPressed is called during GlSurfaceView.Renderer.onDrawFrame but I'm not 100 % sure yet. Even if this isn't the case, I want to know how it works. (It seems difficult to find this kind of simple information anywhere.)
Finally, below is a code example for the layout of my Activity class. The question is, however, not limited to this particular setup.
class MainActivity extends Activity implements Renderer {
onCreate(...) {
layout = new FrameLayout(this);
GLSurfaceHolder glsurface = new GLSurfaceHolder(this, this);
glsurface.setRenderer(this);
layout.addView(glsurface);
setContentView(layout);
GLSurfaceHolder is just a simple dummy class that extends GLSurfaceView. It has the onTouchEvent overloaded and simple passes the data over to the MainActivity class. (The design philosophy in this very, very simple app is just to focus all the sensory and other data to one place and then "make things happen"..)
onbackpressed will be called when you pressed back button. Default behaviour will be destroying the activity. To avoid override the onbackkeypressed or onkeypressed.

Fragments onClick method in fragment element

I read quite some articles about fragments, but I am still confused about how to do what.
I have a MainActivity, which displays two fragments side by side. In one of the fragments I have a button and defined in the fragments layout XML for the button
android:onClick="buttonClicked"
Now I want to implement that method
public void buttonClicked(View view)
I would have assumed that this has to be implemented in FragmentA.java and not in MainActivity.java. But it only works if that method is implemented in MainActivity.java. Why is that? To me that doesn't make sense. Pre Honeycomb a method belonging to one activity stayed in that activity, now on a tablet I am merging many activities to one MainActivity and all the different methods are merged? Whatever do you put for example in FragmentA.java then? What if you have to start you an own activity because this app runs on a handheld, then the onClick method has not to be in the MainActivity but in the Activity which needs to be called then. I am pretty confused at the moment...
I'm not sure what the specific problem is, but maybe this will help.
From the Android documentation on Fragments:
You should design each fragment as a modular and reusable activity component. That is, because each fragment defines its own layout and its own behavior with its own lifecycle callbacks, you can include one fragment in multiple activities, so you should design for reuse and avoid directly manipulating one fragment from another fragment.
That is, you should never manipulate a fragment from another fragment; rather, this should be done through the underlying Activity. Read the "Creating event callbacks to the activity" section in this article for more information (it's important stuff!!).
On the other hand, if you want the button to perform an action within the Fragment itself (i.e. if you wanted a Button click to change the text of a TextView within the Fragment), you should implement this in the Fragment, not the Activity (this is because the resulting behavior is contained within the Fragment and has nothing to do with the parent Activity).
Leave a comment and I can clarify if my post is confusing... I only recently began to understand Fragment's myself :).
Well,
I guess it is related to hierarchy of android context structure.
Activity is host of all child views and hence you can say fragment is actually using its host's context.And that's why when you use onClick with fragment system always searches it in Host activity of fragment.
Check it on.
Android developer onClick attribute description
I haven't checked one thing but you could put a test.
By providing implementation in host activity rather than in fragment,but use onClick on layout file of fragment.It should call parent's method.

Categories