Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CollapsingToolbarLayout image with zoom

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

like image 855
George Avatar asked Jun 28 '17 16:06

George


2 Answers

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.

like image 188
Balamurugan Avatar answered Nov 16 '22 03:11

Balamurugan


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>

like image 2
George Avatar answered Nov 16 '22 01:11

George