Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CoordinatorLayout: View disappears with custom behavior

I am a newbie to CoordinatorLayout and this is a really strange behavior I am getting in CoordinatorLayout.I have an ImageView(or more specifically a subclass of ImageView called CircleImageView(it houses the Profile pic in the center here)) as one of the children of the CoordinatorLayout. I have anchored this CircleImageView to the AppbarLayout(which is another child of the CoordinatorLayout). Here is the entire layout I have:

So far so good. I am currently able to scroll the AppbarLayout and the NestedScrollView moves along with it. But, I thought of animating the Profile pic to move to right as we scroll up and decided to rely on custom CoordinatorLayour.Behavior. I ended up with a custom behavior that tries translation of the CircleImageView. It's not complete yet but is supposed to translate the view roughly some amount except now, the CircleImageView has disappeared completely with the introduction of custom behavior.

What might be the reason for this?

Note: I have tried replacing the CircleImageView with an ImageView and the behavior remains the same.


Here is the layout for reference:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="false">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/main.appbar"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:fitsSystemWindows="false"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light">

            </android.support.v7.widget.Toolbar>

            <android.support.v7.widget.AppCompatImageView
                android:id="@+id/imageView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="bottom|end"
                android:layout_marginBottom="24dp"
                android:layout_marginEnd="24dp"
                android:layout_marginRight="24dp"
                android:layout_weight="1"
                android:tint="@color/white"
                app:srcCompat="@drawable/ic_settings_24px" />

        </android.support.design.widget.CollapsingToolbarLayout>


    </android.support.design.widget.AppBarLayout>

    <de.hdodenhof.circleimageview.CircleImageView
        android:id="@+id/profile_pic"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:elevation="4dp"
           app:layout_behavior="com.learncity.learner.account.profile.ProfilePicBehavior"
        android:src="@drawable/avatar_boy_2"
        app:layout_anchor="@id/main.appbar"
        app:layout_anchorGravity="bottom|center" />

    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">


            <TextView
                android:id="@+id/user_name"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginEnd="8dp"
                android:layout_marginLeft="8dp"
                android:layout_marginRight="8dp"
                android:layout_marginStart="8dp"
                android:layout_marginTop="64dp"
                android:lineSpacingExtra="8dp"
                android:padding="@dimen/activity_horizontal_margin"
                android:text="@string/account_person_name_label"
                android:textAlignment="center"
                android:textSize="40sp"
                app:layout_constraintHorizontal_bias="0.0"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <android.support.v7.widget.AppCompatImageView
                android:id="@+id/id_phone_icon"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="24dp"
                android:layout_marginStart="24dp"
                android:layout_marginTop="8dp"
                android:tint="@color/colorPrimary"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/user_name"
                app:srcCompat="@drawable/ic_phone_black_24dp" />

            <TextView
                android:id="@+id/id_phone_no"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="16dp"
                android:layout_marginStart="16dp"
                android:text="Phone No"
                app:layout_constraintBottom_toBottomOf="@+id/id_phone_icon"
                app:layout_constraintLeft_toRightOf="@+id/id_phone_icon"
                app:layout_constraintTop_toTopOf="@+id/id_phone_icon"
                app:layout_constraintVertical_bias="0.571" />


            <android.support.v7.widget.AppCompatImageView
                android:id="@+id/id_email_icon"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="24dp"
                android:layout_marginStart="24dp"
                android:layout_marginTop="8dp"
                android:tint="@color/colorPrimary"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/id_phone_icon"
                app:srcCompat="@drawable/ic_email_black_24dp" />

            <TextView
                android:id="@+id/id_email_id"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="16dp"
                android:layout_marginStart="16dp"
                android:text="Email Id"
                app:layout_constraintBottom_toBottomOf="@+id/id_email_icon"
                app:layout_constraintLeft_toRightOf="@+id/id_email_icon"
                app:layout_constraintTop_toTopOf="@+id/id_email_icon" />

            <View
                style="@style/Divider"
                android:layout_marginEnd="8dp"
                android:layout_marginLeft="8dp"
                android:layout_marginRight="8dp"
                android:layout_marginStart="8dp"
                android:layout_marginTop="8dp"
                app:layout_constraintTop_toBottomOf="@+id/id_email_icon" />

        </android.support.constraint.ConstraintLayout>

    </android.support.v4.widget.NestedScrollView>


</android.support.design.widget.CoordinatorLayout>

And the custom behavior:(I know the calculations might not be sound but I am trying for an initial crude animation)

public class ProfilePicBehavior extends CoordinatorLayout.Behavior<CircleImageView>{


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

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

    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, CircleImageView child, View dependency) {
        // Translate the CircleImageView to the right
        // Calculate first, what fraction the AppBarLayout has shrunk by
        float proportion = dependency.getHeight() / 200f;
        // Translate the child by this proportion
        float translationX = parent.getWidth() * proportion;
        child.setTranslationX(translationX);

        return true;
    }
}
like image 902
Manish Kumar Sharma Avatar asked Sep 25 '17 19:09

Manish Kumar Sharma


2 Answers

According to this answer: https://stackoverflow.com/a/40023161/6248491

It is stating that The contained CollapsingToolbarLayout fiddles with parent's elevation

Try giving elevation of the AppBarLayout to 0dp. Also, the CircleImageView should hold more (higher) elevation in order to not get "lifted" on top.

Hope this helps. Let me know if it works.

like image 131
Sneh Pandya Avatar answered Oct 14 '22 10:10

Sneh Pandya


I got the same problem with you a few months ago. I solve it by a custom CoordinatorLayout.Behavior as below (I dont remember the link of same question):

public class CollapsingImageBehavior extends CoordinatorLayout.Behavior<View> {

private final static int X = 0;
private final static int Y = 1;
private final static int WIDTH = 2;
private final static int HEIGHT = 3;

private int mTargetId;

private int[] mView;

private int[] mTarget;

public CollapsingImageBehavior() {
}

public CollapsingImageBehavior(Context context, AttributeSet attrs) {

    if (attrs != null) {
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CollapsingImageBehavior);
        mTargetId = a.getResourceId(R.styleable.CollapsingImageBehavior_collapsedTarget, 0);
        a.recycle();
    }

    if (mTargetId == 0) {
        throw new IllegalStateException("collapsedTarget attribute not specified on view for behavior");
    }
}

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

@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {

    setup(parent, child);

    AppBarLayout appBarLayout = (AppBarLayout) dependency;

    int range = appBarLayout.getTotalScrollRange();
    float factor = -appBarLayout.getY() / range;

    int left = mView[X] + (int) (factor * (mTarget[X] - mView[X]));
    int top = mView[Y] + (int) (factor * (mTarget[Y] - mView[Y]));
    int width = mView[WIDTH] + (int) (factor * (mTarget[WIDTH] - mView[WIDTH]));
    int height = mView[HEIGHT] + (int) (factor * (mTarget[HEIGHT] - mView[HEIGHT]));

    CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) child.getLayoutParams();
    lp.width = width;
    lp.height = height;
    child.setLayoutParams(lp);
    child.setX(left);
    child.setY(top);

    return true;
}

private void setup(CoordinatorLayout parent, View child) {

    if (mView != null) return;

    mView = new int[4];
    mTarget = new int[4];

    mView[X] = (int) child.getX();
    mView[Y] = (int) child.getY();
    mView[WIDTH] = child.getWidth();
    mView[HEIGHT] = child.getHeight();

    View target = parent.findViewById(mTargetId);
    if (target == null) {
        throw new IllegalStateException("target view not found");
    }

    mTarget[WIDTH] += target.getWidth();
    mTarget[HEIGHT] += target.getHeight();

    View view = target;
    while (view != parent) {
        mTarget[X] += (int) view.getX();
        mTarget[Y] += (int) view.getY();
        view = (View) view.getParent();
    }

}
}

You have to add a custom styleable attrs.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CollapsingImageBehavior">
    <attr name="collapsedTarget" format="integer"></attr>
</declare-styleable>
</resources>

After that, you can define your xml as below:

<?xml version="1.0" encoding="utf-8"?>

<android.support.design.widget.AppBarLayout
    android:id="@+id/main.appbar"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:fitsSystemWindows="false"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

    <android.support.design.widget.CollapsingToolbarLayout
        android:id="@+id/collapsing_toolbar"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_scrollFlags="scroll|exitUntilCollapsed">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:layout_collapseMode="pin"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light">

            <Space
                android:id="@+id/circle_collapsed_target"
                android:layout_width="40dp"
                android:layout_height="40dp" />
        </android.support.v7.widget.Toolbar>

        <android.support.v7.widget.AppCompatImageView
            android:id="@+id/imageView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|end"
            android:layout_marginBottom="24dp"
            android:layout_marginEnd="24dp"
            android:layout_marginRight="24dp"
            android:layout_weight="1"
            app:srcCompat="@drawable/ic_tab_angel" />


    </android.support.design.widget.CollapsingToolbarLayout>


</android.support.design.widget.AppBarLayout>

<ImageView
    android:id="@+id/profile_pic"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:layout_gravity="top|center_horizontal"
    android:layout_marginTop="220dp"
    android:elevation="4dp"
    android:src="@mipmap/icon_app"
    app:collapsedTarget="@id/circle_collapsed_target"
    app:layout_behavior="com.kp_corp.angelalarm.activity.CollapsingImageBehavior" />
<!---->

<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/user_name"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginEnd="8dp"
            android:layout_marginLeft="8dp"
            android:layout_marginRight="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="64dp"
            android:lineSpacingExtra="8dp"
            android:padding="@dimen/activity_horizontal_margin"
            android:text="Test"
            android:textAlignment="center"
            android:textSize="40sp"
            app:layout_constraintHorizontal_bias="0.0"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />


    </android.support.constraint.ConstraintLayout>

</android.support.v4.widget.NestedScrollView>

like image 33
Kingfisher Phuoc Avatar answered Oct 14 '22 10:10

Kingfisher Phuoc