shelll
shelll

Reputation: 3383

Circular dependencies cannot exist in RelativeLayout

I am rendering a View into a Bitmap. I need a balloon with a pointer at the top or at the bottom, based on if it fits on the screen. For that I use a RelativeLayout, because I need the pointers to be partially over the balloon:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    >

    <LinearLayout android:id="@+id/balloon_body"
        android:layout_width="@dimen/pins_details_balloon_width"
        android:layout_height="wrap_content"
        android:layout_marginTop="-1dp"
        android:layout_marginBottom="-1dp"
        android:layout_below="@+id/pointer_top"
        android:orientation="vertical"
        >

        <TextView android:id="@android:id/title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="4dp"
            />

        <TextView android:id="@android:id/text1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="4dp"
            />

    </LinearLayout>

    <ImageView android:id="@id/pointer_top"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

    <ImageView android:id="@+id/pointer_bottom"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/balloon_body"
        />

</RelativeLayout>

I inflate this view and then I want to measure and layout it, so I can render it into a bitmap:

view.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT));
//view.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT));
view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
//view.measure(View.MeasureSpec.makeMeasureSpec(3000, View.MeasureSpec.AT_MOST), View.MeasureSpec.makeMeasureSpec(3000, View.MeasureSpec.AT_MOST));
view.layout(0, 0, s_View.getMeasuredWidth(), s_View.getMeasuredHeight());

This code crashes on the view.measure(...) with the Circular dependencies cannot exist in RelativeLayout error. I tried different LayoutParams (without setLayoutParams(...) the measure(...) crashes with a null pointer exception), different View.MeasureSpec-s but no success. If I remove the android:layout_below="@id/balloon_body" in the last ImageView, it works, but the bottom pointer is at the top.

I cannot use a LinearLayout, because I need those pointers to be above the body of the balloon, where with LinearLayout the top pointer will be below it. Where is the problem and how can I achieve what I want?

Upvotes: 2

Views: 8720

Answers (4)

Shreshth Kharbanda
Shreshth Kharbanda

Reputation: 1838

The problem is caused because there is a circular reference in the layout parameters.

For example, when view B is layout_below view A, view A can't reference view B anymore in it's below, alignRight etc. This can also exist between multiple views: A references B references C. In that scenario C can't reference A because of a circular dependency.

For more info, go to: Circular dependencies cannot exist in RelativeLayout, android?

Hope it Helps!

Upvotes: 2

Pradeep
Pradeep

Reputation: 808

Circular dependencies mean two consecutive views depending on each other in terms of position.

For example:

 <android.support.v4.view.ViewPager
    android:id="@+id/viewPager"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/tabs"
    android:layout_above="@id/orderpaylayout"
    />

<Button
    android:id="@+id/orderbutton"
    android:layout_width="match_parent"
    android:layout_height="60dp"
    android:layout_margin="20dp"
    android:layout_centerInParent="true"
    android:background="@drawable/orderbuttonstyle"
    android:text="@string/order"
    android:textSize="16sp"
    android:textStyle="bold"
    android:visibility="gone" />

<Button
    android:id="@+id/paybutton"
    android:layout_width="match_parent"
    android:layout_height="60dp"
    android:layout_centerInParent="true"
    android:text="@string/Pay"
    android:textColor="#ffffff"
    android:textSize="16sp"
    android:visibility="gone"
    android:layout_below="@id/viewPager
    android:textStyle="bold"
    android:layout_margin="20dp"
    android:background="@drawable/paybuttonstyle"
    />

In the above XML, there are three views. First View ViewPager is depending on order button as layout_above = orderButton. Once the top view or bottom view depends on other views, reverse/backward dependency cannot occur i.e., two views cannot depend on each other simultaneously.

The Correct XML code for the above wrong example is:

 <android.support.v4.view.ViewPager
    android:id="@+id/viewPager"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/tabs"
    android:layout_above="@id/orderpaylayout"
    />

<RelativeLayout
    android:id="@+id/orderpaylayout"
    android:layout_width="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_height="wrap_content">

<Button
    android:id="@+id/orderbutton"
    android:layout_width="match_parent"
    android:layout_height="60dp"
    android:layout_margin="20dp"
    android:layout_centerInParent="true"
    android:background="@drawable/orderbuttonstyle"
    android:text="@string/order"
    android:textSize="16sp"
    android:textStyle="bold"
    android:visibility="gone" />

<Button
    android:id="@+id/paybutton"
    android:layout_width="match_parent"
    android:layout_height="60dp"
    android:layout_centerInParent="true"
    android:text="@string/Pay"
    android:textColor="#ffffff"
    android:textSize="16sp"
    android:visibility="gone"
    android:textStyle="bold"
    android:layout_margin="20dp"
    android:background="@drawable/paybuttonstyle"
    />
</RelativeLayout>

Hope, this example will help you. If u consider this as correct one, upvote for others benefits or if it is wrong or doesn't work, put your comments.

Upvotes: 0

saigopi.me
saigopi.me

Reputation: 14938

if you are using circle shape background (drawable shape) in your relative layout it will throw that error

remove that shape or change layout

Upvotes: 0

Pankaj Singh
Pankaj Singh

Reputation: 2311

Try this.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>

 <ImageView android:id="@id/pointer_top"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    />
<LinearLayout android:id="@+id/balloon_body"
    android:layout_width="@dimen/pins_details_balloon_width"
    android:layout_height="wrap_content"
    android:layout_marginTop="-1dp"
    android:layout_marginBottom="-1dp"
    android:layout_below="@+id/pointer_top"
    android:orientation="vertical"
    >

    <TextView android:id="@android:id/title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="4dp"
        />

    <TextView android:id="@android:id/text1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="4dp"
        />

</LinearLayout>
<ImageView android:id="@+id/pointer_bottom"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@id/balloon_body"
    />

Upvotes: 0

Related Questions