18

How can I reverse the direction of a linear layout?

for example, if my layout is [view1, view2, view3] I want to create [view3, view2, view1]. My goal is to inflate a left and a right handed instances from one XML layout.

ZeroEric
  • 371
  • 1
  • 4
  • 7

9 Answers9

14

Generally I would say you cannot do this using the standard SDK. You could however create a method which gets all of the subviews out of the LinearLayout, removes them from the LinearLayout, and then adds them back in reverse order.

LinearLayout ll = // inflate
ArrayList<View> views = new ArrayList<View>();
for(int x = 0; x < ll.getChildCount(); x++) {
    views.add(ll.getChildAt(x));
}
ll.removeAllViews();
for(int x = views.size() - 1; x >= 0; x--) {
    ll.addView(views.get(x));
}
mtmurdock
  • 12,756
  • 21
  • 65
  • 108
  • @mtmmurdock this is a good solution though, it works dynamically. but he knows the views r of same type then my solution is better. anyway +1 for this. :) – Android Killer Dec 16 '12 at 17:33
  • One minor correction, I changed the "<=" in the second for loop to ">=". It worked perfectly! Thanks. – ZeroEric Dec 18 '12 at 03:28
9

Just add the following code to LinearLayout:

android:layoutDirection="rtl"

But it permanently reverses the order - not just for RTL locales :(

Dmitry
  • 14,306
  • 23
  • 105
  • 189
6

this is simplest approach :)

for(int k = ll.getChildCount()-1 ; k >= 0 ; k--)
{
    View item = ll.getChildAt(k);
    ll.removeViewAt(k);
    ll.addView(item);
}
mahdi
  • 660
  • 10
  • 20
4

You can control the direction of the layout directly through the layoutDirection. In this code we detect whether the natural direction is RTL, and reverse the direction, obviously one can apply your own logic to reversing:

LinearLayout buttonsContainer = (LinearLayout) findViewById(R.id.buttonsContainer);          
buttonsContainer.setLayoutDirection(isRTL() ? LinearLayout.LAYOUT_DIRECTION_LTR : 
                                    LinearLayout.LAYOUT_DIRECTION_RTL)

public static boolean isRTL() {
        return isRTL(Locale.getDefault());
}

public static boolean isRTL(Locale locale) {
    final int directionality = Character.getDirectionality(locale.getDisplayName().charAt(0));
    return directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT ||
            directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC;
}

Or via XML in case you want to override the natural direction constantly:

<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal"
        android:layoutDirection="ltr"
        >
...
</LinearLayout>

Detection of RTL is taken from this question: Identifyng RTL language in Android

Community
  • 1
  • 1
ohad serfaty
  • 644
  • 6
  • 11
2

Simple way try this

LinearLayout ll = (LinearLayout)findViewById(R.id.ll1);
    View v0 = ll.getChildAt(0);
    View v1 = ll.getChildAt(1);
    View v2 = ll.getChildAt(2);

    ll.removeAllViews();

    ll.addView(v2);
    ll.addView(v1);
    ll.addView(v0);
Ali Imran
  • 8,927
  • 3
  • 39
  • 50
0

How can I reverse the direction of a linear layout?

That is not supported, sorry.

My goal is to inflate a left and a right handed instances from one XML layout.

You are welcome to inflate them both from one XML layout, but you will then need to remove all the children of one and reverse their order in Java code. It may be that this is simpler than maintaining the two separate layout files, but it is definitely not automatic.

Or, you are welcome to create your own subclass of LinearLayout (or perhaps clone LinearLayout) that offers this feature.

Android 4.2 and higher offers RTL support for LinearLayout, but that is tied to locale and would apply to all horizontal LinearLayout containers in your app.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
0

notice for the prev answers, if you want to preserve width/height of views, calculated by direct pass (i.e. fill parent/wrap content), you have to set them explicitly:

for (int i = views.size() - 1; i >= 0; i--)
{
    View v = views.get(i);
    linearLayoutHor.addView(v, v.getWidth(), v.getHeight());
}

perhaps you will have to use post to view to be sure sizes of views are calculated. and add handler for orientation changes to have sizes recalculated correctly.

Dmitry Bryliuk
  • 106
  • 1
  • 3
0

You can try ViewCompat.setLayoutDirection(view, direction)

joecizac
  • 1,077
  • 2
  • 13
  • 14
-1
<LinearLayout
    android:id="@+id/parent"
    ...... 
    ......>
  view1
  view2
  view2
<LinearLayout/>

Now you can try this

LinearLayout parent = (LinearLayout)findViewById(R.id.parent);
View view1 = (View)parent.getChildAt(0);  // it will give first view
View view3 = (View)parent.getChildAt(2);  // it will give you third view

Here by View , it can be TextView,Button....etc.

Android Killer
  • 18,174
  • 13
  • 67
  • 90
  • This is a good solution, but will only work if all three (or at least the first and last) views are of the same type. What if they're different types or have different properties? Your solution would not reverse those. – mtmurdock Dec 16 '12 at 17:25
  • @mtmurdock in that case he has to use one if-else according to his logic. – Android Killer Dec 16 '12 at 17:29
  • If-else can't change the type of an object. What you're proposing doesn't change the order, it just changes the data stored in each view giving the appearance of changing the order. – mtmurdock Dec 16 '12 at 17:32
  • u didn't get itwhat i meant.anyway, all depends on asker of question. – Android Killer Dec 16 '12 at 17:35