Ответ 1
Хорошо, я нашел возможный способ сделать это. Я сделал layoutParams как переменные, которые продолжают меняться с помощью ObjectAnimator в девятой библиотеке Android.. я думаю, что это не лучший способ добиться этого, поскольку он вызывает много onDraw и onLayout, но если контейнер имеет только несколько просмотров и не меняет его размер, возможно, это нормально.
предполагается, что изображениеView, которое я animate, в конечном итоге примет нужный размер, и что (в настоящее время) и миниатюра, и анимированное изображениеView имеют один и тот же контейнер (но его легко изменить.
как я протестировал, также можно добавить функции масштабирования, расширив класс TouchImageView. вы просто устанавливаете тип шкалы в начале для обрезки по центру, и когда анимация заканчивается, вы возвращаете ее обратно в матрицу, и если хотите, вы можете установить 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);
}
}