I have a very trivial confusion regarding the what is the root view of an activity. I searched this throughout google and stack overflow. I got some knowledge about it but didn't come to a convincing solution as no one clearly said about that term. The question which seems to be alike my question tell about what a root view of a given layout is but to me they don't seem to specify the root view of an activity is.Though the answer to my question is quite intuitive, I want a definite answer with no confusion.So here is the code structure.
I have the following activity class :
package com.example.android.viewpager;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
And the XML code associated with it when I created the activity is (activity_main.xml) :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.android.viewpager.MainActivity">
</LinearLayout>
So according to me is this activity_main.xml the root view of the MainActivity?
The Root View of Your MainActivity is LinearLayout
The Root View of Your Activity means the Top most parent layout of Your XML Layout
The Root View may be a RelativeLayout, CoordinatorLayout, ConstraintLayout, LinearLayout,FrameLayout
For Example
Your activity_main.xml Contain LinearLayout as parent layout than LinearLayout is your Root View which hold all the child controlls in it like Buttons, Imageview, EditText, TextView, etc....
The activity_main.xml is the layout of your MainActivity. Inside the layout the root view is the top hierarchical view which in this case is a LinearLayout. It could also be a RelativeLayout, CoordinatorLayout, ConstraintLayout etc.
The first view that is capable of holding child view will be called your root view. In your case, Linear Layout will be your root layout
activity_main is not the root view. This is the XML file where the layout of your activity is defined.
The root view is the view in this layout, containing all the other views.
In your example, the root view is the LinearLayout
When you do setContentView(R.layout.activity_main); the system will parse the XML file and create all the views and subviews defined into it with the attibute and everything
For example if your XML is defined like that:
<RelativeLayout
...
>
<TextView
android:text="HelloWorld"
... />
</RelativeLayout>
When the view is inflated you'll end with a RelativeLayout object containing a TextView object containing "HelloWorld" in one of its fields.
In this example, the root view is the RelativeLayout
Related
I came across this TextView class method() in some code for taking a screenshot. What does it do, what's its purpose?
textView.getRootView()
Actually, what is a root view?
It is a method of the base class View
It basically lets you find the topmost view in the current view hierarchy.
e.g
<LinearLayout>
<TextView/>
<RelativeLayout>
<...something...>
</RelativeLayout>
</LinearLayout>
In the above example, the root view would be the top most declared view ie the linear layout
First, read the documentation for getRootView().
Then the next question is, what is a View Hierarchy? Read that here.
So to be succinct, a root view is the top-most view in your current View Hierarchy that is connected to your object you are calling getRootView() from.
Looking at the above tree map, or a binary tree, it would be the root, or top-most node.
It seem similar to other questions but I doesn't found solutions. I have a layout defined by xml file:
main_layout.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
... >
<package.CustomView
... >
</package.CustomView>
<TextView
android:id="#+id/text_view"
... >
</TextView>
</RelativeLayout>
where CustomView extends SurfaceView.
In onCreate I have setContentView(R.layout.main_layout). Now, If I want to inflate, for example, the TextView in the activity I have to add after setContentView(...)
TextView textView = (TextView) findViewbyId(R.id.text_view);
and all works fine. But if I put this line in a method of my CustomView I got a null pointer. Why?
findViewById() will traverse only the given view and its children. It will not find sibling views. Your textview is a sibling to the custom view, not a child view.
In an activity, the root view where findViewById() traversal starts is the activity window (Activity.findViewById()). In a view, it is the view itself (View.findViewById()).
Understanding helpful explanation above I would like to give an easy way to find a view by its ID from CustomViews:
(Activity)getContext()).findViewById(R.id.youViewToBeFound);
inside your CustomView class.
This code must be run AFTER constructor code e.g. inside onAttachedToWindow()
I am trying to creating a custom view extends RelativeLayout.
To avoid adding view by coding. I prepare a xml with my custom relativelayout.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android">
...
</RelativeLayout>
So in my custom view class, I would inflate the xml by
View.inflate(context, R.layout.custom_view, this);
My question is as my class is already a RelativeLayout, if I doing so, I would have two levels of RelativeLayout. Of course, I can solve it by removing the outer RelativeLayout in xml. But if I am doing so, I cannot see preview in xml editor in eclipse which is the reason I want my custom view inflate from xml.
Even my custom view class extends FrameLayout, there would be one layer more in the view hierachy. How to solve this problem?
To reduce the unnecessary extra layer, you need to use merge tags. Here is a good example on how to use it.
http://android-developers.blogspot.com/2009/03/android-layout-tricks-3-optimize-by.html
<merge xmlns:android="http://schemas.android.com/apk/res/android">
...
</merge>
I am developing an Android 2.1 app.
I have defined a LinearLayout class:
public class MyTopBar extends LinearLayout {
...
}
Then, I have a layout xml file (content.xml):
<LinearLayout>
...
</LienarLayout>
I have a RootActivity.java , I would like to set MyTopBar as content in this RootActivity.
Then I have MyActivity which extends RootActivity:
public class MyActivity extends RootActivity{
//set xml layout as content here
}
I would like to set the content.xml as content of MyActivity.
As a whole, I would like to use the above way to achieve the layout that MyTopBar should be located on top of the screen always. The other Activities which extend RootActivity will have its content below MyTopBar. How to achieve this??
1 You could add your custom LinearLayout directly to the xml layout of the MyActivity class like this:
<LinearLayout>
<com.full.package.MyTopBar
attributes here like on any other xml views
/>
...
</LinearLayout>
or you could use the include tag to include the layout with the custom view:
<LinearLayout>
<include layout="#layout/xml_file_containing_mytopbar"
/>
...
</LinearLayout>
2 Use :
setContentView(R.layout.other_content);
Have a Layout vacant for the TopBar and add Your Topbar in it by using layout.addView(topbarObject);
Regarding your second question the setContentView can be called only once, as far as I know. You can however have those two xml files inflated using View.inflate(other_content.xml) and added in the parent xml layout whenever you need it. You can removeView() on parent layout and addView() with the new layout file.
Edit:
For the solution of both the question, you can have a parent Layout for eg. like the following:
//Omitting the obvious tags
//parent.xml
<RelativeLayout
android:id="#+id/parentLayout">
<RelativeLayout
android:id="#+id/topLayout">
</RelativeLayout>
<RelativeLayout
android:id="#+id/contentLayout">
</RelativeLayout>
</RelativeLayout>
Now in your code set the parent layout as content view,make an object of your TopBar layout and add it to the topLayout.
setContentView(R.layout.parent);
MyTopBar topBar=new MyTopBar(this);
RelativeLayout toplayout=(RelativeLayout)findViewByid(R.id.topLayout);
topLayout.addView(topBar); //or you can directly add it to the parentLayout, but it won't work for the first question. So better stick to it.
Now inflate the required xml layout. and add it to contentLayout.
RelativeLayout layout=(RelativeLayout)View.inflate(R.layout.content,null);
contentLayout.addView(layout);//Assuming you've done the findViewById on this.
and when you need to show the other content xml, just call the following code.
contentLayout.removeAllView();
RelativeLayout layout2=(RelativeLayout)View.inflate(R.layout.other_content,null);
contentLayout.addView(layout2);
I have a program where I want to add two views in one activity, like
public class AnimationActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new GraphicsViewForBitmap(this));
setContentView(new GraphicsView(this));
}
}
where GraphicsViewForBitmap & GraphicsView are two classes extends view.
so I want at a time two views should set to an activity.
Is it possible?
Plz give me answer.
Thanks
setContentView() will display only the view that you have set . If you want to display more than one view then you can add both the view in your layout XML file inside any Layout like LinearLayout,RelativeLayout etc. Then you can use setContentView(R.layout.yourXML).
Here is how you can do it in your XML...
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.yourpkg.GraphicsView
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
<com.yourpkg.GraphicsViewForBitmap
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</LinearLayout>
Yes but first you have to put them inside a ViewGroup, for example a LinearLayout, and then set that ViewGroup with setContentView. Because with the existing code you're not just appending the second view with the first, but you are setting another content.
Add the second view to the first view.
LinearLayout childLayout = new LinearLayout(this);
childLayout.setOrientation(LinearLayout.HORIZONTAL);
childLayout.addView(graphicsView);
parentLayout.add(childLayout);
Another way is to create a 2nd layout XML, say main2.xml (the 1st being main.xml). Then you can swap from one to another via, e.g. an ActionBar button, etc. as follows:
setContentView(R.layout.main2); // Pass from layout #1 to layout #2
setContentView(R.layout.main); // Pass from layout #2 back to layout #1
(You can create as many views as you like ...)