首页 > 解决方案 > Is it possible to combine CoordinatorLayout with ConstraintLayout?

问题描述

In one of my views I have a ConstraintLayout on the bottom of my mainview with three ImageButtons inside of it. I also use a Snackbar to show some informations on the bottom. I want to move the complete ConstraintLayout up if the Snackbar is visible. I tried now different things without any result. In a separate Android-Project i played a little bit around with CoordinatorLayouts and my result so far is, that it is not possible for ConstraintLayouts. Is my assumption right?

This is working

public class CustomBehaviourButton extends CoordinatorLayout.Behavior<Button>{

    public CustomBehaviourButton() {
    }

    public CustomBehaviourButton(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean layoutDependsOn(@NonNull CoordinatorLayout parent, @NonNull Button child, @NonNull View dependency) {
        return dependency instanceof Snackbar.SnackbarLayout;
    }

    @Override
    public boolean onDependentViewChanged(@NonNull CoordinatorLayout parent, @NonNull Button child, @NonNull View dependency) {
        float translationY = Math.min(0, dependency.getTranslationY() - dependency.getHeight());
        child.setTranslationY(translationY);
        return true;
    }

    @Override
    public void onDependentViewRemoved(@NonNull CoordinatorLayout parent, @NonNull Button child, @NonNull View dependency) {
        float translationY = Math.min(0, dependency.getTranslationY() + dependency.getHeight());
        child.setTranslationY(translationY);
    }
}

And this is not working

public class CustomBehaviourConstraintLayout extends CoordinatorLayout.Behavior<ConstraintLayout> {

    public CustomBehaviourConstraintLayout() {
    }

    public CustomBehaviourConstraintLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean layoutDependsOn(@NonNull CoordinatorLayout parent, @NonNull ConstraintLayout child, @NonNull View dependency) {
        return dependency instanceof Snackbar.SnackbarLayout;
    }

    @Override
    public boolean onDependentViewChanged(@NonNull CoordinatorLayout parent, @NonNull ConstraintLayout child, @NonNull View dependency) {
        float translationY = Math.min(0, dependency.getTranslationY() - dependency.getHeight());
        child.setTranslationY(translationY);
        return true;
    }

    @Override
    public void onDependentViewRemoved(@NonNull CoordinatorLayout parent, @NonNull ConstraintLayout child, @NonNull View dependency) {
        float translationY = Math.min(0, dependency.getTranslationY() + dependency.getHeight());
        child.setTranslationY(translationY);
    }
}

Is there by any chance a way for a ConstraintLayout to react if a Snackbar is shown??

Edit:

This is my current Layout

<androidx.coordinatorlayout.widget.CoordinatorLayout>
   <androidx.constraintlayout.widget.ConstraintLayout>
      <!-- different widgets -->
      <androidx.constraintlayout.widget.ConstraintLayout>
         <!-- Some Buttons -->
      </androidx.constraintlayout.widget.ConstraintLayout>
   </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

I want that only the second ConstraintLayout is effected by the behaviour. I get it only for the first ConstraintLayout, but the result is not what I want.

标签: androidandroid-constraintlayoutandroid-coordinatorlayout

解决方案


花了一段时间,但我找到了解决我的问题的方法,我想这个解决方案对其他人有帮助。

诀窍是深入挖掘自定义行为类。看来最外面的ConstraintLayout需要得到Bahviour。在那种情况下,我只是在onDependendViewChanged中引用了我最里面的 ConstraintLayout来只修改我的布局的这一部分。

@Override
    public boolean onDependentViewChanged(@NonNull CoordinatorLayout parent, @NonNull ConstraintLayout child, @NonNull View dependency) {
        ConstraintLayout mainControlsPanel = child.findViewById(R.id.mainControlsPanel);

        float heightDiff = dependency.getY() - mainControlsPanel.getY();
        float translationY = heightDiff - mainControlsPanel.getHeight() - MARGIN;

        mainControlsPanel.setTranslationY(translationY);

        return true;
    }

推荐阅读