Chris Knight Chris Knight - 23 days ago 6
Android Question

How to center an Android table which sometimes has content wider than the screen?

I have the following layout:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/scrollViewFrameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="30dip">
<ScrollView
android:id="@+id/verticalScrollContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="10dip">
<HorizontalScrollView
android:id="@+id/horizontalScrollContainer"
android:layout_width="match_parent"
android:layout_height="match_parent">

</HorizontalScrollView>
</ScrollView>
</FrameLayout>


To the horizontal scroll container I programatically create a TableLayout and add it to the HorizontalScrollView. The user can control which columns should be displayed in the table. Sometimes, if the user chooses many columns, the content can spill off the width of the screen. Much of the time, the table is smaller than the width of the screen and I'd like it centered. Without addressing centering, the above layout works just fine for tables which spill off the screen. E.g. scrolling in both directions works. However, when I do this:

FrameLayout.LayoutParams lp =
new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT, Gravity.CENTER);
theTable.setLayoutParams(lp);


it starts behaving oddly. For times when the content is smaller than the width of the screen, it properly centers it. However, when the content is wider than the screen, the content is centered forcing some of the left hand side of the table to disappear off the left hand side of the screen. E.g.

SSSSSS
SSSSSS
TTTTTTTTTT
SSSSSS
SSSSSS


Where 'S' is the screen and 'T' is the table. Its also impossible to scroll left to see the cut off content (but scrolling right works). What I'm looking for:

If the table is smaller than the width of the screen, then center it.
If the table is wider than the width of the screen, then left align it with horizontal scrolling.

Any ideas on how to achieve this?

Answer

The solution to this involved hooking into the onGlobalLayoutListener of my table which fires after the layout is complete (and therefore I have access to the tables display width). Here is the code:

    final TableLayout table = (TableLayout)findViewById(R.id.the_table);
    ViewTreeObserver vto = table.getViewTreeObserver();
    vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener()
    {
        public void onGlobalLayout()
        {
            ViewTreeObserver obs = table.getViewTreeObserver();
            obs.removeGlobalOnLayoutListener(this);

            int screenWidth = 
                       activity.getWindowManager().getDefaultDisplay().getWidth();


            //If the table is smaller than the screen width, setup new layout
            //parameters to center the table.  Otherwise, leave the table left 
            //aligned
            if (table.getWidth() < screenWidth)
            {
                FrameLayout.LayoutParams lp = 
                      new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, 
                              LayoutParams.WRAP_CONTENT, Gravity.CENTER);
                table.setLayoutParams(lp);
            }
        }