AppBarLayout ScrollingViewBehavior给我一个“java.lang.RuntimeException:此图包含循环依赖”错误

时间:2016-10-25 21:16:52

标签: android android-appbarlayout

所以我一直得到一个“java.lang.RuntimeException:这个图包含循环依赖”错误,我很确定这是由我从AppBarLayout.ScrollingViewBehavior扩展的行为引起的。我有一个使用此行为的AppBarLayout布局,如果我删除行为,错误消失。这是行为

的错误和代码
E/AndroidRuntime: FATAL EXCEPTION: main
Process: yu.heetae.android.mergingtoolbar, PID: 26027
java.lang.RuntimeException: This graph contains cyclic dependencies
at android.support.design.widget.DirectedAcyclicGraph.dfs(DirectedAcyclicGraph.java:164)
at android.support.design.widget.DirectedAcyclicGraph.dfs(DirectedAcyclicGraph.java:172)
at android.support.design.widget.DirectedAcyclicGraph.dfs(DirectedAcyclicGraph.java:172)
at android.support.design.widget.DirectedAcyclicGraph.getSortedList(DirectedAcyclicGraph.java:152)
at android.support.design.widget.CoordinatorLayout.prepareChildren(CoordinatorLayout.java:658)
at android.support.design.widget.CoordinatorLayout.onMeasure(CoordinatorLayout.java:706)
at android.view.View.measure(View.java:18794)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:135)
at android.view.View.measure(View.java:18794)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:748)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:630)
at android.view.View.measure(View.java:18794)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at android.view.View.measure(View.java:18794)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:748)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:630)
at android.view.View.measure(View.java:18794)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at com.android.internal.policy.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2643)
at android.view.View.measure(View.java:18794)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2100)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1216)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1452)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1107)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6013)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
at android.view.Choreographer.doCallbacks(Choreographer.java:670)
at android.view.Choreographer.doFrame(Choreographer.java:606)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
public class MergedAppbarBehavior extends AppBarLayout.ScrollingViewBehavior {

    private Toolbar mToolbar;
    private View mBackground;
    private FrameLayout.LayoutParams mBackgroundLayoutParams;

    private Context mContext;

    private boolean isInit = false;

    public MergedAppbarBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
    }

    @Override
    public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
        return dependency instanceof NestedScrollView;
    }

    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
        if(!isInit) {
            init(child);
            return false;
        }

        if(isDependencyYBelowToolbar(child, dependency) && ! isDependencyYReachTop(dependency)) {
            setToolbarBackground(android.R.color.transparent);
            setPartialBackgroundHeight((int)((child.getHeight() + child.getY()) - dependency.getY()));
        } else if(isDependencyYBelowStatusToolbar(child, dependency) || isDependencyYReachTop(dependency)) {
            setToolbarBackground(Color.parseColor("#3F51B5"));
            setPartialBackgroundHeight(0);
        }

        return false;
    }

    private void init(View child) {
        AppBarLayout appBarLayout = (AppBarLayout) child;

        mToolbar = (Toolbar) appBarLayout.findViewById(R.id.toolbar);
        mToolbar.setTitle(" ");
        mBackground = appBarLayout.findViewById(R.id.background_view);
        mBackgroundLayoutParams = (FrameLayout.LayoutParams) mBackground.getLayoutParams();

        setToolbarBackground(android.R.color.transparent);
        setPartialBackgroundHeight(0);

        isInit = true;
    }

    private boolean isDependencyYBelowToolbar(View child, View dependency){
        return dependency.getY() <= child.getY() + child.getHeight() && dependency.getY() > child.getY();
    }

    private boolean isDependencyYBelowStatusToolbar(View child, View dependency){
        return dependency.getY() <= child.getY();
    }

    private boolean isDependencyYReachTop(View dependency){
        return dependency.getY() == 0;
    }

    private void setPartialBackgroundHeight(int height){
        mBackgroundLayoutParams.height = height;
        mBackground.setLayoutParams(mBackgroundLayoutParams);
    }

    private void setToolbarBackground(int color) {
        mToolbar.setBackgroundColor(ContextCompat.getColor(mContext, color));
    }
}

2 个答案:

答案 0 :(得分:1)

不再是一个活跃的问题,但如果有人遇到同样的错误:检查您的应用:layout_anchors。

当我进行类似的设置时,我发生了这个错误:

<View
    android:id="@+id/firstView"
    app:layout_anchor="@+id/secondView" />

<View
    android:id="@id/secondView"
    app:layout_anchor="@id/firstView" />

当然,实际情况稍微复杂一点,这就是开始时的情况。无论如何,错误提示依赖循环。

答案 1 :(得分:0)

我遇到了与FloatingActionButton相同的问题。我刚从XML中删除了这一行

app:layout_anchor="@id/list_view"