Android parent of root in xml? - android

If I had two layouts, layout1.xml and layout2.xml, that are both just empty LinearLayouts, and I set layout1 as an activity's content view:
setContentView(R.layout.layout1);
Is it possible to add the second layout right under the first?
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout layout2 = (LinearLayout) inflater.inflate(R.layout.layout2);
View parent = // parent of current layout root
parent.addView(layout2);
So the hierarchy would look like:
<parent>
<layout1 />
<layout2 />
</parent>
Basically I'm wondering how to get that parent view if it exists.

I think the easiest way to accomplish what you want is to create a third layout (parent.xml) that includes the other two layouts using include tags. Then setContentView(R.layout.parent);
Have a look here:
http://developer.android.com/training/improving-layouts/reusing-layouts.html
As an example, consider the following parent layout that pulls in your other two layouts:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include android:id="#+id/layoutOne" layout="#layout/layout1" android:layout_width="match_parent" android:layout_height="wrap_content"/>
<include android:id="#+id/layoutTwo" layout="#layout/layout2" android:layout_width="match_parent" android:layout_height="wrap_content"/>
</LinearLayout>

View parent= getWindow().getDecorView().findViewById(android.R.id.content)

I think you want something like this :
LinearLayout layoutMain = new LinearLayout(this);
layoutMain.setOrientation(LinearLayout.VERTICAL);
setContentView(layoutMain);
LayoutInflater inflate = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
RelativeLayout layoutFirst = (RelativeLayout) inflate.inflate(R.layout.abc, null);
RelativeLayout layoutSecond = (RelativeLayout) inflate.inflate(R.layout.xyz, null);
layoutMain.addView(layoutFirst, 100, 100); // width=100, height=100
layoutMain.addView(layoutSecond, 100, 100);
You can read the documetation here.

Related

Compound layout

I want to create a custom layout to reduce redundancy in the code. Currently every layoutfile has about 30 Lines of code which are identical.
My goal was to create a custom layout/view which can hold in itself children.
<BaseLayout xmlns:...>
<!-- Normal Content -->
<Button />
<Label />
</BaseLayout>
While the above xml holds most of the content, the BaseLayout is in itself an xml containing other views and functionality:
<FrameLayout xmlns:...>
<LinearLayout><!-- contains the Header--></LinearLayout>
<LinearLayout><!-- INDIVIDUAL CONTENT HERE--></LinearLayout>
<FrameLayout><!-- contains the loading screen overlay --></FrameLayout>
</FrameLayout>
So all children from the above xml should be inserted into second linear-layout. I have already succeeded into doing so. But am confronted with layout problems (match parents does not match parents and only wraps)
My approach was extending the LinearLayout with following logic:
/**
* extracting all children and adding them to the inflated base-layout
*/
#Override
protected void onFinishInflate() {
super.onFinishInflate();
View view = LayoutInflater.from(getContext()).inflate(R.layout.base_layout, null);
LinearLayout linearLayout = (LinearLayout) view.findViewById(R.id.base_layout_children);
while(0 < getChildCount())
{
View child = getChildAt(0);
LinearLayout.MarginLayoutParams layoutParams = (MarginLayoutParams) child.getLayoutParams();
removeViewAt(0);
linearLayout.addView(child, layoutParams);
}
this.addView(view);
}
Is there a better, cleaner approach to capsule the xml and reuse a basis layout? How do I fix the match_parent issue?
While writing this post and thinking hard how to explain best, the solution for the match_parent issue became clear. Though the question remains if there is a better approach for the whole problem.
//Solution:
this.addView(view, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
//wrong:
this.addView(view);
Suppose you have two layout files. common_views.xml and layout_main.xml. You can include content of one layout file into another like this.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<include
android:id="#+id/common"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
layout="#layout/common_views" />
<WebView
android:id="#+id/webView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="#+id/common"
>
</WebView>
</RelativeLayout>

Insert TextView in other XML file than current ContentView

I want to insert a TextView into a LinearLayout that's in a different XML file that is being used as layout for a ListView. But it seems that I can't access the LinearLayout that's in the other XML file.
I run a loop that gets category titles, and for each title I wanna create a TextView with the title.
How I insert the TextView
LinearLayout Layout = (LinearLayout) findViewById(R.id.itemDesign); //When debugging I can see "Layout" is just null. itemDesign is also not in main.xml.
TextView title = new TextView(this);
title.setText(CatName);
Layout.addView(title);
XML used by ListView "single_list_item.xml"
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/itemDesign"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<!-- Name Label -->
<TextView android:id="#+id/name_label"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="25dip"
android:textStyle="bold"
android:paddingTop="10dip"
android:paddingBottom="10dip"
android:textColor="#43bd00"/>
<!-- Description Label -->
<TextView android:id="#+id/email_label"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#acacac"/>
</LinearLayout>
It sounds like you need to inflate your view. In getView() of adapter class
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.your_layout, parent, false);
Then to access your TextViews
TextView firstTV = (TextView) rowView.findViewById(R.id.some_id);
All about LayoutInflater
I guess, you are not setting the activity content view before using findViewById():
setContentView(R.layout.myLayout);
After that initialize your text view, and add width, height params to that. Then there should be no problems in adding that text view to the layout.
Maybe you should try invalidating the layout after you add the TextView:
Layout.addView(title);
Layout.invalidate();
I'm still not entirely sure what you want to achieve, maybe you could give us some more information regarding what you want to accomplish?
If you want to make a new ListView item based on an xml file, you need to inflate it first. Then you can call findViewById() on the resulting view to get the children.
LayoutInflater inf = LayoutInflater.from(getContext());
LinearLayout listItemLayout = (LinearLayout)inf.inflate(R.layout.single_list_item, null);
TextView nameLabel = (TextView) listItemLayout.findViewById(R.id.name_label);

Android ScrollView in dialog doesn't show the top of the inner TableLayout when rotating

I have the layout of a configuration dialog in an XML like this:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/timerConfigurationDialog"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TableLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:scrollbars="vertical" >
...
</TableLayout>
</ScrollView>
And I use the following code to inflate it:
LayoutInflater inflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.timer_configuration_dialog,
(ViewGroup) findViewById(R.id.timerConfigurationDialog));
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setView(layout)
.setTitle(R.string.configure)
...;
When I test it in the emulator there is no problem when the screen is vertical because all the components of the dialog are visible but, when the screen is horizontal, the first row and the upper half of the second row are not visible (and, of course, they are out of the reach of the scroll).
I have tried different combinations of layouts without success... any help will be appreciated!!
Thanks in advance,
Raúl
As there were no answer, I have changed the layout of the dialog. Now, I don´t use the TableLayout inside the ScrollView... instead I have a LinearLayout inside the ScrollView, so there is no problem with the dialog when the user rotates the screen.

reinflating Viewstub

I have a problem.
I slip my Screen in two areas with 2 ViewStubs.
But if i inflated the ViewStubs they are no more accessible and i can't inflate an other View within this ViewStub.
So what is an alternative to use these kind containers.
Here some Code. You all love Code:
ViewStub contentSpace = (ViewStub) findViewById(R.id.ContentSpace);
contentSpace.setLayoutResource(R.layout.view1);
contentSpace.inflate();
contentSpace.setInflatedId(R.id.Content);
RelativeLayout content = (RelativeLayout) findViewById(R.id.Content);
contentSpace.setLayoutResource(R.layout.view1); //crash
contentSpace.inflate();
It seems like ViewStub can't be re-inflated. It is designed to be inflated just once, then it is removed from the View hierarchy. More details here: https://stackoverflow.com/a/11579271/752781
Here my Solution
rootLayout is a linear Layout where may ViewStubs were located.
rootLayout.removeView(contentLayout);
inflater.inflate(R.id.view1, rootLayout);
contentLayout = findViewById(R.id.contentLayout);
view1:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:id="#+id/contentLayout">
[...]

How to get a view from a resource?

I have a UI, I build it dynamically. I should want to put some component in a xml resource file. So I do :
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+android:id/titreItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
... in a file res/layout/titreitem.xml as I see anywhere. But I don't understand how get it to put inside my UI. So, inside activity.onCreate, I want to do something like :
RelativeLayout myBigOne = new RelativeLayout(this);
TextView thingFromXML = [what here ? ];
myBigOne.addView(thingFromXML);
setContentView(myBigOne);
Use a LayoutInflater....The Entire Layout can be inflated, without dynamically creating it....
LayoutInflater li = LayoutInflater.from(context);
View theview = li.inflate(R.layout.whatever, null);
Approach seems to be little incorrect. You should put RelativeLayout to the xml as your TextView made, and inflate the whole xml. Afterwards, you will be free to add views to your layout. So, do this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="#+androi:id/relLayout>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+android:id/titreItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
</RelativeLayout>
In your activity:
setContentView(R.layout.titreitem);
RelativeLayout layout = (RelativeLayout)findViewByid(R.id.relLayout);
layout.addView(...);

Categories

Resources