
再是模仿的

先说下实现原理,再一步步分析
这里总共有2个Activity一个就是主页,一个就是显示我们图片效果的页面,参数通过Intent传送,素材内容均来自网络,(感谢聪明的蘑菇) 图片都是Glide异步下的,下的,下的重要的事情说三次,然后就是用动画做放大操作然后显示出来了(并没有做下载原图的实现,反正也是一样 下载下来Set上去而且动画都不需要更简便)。
OK,我们来看分析下
obj,目录下分别创建了2个对象,一个用来使用来处理显示页面的图片尺寸信息以及位置信息,还有一个是用来附带URL和分辨率
Config这个类就是我们的URL了没其他什么内容。
我们一个一个页面来看,先看MainActivity
他做的事情很简单,就是把下个页面的一些信息初始化一下然后通过Intent传过去,本身不做什么多余操作
package wjj.com.imitatewechatimage.activity;import android.content.Intent;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.ImageView;import wjj.com.imitatewechatimage.R;import com.apkfuns.logutils.LogUtils;import com.bumptech.glide.Glide;import wjj.com.imitatewechatimage.Config;import wjj.com.imitatewechatimage.obj.ImageInfoObj;import wjj.com.imitatewechatimage.obj.ImageWidgetInfoObj;public class MainActivity extends AppCompatActivity implements View.OnClickListener {private ImageView imageView;private ImageInfoObj imageInfoObj;private ImageWidgetInfoObj imageWidgetInfoObj;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);findId();init();Listener();}private void findId() {imageView = (ImageView) findViewById(R.id.imageView);}private void init() {Glide.with(MainActivity.this).load(Config.IMAGE_URL).placeholder(R.mipmap.maimai).into(imageView);imageInfoObj = new ImageInfoObj();imageInfoObj.imageUrl = Config.IMAGE_URL;imageInfoObj.imageWidth = 1280;imageInfoObj.imageHeight = 720;imageWidgetInfoObj = new ImageWidgetInfoObj();imageWidgetInfoObj.x = imageView.getLeft();imageWidgetInfoObj.y = imageView.getTop();imageWidgetInfoObj.width = imageView.getLayoutParams().width;imageWidgetInfoObj.height = imageView.getLayoutParams().height;}private void Listener() {imageView.setOnClickListener(this);}@Overrideprotected void onResume() {super.onResume();LogUtils.d("--->MainActivity onResume");}@Overrideprotected void onPause() {super.onPause();LogUtils.d("--->MainActivity onPause");}@Overrideprotected void onDestroy() {super.onDestroy();LogUtils.d("--->MainActivity onDestroy");}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.imageView://携带参数跳转Intent intent = new Intent(MainActivity.this, howImageActivity.class);intent.putExtra("imageInfoObj", imageInfoObj);intent.putExtra("imageWidgetInfoObj", imageWidgetInfoObj);startActivity(intent);break;default:break;}}}具体业务类ShowImageActivitypublic class ShowImageActivity extends AppCompatActivity {private RelativeLayout MainView;private ImageView showImageView;private ImageInfoObj imageInfoObj;private ImageWidgetInfoObj imageWidgetInfoObj;Button button;// 屏幕宽度public float Width;//原图高private float y_img_h;// 屏幕高度public float Height;private float size, size_h, img_w, img_h;protected float to_x = 0;protected float to_y = 0;private float tx;private float ty;private final Spring spring = SpringSystem.create().createSpring().addListener(new ExampleSpringListener());@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_how_image);LogUtils.d("--->ShowImageActivity onCreate");findId();init();Listener();}private void findId() {MainView = (RelativeLayout) findViewById(R.id.MainView);button = (Button) findViewById(R.id.button);}private void init() {DisplayMetrics dm = getResources().getDisplayMetrics();Width = dm.widthPixels;Height = dm.heightPixels;imageInfoObj = (ImageInfoObj) getIntent().getSerializableExtra("imageInfoObj");imageWidgetInfoObj = (ImageWidgetInfoObj) getIntent().getSerializableExtra("imageWidgetInfoObj");if (imageInfoObj == null) {LogUtils.d("--->imageInfoObj==null");}if (imageWidgetInfoObj == null) {LogUtils.d("--->imageWidgetInfoObj==null");}showImageView = new ImageView(this);showImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);Glide.with(ShowImageActivity.this).load(imageInfoObj.imageUrl).into(showImageView);img_w = imageWidgetInfoObj.width;img_h = imageWidgetInfoObj.height - 300;size = Width / img_w;y_img_h = imageInfoObj.imageHeight * Width / imageInfoObj.imageWidth;size_h = y_img_h / img_h;RelativeLayout.LayoutParams p = new RelativeLayout.LayoutParams((int) imageWidgetInfoObj.width,(int) imageWidgetInfoObj.height);p.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);p.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);showImageView.setLayoutParams(p);p.setMargins((int) imageWidgetInfoObj.x,(int) imageWidgetInfoObj.y, (int) (Width - (imageWidgetInfoObj.x + imageWidgetInfoObj.width)),(int) (Height - (imageWidgetInfoObj.y + imageWidgetInfoObj.height)));MainView.addView(showImageView);new Handler().post(new Runnable() {public void run() {ShowImageView();}});}private void Listener() {showImageView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {ShowImageView();}});button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {ShowImageView();}});}@Overrideprotected void onResume() {super.onResume();LogUtils.d("--->ShowImageActivity onResume");}@Overrideprotected void onPause() {super.onPause();LogUtils.d("--->ShowImageActivity onPause");}@Overrideprotected void onDestroy() {super.onDestroy();LogUtils.d("--->ShowImageActivity onDestroy");}private class ExampleSpringListener implements SpringListener {@Overridepublic void onSpringUpdate(Spring spring) {double CurrentValue = spring.getCurrentValue();float mappedValue = (float) SpringUtil.mapValueFromRangeToRange(CurrentValue, 0, 1, 1, size);float mapy = (float) SpringUtil.mapValueFromRangeToRange(CurrentValue, 0, 1, 1, size_h);showImageView.setScaleX(mappedValue);showImageView.setScaleY(mapy);if (CurrentValue == 1) {//showImageView.setVisibility(View.GONE);}}@Overridepublic void onSpringAtRest(Spring spring) {}@Overridepublic void onSpringActivate(Spring spring) {}@Overridepublic void onSpringEndStateChange(Spring spring) {}}//实现效果private void MoveView() {ObjectAnimator.ofFloat(MainView, "alpha", 0.8f).setDuration(0).start();MainView.setVisibility(View.VISIBLE);AnimatorSet set = new AnimatorSet();set.playTogether(ObjectAnimator.ofFloat(showImageView, "translationX", tx).setDuration(200),ObjectAnimator.ofFloat(showImageView, "translationY", ty).setDuration(200),ObjectAnimator.ofFloat(MainView, "alpha", 1).setDuration(200));set.addListener(new Animator.AnimatorListener() {@Overridepublic void onAnimationStart(Animator animator) {}@Overridepublic void onAnimationEnd(Animator animator) {showImageView.setScaleType(ImageView.ScaleType.FIT_XY);spring.setEndValue(1);}@Overridepublic void onAnimationCancel(Animator animator) {}@Overridepublic void onAnimationRepeat(Animator animator) {}});set.start();}//关闭页面private void MoveBackView() {AnimatorSet set = new AnimatorSet();set.playTogether(ObjectAnimator.ofFloat(showImageView, "translationX", to_x).setDuration(200),ObjectAnimator.ofFloat(showImageView, "translationY", to_y).setDuration(200));set.addListener(new Animator.AnimatorListener() {@Overridepublic void onAnimationStart(Animator animator) {}@Overridepublic void onAnimationEnd(Animator animator) {finish();}@Overridepublic void onAnimationCancel(Animator animator) {}@Overridepublic void onAnimationRepeat(Animator animator) {}});set.start();}//具体动画处理类private void ShowImageView() {if (spring.getEndValue() == 0) {//弹动摩擦力spring.setSpringConfig(SpringConfig.fromOrigamiTensionAndFriction(300, 5));//动画结束后出现的位置tx = 0;ty = Height / 2 - (imageWidgetInfoObj.y + img_h + 600);MoveView();return;}spring.setSpringConfig(SpringConfig.fromOrigamiTensionAndFriction(1, 5));spring.setEndValue(0);new Handler().post(new Runnable() {public void run() {MoveBackView();}});}@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {if (keyCode == KeyEvent.KEYCODE_BACK) {showImageView.setVisibility(View.VISIBLE);ShowImageView();}return true;}}大致流程: // 相对于给定ID控件 <a href="http://lib.csdn.net/base/15" class="replace_word" title="undefined" target="_blank" style="color: rgb(223, 52, 52); font-weight: bold;">android</a>:layout_above 将该控件的底部置于给定ID的控件之上; android:layout_below 将该控件的底部置于给定ID的控件之下; android:layout_toLeftOf 将该控件的右边缘与给定ID的控件左边缘对齐; android:layout_toRightOf 将该控件的左边缘与给定ID的控件右边缘对齐;android:layout_alignBaseline 将该控件的baseline与给定ID的baseline对齐; android:layout_alignTop 将该控件的顶部边缘与给定ID的顶部边缘对齐; android:layout_alignBottom 将该控件的底部边缘与给定ID的底部边缘对齐; android:layout_alignLeft 将该控件的左边缘与给定ID的左边缘对齐; android:layout_alignRight 将该控件的右边缘与给定ID的右边缘对齐; // 相对于父组件 android:layout_alignParentTop 如果为true,将该控件的顶部与其父控件的顶部对齐; android:layout_alignParentBottom 如果为true,将该控件的底部与其父控件的底部对齐; android:layout_alignParentLeft 如果为true,将该控件的左部与其父控件的左部对齐; android:layout_alignParentRight 如果为true,将该控件的右部与其父控件的右部对齐; // 居中 android:layout_centerHorizontal 如果为true,将该控件的置于水平居中; android:layout_centerVertical 如果为true,将该控件的置于垂直居中; android:layout_centerInParent 如果为true,将该控件的置于父控件的中央; // 指定移动像素 android:layout_marginTop 上偏移的值; android:layout_marginBottom 下偏移的值; android:layout_marginLeft 左偏移的值; android:layout_marginRight 右偏移的值;这个例子只是例子,部分坐标和样式是写死的,如果要运用到实际项目中还是要些许就该,在操作的过程中还对加载多图片进行了测试,暂未发生OOM的情况,补上内存使用情况图(一直很稳定)