I've been learning about merge and include lately, and I have a question I can't seem to figure out the answer too. Say I have a layout that defines a header component that I want to add to multiple layouts. However, I want to change the title, or icon of each header per each include usage. For example say I have the following layout:
<RelativeLayout android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="#style/menu_header">
<Button android:id="#+id/backButton"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#style/button"
android:text="#string/back"/>
<TextView style="#style/headerTitle"
android:layout_centerInParent="true"
android:text="${title}"
android:layout_height="wrap_content"
android:layout_width="wrap_content"/>
</RelativeLayout>
Then I can include that in other layouts using:
<LinearLayout ...>
<include android:id="#+id/searchHeader" layout="#layout/shared_header" title="Search"/>
...
</LinearLayout>
I know I can modify any layout_* attribute of the root element, but can I define other attributes that get substituted into the layout, like say "title" in this example, without having to create my own subclass of View, add declare-styleable definitions in valaues/resources, etc?
Having something like this would make creating reusable views so much simpler, but I can't seem to find any evidence that says if merge + include can do it.
The answer is nope. Unfortunately, Android isn't that powerful. You have to create your own extension of ViewGroup and write more code.
Related
Just wanted to ask a quick question. Here is an example XML tag. Which is the proper way to end it and what are the differences between both?
<TextView **code** />
<TextView> **code** </TextView>
XML in general
Attributes may appear <TextView here /> or <TextView here >...</TextView>— typically used for scalar values.
Elements (or text) may appear <TextView> here </TextView>— typically used for values with substructure.
For empty elements, <TextView/> and <TextView></TextView> are equivalent.
Android Layout XML
Android XML uses both elements and attributes and generally follows the common guidance that elements be used when further substructure is required and attributes be used for scalar values. See the documentation for details.
See also
XML Element vs XML Attribute
Both are acceptable. The one you use depends on what you are doing. For example, a <LinearLayout> tag will contain other tags nested inside, so you use the 2nd version. For example, if you include two TextViews inside, it looks like this:
<LinearLayout>
<TextView />
<TextView />
</LinearLayout>
On the other hand, a <TextView> never contains other tags inside it, but will have attributes:
<TextView
android:id="#+id/text_view_id"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="#string/hello" />
As you work more with Android's XML layouts, you will start to see patterns and get the hang of which of these you will use in a given situation.
I'm confused about why we need the + in some sibling references but not others to make views render correctly in the android studio preview pane. (The behaviour when viewing in a running app differs, so is not in scope)
From the android guide docs under the ID section: The plus-symbol (+) means that this is a new resource name that must be created and added to our resources (in the R.java file).
From the Relative Layout Params docs android:layout_toLeftOf
Positions the right edge of this view to the left of the given anchor view ID. May be a reference to another resource, in the form "#[+][package:]type/name"
From Relative Layout Examples :
In your XML layout, dependencies against other views in the layout can be declared in any order. For example, you can declare that "view1" be positioned below "view2" even if "view2" is the last view declared in the hierarchy. The example below demonstrates such a scenario.
<?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"
android:paddingLeft="16dp"
android:paddingRight="16dp" >
<EditText
android:id="#+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/reminder" />
<Spinner
android:id="#+id/dates"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_below="#id/name" <- no + as 'name' already declared?
android:layout_alignParentLeft="true"
android:layout_toLeftOf="#+id/times" /> <- + present as times not declared yet?
<Spinner
android:id="#id/times"
android:layout_width="96dp"
android:layout_height="wrap_content"
android:layout_below="#id/name"
android:layout_alignParentRight="true" />
<Button
android:layout_width="96dp"
android:layout_height="wrap_content"
android:layout_below="#id/times"
android:layout_alignParentRight="true"
android:text="#string/done" />
</RelativeLayout>
All this info leads me to believe that the + symbol is only used when referencing siblings, if the sibling is declared after the reference?
However this doesn't appear to be the case in my project:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/bg_grey_light"
android:paddingBottom="10dp">
<ImageView
android:id="#+id/img"
android:layout_width="match_parent"
android:layout_height="220dp"
android:adjustViewBounds="true" />
<TextView
android:id="#+id/some_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/img" <- This needs a + to render correctly..
android:text="#{some.name}"/>
</RelativeLayout>
So what is the rule for the + symbol, and is there any solid documentation that i've missed?
From the docs:
The at-symbol (#) at the beginning of the string indicates that the
XML parser should parse and expand the rest of the ID string and
identify it as an ID resource. The plus-symbol (+) means that this is
a new resource name that must be created and added to our resources
(in the R.java file). There are a number of other ID resources that
are offered by the Android framework. When referencing an Android
resource ID, you do not need the plus-symbol, but must add the android
package namespace, like so:
android:id="#android:id/empty"
Defining IDs for view objects is important when creating a
RelativeLayout. In a relative layout, sibling views can define their
layout relative to another sibling view, which is referenced by the
unique ID.
An ID need not be unique throughout the entire tree, but it should be
unique within the part of the tree you are searching (which may often
be the entire tree, so it's best to be completely unique when
possible).
Hope it will help you.
<- This needs a + to render correctly..
In preview mode, in your case it should render without without a +.
Try adding the tools namespace in the root layout as:
xmlns:tools="http://schemas.android.com/tools"
and then in your TextView:
tools:text="Some name"
<RelativeLayout ..>
...
...
<Space
android:id="#+id/space4"
android:layout_width="match_parent"
android:layout_height="5dp"
android:layout_below="#+id/numberOfPersons" />
<TextView
android:id="#+id/txtCostPerPerson"
android:labelFor="#+id/costPerPerson"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/space4"
android:layout_alignBottom="#+id/costPerPerson"
android:layout_alignTop="#+id/costPerPerson"
android:gravity="center_vertical"
android:text="#string/costPerPerson"
android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText
android:id="#id/costPerPerson"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_toEndOf="#+id/txtCostPerPerson"
android:layout_below="#+id/space4"
android:inputType="number" />
</RelativeLayout>
The above xml code snippet has TextView having attribute labelFor="#+id/costPerPerson" whose value is the id of the EditText that follows below.
I'm confused on the convention of weather I should use the way it is now, or should the #+id be used in EditText and it is referenced other way here, if so what is it? What is right and less error-prone approach that the community follows? Thanks in advance!
If you are using an IDE and its graphical layout editor, you're probably letting it handle these things.
In cases where you are doing this work more by hand, the long-standing guidance has been to put the + on the first occurrence of the ID, top-down, in the layout file. In your case, costPerPerson appears first in android:labelFor of the txtCostPerPerson TextView, and so your code is following this convention.
I am new to Android, and wish to do a layout as below:
A Logo on top.
Following with a Rectangle with Rounded corners
Within that Rectangle, I will have two EditText box for User ID and Password, plus one Login button
Below the Rectangle with Rounded corners (outside) I have a Html Link to Terms & Conditions
I have tried various ways of layout out
Using only layout. Different kinds of layouts. All seems to be very difficult to achieve what I need
Using Layout + Background. The background is not really a background, but is more like a template, it will affect your layout, and is very difficult to control where you wants your control located.
Using onDraw. Flexible but worried that it might have problem with different screen sizes.
So, someone please enlight which is the best way to achieve what I need?
No one can really tell you what is best, it depends on exactly what you want but I would suggest using a RelatvieLayout as they are typically the easiest and most efficient to use once you work with them a little, in my opinion. You can read Here to see how to do the rectangle. You basically will use shape drawable and adjust the radius of the corners.
As far as the logo on top, if it will be reused in other Activitys then you can put it in its own layout and use the include tag in your layouts to reuse the logo layout
If you are worried about different screen sizes then read the Docs and find what works for you.
Just start on it and adjust as you go. Don't be afraid to screw up and redo some of it. Hopefully this is enough information to get you started
Using a RelativeLayout will give you more flexibility and allow you to use less Layouts such as nested LinearLayouts and Layouts with only one child which can improve performance
this is how it should be done:
start with linear layout with vertical orientation :
<linearLayourt xmlns=............
android:orientation="vertical"
.....other stuffs goes here
......
.....
<LinearLayout ......this is the child linearlayout
.....other stuffs goes here like width and height
<ImageView ...this is where you are gonna put your logo in
/>
</LinearLayout> ....close your child linear layout
<RelativeLayout ...
.........other stuffs here
<EditText ....1st edit text
...you position your boxes here
/>
<EditText ....2nd edit text
...you position your boxes here
/>
</RelativeLayout>
<TextView
....
...
...put yout hyperlink for this text
/>
</LinearLayout> ...this is the parent linear layout
For your case of creating a Log in screen it's not really matter as it is a relatively easy screen to design. I personally like to use XML to design my layouts and never seen it done using the onDraw method.
My suggestion to you as #codeMagic said is to learn how to use and manipulated RelativeLayouts,as those will prevent you from creating cascaded layouts that are really not recommended and take long time to load.
When I started to program for Android I found LinearLayout to be the easiest to understand and use but using it would bring me to many LinearLayouts inside of a LinearLayouts on complex screen designz, later with the use of RelativeLayout I realized that in most cases one RelativeLayout can replace many cascaded Linear ones.
in your case you could do some thing like that:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:src="#drawable/drop_down_icon" />
<EditText
android:id="#+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_below="#+id/imageView1" >
</EditText>
<EditText
android:id="#+id/editText2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_below="#+id/editText1" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/editText2"
android:layout_centerHorizontal="true"
android:text="Button" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/button1"
android:layout_centerHorizontal="true"
android:text="TextView" />
</RelativeLayout>
All what left is to add the desired padings and margins.
I'm trying to make an Android layout like the one below. I have a couple of questions:
1 - what is the element called that FB uses for posts? Ie, it doesn't look like a text view, but the element looks like it separates each post with a divider line. Also, the text style is different for a person's name and how long ago they posted. I'm looking to duplicate this (minus pictures) but I can't find the right UI elements.
What is the element called at the bottom? It's like a static menu. IE, it's the same as a menu but instead of pressing "menu" to access it, it's on the page at all times.
Finally, are there good tutorials/examples on how to make nice looking, professional layouts like the apps on the market? The tutorials that I've found on layouts are really basic. I'd like to understand what elements exist, what all of the attributes mean and see examples, etc. So far I'm only able to see the capabilities from other applications. I'd like to have a handbook or some type of some type of reference manual to go to.
For the "fancy" text views you can make a linear layout that hosts a <RelativeLayout>:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_weight="0">
<ImageView
android:id="#+id/userPhoto"
android:layout_height="64dip"
android:layout_width="64dip"
/>
<TextView
android:id="#+id/userFullName"
android:layout_height="25dp"
android:layout_width="fill_parent"
android:layout_marginLeft="70dp"
/>
</RelativeLayout>
Once you have a relative layout you can add different views inside of that to create a sort of customeized view.
As far as good examples I would look at this book. It's easy to understand and very helpful on such things.
I found a really helpful tutorial to solve a problem in ListView Row design a bit like yours. It goes a bit further explaining how to do Async Image loading but the first part should help you.
Also, I might be wrong (I am still a bit new to this) but I think the answer above lacks a TextView for the actual message besides the userName and the relative positions of the elements since it is a relative layout. Something like:
<TextView
android:id="#+id/userName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#id/userPhoto"
android:layout_toRightOf="#id/userPhoto"
android:textSize="17dp"
android:textStyle="bold" />
<!-- actual message -->
<TextView
android:id="#+id/message"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/userName"
android:layout_marginTop="1dip"
android:layout_toRightOf="#id/userPhoto"
android:textSize="15dp" />
The key in organizing a relative layout is:
android:layout_alignTop="#id/userPhoto"
android:layout_toRightOf="#id/userPhoto"
and
android:layout_below="#id/userName"
android:layout_toRightOf="#id/userPhoto"
I might be wrong but if it helps, great! Just adding my bit to the other answer.
Cheers