Scrungepipes
Scrungepipes

Reputation: 37581

Is it possible to align a child of a relative layout centered on top of another child?

I have a relative layout that contains some text views and a (circular) image view with the image view centered in the middle.

There is an animation of expanding rings emanating from center of the relative layout, which as the image view is also centered also emanates from the center of the image view.

However now there is a requirement to shift vertically up the image view a bit so its not longer in the center of the layout, and thus the origin of the animations need to also shift vertically by the same degree.

Here's a sketch of how the animation is implemented, its only showing a small portion of the code to show the main features of its implementation.

public class RippleBackground extends RelativeLayout {
private ArrayList<RippleView> rippleViewList=new ArrayList<RippleView>();
    private Paint paint;
    private AnimatorSet animatorSet;
    private ArrayList<Animator> animatorList; 

        ...
        paint = new Paint();
        rippleParams=new LayoutParams((int)(2*(rippleRadius+rippleStrokeWidth)),(int)(2*(rippleRadius+rippleStrokeWidth)));
        rippleParams.addRule(CENTER_IN_PARENT, TRUE);

        animatorSet = new AnimatorSet();
        animatorSet.setInterpolator(new AccelerateDecelerateInterpolator());
        animatorList=new ArrayList<Animator>();
        addView(rippleView,rippleParams);
        rippleViewList.add(rippleView);

        ...
        animatorSet.playTogether(animatorList);


    private class RippleView extends View {
        @Override
        protected void onDraw(Canvas canvas) {
            int radius=(Math.min(getWidth(),getHeight()))/2;
            canvas.drawCircle(radius,radius,radius-rippleStrokeWidth,paint);
        }
    }

This is how its implemented currently, I was wondering if I could just do something like replace rippleParams.addRule(CENTER_IN_PARENT, TRUE) with some other rule, but I can't see any other rule that would be applicable.

I was wondering if its possible to use a rule to align the animation view so its no longer centered on the parent RelativeLayout but on the imageView which is within the RelativeLayout?

Or is it possible to specify the co-ordinates, or some other way I can move the origin point of the animations up to match the imageView center?

Upvotes: 1

Views: 1104

Answers (1)

HexAndBugs
HexAndBugs

Reputation: 5789

Like you, I can't see how you can do it with a simple rule, but what you could do is wrap your RippleView in a FrameLayout with some paddingBottom on it that matches the amount your ImageView is moved up from the centre by.

If, for example, your ImageView is now 100dp up from the centre of your RelativeLayout, you'd also set paddingBottom to 100dp on the new FrameLayout wrapping your RippleView To make it clearer what I mean, here's the XML layout that would achieve it (I've only used XML as I think it's clearer what's going on, and I'm confident you're able to easily translate it to do it programmatically in your code):

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MyActivity">

    <FrameLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#0f0"
        android:layout_centerInParent="true"
        android:paddingBottom="100dp"
        >
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/ic_launcher"
            android:background="#f00"/>
    </FrameLayout>
</RelativeLayout>

I've added background colours to the FrameLayout and the ImageView (which in your case would be your RippleView) so you can clearly see their bounds - note that the ImageView is fully contained in the FrameLayout:

Screen Shot

Another option would be to put your ImageView and your RippleView in a FrameLayout which is set to wrap_content for width and height, then position the FrameLayout where you would have put the ImageView and set layout_gravity="center" on yourRippleView, so that theRippleViewends up centred on theImageViewby virtue of the fact the bounds of theFrameLayoutmatch the bounds of theImageView` - e.g.:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MyActivity">

    <FrameLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#0f0"
        android:layout_centerVertical="true"
        >
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/ic_launcher"
            android:background="#f00"/>

        <View
            android:id="@+id/rippleView"
            android:layout_width="20dp"
            android:layout_height="20dp"
            android:background="#00f"
            android:layout_gravity="center"
            />
    </FrameLayout>
</RelativeLayout>

Screen Shot 2

Upvotes: 1

Related Questions