CollapsingToolbarLayout image with zoom
Asked Answered
A

2

6

I've been reading around all day without any success on this.

Basically want to be able to set an ImageView inside a android.support.design.widget.CollapsingToolbarLayout to change it's height depending on the onOffsetChanged change detected so that it will "zoom-out" when collapsed to fit the whole image width and "zoom-in" when expanded to do normal centerCrop behavior.

I tried setting the ImageView height in the onOffsetChanged but that causes other issues assuming due to the CollapsingToolbarLayout is also repositioning it.

Sample functionality I've seen in ParallaxListView project but wish to use the CollapsingToolbarLayout.

Anyone able to give sample code (if it is possible)?

enter image description here

Also seen this project but again similar limitation. Other projects as well.

enter image description here

Aloysius answered 28/6, 2017 at 16:38 Comment(0)
D
3

You can try using android:scaleType="matrix"for the collapsing image's layout definition.

In the code, store the initial ImageMatrix in a Matrix using matrix.set(imageView.getImageMatrix());

And depending upon the scroll of collapsing toolbar, you can use matrix.postScale() to scale the image and finally set it back to the ImageView using imageView.setImageMatrix(matrix). That can give you the zoom in / out effect.

Deterrence answered 28/6, 2017 at 20:36 Comment(0)
A
2

I managed to do it in the end with the following code for anyone else out there that it may help. The code will fit to width when expanded and fit to height when collapsed. It can be changed to scale (zoom) further in if needed.

Not sure if optimal code is written, suggestions welcome. To measure the bitmap and the view and calculate the min/max scale I use the first call to onOffsetChanged which seems to work fine.

public class MyActivity extends AppCompatActivity implements AppBarLayout.OnOffsetChangedListener {

    private float collapsedScale;
    private float expandedScale;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.my_activity_layout);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        setTitle(entry.label);

        photoView = (ImageView) findViewById(R.id.photo_image);

        AppBarLayout mAppBarLayout = (AppBarLayout) findViewById(R.id.appbar);
        mAppBarLayout.addOnOffsetChangedListener(this);

    }

    @Override
    public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {

        int maxScroll = appBarLayout.getTotalScrollRange();

        float scrollPercent = (float) Math.abs(verticalOffset) / (float) maxScroll;

        if (collapsedScale == 0) {

            Drawable photo = photoView.getDrawable();

            int bitmapWidth = photo.getIntrinsicWidth();
            int bitmapHeight = photo.getIntrinsicHeight();

            collapsedScale = (float)photoView.getWidth()/(float)bitmapWidth;
            expandedScale = (float)photoView.getHeight()/(float)bitmapHeight;

            scalePhotoImage(photoView, expandedScale);

        } else {

            scalePhotoImage(photoView, collapsedScale + (expandedScale - collapsedScale) * (1f - scrollPercent));
        }
    }

    private static void scalePhotoImage(ImageView photoView, float scale) {

        Drawable photo = photoView.getDrawable();

        int bitmapWidth = photo.getIntrinsicWidth();
        int bitmapHeight = photo.getIntrinsicHeight();

        float offsetX = (photoView.getWidth() - bitmapWidth) / 2F;
        float offsetY = (photoView.getHeight() - bitmapHeight) / 2F;

        float centerX = photoView.getWidth() / 2F;
        float centerY = photoView.getHeight() / 2F;

        Matrix imageMatrix = new Matrix();
        imageMatrix.setScale(scale, scale, centerX, centerY);
        imageMatrix.preTranslate(offsetX, offsetY);

        photoView.setImageMatrix(imageMatrix);
    }
}

My layout

<?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:background="@color/menu_background_color"
tools:context="style.donkey.android.EntryDetailsActivity">

<android.support.design.widget.AppBarLayout
    android:id="@+id/appbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:fitsSystemWindows="true"
    app:elevation="6dp"
    android:theme="@style/AppTheme.AppBarOverlay">

    <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|snap"
        app:contentScrim="@android:color/transparent">

        <ImageView
            android:id="@+id/photo_image"
            android:layout_width="match_parent"
            android:layout_height="300dp"
            android:src="@drawable/demo_photo"
            android:fitsSystemWindows="true"
            android:scaleType="matrix"
            app:layout_collapseMode="parallax"/>

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:theme = "@style/ToolBarStyle"
            app:layout_collapseMode="pin">

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

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

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

<android.support.v4.widget.NestedScrollView 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"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <include layout="@layout/content_layout" />

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

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

Aloysius answered 28/6, 2017 at 22:50 Comment(1)
How can I achieve a reversed version of this?Dicotyledon

© 2022 - 2024 — McMap. All rights reserved.