Androidは微信の友达の輪のピクチャーをまねて開いて移行のアニメーションを退出します
12315 ワード
皆さん、こんにちは、最近また絶えず需要を変えて、ついに暇になりました.微信のモーメンツの画像を見て、脱退した移行アニメーションを開くと、ちょうど私たちのプロジェクトにも似たような機能がありますが、変換効果は乾いていて、麻痺していて、少しも丸くありません.大丈夫、彼を殺せ!まず私が実現した効果を見てみましょう.
実現の大まかな原理は、現在クリックしているImageViewの画面内の位置と幅の高さを大図インタフェースに伝え、大図インタフェースに拡大アニメーションを追加することです.同様に、アニメーション取得画面で選択したpositionに対応する外部の現在のpositionのImageViewの位置と幅を縮小するアニメーションを終了します.
まず、すべてのImageViewの位置と幅を取得します.一つもそうです.ここでは、すべてのImageViewの位置の幅を保存し、伝達するために、Parcelableインタフェースを実現するモデルを新規作成しました.期初はすべてのImageViewをIntentで伝えようと思っていたのですが、どのように伝えようか分かりません..知っていることがあれば教えてください.
すべてのアスペクトを巡回してジャンプ
次の肝心なコードはすべて大きい図のインタフェースで、ここで私はViewPager+PhotoViewを使って、あなたはImageViewだけを見てもいいです.コメントはすべてコードの中にあって、役に立たないコードは私はすべて削除して、機能と関係があるコードだけを残しました
以上のコードはすべてですが、プロジェクトに书いてあるので、Demoはありません.
ついでに広告を打って、上の図の展示したAPPは恵购を叫んで、私が独立して开発して、あなたに宝を洗うことができて、京东の大额のクーポンを受け取ることができて、また现金を返すことができて、各大きいアプリケーションのプラットフォームはすべてダウンロードすることができて、私の招待コードを記入することを覚えています(HXFNUN).このアプリをインストールして、何か問題があったら、必ず教えてください.私のテスト機が少なすぎてemmmmが...
実現の大まかな原理は、現在クリックしているImageViewの画面内の位置と幅の高さを大図インタフェースに伝え、大図インタフェースに拡大アニメーションを追加することです.同様に、アニメーション取得画面で選択したpositionに対応する外部の現在のpositionのImageViewの位置と幅を縮小するアニメーションを終了します.
まず、すべてのImageViewの位置と幅を取得します.一つもそうです.ここでは、すべてのImageViewの位置の幅を保存し、伝達するために、Parcelableインタフェースを実現するモデルを新規作成しました.期初はすべてのImageViewをIntentで伝えようと思っていたのですが、どのように伝えようか分かりません..知っていることがあれば教えてください.
package com.kairui.discounts.bean;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Created by fySpring
* Date : 2019-03-19
* To do :
*/
public class ImgOptionEntity implements Parcelable{
private int left;
private int top;
private int width;
private int height;
private String imgUrl;
public ImgOptionEntity() {
}
public ImgOptionEntity(int left,int top, int width, int height) {
this.left = left;
this.top = top;
this.width = width;
this.height = height;
}
protected ImgOptionEntity(Parcel in) {
top = in.readInt();
left = in.readInt();
width = in.readInt();
height = in.readInt();
imgUrl = in.readString();
}
public static final Creator CREATOR = new Creator() {
@Override
public ImgOptionEntity createFromParcel(Parcel in) {
return new ImgOptionEntity(in);
}
@Override
public ImgOptionEntity[] newArray(int size) {
return new ImgOptionEntity[size];
}
};
public int getTop() {
return top;
}
public void setTop(int top) {
this.top = top;
}
public int getLeft() {
return left;
}
public void setLeft(int left) {
this.left = left;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public String getImgUrl() {
return imgUrl;
}
public void setImgUrl(String imgUrl) {
this.imgUrl = imgUrl;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(top);
dest.writeInt(left);
dest.writeInt(width);
dest.writeInt(height);
dest.writeString(imgUrl);
}
}
すべてのアスペクトを巡回してジャンプ
// ImageVIew list,
ArrayList imgDatas = new ArrayList<>();
ArrayList optionEntities = new ArrayList<>();
int[] screenLocationS = new int[2];
for (int i = 0; i < imgDatas.size(); i++) {
ImageView img = imgDatas.get(i);
// ImageView
img.getLocationOnScreen(screenLocationS);
ImgOptionEntity entity = new
ImgOptionEntity(screenLocationS[0],screenLocationS[1],img.getWidth(),img.getHeight());
optionEntities.add(entity);
}
Intent bIntent = new Intent(this, BigImgViewActivity.class);
bIntent.putExtra(ConstantCode.imgPosition, curPosition);
bIntent.putParcelableArrayListExtra(ConstantCode.optionEntities, optionEntities);
startActivity(bIntent);
// Activity Activity
overridePendingTransition(0, 0);
次の肝心なコードはすべて大きい図のインタフェースで、ここで私はViewPager+PhotoViewを使って、あなたはImageViewだけを見てもいいです.コメントはすべてコードの中にあって、役に立たないコードは私はすべて削除して、機能と関係があるコードだけを残しました
/**
* Created by fySpring
* Date : 2019-03-19
* To do :
*/
public class BigImgViewActivity extends BaseActivity implements ViewPager.OnPageChangeListener {
private static final int DURATION = 250;
@Bind(R.id.big_image_list_vp)
private ViewPager imgListVp;
@Bind(R.id.big_image_num_tv)
private TextView imageNumTv;
@Bind(R.id.big_image_bg_rl)
private RelativeLayout bgRl;
private int imgPosition;
private List photoViewList;
//
private int startY;
private int startX;
//
private int startWidth;
private int startHeight;
//X、Y
private int xDelta;
private int yDelta;
//X、Y
private float mWidthScale;
private float mHeightScale;
//
private ColorDrawable colorDrawable;
// photoView
private PhotoView curPhotoView;
//
private ArrayList optionEntities;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_big_image);
initView();
initData();
}
@Override
protected void initView() {
//
StatusBarUtil.setColorNoTranslucent(this, Color.BLACK);
//
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
// ,
colorDrawable = new ColorDrawable(ContextCompat.getColor(this, R.color.black));
bgRl.setBackground(colorDrawable);
}
@Override
protected void initData() {
photoViewList = new ArrayList<>();
imgPosition = getIntent().getIntExtra(ConstantCode.imgPosition, 0);
// ImageView
optionEntities = getIntent().getParcelableArrayListExtra(ConstantCode.optionEntities);
if (optionEntities != null && !optionEntities.isEmpty()) {
//
ImgOptionEntity entity = optionEntities.get(imgPosition);
startY = entity.getTop();
startX = entity.getLeft();
startWidth = entity.getWidth();
startHeight = entity.getHeight();
imageNumTv.setText(imgPosition + 1 + "/" + optionEntities.size());
for (int i = 0; i < optionEntities.size(); i++) {
addItemPhotoView(optionEntities.get(i).getImgUrl());
}
if (optionEntities.size() == 1) imageNumTv.setVisibility(View.GONE);
else imageNumTv.setVisibility(View.VISIBLE);
}
ImageListAdapter imageListAdapter = new ImageListAdapter();
imgListVp.setAdapter(imageListAdapter);
imgListVp.setOnPageChangeListener(this);
imgListVp.setCurrentItem(imgPosition);
if (!photoViewList.isEmpty()) {
curPhotoView = photoViewList.get(imgPosition);
// , 。
ViewTreeObserver observer = curPhotoView.getViewTreeObserver();
observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
curPhotoView.getViewTreeObserver().removeOnPreDrawListener(this);
int[] screenLocation = new int[2];
curPhotoView.getLocationOnScreen(screenLocation);
//
xDelta = startX - screenLocation[0];
yDelta = startY - screenLocation[1];
//
mWidthScale = (float) startWidth / curPhotoView.getWidth();
mHeightScale = (float) startHeight / curPhotoView.getHeight();
enterAnimation(new Runnable() {
@Override
public void run() {
//
}
});
// true , false 。
return true;
}
});
}
}
private void enterAnimation(final Runnable enterAction) {
//
curPhotoView.setPivotX(0);
curPhotoView.setPivotY(0);
curPhotoView.setScaleX(mWidthScale);
curPhotoView.setScaleY(mHeightScale);
curPhotoView.setTranslationX(xDelta);
curPhotoView.setTranslationY(yDelta);
TimeInterpolator sDecelerator = new DecelerateInterpolator();
curPhotoView.animate().setDuration(DURATION).scaleX(1).scaleY(1).
translationX(0).translationY(0).setInterpolator(sDecelerator).withEndAction(enterAction);
//
ObjectAnimator bgAnim = ObjectAnimator.ofInt(colorDrawable, "alpha", 0, 255);
bgAnim.setDuration(DURATION);
bgAnim.start();
}
private void exitAnimation(final Runnable endAction) {
//
curPhotoView.setPivotX(0);
curPhotoView.setPivotY(0);
curPhotoView.setScaleX(1);
curPhotoView.setScaleY(1);
curPhotoView.setTranslationX(0);
curPhotoView.setTranslationY(0);
TimeInterpolator sInterpolator = new AccelerateInterpolator();
curPhotoView.animate().setDuration(DURATION).scaleX(mWidthScale).scaleY(mHeightScale).
translationX(xDelta).translationY(yDelta).setInterpolator(sInterpolator).withEndAction(endAction);
//
ObjectAnimator bgAnim = ObjectAnimator.ofInt(colorDrawable, "alpha", 0);
bgAnim.setDuration(DURATION);
bgAnim.start();
}
@Override
public void onBackPressed() {
int[] screenLocation = new int[2];
curPhotoView.getLocationOnScreen(screenLocation);
xDelta = startX - screenLocation[0];
yDelta = startY - screenLocation[1];
mWidthScale = (float) startWidth / curPhotoView.getWidth();
mHeightScale = (float) startHeight / curPhotoView.getHeight();
exitAnimation(new Runnable() {
public void run() {
//
finish();
overridePendingTransition(0, 0);
}
});
}
private void addItemPhotoView(String imgUrlStr) {
PhotoView photoView = new PhotoView(this);
Glide.with(this)
.load(imgUrlStr)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.crossFade()
.into(photoView);
photoView.setOnPhotoTapListener(new PhotoViewAttacher.OnPhotoTapListener() {
@Override
public void onPhotoTap(View view, float x, float y) {
onBackPressed();
}
});
photoViewList.add(photoView);
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
// ViewPager position ImageView
curPhotoView = photoViewList.get(position);
if (optionEntities != null && !optionEntities.isEmpty()) {
ImgOptionEntity entity = optionEntities.get(position);
startY = entity.getTop();
startX = entity.getLeft();
startWidth = entity.getWidth();
startHeight = entity.getHeight();
imageNumTv.setText(position + 1 + "/" + optionEntities.size());
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
public class ImageListAdapter extends PagerAdapter {
@Override
public int getCount() {
return photoViewList.size();
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
}
/**
* , position
*/
public Object instantiateItem(android.view.ViewGroup container, int position) {
container.addView(photoViewList.get(position));
return photoViewList.get(position);
}
public void destroyItem(android.view.ViewGroup container, int position, Object object) {
container.removeView(photoViewList.get(position));
}
}
}
以上のコードはすべてですが、プロジェクトに书いてあるので、Demoはありません.
ついでに広告を打って、上の図の展示したAPPは恵购を叫んで、私が独立して开発して、あなたに宝を洗うことができて、京东の大额のクーポンを受け取ることができて、また现金を返すことができて、各大きいアプリケーションのプラットフォームはすべてダウンロードすることができて、私の招待コードを記入することを覚えています(HXFNUN).このアプリをインストールして、何か問題があったら、必ず教えてください.私のテスト機が少なすぎてemmmmが...