gpt4 book ai didi

android - 如何从中心裁剪为 ImageView 设置动画以填充屏幕,反之亦然(facebook 风格)?

转载 作者:IT老高 更新时间:2023-10-28 22:22:56 40 4
gpt4 key购买 nike

背景

Facebook 应用在帖子上的小图像和用户也可以放大的放大模式之间有一个很好的过渡动画。

在我看来,动画不仅根据之前的位置和大小放大和移动了imageView,而且还显示了内容,而不是拉伸(stretch)了imageView的内容。

使用我制作的下一个草图可以看到这一点:

enter image description here

问题

他们是怎么做到的?他们真的有 2 个 View 动画来显示内容吗?

他们是如何让它变得像单一 View 一样流畅?

我见过的唯一一个教程(链接 here)在将缩略图设置为中心裁剪时无法很好地显示放大到全屏的图像。

不仅如此,它甚至可以在 Android 的低 API 上运行。

有人知道有类似能力的图书馆吗?


编辑:我找到了方法和posted an answer ,但它基于更改 layoutParams ,我认为它效率不高且推荐。

我尝试过使用普通动画和其他动画技巧,但目前这对我来说是唯一有效的方法。

如果有人知道该怎么做才能使其以更好的方式工作,请写下来。

最佳答案

好的,我找到了一种可行的方法。我已经使用 nineOldAndroids library 的 ObjectAnimator 将 layoutParams 设置为不断变化的变量。 .我认为这不是实现它的最佳方法,因为它会导致很多 onDraw 和 onLayout,但如果容器只有几个 View 并且不改变其大小,也许没关系。

假设我制作动画的 imageView 最终将采用所需的确切大小,并且(当前)缩略图和动画 imageView 具有相同的容器(但应该很容易更改它。

正如我测试过的,还可以通过扩展 TouchImageView 来添加缩放功能。类(class) 。您只需在开始时将缩放类型设置为 center-crop,然后在动画结束时将其设置回矩阵,如果需要,您可以将 layoutParams 设置为填充整个容器(并将边距设置为 0,0 )。

我也想知道为什么 AnimatorSet 不适合我,所以我将在这里展示一些有效的东西,希望有人能告诉我应该怎么做。

代码如下:

MainActivity.java

public class MainActivity extends Activity {
private static final int IMAGE_RES_ID = R.drawable.test_image_res_id;
private static final int ANIM_DURATION = 5000;
private final Handler mHandler = new Handler();
private ImageView mThumbnailImageView;
private CustomImageView mFullImageView;
private Point mFitSizeBitmap;

@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mFullImageView = (CustomImageView) findViewById(R.id.fullImageView);
mThumbnailImageView = (ImageView) findViewById(R.id.thumbnailImageView);
mHandler.postDelayed(new Runnable() {

@Override
public void run() {
prepareAndStartAnimation();
}

}, 2000);
}

private void prepareAndStartAnimation() {
final int thumbX = mThumbnailImageView.getLeft(), thumbY = mThumbnailImageView.getTop();
final int thumbWidth = mThumbnailImageView.getWidth(), thumbHeight = mThumbnailImageView.getHeight();
final View container = (View) mFullImageView.getParent();
final int containerWidth = container.getWidth(), containerHeight = container.getHeight();
final Options bitmapOptions = getBitmapOptions(getResources(), IMAGE_RES_ID);
mFitSizeBitmap = getFitSize(bitmapOptions.outWidth, bitmapOptions.outHeight, containerWidth, containerHeight);

mThumbnailImageView.setVisibility(View.GONE);
mFullImageView.setVisibility(View.VISIBLE);
mFullImageView.setContentWidth(thumbWidth);
mFullImageView.setContentHeight(thumbHeight);
mFullImageView.setContentX(thumbX);
mFullImageView.setContentY(thumbY);
runEnterAnimation(containerWidth, containerHeight);
}

private Point getFitSize(final int width, final int height, final int containerWidth, final int containerHeight) {
int resultHeight, resultWidth;
resultHeight = height * containerWidth / width;
if (resultHeight <= containerHeight) {
resultWidth = containerWidth;
} else {
resultWidth = width * containerHeight / height;
resultHeight = containerHeight;
}
return new Point(resultWidth, resultHeight);
}

public void runEnterAnimation(final int containerWidth, final int containerHeight) {
final ObjectAnimator widthAnim = ObjectAnimator.ofInt(mFullImageView, "contentWidth", mFitSizeBitmap.x)
.setDuration(ANIM_DURATION);
final ObjectAnimator heightAnim = ObjectAnimator.ofInt(mFullImageView, "contentHeight", mFitSizeBitmap.y)
.setDuration(ANIM_DURATION);
final ObjectAnimator xAnim = ObjectAnimator.ofInt(mFullImageView, "contentX",
(containerWidth - mFitSizeBitmap.x) / 2).setDuration(ANIM_DURATION);
final ObjectAnimator yAnim = ObjectAnimator.ofInt(mFullImageView, "contentY",
(containerHeight - mFitSizeBitmap.y) / 2).setDuration(ANIM_DURATION);
widthAnim.start();
heightAnim.start();
xAnim.start();
yAnim.start();
// TODO check why using AnimatorSet doesn't work here:
// final com.nineoldandroids.animation.AnimatorSet set = new AnimatorSet();
// set.playTogether(widthAnim, heightAnim, xAnim, yAnim);
}

public static BitmapFactory.Options getBitmapOptions(final Resources res, final int resId) {
final BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmapOptions.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, bitmapOptions);
return bitmapOptions;
}

}

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >

<com.example.facebookstylepictureanimationtest.CustomImageView
android:id="@+id/fullImageView"
android:layout_width="0px"
android:layout_height="0px"
android:background="#33ff0000"
android:scaleType="centerCrop"
android:src="@drawable/test_image_res_id"
android:visibility="invisible" />

<ImageView
android:id="@+id/thumbnailImageView"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:scaleType="centerCrop"
android:src="@drawable/test_image_res_id" />

</RelativeLayout>

CustomImageView.java

public class CustomImageView extends ImageView {
public CustomImageView(final Context context) {
super(context);
}

public CustomImageView(final Context context, final AttributeSet attrs) {
super(context, attrs);
}

public CustomImageView(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
}

public void setContentHeight(final int contentHeight) {
final LayoutParams layoutParams = getLayoutParams();
layoutParams.height = contentHeight;
setLayoutParams(layoutParams);
}

public void setContentWidth(final int contentWidth) {
final LayoutParams layoutParams = getLayoutParams();
layoutParams.width = contentWidth;
setLayoutParams(layoutParams);
}

public int getContentHeight() {
return getLayoutParams().height;
}

public int getContentWidth() {
return getLayoutParams().width;
}

public int getContentX() {
return ((MarginLayoutParams) getLayoutParams()).leftMargin;
}

public void setContentX(final int contentX) {
final MarginLayoutParams layoutParams = (MarginLayoutParams) getLayoutParams();
layoutParams.leftMargin = contentX;
setLayoutParams(layoutParams);
}

public int getContentY() {
return ((MarginLayoutParams) getLayoutParams()).topMargin;
}

public void setContentY(final int contentY) {
final MarginLayoutParams layoutParams = (MarginLayoutParams) getLayoutParams();
layoutParams.topMargin = contentY;
setLayoutParams(layoutParams);
}

}

关于android - 如何从中心裁剪为 ImageView 设置动画以填充屏幕,反之亦然(facebook 风格)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19519921/

40 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com