Center ListView horizontally - android

As easy as it seems to be, as stubbornly this ListView won't center itself (or it's content within - doesn't matter to me).
This is activity layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.drobiazko.den.mobineon.MainActivity"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center_horizontal"
android:background="#drawable/bg">
<RelativeLayout android:id="#+id/clock_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<!--<RelativeLayout android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/holo_blue_dark">-->
<com.drobiazko.den.mobineon.ListViewRowsHeight
android:id="#+id/listview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:overScrollMode="never"
android:scrollbars="none"
android:divider="#null"
android:listSelector="#android:color/transparent"
android:persistentDrawingCache="scrolling|animation"
android:background="#android:color/holo_green_dark" />
<!--</RelativeLayout>-->
</LinearLayout>
This is ListView's item layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView android:id="#+id/btn_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#style/custom_btn_icon" />
<TextView android:id="#+id/btn_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#style/custom_btn_name" />
<TextView android:id="#+id/btn_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#style/custom_btn_count" />
</RelativeLayout>
I've tried everything (including simplifying layout to max), but it still won't go.
Funny that the first relative layout clock_container - centers like a charm, due to parent LinearLayout's android:gravity="center_horizontal". Why won't ListView?
Added later:
Inspired by FOliveira's answer, I've done some investigation and found that:
everything works fine, parent LinearLayout has android:gravity="center_horizontal" and centers his children respectfully. The reason for ListView's children are left-aligned is that ListView takes all possible width despite his android:layout_width="wrap_content" attribute.
Anyone knows why is that?

First of all , i would remove the first linear layout and stay only with the relative layout as the parent.
After having the relative layout as the main parent , set the CENTER_IN_PARENT attribute to true.
The mistake you are making is that you are setting the gravity of Linear Layout child to center horizontal, which is correct, but the only children being affected by this option is the Relative layout itself.

Related

How can I center a linear layout to the middle of its parent?

I am in the process of writing my first full Android app, and I want to center a linear layout so that the layout itself is centered, not just the content inside of the layout. I have seen through old posts that android:layout_gravity is used to do this, but as I enter that into my activity's XML, there are no suggestions, and nothing happens when fully entered.
Am I not supposed to use a linear layout to achieve this? Am I supposed to make its size match_parent and just constrain the sizes of all of its children? My idea for the layout was to constrain the size of the linear layout, center it, and have all of its children's horizontal size match_parent.
Here is my activity's XML for reference:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.frc5113.combustiblescouting.MainActivity">
<LinearLayout
android:layout_width="140dp"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Team Number" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="Color" />
</LinearLayout>
Your root layout is a ConstraintLayout. I don't think that supports the attribute layout_gravity. You should either use LinearLayout or use constraints relative to your root view as described here.
Try this, it makes your containt horizontal & vertical center simultaneously:
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.frc5113.combustiblescouting.MainActivity"
android:orientation="vertical"
android:gravity="center">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Team Number" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="Color" />
</LinearLayout>
using android:gravity="center" on the LinearLayout will center it's childs not itself.
There would be the android:layout_gravity attribute which is telling the parent how this child wants to be layed out. But this needs to be supported by the Containers' LayoutParams (which is true for e.g. FrameLayout, LinearLayout...)
But Constraintlayout does not support this kind of child gravity.
Here you need to set Constraints on the child (in your case the LinearLayout) in order to place it properly.
Therefore if you want to center the LinearLayout (which would somehow be obsolete as you could center it's childs directly in the ConstraintLayout)
you can achieve this like the following:
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="140dp"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<!-- content -->
</LinearLayout>
</android.support.constraint.ConstraintLayout>

Adding layout to a scrollview gets eaten up

I have a layout something like this:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="10dp"
android:background="#ff303f"
android:id="#+id/layout">
<ImageView
android:id="#+id/picture"
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_centerInParent="true"/>
<Button
android:id="#+id/cancel"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_alignRight="#id/picture"
android:background="#drawable/cross_out"/>
</RelativeLayout>
I inflate it using the usual layout inflator service, set up some functionality to the button and an image to the imageview (all images are of same size and aspect ratio).
After that, I add this view to my fragment's layout which is nothing but a ScrollView which is a parent, it has a child linear layout that I call 'map' and simply add it to the map.
Expected : The added layouts should get added properly and I can scroll through it.
Actual : If more than 2 are added, the first one gets eaten up. I can see it half or sometimes it is completely eaten up. :\
Any idea whats going on here? Thanks a lot for your time.
EDIT:
Here's the layout file I add the inflated layout into:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f6ff45">
<LinearLayout
android:id="#+id/map"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#43ff44"
android:orientation="vertical"
android:layout_margin="10dp"
android:layout_gravity="center"
android:layout_marginTop="15dp">
</LinearLayout>
</ScrollView>
I also forgot to mention that after adding 3 or more of these layouts, I realized there's unnecessary empty space in the end. :\
If you have some android:layout_gravity or gravity property in your ScrollView, that may be the reason. Try deleting it, or make it center_horizontal.
Try this code for your layout file;
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f6ff45">
<LinearLayout
android:id="#+id/map"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#43ff44"
android:orientation="vertical"
android:layout_margin="10dp"
android:layout_gravity="center"
android:layout_marginTop="15dp">
</LinearLayout>
</ScrollView>
As I mentioned before, android:layout_gravity="center"in this LinearLayout causes this problem. Because it doesn't only horizontally center but also verticelly center the contents. It means when they are longer than the available height, the center part will appear. I only changed it into android:layout_gravity="center_horizontal" and the problem is fixed.

2 RelativeLayouts in one layout

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>

GridLayout pushes down its children and overflow when given fill_parent for height

As it seems the GridLayout will always push its children to layout corresponding to their needs. for instance the following declaration:
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:columnCount="3"
android:orientation="vertical"
android:rowCount="4"
android:useDefaultMargins="true" >
...
<ImageView
android:id="#+id/main_image"
android:layout_column="1"
android:layout_columnSpan="2"
android:layout_row="3"
android:scaleType="fitStart" />
</GridLayout>
The GridLayout declares fill_parent and as such I would expect it to not overflow. The GridLayout should take the size of the parent which in this case is the window (full height). However in hierarchy viewer the GridLayout is set as Wrap_content for both vertical and horizontal.
As such the ImageView (which is a large image) or any text view will be push to fit themself and as such overflow the container.
This can be seen within the hierarchy viewer where the container grid view fits the parent:
while the image view overflow
Reading the documentation, I understand there is a need to set gravity. As far as I can try, I used all kinds of gravity options and image scaling options without much effect. Removing the margins with useDefaultMargins="false" does change the layout overflow which leads the issue towards gridlayout.
My question follows:
Is this a bug or am I using the GridLayout incorrectly
How can I force the GridLayout's children to fit their container and to fill
remaining spaces
The trick in other layouts is to give the first element an android:layout_weight="1.0" and nothing to the other elements. Why it works I have no idea, but it does. Here's a simple XML that displayed an ImageView, a TextView and a Button. Without the layout_weight parameter assigned to the ImageView the text and button were shifted down.
<?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:background="#color/white"
android:orientation="vertical"
android:keepScreenOn = "true" >
<ImageView
android:id="#+id/imageView_surprise"
android:layout_width="wrap_content"
android:layout_height="0dip"
android:scaleType="centerInside"
android:contentDescription="#string/accessibility_imageView_surprise"
android:layout_weight="1.0" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="bottom" >
<TextView
android:id="#+id/textView_message"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#color/black"
android:textSize="24sp"
android:gravity="center_horizontal" />
<Button
android:id="#+id/button_share"
style="#style/button_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>

RelativeLayout position and merge

I am trying to 'float' a RelativeLayout to the bottom of a Window, and have the following layout:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<com.my.activity.CanvasView
android:id="#+id/canvas"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="true" />
<RelativeLayout
android:id="#+id/toolbar_notification"
android:layout_width="match_parent"
android:layout_height="35dp"
android:layout_alignParentBottom="true"
android:gravity="bottom|center_vertical">
<ImageView
android:id="#+id/toolbar_notification_icon"
android:layout_width="40dp"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:contentDescription="#string/content_desc_save_icon"
android:gravity="center|center_vertical" />
</RelativeLayout>
</merge>
Unfortunately, the toolbar_notification RelativeLayout is not being bottom-aligned. Replacing the merge tag with a FrameLayout tag results in the desired effect, but in the name of efficiency I'd like to remove that if possible.
Anyone seen this issue, or have any suggestions? Is the fact that the merge element is not a 'parent' in the true sense resulting in the toolbar_notification element being unable to place itself?
android:gravity="bottom|center_vertical" is referred to children of RelativeLayout and not to RelativeLayout itself.
If you want to align RelativeLayout to the bottom of the parent (that is a FrameLayout) you have to use layout_gravity instead.
...
<RelativeLayout
android:id="#+id/toolbar_notification"
android:layout_width="match_parent"
android:layout_height="35dp"
android:layout_alignParentBottom="true"
android:layout_gravity="bottom|center_vertical">
...

Categories

Resources