Reputation: 3383
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
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
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
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
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