I need your advice regarding my design and if you have a better idea (or you agree with me) that it is good. for some reason I have a feeling it is a "stone age programming style" but lets see.
Basically I have my xml relative layout. In the center (vertical and horizenatlly). I want to display "either" 3 buttons OR 3 texts depending on some user input. So what I did is the following:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mainLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clipChildren="false"
android:clipToPadding="false" >
<RelativeLayout android:id="#+id/Buttons"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" >
<Button1 .../>
<Button2 .../>
<Button3 .../>
</RelativeLayout>
<RelativeLayout android:id="#+id/Texts"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" >
<TextView1 .../>
<TextView2.../>
<TextView3.../>
</RelativeLayout>
</RelativeLayout>
Depending on the user input in the code I set visibility to either Visible or Invisible
Is this alright? and if not what do you suggest?
What you need is View.GONE, and View.VISIBLE.
With View.GONE - the layout doesn't occupy any space (almost as if it didn't exist at all). If you use View.INVISIBLE, to the user, the view (buttons, or text in your case) will not be visible, but they will still be there on the screen, thus shifting the other view (buttons, or text) up or down (the view won't be in dead center).
TIP: You can use 'android:layout_centerInParent' instead of 'android:layout_centerHorizontal' and 'android:layout_centerVertical'.
In my opinion, what you have done may be primitive, but it is simple, which is good :) But if you still want some options and make life complicated, then
Put each of the blocks in a separate xml and use include.
Make 2 views and then use ViewFlipper to flip them based on user requirements.
But for the simple requirement that you have, I think u r doing fine.
The include option would work something like this,
layout_1.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/Buttons"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" >
<Button1 .../>
<Button2 .../>
<Button3 .../>
</RelativeLayout>
layout_2.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/Texts"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" >
<TextView1 .../>
<TextView2.../>
<TextView3.../>
</RelativeLayout>
your main_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mainLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clipChildren="false"
android:clipToPadding="false" >
<include layout="#layout/layout_1" />
<include layout="#layout/layout_2" />
</RelativeLayout>
The include helps you in making reusable layouts and also helps in keeping your xml files grow out of proportions, specially when you have complicated UIs.
First option is:
You can add all the three buttons or textviews in Linearlayout and center it in parent by using android:layout_centerInParent.
Second option is:
You can center the middle button out of all the three buttons and adjust the other two buttons with respective to the middle button. Same way we should also repeat this for textviews. In this option, we should make all the three views visibility to View.GONE explicitly.
Related
I am thinking to create a layout whose height is much more than the screen height. OK say, the parent layout is LinearLayout and it is set to provide a vertical scrollbar automatically.
Inside the parent layout, there are many controls (listview, gridview, listboxes, editboxes etc). To make it easier for design, can I put listview in one xml, gridview in one xml, listbox in one, editbox in one etc and then later use some defined function to concatenate and allocate them all in the parent layout ?
If this is not possible, how can I design a layout that has many controls allocated that design screen can't fit at design time ?
xml_common.xml
code:
<?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="#dimen/common_topheader_width"
android:background="#drawable/topheaderfor9patch" >
<ImageView
android:id="#+id/xml_common_header_imageLogotop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="2dp"
android:layout_marginRight="#dimen/common_left_right_margin"
android:src="#drawable/qarrow" />
</RelativeLayout>
///////////////////////////////////////////
Main_view.xml
Code:
<?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:background="#drawable/mainbg"
android:orientation="vertical" >
<include layout="#layout/xml_common" />
</LinearLayout>
you can set different images as per your choice set in runtime of common view.
what changes shall I make to bring the relative layout in bottom?
<?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" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="86dp"
android:layout_alignParentBottom="true"
android:layout_weight="0.08"
android:gravity="bottom" >
</RelativeLayout>
</LinearLayout>
You need to change your parent Layout to be a RelativeLayout, since the attribute android:layout_alignParentBottom does nothing for LinearLayout children:
<?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" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="86dp"
android:layout_alignParentBottom="true" >
</RelativeLayout>
</RelativeLayout>
You can achieve that by using a FrameLayout instead of a LinearLayout since it stacks childs from top to bottom by default.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="86dp"
android:layout_gravity="bottom" >
</RelativeLayout>
</FrameLayout>
use
<?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" >
<!-- replace this by any other layout or view. You might want something here, right? -->
<View android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="86dp">
</RelativeLayout>
</LinearLayout>
There are two issues here. The first being that
android:gravity
is wrong. This sets the gravity for the contents of this Views children. So for example used in a TextView it would place the text at the bottom if the TextView. What you want instead is
android:layout_gravity
this sets the Views gravity within its parent.
The second problem is that android:gravity="bottom" doesn't work as you would expect in a LinearLayout who's orientation is vertical. I'm not sure I can explain why well so I will try to find a link in a bit that explains it. But if you change the orientation of the LinearLayout to horizontal you will see this.
So your best options are to change the orientation if that's a possibility and if not then change the root ViewGroup to a RelativeLayout and use the property android:alignParentBottom="true" as someone already suggested.
Edit for explanation
This blog post and this SO answer, among others explain it a little. But basically, if the orientation is horizontal then the Views are layed out from left to right as we expect so you can't control the left and right gravity. With a vertical orientation, the same is true for top and bottom gravity because where they are placed vertically is already determined by Android when you set that orientation. I hope this makes sense.
I've decided to use 2 RelativeLayouts for my app, one Layout for one portion of child Views on the screen to the left, the other for child Views to go to the right.
The problem is I don't know how to lay them out in XML so that the middle white space isn't included when I inflate my Layout.
This is what I want.
When I use 1 RelativeLayout, the middle white space is filled with the RelativeLayout, and I can't touch anything behind it.
Thank you very much for reading.
Do something similar to the following example.
This will create a LinearLayout with 2 RelativeLayouts using layout_weight to space the RelativeLayouts and then you can populate the RelativeLayouts with whatever you want.
The Buttons are just place holders for the example.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" >
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TEST1" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" >
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TEST2" />
</RelativeLayout>
</LinearLayout>
I am new to Android and am reading Wrox's professional android 4 app dev book. In chapter 4 of the book it explains how to modify the existing text view. The problem i am facing is that the listview in my app hides the edit text box. Its hidden (can be seen in the background) but still works that is more stuff can be added to the list through it. Below is the code for my main activity xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<EditText
android:id="#+id/myEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:contentDescription="#string/addItemContentDescription"
android:hint="#string/addItemHint"
/>
<ListView
android:id="#+id/myListView"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</RelativeLayout>
and my todolist_item xml
<?xml version="1.0" encoding="utf-8"?>
<com.example.wroxexample.ToDoListItemView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:scrollbars="vertical"
android:textColor="#color/notepad_text"
android:fadingEdge="vertical"
/>
The first option you have is to use a LinearLayout instead of a RelativeLayout.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<EditText
android:id="#+id/myEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:contentDescription="#string/addItemContentDescription"
android:hint="#string/addItemHint"
/>
<ListView
android:id="#+id/myListView"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
A RelativeLayout will allow you to position the elements relatively to the others.
On the other hand a LinearLayout will position the elements one below the other in the order they appear in the xml file.
The second option you have is to keep your RelativeLayout and just add the following tag to your ListView:
android:layout_below="#id/myEditText"
This will position the ListView below the EditText.
Try this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<EditText
android:id="#+id/myEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:contentDescription="#string/addItemContentDescription"
android:hint="#string/addItemHint"
android:layout_alignParentTop="true"
/>
<ListView
android:id="#+id/myListView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/myEditText"/>
</RelativeLayout>
Use a LinearLayout and the property android:layout_weight
http://developer.android.com/reference/android/widget/LinearLayout.LayoutParams.html
Try something like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ListView
android:id="#+id/myListView"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:entries="#array/testea"
android:layout_height="wrap_content"/>
<EditText
android:id="#+id/myEditText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="#string/addItemContentDescription"
android:hint="#string/addItemHint"
/>
</LinearLayout>
This way ListView will grow to fill only the unused space.
Timothee got there before me but ill just add a little more.
you can, as he says, use a linear layout, or as user1387035 says, you can set the listview to be below the editText.
Relative Layout means "i want to lay things out relatively" and if you dont tell things where to go they will just float to where the 'gravity' is pulling them. The default gravity is top - so I'm guessing your items both ended up bunched at the top left?
As a rule of thumb - do you want your items to come one after another, bunched together (either horizontally or vertically)? if yes then use linear layout. If you want them to be pushed in different directions, use a relative layout. There are some exceptions, normally involving the "weight" attribute you can set in a linearlayout. (here's one I've just had to use: http://www.curious-creature.org/2010/08/15/scrollviews-handy-trick/)
If you have a Relative layout and are just using the layout_below/above attributes, without any 'alignParentBottom' or other thing set, then you probably just want a linearlayout
In your case I would say it sounds like you want Timothee's solution. If you want a little separation between the objects, you can use padding/margins to space them a little.
As for gravities, here is a useful blog entry that helped me get my head around LinearLayout's gravities (as well as generally): http://sandipchitale.blogspot.co.uk/2010/05/linearlayout-gravity-and-layoutgravity.html
I keep browsing different posts and they all have the footer try to stay on the screen.
But I want the footer to appear on every page. Some of my pages do not have a scroll, but some do. Whenever there is a scroll, I would like the footer to appear below the scroll. How can that be done?
For example, if I have this page:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:id="#+id/page_exlain"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Some text that either extends far down or is pretty short."
android:layout_marginTop ="20dp"
/>
</LinearLayout>
</ScrollView>
</LinearLayout>
What is a good way to add a footer to this that does not necessarily appear above the fold?
Thanks!
My way of doing this is by having two linear layouts inside the parent layout. The first one is what I call the content area and will have a weight of 1, meaning it will try to take as much space it can from the parent view. The footer layout on the other hand will have no weight and will therefor remain with a height matching the content inside even if the other view (the content area) is empty.
You can add a scrollview or any other type of layout inside the content part of this layout without breaking the disposition of the two elements and without needing to worry about the position of the footer since it will always be at the bottom of the screen.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/main"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical" >
</LinearLayout>
<LinearLayout
android:id="#+id/footer"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</LinearLayout>
With a little content added to the prior code, you end with something like this, note that it's extremely simplified. You'll have no issues modifying it to your needs as long as you understand the weight property in place.
You just need to treat the "content" LinearLayout as if it was the parent one, inserting scrollviews or whatever your needing and forgetting about the footer. Note that if the footer is recursive, meaning you are going to be using it multiple times, you could load it in the xml directly without copying it in to all your layouts
<include layout="#layout/footer" />
Where #layout/footer is an xml file in your layouts folder with the content of the footer that you want to reuse. This is virtually the same as adding it manually but with the convenience of not having to maintain it across several files.
Hope I was of help.