将 ImageView 锚定到折叠工具栏
Posted
技术标签:
【中文标题】将 ImageView 锚定到折叠工具栏【英文标题】:Anchor ImageView to Collapsing Toolbar 【发布时间】:2016-04-10 12:09:03 【问题描述】:当 FloatingActionButton 锚定到 CollapsingToolbarLayout 时,它会在您向上滚动时消失,在您向下滚动到某个点后重新出现。我想知道您是否可以使用任何类型的视图来做到这一点。在我的应用程序中,我试图将 ImageView 锚定到 CollapsingToolbarLayout 但它不会像 FloatingActionButton 那样消失。这是 XML 代码。
<android.support.design.widget.AppBarLayout
android:id="@+id/bar"
android:layout_
android:layout_
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_
android:layout_
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_
android:layout_
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_
android:layout_
app:layout_collapseMode="pin"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" >
<ImageView
android:layout_
android:layout_
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_
android:layout_
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<com.example.sudarshan.testapp.MLRoundedImageView
android:layout_
android:layout_
app:layout_anchor="@+id/bar"
app:layout_anchorGravity="bottom|center"
android:id="@+id/circularImage"/>
</android.support.design.widget.CoordinatorLayout>
ImageView 被锚定,但它不会像 FAB 那样消失和重新出现。
【问题讨论】:
【参考方案1】:这种View消失和出现的行为只与FAB
(FloatingActionButton
)相关。
你应该看看FloatingActionButton
类的源代码。
这是Behavior
类中的方法,FloatingActionButton
的内部类负责该行为。
@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;
编辑
你可以扩展 FloatingActionButton
类来实现我认为你需要的。
我已经扩展如下-
/**
* 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);
这是输出 -
【讨论】:
真是一个绝妙的解决方案。谢谢【参考方案2】:经过测试并运行良好
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;
然后在xml中调用
<yourPackageName.RoundedImage
android:id="@+id/singleCompLogo"
android:layout_
android:layout_
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_
app:layout_anchorGravity="bottom|left|start"
android:src="@mipmap/image" />
用你的包名替换你的包名
【讨论】:
【参考方案3】:在您的工具栏 xml 中添加 app:layout_scrollFlags="scroll|enterAlways"
<android.support.v7.widget.Toolbar
android:id="@+id/anim_toolbar"
android:layout_
android:layout_
app:layout_collapseMode="pin"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" >
....
</android.support.v7.widget.Toolbar>
查看here
希望对你有帮助。
【讨论】:
以上是关于将 ImageView 锚定到折叠工具栏的主要内容,如果未能解决你的问题,请参考以下文章
如何将 UIAlertController 操作表锚定到特定单元格 UICollectionView?