Android RelativeLayout中循环依赖项导致的奇怪的非法状态异常
我在Android项目中遇到了一个奇怪的错误。有时应用程序会因以下非法状态异常而崩溃:Android RelativeLayout中循环依赖项导致的奇怪的非法状态异常,android,android-relativelayout,illegalstateexception,Android,Android Relativelayout,Illegalstateexception,我在Android项目中遇到了一个奇怪的错误。有时应用程序会因以下非法状态异常而崩溃: 11-23 08:20:51.610: E/AndroidRuntime(16714): FATAL EXCEPTION: main 11-23 08:20:51.610: E/AndroidRuntime(16714): java.lang.IllegalStateException: Circular dependencies cannot exist in RelativeLayout 11-23 08
11-23 08:20:51.610: E/AndroidRuntime(16714): FATAL EXCEPTION: main
11-23 08:20:51.610: E/AndroidRuntime(16714): java.lang.IllegalStateException: Circular dependencies cannot exist in RelativeLayout
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.widget.RelativeLayout$DependencyGraph.getSortedViews(RelativeLayout.java:1286)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.widget.RelativeLayout.sortChildren(RelativeLayout.java:294)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:314)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.view.View.measure(View.java:12775)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4709)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1385)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.widget.LinearLayout.measureVertical(LinearLayout.java:670)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.widget.LinearLayout.onMeasure(LinearLayout.java:563)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.view.View.measure(View.java:12775)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4709)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.widget.FrameLayout.onMeasure(FrameLayout.java:293)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.view.View.measure(View.java:12775)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.widget.LinearLayout.measureVertical(LinearLayout.java:822)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.widget.LinearLayout.onMeasure(LinearLayout.java:563)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.view.View.measure(View.java:12775)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4709)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.widget.FrameLayout.onMeasure(FrameLayout.java:293)
11-23 08:20:51.610: E/AndroidRuntime(16714): at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2240)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.view.View.measure(View.java:12775)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1117)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2505)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.os.Handler.dispatchMessage(Handler.java:99)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.os.Looper.loop(Looper.java:137)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.app.ActivityThread.main(ActivityThread.java:4514)
11-23 08:20:51.610: E/AndroidRuntime(16714): at java.lang.reflect.Method.invokeNative(Native Method)
11-23 08:20:51.610: E/AndroidRuntime(16714): at java.lang.reflect.Method.invoke(Method.java:511)
11-23 08:20:51.610: E/AndroidRuntime(16714): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
11-23 08:20:51.610: E/AndroidRuntime(16714): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
11-23 08:20:51.610: E/AndroidRuntime(16714): at dalvik.system.NativeStart.main(Native Method)
我知道这应该是由RelativeLayout中的两个小部件相互引用引起的,但这里肯定不是这样。
我在此布局文件中使用了RelativeLayout(在底部):
有人已经面对过这样的事情吗?非常感谢您的帮助……在logcat中打印您的ID,对于您动态添加的所有视图,您一定会在布局中找到一个定义循环依赖关系的视图。您的代码不容易理解,但您的错误仍然存在。尝试从左侧查看一个
。如果有效,请尝试从左侧选择两个视图。然后尝试从左侧查看一个视图,从右侧查看一个,等等。然后我相信您会发现问题。@DmitryZaitsev谢谢,我会尝试的。我应该提到,当我第一次开始活动时,布局工作正常,但从其他活动返回后它崩溃了。问题一定在哪里…谢谢你的回答!仍然不确定是什么导致了错误。但是,我通过在(重新)启动活动之前从布局中删除所有视图来解决这个问题。也许有些观点还保留在记忆中,然后我试着把它们添加到自己的旁边,或者。。。
<LinearLayout xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="450dp" >
<fragment
android:id="@+id/identification_navigation_fragment"
android:name="plt.demonstrator.common.NavigationFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<View
android:id="@+id/view1"
android:layout_width="3dp"
android:layout_height="match_parent"
android:layout_weight="0"
android:background="@color/lightgray" />
<fragment
android:id="@+id/identification_fragment"
android:name="plt.demonstrator.identifikation.IdentificationFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3.5" />
</LinearLayout>
<RelativeLayout
android:id="@+id/bottom_actionbar"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_gravity="center_vertical"
android:background="#DDDDDD" >
</RelativeLayout>
public static void addActionbarItem(RelativeLayout actionbar, Context ctx, int itemid, int textid,
int iconid, Direction direction, View.OnClickListener listener) {
TextView item = new TextView(ctx);
item.setText(ctx.getString(textid).toUpperCase());
item.setTextAppearance(ctx, android.R.style.TextAppearance_Medium);
int paddingPx = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 12, ctx.getResources().getDisplayMetrics());
item.setPadding(paddingPx, 0, paddingPx, 0);
item.setGravity(Gravity.CENTER_VERTICAL);
item.setId(itemid);
Drawable icon = ctx.getResources().getDrawable(iconid);
icon.setBounds(0, 0, 24, 24);
item.setCompoundDrawables(icon, null, null, null);
RelativeLayout.LayoutParams separatorParams = new LayoutParams(1, 32);
// vertical separator
View separator = new View(ctx);
int color = ctx.getResources().getColor(android.R.color.secondary_text_light);
separator.setBackgroundColor(color);
separator.setId(separatorId++);
separatorParams.setMargins(0, 8, 0, 0);
RelativeLayout.LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
if (direction == Direction.LEFT) {
// Item should be added at left side
if (leftAnchor != -1) {
// There is already an item at left side -> place the new item right to it
separatorParams.addRule(RelativeLayout.RIGHT_OF, leftAnchor);
separator.setLayoutParams(separatorParams);
actionbar.addView(separator);
params.addRule(RelativeLayout.RIGHT_OF, separator.getId());
} else {
// Item is the first on left side, place it at left edge
params.addRule(RelativeLayout.ALIGN_PARENT_LEFT, -1);
// Add some space to the display edge
params.setMargins(8, 0, 0, 0);
}
// Update anchor ID
leftAnchor = itemid;
} else {
// Item should be added at right side
if (rightAnchor != -1) {
// There is already an item at right side -> place the new item left to it
separatorParams.addRule(RelativeLayout.LEFT_OF, rightAnchor);
separator.setLayoutParams(separatorParams);
actionbar.addView(separator);
params.addRule(RelativeLayout.LEFT_OF, rightAnchor);
} else {
// Item is the first on right side, place it at right edge
params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, -1);
// Add some space to the display edge
params.setMargins(0, 0, 8, 0);
}
// Update anchor ID
rightAnchor = itemid;
}
item.setLayoutParams(params);
// Set item behaviour
item.setOnClickListener(listener);
// Add a touch listener for visual feedback
// Touch listener is invoked before click listener, so event must be forwarded after onTouch method
item.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(final View v, MotionEvent e) {
// ICS clicked button style
v.setBackgroundColor(0x880099CC);
v.invalidate();
Runnable timer = new Runnable() {
public void run() {
// Reset color
v.setBackgroundColor(Color.TRANSPARENT);
v.invalidate();
}
};
Handler h = new Handler();
h.removeCallbacks(timer);
// Reset button style after 50ms
h.postDelayed(timer, 50);
// Forward event to OnClickListener
return false;
}
});
actionbar.addView(item);
}