When a FloatingActionButton is anchored to a CollapsingToolbarLayout, it disappears when you scroll up, reappears when you scroll down after a certain point. I was wondering if you can do that with any type of view. In my app, I'm trying to anchor an ImageView to the CollapsingToolbarLayout but it won't disappear like the FloatingActionButton. Here's the XML code.
<android.support.design.widget.AppBarLayout
android:id="@+id/bar"
android:layout_width="match_parent"
android:layout_height="252dp"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginBottom="32dp"
app:expandedTitleMarginEnd="64dp"
app:expandedTitleMarginStart="48dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/random"
android:fitsSystemWindows="true"
android:scaleType="centerCrop"
app:layout_collapseMode="parallax" />
<android.support.v7.widget.Toolbar
android:id="@+id/anim_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"/>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/scrollableview"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<com.example.sudarshan.testapp.MLRoundedImageView
android:layout_width="152dp"
android:layout_height="152dp"
app:layout_anchor="@+id/bar"
app:layout_anchorGravity="bottom|center"
android:id="@+id/circularImage"/>
</android.support.design.widget.CoordinatorLayout>
The ImageView gets anchored but it does not disappear and reappear like the FAB does.
This behaviour of disappearing and appearing of View is only associated with FAB
(FloatingActionButton
).
You should have a look on the source code of class FloatingActionButton
.
Here is the method in Behavior
class , inner class of FloatingActionButton
which is responsible for the behaviour.
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, FloatingActionButton child,
View dependency) {
if (dependency instanceof Snackbar.SnackbarLayout) {
updateFabTranslationForSnackbar(parent, child, dependency);
} else if (dependency instanceof AppBarLayout) {
// If we're depending on an AppBarLayout we will show/hide it automatically
// if the FAB is anchored to the AppBarLayout
updateFabVisibility(parent, (AppBarLayout) dependency, child);
}
return false;
}
Edit
You can extend the class FloatingActionButton
to achieve what I think you need.
I have extended as follows-
/**
* Sked Series, All rights Reserved
* Created by Sanjeet on 06-Jan-16.
*/
public class FloatingActionImageView extends FloatingActionButton {
public FloatingActionImageView(Context context) {
super(context);
}
public FloatingActionImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public FloatingActionImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public static Bitmap getCroppedBitmap(Bitmap bmp, int radius) {
Bitmap sBmp;
if (bmp.getWidth() != radius || bmp.getHeight() != radius) {
float smallest = Math.min(bmp.getWidth(), bmp.getHeight());
float factor = smallest / radius;
sBmp = Bitmap.createScaledBitmap(bmp, (int) (bmp.getWidth() / factor), (int) (bmp.getHeight() / factor), false);
} else {
sBmp = bmp;
}
Bitmap output = Bitmap.createBitmap(radius, radius,
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, radius + 5, radius + 5);
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(Color.parseColor("#BAB399"));
canvas.drawCircle(radius / 2,
radius / 2, radius / 2, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(sBmp, rect, rect, paint);
return output;
}
@Override
protected void onDraw(@NonNull Canvas canvas) {
Drawable drawable = getDrawable();
if (drawable == null) {
return;
}
if (getWidth() == 0 || getHeight() == 0) {
return;
}
Bitmap b = ((BitmapDrawable) drawable).getBitmap();
Bitmap bitmap = null;
if (b != null) {
bitmap = b.copy(Bitmap.Config.ARGB_8888, true);
} else {
BitmapDrawable bitmapDrawable = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
bitmapDrawable = ((BitmapDrawable) getResources().getDrawable(com.sked.dd.R.drawable.ic_menu_gallery, null));
} else {
bitmapDrawable = ((BitmapDrawable) getResources().getDrawable(com.sked.dd.R.drawable.ic_menu_gallery));
}
if (bitmapDrawable != null) {
bitmap = bitmapDrawable.getBitmap();
}
}
int w = getWidth();
Bitmap roundBitmap = getCroppedBitmap(bitmap, w);
canvas.drawBitmap(roundBitmap, 0, 0, null);
}
}
And here is the output -
Tested and working well
public class RoundedImage extends FloatingActionButton {
public RoundedImage(Context context) {
super(context);
}
public RoundedImage(Context context, AttributeSet attrs) {
super(context, attrs);
}
public RoundedImage(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onDraw(Canvas canvas) {
BitmapDrawable drawable = (BitmapDrawable) getDrawable();
if (drawable == null) {
return;
}
if (getWidth() == 0 || getHeight() == 0) {
return;
}
Bitmap fullSizeBitmap = drawable.getBitmap();
int scaledWidth = getMeasuredWidth();
int scaledHeight = getMeasuredHeight();
Bitmap mScaledBitmap;
if (scaledWidth == fullSizeBitmap.getWidth()
&& scaledHeight == fullSizeBitmap.getHeight()) {
mScaledBitmap = fullSizeBitmap;
} else {
mScaledBitmap = Bitmap.createScaledBitmap(fullSizeBitmap,
scaledWidth, scaledHeight, true );
}
Bitmap circleBitmap = getCircledBitmap(mScaledBitmap);
canvas.drawBitmap(circleBitmap, 0, 0, null);
}
public Bitmap getRoundedCornerBitmap(Context context, Bitmap input,
int pixels, int w, int h, boolean squareTL, boolean squareTR,
boolean squareBL, boolean squareBR) {
Bitmap output = Bitmap.createBitmap(w, h, Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final float densityMultiplier = context.getResources()
.getDisplayMetrics().density;
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, w, h);
final RectF rectF = new RectF(rect);
// make sure that our rounded corner is scaled appropriately
final float roundPx = pixels * densityMultiplier;
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
// draw rectangles over the corners we want to be square
if (squareTL) {
canvas.drawRect(0, 0, w / 2, h / 2, paint);
}
if (squareTR) {
canvas.drawRect(w / 2, 0, w, h / 2, paint);
}
if (squareBL) {
canvas.drawRect(0, h / 2, w / 2, h, paint);
}
if (squareBR) {
canvas.drawRect(w / 2, h / 2, w, h, paint);
}
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(input, 0, 0, paint);
return output;
}
Bitmap getCircledBitmap(Bitmap bitmap) {
Bitmap result = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(result);
int color = Color.BLUE;
Paint paint = new Paint();
Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
// canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
canvas.drawCircle(bitmap.getWidth()/2, bitmap.getHeight()/2, bitmap.getHeight()/2, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return result;
}
}
Then call it in xml
<yourPackageName.RoundedImage
android:id="@+id/singleCompLogo"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_margin="16dp"
android:clickable="true"
android:padding="5dp"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.4"
app:layout_anchor="@id/app_bar_layout"
app:civ_border_width="2dp"
app:layout_anchorGravity="bottom|left|start"
android:src="@mipmap/image" />
Replace yourPackageName with YOUR PACKAGE NAME
Add app:layout_scrollFlags="scroll|enterAlways"
in your Toolbar xml
<android.support.v7.widget.Toolbar
android:id="@+id/anim_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" >
....
</android.support.v7.widget.Toolbar>
Check here
I hope it's helps you.