Is it possible to extend a layout? - android

In my application I need to use the RecyclerView in two different activities.
I was thinking to extend the layout, because the base layout (the recycler view) is the same for the two activities, but I don't know if it's possible.
With "to extend a layout" I mean something like this:
If this is my base_layout.xml:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/recyclerView">
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
I would like to do something like this in my child_layout.xml:
include "base_layout.xml"
<Button
android:id="#+id/btnAddVehicle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="+"
android:onClick="launchAddVehicleActivity"/>
so, the activity which uses chid_layout.xml will have got a RecyclerView and a Button inside.
Is it possible to do something like that?

You could create a generic layout, then add it on your layout's activities.
Generic Layout
my_generic_layout.xml
<RelativeLayout
android:id="#+id/generic_layout">
<RecyclerView/>
</RelativeLayout>
Layout's Activities
<RelativeLayout
android:id="#+id/layout_1">
<include layout="#layout/my_generic_layout" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/layout_2">
<include layout="#layout/my_generic_layout" />
</RelativeLayout>

just use this <include layout="#layouts/chid_layout" />

If you want to add the button inside the layout you need to write a Custom Component. See Android Documentation here https://developer.android.com/guide/topics/ui/custom-components.html#compound
Basically you could create a class which inherits from RelativeLayout which inflates base_layout.xml

Related

android - xml - include same layout multiple times does not work

I'm trying to include the following layout twice:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<com.viewpagerindicator.TabPageIndicator
android:id="#+id/indicator"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
like the following
<include
android:id="#+id/include1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
layout="#layout/view_pager" />
<include
android:id="#+id/include2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
layout="#layout/view_pager" />
Actually, the second view pager does not work if I do it like that... The second view pager always stays empty... If I copy my view_pager layout and change the ids in this layout (pager to pager2 and indicator to indicator2) everything works fine. Is there a better way to do that? Copying layouts to achieve that seems to make the include useless for multiple includes of the same layout....
I'm getting the references correctly I think, but though it just does not work if I include the same layout...
pager1= (ViewPager)(findViewById(R.id.include1).findViewById(R.id.pager));
pager2= (ViewPager)(findViewById(R.id.include2).findViewById(R.id.pager));
Everything works perfectly if I copy the layout...
Edit:
I think it has to do with the FragmentManager, because the view pagers have the same id... But I don't know how to solve that correctly...
Yes it can be done. You can inflate the layout many times, but you have to make the inclusion programmatically. See the answer to same kind of question.

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

Z-Layering Fragments in Android

It's is possible to "stack" fragments on top of each other?
Just tried to do this without really thinking about it and everything got kinda crazy.
I can (and probably should) create a ViewGroup instead if it's not possible, but I was just wondering.
Yes, it's possible. E.g. by wrapping them inside a FrameLayout like this:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<fragment android:name="com.package.FragmentOne"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<fragment android:name="com.package.FragmentTwo"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</FrameLayout>
The z-index depends on the order of the children within the layout. In this example FragmentTwo is above FragmentOne because it's the second child.

include tag in android manifest xml

how can we use include tag in layout.xml. Also by using this what are the features we can implement.
<include> </include>
include is normally used to reuse the layouts if suppose you are doing app which consists of common header and footer layouts you can use like this
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:background="#drawable/bg1" android:orientation="vertical">
<!—header layout->
<include android:id="#+id/container_header_lyt"
android:layout_height="wrap_content" android:layout_width="fill_parent"
layout="#layout/main" />
<!—contains other views in layout>
</LinearLayout>
in this case you are reusing layout main
But according to http://developer.android.com/guide/topics/manifest/manifest-intro.html no such tag is allowed

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