Center elements of HorizontalScrollView when not enough to make it scroll
Solution 1
I just solved this issue. I ran into it a few hours ago. You need to center the HorizontalScrollView in its parent and set its width/height to wrap_content. The layout you put in the the HSV must have its width/height set to wrap content as well. The important part here is to not set any gravity/layout_gravity on this layout or you may experience (very annoying) clipping issues after inflating your views. Example below is contained in a RelativeLayout.
<HorizontalScrollView android:id="@+id/svExample"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="@id/rlExample">
<LinearLayout
android:id="@+id/llExample"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
</LinearLayout>
</HorizontalScrollView >
Solution 2
I had the same problem and finally got it to work. Here is a minimal example:
The main activity layout with the HorizontalScrollView:
<?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">
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true" >
<LinearLayout
android:id="@+id/container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
</LinearLayout>
</HorizontalScrollView>
</LinearLayout>
The layout of the elements that will be inflated and put inside the scroll view:
<?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="wrap_content"
android:gravity="center_horizontal"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="your text" />
</LinearLayout>
And this is an example of the code to inflate and add the elements:
LinearLayout container = (LinearLayout) findViewById(R.id.container);
LayoutParams elementLayoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, 1f);
int elementCount = 3; // ...or however many you like
for (int i = 0; i < elementCount; i++) {
LinearLayout element = (LinearLayout) getLayoutInflater().inflate(R.layout.element, null);
container.addView(element, elementLayoutParams);
}
It's mainly based on a technique for stretching the content of ScrollViews explained in this article by Romain Guy.
However in this case where you are adding contents dynamically, another key point is setting the positive value for the weight (1f in this example) using LayoutParams when adding the elements to the container. If you have a static set of elements that you can include directly in the container and don't need to inflate you can specify the weight of the elements' outer LinearLayout in the XML layout like so:
android:layout_weight="1"
But if you do it dynamically that won't work because the weight will reset to 0 and the elements collapse. Hence you need to set it via the LayoutParams.
Solution 3
Below is the simplest way worked for me.
<HorizontalScrollView
android:id="@+id/horizontalScrollView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center">
<LinearLayout
android:id="@+id/layout_others"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</HorizontalScrollView>
Solution 4
managed to get round center-horizontal clipping the left side:
HorizontalScrollView part of layout has been changed to:
<LinearLayout
android:id="@+id/footerWrapperLayoutToGetAroundCenteringIssue"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:gravity="center_horizontal">
<HorizontalScrollView
android:id="@+id/horizontalScrollView1"
android:layout_height="fill_parent"
android:layout_width="wrap_content">
<LinearLayout
android:id="@+id/footerLayout"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
</LinearLayout>
</HorizontalScrollView>
</LinearLayout>
Its just a pity when it centers them they are not evenly distributed.
If anyone has any ideas please let me know.
Related videos on Youtube
Alasdair
Updated on July 24, 2022Comments
-
Alasdair almost 2 years
I have a Layout with a
HorizontalScrollView
containing aLinearLayout
for a Menu where the contents are inflated with the contents of the DB. This works fine however when there are not enough elements to make theHSV
scroll this does not fill the width of the screen which ideally should be centered. i.e. Currently:| Element 1 Element 2 | <- edge of screen
Instead of:
| Element 1 Element 2 | <- edge of screen
whilst still being able to:
| Element 1 Element 2 Element 3 Element 4 Elem| <- edge of screen now scrolling
The layout XML is:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/mainLinearLayout" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:id="@+id/header" android:layout_width="fill_parent" android:layout_height="25dp" > </TextView> <ScrollView android:id="@+id/scroll1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1" > <LinearLayout android:id="@+id/contentLayout" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" > </LinearLayout> </ScrollView> <HorizontalScrollView android:id="@+id/horizontalScrollView1" android:layout_width="fill_parent" android:layout_height="30dp"> <LinearLayout android:id="@+id/footerLayout" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal" > </LinearLayout> </HorizontalScrollView> </LinearLayout>
With the following XML being inflated inside footerLayout:
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/footer_content" android:textSize="18sp" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingLeft="5dp" android:paddingRight="5dp" android:text="FOOTER" android:singleLine="true" />
-
Alasdair about 12 yearshas no effect, still looks the same
-
Alasdair about 12 yearsit seems like the LinearLayout footerLayout does not expand to fill the full width if only one or two elements are inside.
-
Aashish Bhatnagar about 12 yearstry one more thing may be it works assign wieght sum to linearlayout in ur code to whatever number of elements ur inserting and assign the wieght 1 in xml to the textView to be inflated.
-
Tony Chan over 9 years
fillViewport="true"
was the missing piece I was looking for to solve my similar problem. For future readers: if you're experiencing really weird left-side clipping of your centeredTextView
inside theHorizontalScrollView
, try tweaking with thefillViewport
attribute. It allows weights to be turned on. -
GFPF about 9 yearsFor me it worked correctly the properties: android: layout_centerHorizontal = "true" android: layout_width = "wrap_content"
-
Adrian Buciuman over 6 yearsthe article by Romain Guy helped me a lot
-
Mike Keskinov over 3 yearsThis is brilliant!