Nic Hubbard
Nic Hubbard

Reputation: 42139

Android Shadow on bottom of RelativeLayout outside of bounds

I have a 9 patch image of a shadow that I want to add to the bottom of a RelativeLayout. The layout fills the screen, but slides up then the user taps a button. So, I would like to have the shadow image be below the RelativeLayout (pulled down with a negative bottom margin) so that when the layout sides up, the shadow is on the bottom edge of the layout, giving it a layered effect.

<ImageView
            android:id="@+id/shadow"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"
            android:layout_marginBottom="-10dp"
            android:src="@drawable/shadow" />

I am sliding up the frame using:

ObjectAnimator mover = ObjectAnimator.ofFloat(mainView, "translationY", !historyShown ? -ph : 0);
 mover.setDuration(300);
 mover.start();

Strangely, when I add the image to the layout and it give it a negative margin, it just isn't shown, like it is cutting off anything outside the bounds of the layout.

Is there a way around this?

Upvotes: 0

Views: 1454

Answers (1)

nmw
nmw

Reputation: 6764

I can think of one way of doing it, but I'm sure there must be a cleaner way.

Make the layout in which the mainView resides a FrameLayout (or RelativeLayout), and include the ImageView in that, making it a sibling of mainView, but list it before mainView. Set it to be at the bottom using layout_gravity="bottom" (or layout_alignParentBottom="true" if using a RelativeLayout).

Now change the target in the ObjectAnimator to something above the mainView (so either its container View or the Activity/Fragment), and change the property to something like "scrollUp", then create a method named setScrollUp(float) in the target. In this method set the translation of the mainView and shadow using setTranslationY(). Offset the shadow by its height.

Works for me here in a simple app using solid colours:

XML:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:background="#f00">

    <View
        android:id="@+id/shadow"
        android:layout_width="match_parent"
        android:layout_height="20px"
        android:layout_gravity="bottom"
        android:background="#00f"/>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#0f0"
        android:id="@+id/container"/>

</FrameLayout>

Activity code:

@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    container = findViewById(R.id.container);
    shadow = findViewById(R.id.shadow);

    container.setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(final View v)
        {
            final float translationTo = (open) ? 0 : -300;
            final float translationFrom = (open) ? -300 : 0;

            open = !open;

            ObjectAnimator anim = ObjectAnimator.ofFloat(MyActivity.this, "scrollUp", translationFrom, translationTo);
            anim.setDuration(500);
            anim.start();
        }
    });
}

public void setScrollUp(final float position)
{
    container.setTranslationY(position);
    shadow.setTranslationY(position + shadow.getHeight());
}

Upvotes: 2

Related Questions