Android layout <include /> tag - android

i want to use include tag in my xml layout to recycle a common layout part.
Android documentation says i can modify some attribute of imported layout, for example
<include layout="#layout/topbar" />
Include topbar layout without specify width and height.
<include layout="#layout/topbar" android:layout_width="fill_parent" />
Include topbar layout with specific width.
So, in my topbar layout, i've a textview without text, can i set textview text from include tag like below?
<include layout="#layout/topbar" android:text="Hello world" />
Thank you.

No, you'll need to do this in code. In your activity, call findViewById() to find the TextView, then call TextView.setText() to set the text.

Related

Android, Reusing Not Layouts, But Views via XML

I have a button I use a lot in one of my layouts. Or rather, I have like ten buttons all with the same text color, background color, text size, width, and height. I don't want to define all of these parameters for each button. So I want to be able to write something like...
<include view="#layout/standard_button"
android:id="#+id/button-id"
android:text="button-specific-text"/>
But of course, there is no include view="", there is only include layout, and include layout the xml file as a Layout, not a View, so setting the text is not possible and when I findViewById() in my activity, it would refer to a Layout and not a View.
Is there something like <include view="... ?
You can create a layout with your customized style button that you want to use multiple times, and wrap it in a <merge> tag like below sample.
And then you can reuse it over and over again using the include tag in any other layout.
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</merge>
Usage within any other layout, assuming the top layout named as my_button.xml
<include layout="#layout/my_button" />

How do I avoid repetitive TextView code?

I want to include the below layout in a main layout file, at multiple points, but at each usage, I want to change ONLY the "android:text" attribute of the text view inside the relative layout (as seen below). How can I achieve that?
P.S. I know how to include it in the main layout. This includes the relative layout (as seen below), but the main purpose of creating another layout file is because the code (of the textview) is being repeatedly used in the main layout, and the only attribute that differs is "android:text" between these repeated text views.
<?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">
<TextView
android:id="#+id/order_id_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="test"
android:fontFamily="sans-serif-light"
android:padding="20dp"
android:textSize="20sp"
android:textStyle="bold" />
</RelativeLayout>
in your another Layout file you can use this .
<include layout="#layout/main_layout"/>
And From your activity class you can set text by this.
TextView tv = (TextView) findViewById(R.id.order_id_label)
tv.setText("New Text");
This is the only way you can do this .
If all TextView element arguments are the same you could define this component in a separate file using <merge> </merge> directive and then <include layout="" />
Check here how to reuse
But if any of the TextView argument is changing, i.e. android:text attribute, the best way is to separate all other TextView attributes to custom style and reuse this custom style in different xml layout files
Check here how to use styles

Is is possible to view two xml at the same time in Android?

Is is possible to view two xml at the same time in Android? Suppose xml1 contains an ImageView and xml2 contains another ImageView. Likes to view both images at the same time sharing half of the total window size
Try using the include feature: http://developer.android.com/resources/articles/layout-tricks-reuse.html
Here's an example that might work for you (make sure you put these inside of a root layout tag, like LinearLayout, as if they were any other View items):
<include android:id="#+id/image1" layout="#layout/xml1" />
<include android:id="#+id/image2" layout="#layout/xml2" />
The ids can be whatever you want, but the layout must match the name of the separate XML file in your project.
As far as making each one take up exactly half the screen at the same time, you'll want to try setting the weight for each one to the same value. See the example here: Assign width to half available screen width declaratively
So like this:
<include android:id="#+id/image1" layout="#layout/xml1" android:layout_weight="1" />
<include android:id="#+id/image2" layout="#layout/xml2" android:layout_weight="1" />
You might also need to add android:layout_height or layout_width (depending on whether your layout is vertical or horizontal) set to fill_parent to get your desired effect.
we can see both xml files in one window .But at a time we modified only one xml file only,
Use the below poperty in Activity tag in manifest file
android:theme="#android:style/Theme.Translucent.NoTitleBar.Fullscreen"

How would I display one view as an overlay of another?

I have two views that take the whole screen and I want to display both views at the same time, one on top of the other. My layout looks like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<WebView
android:id="#+id/webview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
<org.example.myCustomView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
Note that myCustomView uses onDraw (this method last statement is invalidate()) to draw custom graphics. The problem I am getting is that it only displays myCustomView, WebView is hidden. I tried to change the background colour of mycustomView to transparent but this makes no difference.
I would also like to have the ability to make myCustomView as an overlay on WebView or vice versa.
Use a RelativeLayout for starters.
You could use the ViewGroup.addView(View child, int index, ViewGroup.LayoutParams params) or a variant along with ViewGroup.removeView(View view) or ViewGroup.removeViewAt(int index).
This would obviously require you to inflate the views manually using LayoutInflater but you could keep a global reference to each after inflating and just flip between the two.
I'm not sure if you can do this when they are in the same xml file, but I know that if you move:
<org.example.myCustomView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
to another xml file, and create another activity. set the content view to the xml file that contains the org.example.myCustomView and call that activity. in the manifest, when you add that activity, add a theme statement as so:
android:theme="#android:style/Theme.Dialog"
the full statement should look like this:
<activity android:name=".name_of_activity"
android:label="TextToBeOnTop"
android:theme="#android:style/Theme.Dialog">
</activity>
the result will look like this (only it will be with your components instead):
although it mabey possible to do it when they are still in the same xml file. if it is possible, it would likely be done by leaving the manifest alone, and editing your costomeView to the following:
<org.example.myCustomView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:theme="#android:style/Theme.Dialog" />
(I added the theme statement into the CustomView )
if this isn't what you are looking for, than I would recoment something simmilar to what Nick Campion said, which was to change fillParent to wrapContent.
you could do that, or you could choose what size you wanted it to be. here are two options you could use:
<org.example.myCustomView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="50dip"
android:layout_height="50dip" />
(you could change "50dip" to whatever number you want as long as it ends with dip)
or:
<org.example.myCustomView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
The term fill_parent means consume all the allowable space in the parent. Try setting it to wrap_content. Then you can try adding weight = 1 to both to try to evenly distribute the remaining space.

How to specify id when uses include in layout xml file

In my layout xml file, I have included other layout xml file (each
with a different android id).
<include layout="#layout/view_contact_name" android:id="+id/test1"/>
<include layout="#layout/view_contact_name" android:id="+id/test2"/>
But when I run it in the emulator, and start Hierarchy Viewer, each of
the layout still shows 'NO_ID', and in my code, I have
findViewById(R.id.test1) and findViewById(R.id.test2) both returns null.
Can anyone please help me with my problem ?
Specify the ID in the <include>
<include layout="#layout/test" android:id="#+id/test1" />
Then use two findViewById to access fields in the layout
View test1View = findViewById(R.id.test1);
TextView test1TextView = (TextView) test1View.findViewById(R.id.text);
Using that approach, you can access any field in any include you have.
I found out, that if you are using <merge> tag in your include layout, then the ID of include transfers to the merge tag which is not real view.
So either remove merge, or replace it with some layout.
Tor Norbye wrote:
The <include> tag is not a real view, so findByView will not find it. The #id attribute (and any other attributes you've set on the include tag) gets applied on the root tag of the included layout instead. So your activity.getView(R.id.included1) should in fact be the <TextView> itself.
Romain Guy indicates that you can override the ID of an included layout by putting an android:id attribute inside the <include> tag.
<include android:id="#+id/cell1" layout="#layout/workspace_screen" />
I think the top answer misses the most important point and might mislead people into thinking the <include/> tag creates a View that holds the include contents.
The key point is that include's id is passed to the root view of the include's layout file.
Meaning that this:
// activity_main.xml
<include layout="#layout/somelayout" android:id="#+id/someid"/>
// somelayout.xml
<?xml version="1.0" encoding="utf-8"?>
<ImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
Becomes this:
// activity_main.xml
<ImageView
android:id="#+id/someid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
yes is like this, but careful when the layout inserted in include field is a custom one and you want to access that root layout. That layout in this case #layout/test test, is actually returned in first line.
test test1View = (test)findViewById(R.id.test1);
you must set id each include tag
included child element set a
new id. if you look how to generate new id, look at this entry:
https://stackoverflow.com/a/15442898/1136117
Problem is we try to use id which is not declared in current layout file.
Instead of declaring again, id can be simply referred using #+id/. If you refactor original id name through Android Studio it does refactor in included layout as well.
<include layout="#layout/toolbar"/>
<TextView
android:id="#+id/txt_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
**android:layout_below="#+id/toolbar"**
android:layout_marginTop="16dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"/>
In a case of using <RecyclerView> find the id of <include> by using an instance of inflated view or else it will return null.
public class ViewHolder extends RecyclerView.ViewHolder {
private mTextView;
public ViewHolder(View view) {
super(view);
View include_1 = view.findViewById(R.id.include_1);
mTextView = (TextView) include_1.findViewById(R.id.text_id);
}
}
If you have set id to either root tag of included layout then you can use that id
or you can set id to included layout.
But you can not set id to both it may throw exception.
<include layout="#layout/view_contact_name" android:id="+id/test1"/>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
....
</LinearLayout>
Or
<include layout="#layout/view_contact_name"/>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="#+id/llBottomMainView"
android:layout_width="match_parent"
android:layout_height="wrap_content">
....
</LinearLayout>
When talking about include you either have an id on the root view inside the included layout file or on the include line itself and not on both. For example:
<include layout="#layout/layout1" android:id="#+id/layout1"/>
Layout 1 file
<RelativeLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/layout2">
</RelativeLayout>
The above example is wrong because technically you have two id's declared for the same layout. So what you have to do is pick which element will have the id.
To specify the id when you are including a xml file is like setting it to any xml element
Example:
*list_layout.xml*
`<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rvNames"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>`
*activity_main.xml*
`<RelativeLayout
tools:context=".MainActivity">
<include
layout="#layout/list_layout"
android:id="#+id/myList" />
</RelativeLayout>`
Now if you want to get that to use in .kt file, just use normally findViewById
Exemplo
*MainActivity.kt*
`val myList: RecycleView = findViewById(R.id.myList)`
Wow, I can't believe this question doesn't have the right answer yet. It's simple tags suck. You can only change things that start with android:layout_ which android:id doesn't match. So the answer is you can't. Sorry. What you can do instead is create a class that will be a ViewGroup which will inflate the included views inside, then add that as a tag in your layout, but that's about it.

Categories

Resources