ActionBar Tab with custom View not centered - android

I need to use a custom View for my tabs, the problem is that fill_parent doesn't work (as seen here).
So I need to use margin and stuff, but in order to have the view centered inside the tab in all configuration (landscape/portrait, or on a tablet where the height of the tabs will change) it's a bit tricky to do.
I don't know what value to use on each configuration. Plus, I don't find the default layout that the system uses to start with.

I'd recommend that you use the ActionBar Tab styles. This is clean and simple. For example (zeroing in on the TabView):
<style name="MyActionBar" parent="#style/android:Widget.Holo.ActionBar">
<item name="android:titleTextStyle">#style/MyActionBarTitleText</item>
<item name="android:attr/actionBarTabTextStyle">#style/MyActionBarTabText</item>
<item name="android:attr/actionBarTabStyle">#style/MyActionBarTabStyle</item>
</style>
<!-- styling for the tabs -->
<style name="MyActionBarTabStyle" parent="#style/android:Widget.Holo.Light.ActionBar.TabView">
<item name="android:background">#drawable/tab_bar_bg_master</item>
<item name="android:gravity">center</item>
</style>
(I'll also note that the tabs are highly styleable by using custom Drawables. But that's a topic for another day!)

the above reply from #Stephane-Mathis is on the right track, but I couldn't get it to work just right in my code. Here's a simpler version that uses the same concept.
Again, the idea is to force your view to be much taller than the tab itself.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingTop="3dp"
android:paddingBottom="3dp">
<View
android:id="#+id/spacer_1"
android:layout_width="0dp"
android:layout_height="1000dp"
android:layout_weight="1" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:src="#drawable/ic_tabicon_1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:layout_gravity="center_vertical"
android:textColor="?accentColor"
android:text="My Albums" />
<View
android:id="#+id/spacer_2"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
The spacer_1 and spacer_2 views exist to pad the ImageView and TextView evenly on the left and right side. Furthermore, the height on spacer_1 is set to something absurdly high (1000dp) so force the parent view to be excessively tall. Then the ImageView and the TextView re both set to center_vertical.

So, if you want to do that you will need to do a bit of dirty stuff.
Since fill_parent doesn't work, you need to force the root view to have more height than the tab height and then center what you really need. So my first LinearLayout is useless, and the second one will be in the center of the tab.
Here is what I used. I just wanted one textview with another one at the top right of it.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="invisible">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="vertical">
<TextView
android:id="#+id/tv_tab_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/tv_tab_title"
android:layout_gravity="right"
android:background="#drawable/bg_notification"
android:paddingLeft="2dp"
android:paddingRight="2dp"
android:text="1"
android:gravity="center"
android:minWidth="14dp"
android:textStyle="bold"
android:textColor="#color/blanc"
android:textSize="8dp" />
<TextView
android:id="#+id/tv_tab_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:textColor="#color/noire"
android:textSize="12dp"
android:textStyle="bold" />
<TextView //this has the same height as the `tv_tab_count` so it remains centered vertically
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/tv_tab_title"
android:layout_gravity="right"
android:background="#0f0"
android:paddingLeft="2dp"
android:paddingRight="2dp"
android:text="1"
android:textSize="8dp"
android:visibility="invisible" />
</LinearLayout>
This work for the vertical alignment but the view only has the width of the content I put in my textview. So if you need to use the complete width, you should put a really really long word in one of the invisible textviews.

Related

How to make horizontal Linear Layout Child wrap its content? [duplicate]

This question already has answers here:
Android - LinearLayout Horizontal with wrapping children
(12 answers)
Closed 1 year ago.
As the title suggests in my case the child view is a TextView with some content. and I want it to be one per line
So putting layout_width to 0dp and adding layout_weight to 1 did not work, Im assuming that because its the only one in its line so 1 is the highest wight... not sure about it though
this is the xml:
<LinearLayout
android:id="#+id/tagsVerticalLineup"
android:layout_width="0dp"
android:layout_height="0dp"
android:orientation="vertical"
android:gravity="center_horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
/>
</LinearLayout>
At the end I want them one after another vertically (one on each row)
with horizontal size as their text length (content)
Is this even possible with Linear Layout?
Thanks
EDIT:
As #Ajil O answer is working, my own problem still remains. I isolated the main difference.
In my project Im adding the Text Views from the code using Inflate because I have default styling.
Inflating Code:
final LinearLayout tagAreaView = (LinearLayout) findViewById(R.id.tagsVerticalLineup);
TextView tag = (TextView) getLayoutInflater().inflate(R.layout.answer_tag, null);
int tagId = someListArray.size();
tag.setId(tagId);
tag.setText(someChangingObject.text);
tagAreaView.addView(tag, tagId);
Text View answer_tag:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/SelectedTagAnswer" />
style xml SelectedTagAnswer:
<style name="SelectedTagAnswer">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_marginStart">8dp</item>
<item name="android:layout_marginEnd">16dp</item>
<item name="android:background">#drawable/selected_answer</item>
<item name="android:drawablePadding">8dp</item>
<item name="android:gravity">center_horizontal</item>
<item name="android:drawableStart">#drawable/ic_cross_round</item>
<item name="android:elevation">3dp</item>
<item name="android:paddingBottom">8dp</item>
<item name="android:paddingEnd">25dp</item>
<item name="android:paddingStart">15dp</item>
<item name="android:paddingTop">8dp</item>
</style>
NOTE:
When inserting a simple Text View to xml that uses same style,
it works like in #Ajil O answer. Some thing in the inflating process messing it up.
Make the LinearLayout width to match_parent and height to wrap_content
<LinearLayout
android:id="#+id/tagsVerticalLineup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
If you want the TextView to occupy 1 line use android:maxLines="1" attribute
EDIT
The TextView are all in color now. You can see that the TextView is as wide as it's content.
The container, LinearLayout is shaded in the light violet(?) color. This LinearLayout has to be atleast as wide as the longest TextView or the view (or it's content) would get clipped.
<LinearLayout
android:id="#+id/tagsVerticalLineup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center"
android:background="#AAAAFF"
android:layout_gravity="center">
<TextView
android:layout_margin="8dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#080"
android:text="small text"
android:textColor="#FFF"
android:textSize="18sp"
android:maxLines="1"/>
<TextView
android:layout_margin="8dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Slightly longer text"
android:background="#400"
android:textColor="#FFF"
android:textSize="18sp"
android:maxLines="1"/>
<TextView
android:layout_margin="8dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="loooooooooooooooooong text"
android:background="#008"
android:textColor="#FFF"
android:textSize="18sp"
android:maxLines="1"/>
</LinearLayout>
Finally found a solution, So turns out Android wont refresh layout of views with wrap_content once it has been displayed.
As found in this answer WRAP_CONTENT not working after dynamically adding views
So my problem was inflating the view and then adding content (text).
To over come that, I set again the the height and width like so:
tag.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
Now, if all from Ajil O answer is implemented, it is working!
Hope this edge case will come handy to someone in the future
Just use wrap_content parameter in your android:layout_widthand you will be fine You are using 0dp now:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:id="#+id/tagsVerticalLineup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_horizontal"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
It is preferable that you use the ContrainstLayout and you can manipulate any event to the dimensions that you want
Try this
make the parent layout's Height and Width=match_parent
textView make width match_parent so that you can use textalignment=centre or you can use gravity=centre
<LinearLayout
android:id="#+id/tagsVerticalLineup"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center_horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"/>
</LinearLayout>

Android: Container XML Layout wrap weight and fill height

I have been battling for a couple of days trying to create a custom layout in Android divided in 3 parts, a "vote" counter container that displays the amount of people that voted a message, a text message container that will contain the text and the author of a message and a button container that will be used to vote up or down a message.
So far I have this code
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/containerInner"
>
<!-- # VOTES CONTAINER -->
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/containerVotes"
android:layout_centerVertical="true"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:id="#+id/votesPost"
android:textStyle="bold"
android:textSize="16sp"
/>
</RelativeLayout>
<!-- MESSAGE CONTAINER -->
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/containerText"
android:layout_marginLeft="4dp"
android:layout_marginTop="4dp"
android:layout_toRightOf="#+id/containerVotes"
android:background="#color/gray"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:id="#+id/titleGlobus"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/AutorGlobus"
android:textColor="#000000"
android:textSize="12sp"
android:textStyle="italic"
android:maxWidth="180dp"
android:layout_weight="0.1"
android:layout_below="#+id/titleGlobus"
/>
</RelativeLayout>
<!-- VOTE UP/DOWN CONTAINER -->
<RelativeLayout
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="#+id/containerButtons"
android:layout_alignParentTop="true"
android:layout_toRightOf="#+id/containerText"
android:layout_toEndOf="#+id/containerText"
>
<RelativeLayout
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="#+id/containerButtonUp"
>
<at.markushi.ui.CircleButton
android:layout_width="32dip"
android:layout_height="32dip"
android:src="#mipmap/ic_arrow_drop_up_black_24dp"
app:cb_color="#color/white"
app:cb_pressedRingWidth="8dip"
android:id="#+id/upvote_button"
/>
</RelativeLayout>
<RelativeLayout
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="#+id/containerButtonDown"
android:layout_below="#+id/containerButtonUp"
>
<at.markushi.ui.CircleButton
android:layout_width="32dip"
android:layout_height="32dip"
app:cb_color="#color/white"
app:cb_pressedRingWidth="8dip"
android:src="#mipmap/ic_arrow_drop_down_black_24dp"
android:id="#+id/downvote_button"
/>
</RelativeLayout>
</RelativeLayout>
The Layout I am getting in the phone using the above code is this:
And I want to achieve this:
So there are two main things that I need to achieve here:
Make the RelativeLayout containerText fill the whole height of its superior container.
Alight the Author name to the right of the container, but aligned just at the end of the "message" TextView.
I have been trying to fix the fix issue changing the height of the containerText container to fill_parent without success, changing all the way up to the main container all the height properties to fill_parent.
If I try to align the author name to the right using alignParentRight=true , the RelativeLayout then takes the whole space of the screen, pushing out the buttons container. I have also tried changing the way I am positioning the different layouts respect others, changing the toLeftOf or toRightTo, with terrible results.
Any help would be highly appreciated as I am stuck with this issue.
Cheers!
Try this:
<!-- MESSAGE CONTAINER -->
<RelativeLayout
android:layout_width="wrap_content"
<!-- Set this height to match_parent -->
android:layout_height="match_parent"
android:id="#+id/containerText"
android:layout_marginLeft="4dp"
android:layout_marginTop="4dp"
android:layout_toRightOf="#+id/containerVotes"
android:background="#color/gray"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:id="#+id/titleGlobus"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/AutorGlobus"
android:textColor="#000000"
android:textSize="12sp"
android:textStyle="italic"
android:maxWidth="180dp"
android:layout_weight="0.1"
<!-- Removed below tag and added alignParentBottom and alignParentRight -->
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
/>
</RelativeLayout>

Android how to use auto-layout to move other views when a view is hidden?

I wanted to make resizable views when one of them is hidden. The question is already asked for iOS in the following link. I wanna make it for android. Any helps are appreciated. I wanted to add free space to three TextViev: position, stat_name, price after setting visibility hidden to count and discount
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="1dp"
android:gravity="center"
android:orientation="horizontal"
android:paddingBottom="10dp"
android:paddingLeft="5dp"
android:paddingTop="30dp"
android:weightSum="100" >
<TextView
style="#style/list_titles_style"
android:layout_weight="10"
android:text="#string/position" />
<TextView
style="#style/list_titles_style"
android:layout_weight="35"
android:paddingLeft="15dp"
android:text="#string/stat_name" />
<TextView
style="#style/list_titles_style"
android:layout_weight="20"
android:text="#string/price" />
<TextView
android:id="#+id/count_label"
style="#style/list_titles_style"
android:layout_weight="10"
android:visibility="invisible"
android:text="#string/count" />
<TextView
android:id="#+id/discount_label"
style="#style/list_titles_style"
android:visibility="invisible"
android:layout_weight="25"
android:text="#string/discount" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="2dp"
android:layout_marginLeft="2dp"
android:layout_marginRight="2dp"
android:layout_marginTop="1dp"
android:background="#drawable/border_layout"
android:orientation="horizontal" >
<ListView
android:id="#+id/stats_listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:layout_marginBottom="5dp"
android:divider="#drawable/list_divider"
android:dividerHeight="2dp"
android:paddingBottom="0dp"
android:paddingLeft="10dp"
android:paddingTop="0dp" />
</LinearLayout>
And my style here it is:
<style name="list_titles_style">
<item name="android:layout_width">0dp</item>
<item name="android:layout_height">match_parent</item>
<item name="android:textColor">#color/Blue</item>
<item name="android:gravity">center</item>
<item name="android:textSize">18sp</item>
</style>
I have gone through the provided link...To remove the left side view just set the android:visibility="gone" for the view in your xml layout file....if you want remove programmatically try view.setVisibility(View.GONE);....
You can achieve this using LinearLayout with match_parent parameter depending on what orientation you desire. So you might set weights for each child view and also put an stub view in order to stretch out the size.
Note that if you hide your views with INVISIBLE flag they will hold the space whereas with GONE it's like the view never been there.
Hope that helps.

Centering CheckBox Views

If you're interested in RadioButtons in addition to (or instead of) CheckBoxes, see this question instead.
Despite the presence of
<item name="android:layout_gravity">center_horizontal</item>
in the style file, the two checkboxes are not centered, but appear "left-justified".
res/layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/MyLL"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<CheckBox
android:id="#+id/cb1"
style="#style/CB_style" />
<CheckBox
android:id="#+id/cb2"
style="#style/CB_style" />
</LinearLayout>
res/values/styles.xml
<style name="CB_style" parent="#android:style/TextAppearance.Medium">
<item name="android:layout_gravity">center_horizontal</item>
<item name="android:layout_weight">1</item>
<item name="android:gravity">center</item>
<item name="android:checked">false</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
</style>
You have android:layout_weight = 1. So your checkboxes fill all width of screen.
Remove android:layout_weight from style and add margin between checkboxes.
Gravity in Checkbox don't affect the inner tick button, only text.
EDIT
Ok, try this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/MyLL"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="0dp"
android:layout_height="5dp"
android:layout_weight="1"/>
<CheckBox
android:id="#+id/cb1"
style="#style/CB_style" />
<TextView
android:layout_width="0dp"
android:layout_height="5dp"
android:layout_weight="1"/>
<CheckBox
android:id="#+id/cb2"
style="#style/CB_style" />
<TextView
android:layout_width="0dp"
android:layout_height="5dp"
android:layout_weight="1"/>
</LinearLayout>
And remove layout_weight from style.
Another way is create custom checkbox. But I think it's too complicated for this problem.
Here's something that may help:
android:gravity vs android:layout_gravity
android:gravity is usually internal, usually asking the view itself what to do with the pixels it has
android:layout_gravity is usually external, usually asking the parent ViewGroup (LinearLayout/RelativeLayout/FrameLayout) how to position the view with extra pixels that the view is not using
If you are using a view with wrap_content, you probably want to use layout_gravity. If you are using a view with match_parent, you probably want to try gravity.
Sometimes wrapping another ViewGroup around a troublesome View can help with positioning. Views and ViewGroups go through an intricate "screen space" negotiating phase, and different Views (Buttons/TextView/ImageView/etc) and ViewGroups (LinearLayout/RelativeLayout/TableLayout/etc) have different rules and negotiating powers
This is why sometimes pairing a troublesome View with another parent like a FrameLayout or LinearLayout can make it behave all of the sudden
This is a little messy but it works, and yes it works as well for 3 or more checkbox inputs:
<LinearLayout
android:padding="0dip"
android:layout_width="0dp"
android:layout_weight="1"
android:hint="name"
android:layout_height="40dip"
android:textAlignment="center" android:layout_gravity="center"
android:orientation="horizontal"
>
<TextView
android:layout_width="0dip"
android:layout_height="1dip" android:layout_weight="1" android:text=" " />
<CheckBox
android:id="#+id/chk1"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:scaleX="1.5" android:scaleY="1.5"
>
</CheckBox>
<TextView
android:layout_width="0dip"
android:layout_height="1dip" android:layout_weight="1" android:text=" " />
<CheckBox
android:id="#+id/chk2"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:scaleX="1.5" android:scaleY="1.5"
>
</CheckBox>
<TextView
android:layout_width="0dip"
android:layout_height="1dip" android:layout_weight="1" android:text=" " />
</LinearLayout>
Try it in style
<item name="android:layout_width">0dp</item>
I hope it will work.. thanks..
<style name="TextlessCheckBox" parent="android:Widget.Material.CompoundButton.CheckBox">
<item name="android:button">#null</item>
<item name="android:foreground">?android:listChoiceIndicatorMultiple</item>
<item name="android:foregroundGravity">center</item>
</style>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/MyLL"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:orientation="horizontal" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:background="#ff0000"
android:gravity="center" >
<CheckBox
android:id="#+id/cb1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:background="#00FF00"
android:gravity="center" >
<CheckBox
android:id="#+id/cb2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
ok, last try for today ;) you should post a picture next time, HOW it should look... well, now you ll have your LinearLayout divided into two similar wide part (red & green), and in every block your checkbox is in the center...did i got it right this time?!
Just add this to your LinearLayout :
android:gravity="center_horizontal"
This line specifies that anything inside this layout will be in the center.
The Full layout code :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal">
<CheckBox
android:id="#+id/cb1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="CheckBox ONE"
/>
<CheckBox
android:id="#+id/cb2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="CheckBox TWO" />
</LinearLayout>
Here is the output i got :

Taming Android ListView Height within a TableRow

n.b.: I was going to post all this XML on Pastebin but I think it's important to have it archived here for posterity, so please pardon the code sample length! Better to have more info than less, right?
Consider the following calculator-ish layout. (I hard-coded the strings just for this post - they are normally resources.)
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/calculator"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dp"
android:orientation="vertical"
android:stretchColumns="*">
<TableRow android:id="#+id/tableRowFieldName"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:id="#+id/textViewFieldName"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1.0"
android:layout_marginTop="0dp"
android:layout_marginRight="5dp"
android:layout_marginBottom="0dp"
android:layout_marginLeft="5dp"
android:padding="0dp"
android:text="Label"
android:textSize="20dp"
android:textColor="#FFFFFF"
android:textAppearance="?android:attr/textAppearanceMedium" />
</TableRow>
<TableRow android:id="#+id/tableRowDisplay"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:id="#+id/textViewDisplay"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1.0"
android:layout_margin="5dp"
android:layout_marginTop="0dp"
android:layout_marginRight="5dp"
android:layout_marginBottom="0dp"
android:layout_marginLeft="5dp"
android:padding="0dp"
android:text="Value"
android:textSize="35dp"
android:textColor="#FFFFFF"
android:textAppearance="?android:attr/textAppearanceLarge" />
</TableRow>
<TableRow android:id="#+id/tableRow1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="0.2">
<Button android:id="#+id/buttonA"
style="#style/ParameterButton"
android:text="Param A" />
<Button android:id="#+id/buttonB"
style="#style/ParameterButton"
android:text="Param B" />
</TableRow>
<TableRow android:id="#+id/tableRow2"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="0.2">
<Button android:id="#+id/buttonC"
style="#style/ParameterButton"
android:text="Param C" />
<Button android:id="#+id/buttonD"
style="#style/ParameterButton"
android:text="Param D" />
</TableRow>
<TableRow android:id="#+id/tableRow3"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="0.2">
<Button android:id="#+id/buttonE"
style="#style/ParameterButton"
android:text="Param E" />
<Button android:id="#+id/buttonF"
style="#style/ParameterButton"
android:text="Param F" />
</TableRow>
<TableRow android:id="#+id/tableRow4"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="0.4">
<ListView android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="gone"
android:layout_weight="1.0" />
<TableLayout android:id="#+id/calcKeypad"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1.0"
android:stretchColumns="*">
<TableRow
android:layout_weight="0.25"
android:gravity="center">
<Button android:id="#+id/button7"
style="#style/KeypadButton"
android:text="7" />
<Button android:id="#+id/button8"
style="#style/KeypadButton"
android:text="8" />
<Button android:id="#+id/button9"
style="#style/KeypadButton"
android:text="9" />
</TableRow>
<TableRow
android:layout_weight="0.25"
android:gravity="center">
<Button android:id="#+id/button4"
style="#style/KeypadButton"
android:text="4" />
<Button android:id="#+id/button5"
style="#style/KeypadButton"
android:text="5" />
<Button android:id="#+id/button6"
style="#style/KeypadButton"
android:text="6" />
</TableRow>
<TableRow
android:layout_weight="0.25"
android:gravity="center">
<Button android:id="#+id/button1"
style="#style/KeypadButton"
android:text="1" />
<Button android:id="#+id/button2"
style="#style/KeypadButton"
android:text="2" />
<Button android:id="#+id/button3"
style="#style/KeypadButton"
android:text="3" />
</TableRow>
<TableRow
android:layout_weight="0.25"
android:gravity="center">
<Button android:id="#+id/buttonClear"
style="#style/KeypadButton"
android:text="C" />
<Button android:id="#+id/button0"
style="#style/KeypadButton"
android:text="0" />
<Button android:id="#+id/buttonDecimal"
style="#style/KeypadButton"
android:text="." />
</TableRow>
</TableLayout>
<LinearLayout android:id="#+id/linearLayoutTotal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<Button android:id="#+id/buttonTotalWeight"
style="#style/FunctionButton"
android:text="Function A" />
<Button android:id="#+id/buttonTotalCost"
style="#style/FunctionButton"
android:text="Function B" />
<Button android:id="#+id/buttonAbout"
style="#style/FunctionButton"
android:layout_height="0dp"
android:layout_weight="0.25"
android:text="Function C" />
</LinearLayout>
</TableRow>
</TableLayout>
This uses the following styles (essentially factored out of the original XML):
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="CalcButton">
<item name="android:textColor">#ffffff</item>
<item name="android:textSize">15dp</item>
<item name="android:textStyle">bold</item>
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">fill_parent</item>
<item name="android:layout_margin">2dp</item>
</style>
<style name="ParameterButton" parent="CalcButton">
<item name="android:layout_width">0dp</item>
<item name="android:layout_weight">0.5</item>
</style>
<style name="KeypadButton" parent="CalcButton">
<item name="android:textSize">20dp</item>
</style>
<style name="FunctionButton" parent="CalcButton">
<item name="android:layout_height">0dp</item>
<item name="android:layout_weight">0.375</item>
</style>
</resources>
If you were to drop all of this in to an Android project, you should see three rows of two parameter buttons up top, followed by a numeric keypad below that, with three function buttons to the right of the keypad. Mostly harmless. (Also, it will only ever be used in portrait - so no worries about taking landscape into consideration.)
However ... pay particular attention to the ListView within the XML. You won't see it in the visual just yet, since it has android:visibility="gone". The idea is that, at certain times, I will remove that, then set the numeric keypad (the adjacent TableLayout) to have android:visibility="gone" instead, thus showing the list in its place.
Put another way, the desired effect is to have the list and the numeric keypad occupy exactly the same space, such that I can flip back and forth between the two at will.
The problem I'm having is that the ListView, once populated, seems intent on taking up the entire height of the overall table, obliterating the poor parameter buttons and bringing the three function buttons along for the ride.
You can see this by rigging a very basic ArrayAdapter (I used android.R.layout.simple_list_item_1 and android.R.id.text1) and tossing a rudimentary String array its way. For now, manually move the gone assignment from the list over to the adjacent table layout (or do it in code).
Setting a fixed height seems out of the question, since this should be working on a variety of displays. In fact, I even tried what is perhaps a misguided endeavor:
ListView list = (ListView) findViewById(android.R.id.list);
TableLayout calcKeypad = (TableLayout) findViewById(R.id.calcKeypad);
list.layout(calcKeypad.getLeft(), calcKeypad.getTop(), calcKeypad.getRight(), calcKeypad.getBottom());
calcKeypad.setVisibility(View.GONE);
list.setVisibility(View.VISIBLE);
Nope, that didn't help either.
In keeping with the documentation, I've even given ListView the proper ID since I want to customize its layout. Of course I'm not using a ListActivity, so perhaps it doesn't matter in this case. (I'm just using a regular Activity. Yes, I tried changing that to ListActivity too. No dice.)
Still, I'm totally open to this being pilot error. (In fact, I'm counting on it.) I'm just at the point where it's become head-hitting-the-wall-in-myopia mode. "There's got to be a better way!"
Again, keep in mind I'm trying very hard to keep the layout fluid, so that it works well on a variety of display sizes (not tablets, just handhelds), hence the chosen layout. If there's a better way that accomplishes the same visual, I'm all ears.
Bottom line: How do I make the ListView only take up the area occupied by that adjacent calculator keypad (TableLayout)?
Clues/answers/guidance appreciated!
There are some problems in your layout, but I didn't spend a lot of time trying to sort out the various layout_weight and layout_height situations that you have. I think you might be able to get this to work, but I took a little different approach.
I broke the layout up into a series of rows above the three elements at the bottom. Basically you have:
TextView-------------------------------
TextView-------------------------------
LinearLayout---------------------------
LinearLayout---------------------------
LinearLayout---------------------------
---------------------------------------
TableLayout and ListView | LinearLayout
I'm not saying this is the most efficient layout, but every layout element has a job, so you might have to go to some lengths to replace them with something more efficient.
In particular, the use of LinearLayout for your Parameter buttons and Function buttons makes good use of the layout_weight feature. It's not available in other layouts that are not subclasses of LinearLayout (you may not be aware that TableRow is a subclass of LinearLayout, and that's why layout_weight works there but not in RelativeLayout) and the ability to subdivide available space on a percentage basis seems to be appropriate for those elements.
The TableLayout holding the numeric buttons could probably be replaced, but it's doing a good job of allocating space for the buttons in different sized views, and it is also doing a nice job of spacing the rows to fill the available space. Again, it might be difficult to replace this.
What I did was replace your overall TableLayout with a RelativeLayout with appropriate alignment attributes. That allows you to put the Function button LinearLayout against the right border and have the ListView or TableLayout consume the remaining space below the Parameter buttons and to the left of the Function buttons. I'm not saying you have to do this, necessarily, but it saves some extra layout elements over your original design and does the job you are looking for.
Here's a workup of what I did. Notice that I added a layout_height of wrap_content to your ParameterButton style. Also, both the ListView and TableLayout are visible in this layout. You may want adjust in the layout or in your code.
The style:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="CalcButton">
<item name="android:textColor">#ffffff</item>
<item name="android:textSize">15dp</item>
<item name="android:textStyle">bold</item>
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">fill_parent</item>
<item name="android:layout_margin">2dp</item>
</style>
<style name="ParameterButton" parent="CalcButton">
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_width">0dp</item>
<item name="android:layout_weight">0.5</item>
</style>
<style name="KeypadButton" parent="CalcButton">
<item name="android:textSize">20dp</item>
</style>
<style name="FunctionButton" parent="CalcButton">
<item name="android:layout_height">0dp</item>
<item name="android:layout_weight">0.375</item>
</style>
</resources>
The layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/calculator"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dp"
android:orientation="vertical"
android:stretchColumns="*">
<TextView android:id="#+id/textViewFieldName"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:layout_marginTop="0dp"
android:layout_marginRight="5dp"
android:layout_marginBottom="0dp"
android:layout_marginLeft="5dp"
android:padding="0dp"
android:text="Label"
android:textSize="20dp"
android:textColor="#FFFFFF"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView android:id="#+id/textViewDisplay"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:layout_margin="5dp"
android:layout_marginTop="0dp"
android:layout_marginRight="5dp"
android:layout_marginBottom="0dp"
android:layout_marginLeft="5dp"
android:padding="0dp"
android:layout_below="#id/textViewFieldName"
android:text="Value"
android:textSize="35dp"
android:textColor="#FFFFFF"
android:textAppearance="?android:attr/textAppearanceLarge" />
<LinearLayout android:id="#+id/tableRow1"
android:layout_below="#id/textViewDisplay"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<Button android:id="#+id/buttonA"
style="#style/ParameterButton"
android:layout_height="wrap_content"
android:text="Param A" />
<Button android:id="#+id/buttonB"
style="#style/ParameterButton"
android:text="Param B" />
</LinearLayout>
<LinearLayout android:id="#+id/tableRow2"
android:layout_below="#id/tableRow1"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<Button android:id="#+id/buttonC"
style="#style/ParameterButton"
android:text="Param C" />
<Button android:id="#+id/buttonD"
style="#style/ParameterButton"
android:text="Param D" />
</LinearLayout>
<LinearLayout android:id="#+id/tableRow3"
android:layout_below="#id/tableRow2"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<Button android:id="#+id/buttonE"
style="#style/ParameterButton"
android:text="Param E" />
<Button android:id="#+id/buttonF"
style="#style/ParameterButton"
android:text="Param F" />
</LinearLayout>
<ListView android:id="#android:id/list"
android:layout_below="#id/tableRow3"
android:layout_toLeftOf="#+id/linearLayoutTotal"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<TableLayout android:id="#+id/calcKeypad"
android:layout_below="#id/tableRow3"
android:layout_toLeftOf="#id/linearLayoutTotal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:stretchColumns="*">
<TableRow
android:layout_weight="0.25"
android:gravity="center">
<Button android:id="#+id/button7"
style="#style/KeypadButton"
android:text="7" />
<Button android:id="#+id/button8"
style="#style/KeypadButton"
android:text="8" />
<Button android:id="#+id/button9"
style="#style/KeypadButton"
android:text="9" />
</TableRow>
<TableRow
android:layout_weight="0.25"
android:gravity="center">
<Button android:id="#+id/button4"
style="#style/KeypadButton"
android:text="4" />
<Button android:id="#+id/button5"
style="#style/KeypadButton"
android:text="5" />
<Button android:id="#+id/button6"
style="#style/KeypadButton"
android:text="6" />
</TableRow>
<TableRow
android:layout_weight="0.25"
android:gravity="center">
<Button android:id="#+id/button1"
style="#style/KeypadButton"
android:text="1" />
<Button android:id="#+id/button2"
style="#style/KeypadButton"
android:text="2" />
<Button android:id="#+id/button3"
style="#style/KeypadButton"
android:text="3" />
</TableRow>
<TableRow
android:layout_weight="0.25"
android:gravity="center">
<Button android:id="#+id/buttonClear"
style="#style/KeypadButton"
android:text="C" />
<Button android:id="#+id/button0"
style="#style/KeypadButton"
android:text="0" />
<Button android:id="#+id/buttonDecimal"
style="#style/KeypadButton"
android:text="." />
</TableRow>
</TableLayout>
<LinearLayout android:id="#id/linearLayoutTotal"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_below="#id/tableRow3"
android:layout_alignParentRight="true"
android:orientation="vertical">
<Button android:id="#+id/buttonTotalWeight"
style="#style/FunctionButton"
android:text="Function A" />
<Button android:id="#+id/buttonTotalCost"
style="#style/FunctionButton"
android:text="Function B" />
<Button android:id="#+id/buttonAbout"
style="#style/FunctionButton"
android:layout_height="0dp"
android:layout_weight="0.25"
android:text="Function C" />
</LinearLayout>
</RelativeLayout>
The reason is that layout width is set to be fill parent
use wrap content instead and assign weight 1 to both table layout and llistview after placing them under horizontal linear layout
Joe,
There are a number of solutions that can provide the solution that you seek. After looking at your Layout, I am left to wonder why you are using a TableLayout? I mean, at first glance, a calculator is like a Table, kind of. Have you considered other Layout solutions yourself? You certainly mention that others are ok, but the real question is how you have considered them or what you know about them. Because of the lack of information in this regard, I am going to highlight the different kinds of Layouts and their particular strengths. The reason I am addressing it in this way is that most Layout issues result from choosing the wrong layout type.
FrameLayout
This Layout is tricky for some. It is great if you have multiple Views that are the same size. The positioning of the immediate children is always the same (top left of the Frame), regardless of size. The weakness of FrameLayout is that you must manually position children if they are going to be on the screen at the same time. Many developers (wrongfully) stick them inside a container in order to keep positioning.
LinearLayout
One of the most over-used Layouts. LinearLayouts are particularly awesome if you have similarly sized views that must grow the parent linearly. Many, many novice developers use LinearLayout and layout_weight for everything. The issue is that in many cases, things aren't truly growing linearly and layout_weight is relatively inefficient, according to Google itself.
RelativeLayout
A great layout that offers incredibly flexibility with relative positioning. Positioning is based on previously declared view ids or parent attributes. If your positioning is based on sibling properties, this layout is the best to use. It also does not require layout_weight, but allows you to utilize it. The most important thing here is ordering. If your views aren't ordered correctly in your XML then they don't render correctly or error out. Ordering is determined by what views determine your other properties.
TableLayout
Layout that provides a grid/cell like structure for your layouts. Its sizing is entirely dependent upon the parent, and positioning is, in most cases, based upon the previous cell. One of the things many devs learn is that it can be troublesome with hidden Views and cells of different sizes. This is best for displaying data or its interfaces.
Now, for your Solutions
If you are still keen on using the TableLayout, set the visibility of your ListView to "invisible" rather than "gone". The difference between these two is subtle but important. "invisible" means that it still takes up layout even though it is not visible. "gone" means that it loses all of its layout properties and they must be set manually when you show the object.
Given your particular requirements, I think a RelativeLayout would be optimal for positioning. It doesn't require you to use the layout_weight which optimizes the layout and measure passes. And it allows you to size and position according to how other views and layouts are placed on the screen. You simply have to decide what your anchor views are and start there. Then you can place your ListView with layout_below
If you need more information on any of these Layouts, I will gladly provide links for you to the official sources.
Hope this helps,
FuzzicalLogic

Categories

Resources