14

Is it possible to show the first view in a LinearLayout overlapping the second?

I would like to layout my views like so:

<LinearLayout 
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:layout_alignParentRight="true" >

    <TextView
        android:id="@+id/firstTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrapContent" />

    <TextView
        android:id="@+id/secondTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

But I need my first view from the layout, firstTextView, to be placed on top of (overlapping) secondTextView. Is this possible? I am using the LinearLayout because I'm also playing with the margins to get an overlapping effect.

RileyE
  • 10,874
  • 13
  • 63
  • 106
  • Why do you want it place on top? You mean directly covering your `secondTextView`? – codeMagic Jun 06 '13 at 22:34
  • @codeMagic I'm placing it on top because "I'm also playing with the margins to get an overlapping effect" – RileyE Jun 06 '13 at 22:38
  • So you want the second view to be under and to the right of first view? – Voicu Jun 06 '13 at 22:39
  • @Voicu Exactly! :) Except I am also using the other LienarLayout properties, so I'd prefer to not use another layout scheme. – RileyE Jun 06 '13 at 22:39
  • I saw that but why not use `RelativeLayout` then? By default, both will be in top-left then you can play with `margins` from there, if I understand you correctly – codeMagic Jun 06 '13 at 22:40
  • @codeMagic It's because I'm using certain LinearLayout layout parameters, as well. – RileyE Jun 06 '13 at 22:41
  • @Voicu How is this a waste of time? Have you even tried this? If I overlap the two views, the second view will be on top of the first. Try it yourself, first. – RileyE Jun 07 '13 at 21:02
  • @Voicu I need the backgrounds to be colored, so they can't be transparent.. – RileyE Jun 07 '13 at 21:03

6 Answers6

9

What worked for me and probably will work for you is that:

  1. Wrap your 2 TextViews with RelativeLayout instead of LinearLayout and set android:clipChildren="false". This will prevent the overlapping portion from being clipped.
  2. Layout the 2nd TextView below the first TextView
  3. In the code, call bringToFront() on the first TextView. By default, the first textview is drawn first and will be below the second textview. Calling bringToFront() will change that order.

So the layout can be something like this:

<RelativeLayout  
xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" 
android:clipChildren="false">

<TextView
    android:id="@+id/firstTextView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="#00000000"
    android:text="First View" />

<TextView
    android:id="@+id/secondTextView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@id/firstTextView"
    android:background="#00000000"
    android:layout_marginTop="-13dp"
    android:text="Second View"/>
</RelativeLayout>

and:

TextView firstTextView = (TextView)findViewById(R.id.firstTextView);
firstTextView.bringToFront();
Tony Vu
  • 4,251
  • 3
  • 31
  • 38
  • 5
    You don't need clipChildren. If both views are in the same layout, they can overlap. In a relative layout this is done all the time. ClipChildren is for letting things be drawn outside the parent relative layout. BringToFront is also not needed, the z order is controlled by the order in the file that the views are defined in. – Gabe Sechan May 19 '16 at 18:47
8

If all you want is to overlap the two views vertically, then use this XML:

<LinearLayout  
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/firstTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#00000000"
        android:text="First View" />

    <TextView
        android:id="@+id/secondTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#00000000"
        android:layout_marginTop="-13dp"
        android:text="Second View"/>
</LinearLayout>

enter image description here

Voicu
  • 16,921
  • 10
  • 60
  • 69
  • 1
    And the first view is still below the second! – RileyE Jun 07 '13 at 19:55
  • I don't need Java code to know that the second view will be overlayed on top of the first view. I'm just using a basic LayoutInflater. – RileyE Jun 07 '13 at 21:00
  • Feel free to change background to whatever color you want if transparency is not desired. First two digits are for the alpha and the other are the RRGGBB. – Voicu Jun 08 '13 at 01:55
  • Yes, but can you see that if you change the background color, the second `View` is on top of the first. If you made the first `View`'s background "#DDAA00" and the second `View`'s background "#3300DD", the blue will cover the yellow. I need the yellow on top of the blue. – RileyE Jun 08 '13 at 02:34
  • The confusion started from the use of "on top" instead of "in front". In the Android world, "on top" refers to the vertical placement of a view in respect to another. Unfortunately, the z-axis doesn't work in `LinearLayout`, so you either use `RelativeLayout` or `FrameLayout` for that. A workaround would be to inverse the views and margin-push the second with enough `dp`s to look like it's the first while still staying in front. – Voicu Jun 10 '13 at 03:19
  • Okay. And that will be impossible for me, since the other view is based on `wrap_content`. That kinda sucks. I really need the `LinearLayout.LayoutParams`. Sorry for the confusion. – RileyE Jun 10 '13 at 03:50
3

Or you can stick with Linear Layout, but place a RelativeLayout within it, as a child. You can than place your TextViews withing the RelativeLayout, so they'll inheret properties from RelativeLayout. You can then still use your LinearLayout for other views. http://developer.android.com/reference/android/widget/RelativeLayout.html

XxTIBZxX
  • 58
  • 5
2

The Android System leaves you an entrance to change children's drawing order.

  1. Define a custom LinearLayout called ReverseDrawingOrderLLayout
  2. Enable isChildrenDrawingOrderEnabled = true
  3. Override getChildDrawingOrder to change your children's drawing order
  4. Put your layout into the ReverseDrawingOrderLLayout

enter image description here

    <com.example.widget.ReverseDrawingOrderLLayout

        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <TextView
            android:layout_marginRight="-10dp"
            android:background="@color/b_normal"
            android:layout_width="120dp"
            android:layout_height="100dp" />

        <TextView
            android:background="@color/r_normal"
            android:layout_marginTop="10dp"
            android:layout_marginRight="-10dp"
            android:layout_width="120dp"
            android:layout_height="100dp" />

        <TextView
            android:background="@color/g_normal"
            android:layout_marginTop="20dp"
            android:layout_width="120dp"
            android:layout_height="100dp" />
    </com.example.widget.ReverseDrawingOrderLLayout>

Result Result

Bruce Lin
  • 311
  • 3
  • 6
0

By assigning margin value "<0" we can overlap the views. But Relative layout is preferable when we need o overlap views.

0

I know this is an old question, but in case anyone is looking for this again as I was today - I have a dynamically build layout so I don't really have a specific xml rather a separate view I want to add ontop of my stack depending on certain settings; @GabeSechan 's comment let me in the right direction, I used -bottom margin to bring the second view up, inserted the new view at position 0

LinearLayout stack = (LinearLayout) findViewById(R.id.mystackview);//get your stack

stack.addView(getView(count), 0); //place it at the top

public View getView(){
        TextView view = menuLayout.findViewById(R.id.myview);

    LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(size, size);
    layoutParams.setMargins(0, 0, 0, -size));//this pulls the view back up to overlap evenly
    layoutParams.setMarginEnd(0);
    layoutParams.setMarginStart(size);

    if (view.getParent() != null)
        ((ViewGroup) view.getParent()).removeView(view);
    view.setLayoutParams(layoutParams);
    view.setZ(1);//this then sets the zindex above the other layout and hey presto, almost a simple css style fix

    return view;
}
imposterSyndrome
  • 896
  • 1
  • 7
  • 18