how to assign data to include layout in xml? - android

Assume we have a layout contains a TextView:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView android:id="#+id/text1"
style="#style/text_style"/>
</LinearLayout>
and then include this layout several times:
<include android:id="#+id/info1" layout="#layout/myLayout" />
<include android:id="#+id/info2" layout="#layout/myLayout" />
<include android:id="#+id/info3" layout="#layout/myLayout" />
Is it possible to assign text into each TextView in the xml file which contains these layouts?
If not, then how to assign in runtime?

You can, For this you need to identify you layout
LinearLayout info1 = (LinearLayout)findViewById(R.id.info1);
Then with this layout object you need to identify you TextView
TextView text1 = (TextView)info1.findViewById(R.id.text1);
text1.setText("Your text");

Related

Include same layout multiple times

I have a common layout (common.xml) which I want to include many times in another layout (layout_a.xml). But it only shows me just one time. Why?
common.xml
<merge xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#android:drawable/alert_light_frame">
<ImageView
android:layout_width="match_parent"
android:layout_height="150dp"
android:id="#+id/imageView"
android:src="#drawable/test"
android:scaleType="centerCrop" />
<TextView
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_below="#+id/imageView"
android:id="#+id/textView"
android:text="test"
android:layout_marginTop="10dp"
android:layout_marginRight="10dp"
android:layout_marginLeft="10dp" />
</RelativeLayout>
</merge>
layout_a.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="#layout/common" />
<include layout="#layout/common" />
</LinearLayout>
The ids when defined in XML must be unique. You are including two layouts that have views that contain the same id.
Here is how you would go about fixing it.
p.s. Unless there is more code that you are not including in your first layout file, that merge tag is useless.
As btse said, the ids in the XML must be unique.
It can be achieved in this way:
<include android:id="#+id/common1"
layout="#layout/common" />
<include android:id="#+id/common2"
layout="#layout/common" />
For information about how to access the elements inside those two included views, you can check out this blog post.
That's what I had done in my Project with Inflater.
test1is just a Layout made with a LinearLayout(Vertical) with text and a button and mainofferslayout in that case, the main layout with an image.
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_offers_display, container, false);
View inflatedLayout = inflater.inflate(R.layout.test1, (ViewGroup) view, false);
LinearLayout ll = (LinearLayout) view.findViewById(R.id.mainofferslayout);
ll.addView(inflater.inflate(R.layout.test1, (ViewGroup) view, false));
ll.addView(inflater.inflate(R.layout.test1, (ViewGroup) view, false));
ll.addView(inflater.inflate(R.layout.test1, (ViewGroup) view, false));
I fixed by setting the layout_height of the RelativeLayout to 250dp since they are overlapped.

Margin does not impact in "include"

I have a view with articles. It uses "include", and I'm trying to make a little margin between them. However, "android:layout_marginTop" does not seem to have any impact on the layout.
What am I doing wrong?
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<include android:id="#+id/article1" layout="#layout/mainarticle" />
<include android:id="#+id/article2" android:layout_marginTop="10dip" layout="#layout/article" />
<include android:id="#+id/article3" android:layout_marginTop="10dip" layout="#layout/article" />
<include android:id="#+id/article4" android:layout_marginTop="10dip" layout="#layout/article" />
<include android:id="#+id/article5" android:layout_marginTop="10dip" layout="#layout/article" />
</LinearLayout>
You should add the android:layout_width and android:layout_height attributes in the include tag. Otherwise, the margins are not taken into consideration.
However, if you want to override layout attributes using the <include> tag, you must override both android:layout_height and android:layout_width in order for other layout attributes to take effect.
https://developer.android.com/training/improving-layouts/reusing-layouts.html#Include
I had the same problem and the answer from Kamen Goranchev doesn't work for me.
I have used ADT's feature "Extract include..." from the layout editor to extract some commonly used badges as a list of TextView-elements. So the Extract-include-tool wrapped my TextView-Elements in a merge-tag, which usually would be fine.
But, according to the very helpful sourcecode-link from boiledwater I see in line 888 https://github.com/android/platform_frameworks_base/blob/master/core/java/android/view/LayoutInflater.java#L888, the layout-attributes from the include-tag itself are only parsed if the include doesn't have the merge-tag as its root-element.
So I removed the merge-tag from the include and used another ViewGroup-tag like e.g. FrameLayout. Then the margins in the include-tag are working as expected.
include tag support below properties:
Any android:layout_* attributes which you can overwrite.
android:id attribute.
layout attribute.
android:visibility attribute.
Etc:
include android:id=”#+id/news_title”
android:layout_width=”match_parent”
android:layout_height=”match_parent”
layout=”#layout/title”/>
Please read:
https://github.com/android/platform_frameworks_base/blob/master/core/java/android/view/LayoutInflater.java#L777
http://developer.android.com/training/improving-layouts/reusing-layouts.html
Another solution would be to add Space before include:
<Space
android:layout_height="8dp"
android:layout_width="match_parent" />
must insert include into other layout.
e.g. Relativelayout
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="15dp">
<include
android:layout_width="match_parent"
android:layout_height="match_parent"
layout="#layout/sub_edit_new_customer" />
</RelativeLayout>
In my case I solved the problem by adding some padding.
The layout you want to include:
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="15dp"> <!-- add padding here -->
<!-- your custom layout -->
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

Creating XML Layout file composed from other XML files?

I know this can seem a weird question but for me it would be really handy if I could compose a layout XML from a set of other xml files pointed by the main XML file. The reason is that I have some list item views defined in this xml and would like to reuse then in other places. Is it possible or the only way to do it is just Coping and pasting it?
You can include different layout files in a single layout using the 'include' tag
<LinearLayout>
<include layout="#layout/toinclude1" />
<include layout="#layout/toinclude1" />
</LinearLayout>
Another way is the ViewStub. If you want to load asynchronously your layout you can have:
<ViewStub android:id="#+id/stub"
android:inflatedId="#+id/subTree"
android:layout="#layout/mySubTree"
android:layout_width="120dip"
android:layout_height="40dip" />
And the in your code when you want you can write:
ViewStub stub = (ViewStub) findViewById(R.id.stub);
View inflated = stub.inflate();
For some reference: http://developer.android.com/reference/android/view/ViewStub.html
Say you have a header.xml like this
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/somestyle" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:clickable="false"
android:paddingLeft="15dip"
android:scaleType="center"
android:src="#drawable/logo" />
</LinearLayout>
You can use <include layout="#layout/header"/> to include the header layout code in many layouts.
main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/home_root"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<include layout="#layout/header"/>
</LinearLayout>
Fragment is good option. Here is an example: http://mobile.tutsplus.com/tutorials/android/android-sdk_fragments/
and document: http://developer.android.com/guide/components/fragments.html

Include a TextView and override the text

I have a TextView I use as the headline of my menu page:
<TextView
android:id="#+id/menuTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Menu"
android:textColor="#color/white"
android:textSize="25sp"
android:textStyle="bold" />
Now I need a TextView with the same color, size and style on every sub menu in my app. Instead of copy pasting the whole TextView to every layout and just change the text in each one I thought I'd make one layout with the TextView and include it in every sub menu view, only overriding the text.
My code looks like this:
/layout/menutextview.xml:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/menuTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/default"
android:textColor="#color/white"
android:textSize="25sp"
android:textStyle="bold" />
The includes in each layout xml file tries to override the text attribute:
<include layout="#layout/menutextview" android:text="#string/menu" />
<include layout="#layout/menutextview" android:text="#string/settings" />
But the default text is displayed everywhere. Anyone have an idéa of what the problem might be?
Regards,
Mattias
Include cannot be used to "overrride" children properties. It doesn't know which type of layout you will include, it will only inflate it and add it to the current layout.
To dynamically change the text, you need to do it in code.
final TextView textView1 = (TextView) findViewById(R.id.menuTextView);
textView1.setText(R.string.menu);
final TextView textView2 = (TextView) findViewById(R.id.settingsTextView);
textView2.setText(R.string.settings);
Try using styles and have the TextView implement that style. This will make it easier to maintain consistency in your Views.
You can achieve this with DataBinding. First you define a variable in your child layout:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="buttonText"
type="String" />
</data>
<android.support.v7.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#{buttonText}"/>
</layout>
Then you set it in the other layout file where you include it:
<!-- .... other views -->
<include
layout="#layout/inc_icon_button"
bind:buttonText="#{`Put your String here`}" />
<!-- .... other views -->
Best case you would also have a variable in your parent layout to then just forward the binding.
You could use the following solution:
Give the include tag and the TextView in the include layout a specific id (like "section")
Declare the include tag as a view and a TextView in your code View section; and TextView textview;
Bind the View with the id of your include section = findViewById(R.id.section);
Bind the TextView of your include with View.findViewById();
textview = section.findViewById(R.id.textview);
I used the information from this side.

import xml into another xml

I have lots of control repeated in my xml (a Button for instance). Is there any possibility to write the Button once in a xml and then import it in all the layout I need it?
You can use
<include layout="#layout/commonlayout" android:id="#+id/id" />
commonlayout.xml should be defined in res/layout where you can add the repeated parts.
As Labeeb P rightly said, it works.
Just want to add that you can also override parameters too:
<include
layout="#layout/commonlayout"
android:id="#+id/id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="2sp"
android:layout_marginRight="2sp"
/>
In addition to those great answers, you can also avoid code duplication by using the <merge> tag, like so:
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/add"/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/delete"/>
</merge>
The <merge> part gets stripped when you include it into other xml. This might help including more than a single Button at a time. See the official documentation.
You can use the default include XML tag to include an external layout:
<include layout="#layout/somelayout" />
This layout should have an outside ViewGroup that encapsulates the content or a merge tag to avoid having to use an unnecessary layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/hello_world" />
</LinearLayout>
<!-- OR -->
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<TextView android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/hello_world" />
</merge>
Also, if you need a better way to include pieces of layout that acts like a container (a custom ViewGroup), you can use this custom ViewGroup. Note that this does not import an XML into another XML file, it inflates the content from the external layout and replaces into the view. It's similar to ViewStub, a "ViewGroupStub" like.
This lib acts as if the ViewStub could be used as following (note that this example does not work! ViewStub isn't a ViewGroup subclass!):
<ViewStub layout="#layout/somecontainerlayout"
inflate_inside="#+id/somecontainerid">
<TextView android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/hello_world" />
</ViewStub>

Categories

Resources