What are the benefits of extending LinearLayout over View? - android

I am trying to build a soundboard app that plays a sound whenever you tap on a custom view. In order to organize my UI, I used a layout file.
When I extended View, I found that when I tried to inflate my layout, it wouldn't work.
//Didn't work
View v = View.inflate(context, R.layout.sound_view_layout, null);
When I extended LinearLayout, however, it did work.
//Worked
View v = View.inflate(context, R.layout.sound_view_layout, this);
My question is,
how come I needed to extend a Layout class in order for the program to work, and what are the benefits of doing so?

Well you can only inflate a layout. If you want to just create a View, use new CustomView(context).
Ignoring that- the main reason to extend a layout is if you want to add children to it programmatically, or if its a collection of views already (for example you may want to create a view CaptionedPhoto that has an image on top of text. One way to do this would be to make CaptionedPhoto extend LinearLayout and hold an image view and a text view).

Related

Android Performance : Adding view programmatically vs setting view to GONE/VISIBLE

I'm working in a project that requires to inflate a simple tutorial View when the user opens the app for the first time. I'm trying to do it "the right way", and I'm wondering about performance issue.
Currently, I have in my layout a view sets to android:visibility="GONE", which I change to VISIBLE depending on a SharedPreference. This allows me to let the user learn how the app works on first launches.
What I'm wondering is what it implies when the view is rendered in my Fragment. My guess is that the view will be uselessly inflated, even if its visibility is set to GONE.
Now, I'm thinking about an alternative: what if I would only add my View on first launches, but programmatically, in my Fragment's onCreateView. That should allow the view not to be inflated on later launches, but wouldn't inflating the view programmatically implies bad performance on first launches?
So, to answer my own question I used the DDMS tool TraceView to monitor the calls from my fragment onAttach until its onResume. It let me see which implementation are the less efficient.
To do the test, I had a simple RelativeLayout with a FrameLayout inside it (shown all the time). I used a custom layout to add each time, either programmatically or with a visibility of GONE on my layout file. The custom layout was composed of a RelativeLayout with 4 childs (an ImageView, a TextView, a View, and a Button).
My onCreateView was the following, allowing the app to inflate the right layout based on two static final boolean constants to change the layouts.
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
LinearLayout root;
if(INFLATE_PROGRAMMATICALY) {
root = (LinearLayout) inflater.inflate(R.layout.fragment_test_prgmcly, container, false);
if(SHOULD_FYI_VIEW_BE_SHOWN) {
View tutoView = inflater.inflate(R.layout.inner_view, root, false);
root.addView(tutoView);
}
} else {
root = (LinearLayout) inflater.inflate(R.layout.fragment_test_gone,container,false);
if(SHOULD_FYI_VIEW_BE_SHOWN) {
View tutoView = root.findViewById(R.id.RL_inner_view);
tutoView.setVisibility(View.VISIBLE);
}
}
return root;
}
This lead to the following results:
When the optional layout in inflated
SHOULD_FYI_VIEW_BE_SHOWN=true
The maximum "real time estimate" given by the TraceView are of 75ms when there is just a view to change from GONE to VISIBLE, but of 110ms when we need to instantiate the inner_view.
When the optional layout isn't inflated
SHOULD_FYI_VIEW_BE_SHOWN=false
In this case, the maximum real time estimate given by TraceView are of 102ms for the inflation of the GONE view, versus 39ms when the view inflated doesn't have the GONE view.
So, for the performance gain when the views doesn't need to be inflated, I'd say that the best solution is to inflate your view programmatically if you only need to show it a few time.
You can find the test project on a Gist
I think you are reinventing a wheel. For this scenario is already existing tool in Android xml layouts. It is called ViewStub. You can read more here: Loading ondemand
I think I just randomly stumbled over the answer of your performance question.
From the Animation Docs:
For the view that is being faded in, set its visibility to GONE. This
prevents the view from taking up layout space and omits it from layout
calculations, speeding up processing.
This would mean performance is not compromised as long as you don't set android:visibility to anything else than GONE.

Difference between View and Subview - Android

What is the difference between a view and a subview in Android?
there is no such thing called a 'subview', its just used to refer to a view inside another view.
View is the base class for widgets, which are used to create interactive UI components (buttons, text fields, etc.). and if we insert a view inside the another the its become Subview like a linear Layout containing a button view, here button is a subview
Like Vinay said, there is no such a thing. But you have ViewGroup that contains other Views. For example, LinearLayout, RelativeLayout etc are derived from that class.
If you wish, you can read more about it here:
http://developer.android.com/reference/android/view/ViewGroup.html

Android: Best way to load views dynamically in Android 2.1

I am developing an application in Android 2.1 which requires loading of views dyamically based on button click. Here is the rough layout of my Activity.
Say on Clicking button1, it should display imageview, and on clicking button2, it should show listview, for button3 - linearlayout of button and images, and so on. All the views should be loaded in the provided white space only.
The approach I thought to follow is "Inflating layouts".But on clicking another button, old inflated layout should be removed and new inflated layout should be visible.
Are there any better ways to achieve this?? If Inflating layouts is the only better way, how can I remove old inflated layout and load new inflated layout.
You can use a ViewFlipper to hold the three layouts and simply call showNext() or setDisplayedChild() to determine which layout is shown.
Inflating is good when you have more complex layout than just one ImageView or so. In this case you should just create an ImageView dynamically and add it to "the white space" (it should be some ViewGroup (i. e. RelativeView)). In this case:
mRelativeView.removeAllViews();
ImageView newView = new ImageView(mContext);
newView.setImageResource(R.drawable.someImage);
mRelativeView.addView(newView);
When having more complex layout, do it with LayoutInflater (but remember inflating is very slow):
mRelativeView.removeAllViews();
View newView = LayoutInflater.from(mContext).inflate(R.layout.some_layout, null);
mRelativeView.addView(newView);
In above examples mContext can be current Activity for instance.
It sounds like you're trying to do something very similar to TabHost, try reading on TabHost here:
http://developer.android.com/reference/android/widget/TabHost.html
And see the tutorial here:
http://developer.android.com/resources/tutorials/views/hello-tabwidget.html
I think you'd better off using built-in components like this then implementing something similar on your own

Android GLSurfaceView as subview

I'm very new to an Android platform and currently trying figure out why things work this way:
If I create GLSurfaceView and add it using the setContentView or addContentView to an activity everything works fine (Renderer.onDrawFrame is called as expected). However if I add my GLSurfaceView to another ViewGroup (which is then added using setContentView) nothing is rendered.
So what is the difference between addView and addContentView ?
In the end I need to create a custom view with OpenGL rendering in background and some controls on top.
Also what is the point of separating View and ViewGroup? Why not to join them (like it is done in CocoaTouch) ?
setContentView(View) sets the parent View for an Activity (or dialog etc...).
addView(View) adds a View to a ViewGroup.
View and ViewGroup are mostly different. View is a more specific single entity. It should be used more on one facet of what you are trying to do. ViewGroup, however, focuses more on the whole and acts (is) a container and layout organizer for a collection of Views.
Can you post all the code related to the GLSurfaceView and how you are setting it as contentView?

Creating autohide custom view in android

I am working on creating a custom view in android. I want to create an autohide custom view control.
This control will be holding other UI elements mostly buttons or icons. It has a small button which is mandatory, clicking which will slide the control in or out thus changing its visibility.
one should be able to add other buttons or icons to this control
The control can be placed only at the borders, which needs to be specified while creating the view.
I don't know how to start with it
Should I be extending the View class or ViewGroup class.
have a look at this
and then you have to add a dynamic layout to this drawer
I used a RelativeLayout and added a Button to the View.
When I call expandView() or collapseView(), I call mybutton.setVisibility() and let RelativeLayout know it has changed with this.requestLayout().

Categories

Resources