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)?
Also seen this project but again similar limitation. Other projects as well.
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.
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With