模仿微信图片点击全屏效果

Jupiter 8年前
   <p>昨天想着模仿写些什么,然后觉得什么仿京东啊,仿美团之类的外面都有,正好又找到点资源就写了这篇“高仿微信图片放大”</p>    <p>废话不多说,先看下效果:</p>    <p>先是微信的</p>    <p><img alt="这里写图片描述" src="https://simg.open-open.com/show/b90974b0f1fdd8bd119ad1eb540e4400.gif"></p>    <p>再是模仿的</p>    <p><img alt="这里写图片描述" src="https://simg.open-open.com/show/5a04c193c29c203493785b9f7b5d8a26.gif"></p>    <p>包目录</p>    <p><img alt="这里写图片描述" src="https://simg.open-open.com/show/f09510793190afd0080f608574185919.png"></p>    <p>先说下实现原理,再一步步分析</p>    <p>这里总共有2个Activity一个就是主页,一个就是显示我们图片效果的页面,参数通过Intent传送,素材内容均来自网络,(感谢<a href="http://weibo.com/2657719753/profile?topnav=1&wvr=6">聪明的蘑菇</a>) 图片都是<strong>Glide</strong>异步下的,下的,下的重要的事情说三次,然后就是用动画做放大操作然后显示出来了(并没有做下载原图的实现,反正也是一样 下载下来Set上去而且动画都不需要更简便)。</p>    <p>OK,我们来看分析下</p>    <p>obj,目录下分别创建了2个对象,一个用来使用来处理显示页面的图片尺寸信息以及位置信息,还有一个是用来附带URL和分辨率</p>    <p>Config这个类就是我们的URL了没其他什么内容。</p>    <p>我们一个一个页面来看,先看MainActivity</p>    <p>他做的事情很简单,就是把下个页面的一些信息初始化一下然后通过Intent传过去,本身不做什么多余操作</p>    <pre>  <code class="language-java">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;        @Override      protected 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);      }        @Override      protected void onResume() {          super.onResume();          LogUtils.d("--->MainActivity onResume");      }        @Override      protected void onPause() {          super.onPause();          LogUtils.d("--->MainActivity onPause");      }        @Override      protected void onDestroy() {          super.onDestroy();          LogUtils.d("--->MainActivity onDestroy");      }        @Override      public 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;          }      }  }  </code></pre>    <p>具体业务类ShowImageActivity</p>    <pre>  <code class="language-java">public 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());        @Override      protected 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() {              @Override              public void onClick(View v) {                  ShowImageView();              }          });            button.setOnClickListener(new View.OnClickListener() {              @Override              public void onClick(View v) {                  ShowImageView();              }          });      }        @Override      protected void onResume() {          super.onResume();          LogUtils.d("--->ShowImageActivity onResume");      }        @Override      protected void onPause() {          super.onPause();          LogUtils.d("--->ShowImageActivity onPause");      }        @Override      protected void onDestroy() {          super.onDestroy();          LogUtils.d("--->ShowImageActivity onDestroy");      }        private class ExampleSpringListener implements SpringListener {            @Override          public 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);              }          }            @Override          public void onSpringAtRest(Spring spring) {            }            @Override          public void onSpringActivate(Spring spring) {            }            @Override          public 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() {              @Override              public void onAnimationStart(Animator animator) {                }                @Override              public void onAnimationEnd(Animator animator) {                  showImageView.setScaleType(ImageView.ScaleType.FIT_XY);                  spring.setEndValue(1);              }                @Override              public void onAnimationCancel(Animator animator) {                }                @Override              public 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() {              @Override              public void onAnimationStart(Animator animator) {                }                @Override              public void onAnimationEnd(Animator animator) {                  finish();              }                @Override              public void onAnimationCancel(Animator animator) {                }                @Override              public 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();              }          });        }        @Override      public boolean onKeyDown(int keyCode, KeyEvent event) {          if (keyCode == KeyEvent.KEYCODE_BACK) {                showImageView.setVisibility(View.VISIBLE);              ShowImageView();            }          return true;      }    }</code></pre>    <p>大致流程:<br> 1.在 init()获取了屏幕信息,上一个类传来的参数,以及对坐标点进行了一些计算 ,然后用Handler来启动动画的效果</p>    <p>2.ShowImageView()处理了动画的实现,(动画效果是<code>compile 'com.非死book.rebound:rebound:0.3.8'</code> 实现的,这边不做教程了给出传送门:<a href="/misc/goto?guid=4958822653952750826">http://非死book.github.io/rebound/</a>)</p>    <p>总结:</p>    <p>总体实现并不是太难,因为有框架的关系,使得复杂的动画部分不用自己去写,调用下在回调里做业务就行,这里补充下一些过程中用到的技术点</p>    <p>1.图片的缩放模式:<a href="/misc/goto?guid=4959670837799118701">http://blog.csdn.net/encienqi/article/details/7913262</a></p>    <p>2.Layout常用的属性:<a href="/misc/goto?guid=4959670837876698642">http://blog.csdn.net/richway2010/article/details/6587842</a></p>    <p>这个例子只是例子,部分坐标和样式是写死的,如果要运用到实际项目中还是要些许就该,在操作的过程中还对加载多图片进行了测试,暂未发生OOM的情况,补上内存使用情况图(一直很稳定)</p>    <p><img alt="这里写图片描述" src="https://simg.open-open.com/show/bbcb3f347bd74c2e0af922d78a0d0392.png"></p>    <p>代码地址:<a href="/misc/goto?guid=4959670837961584257">https://github.com/ddwhan0123/BlogSample/tree/master/ImitateWeChatImage</a><br> 源码下载地址:<a href="/misc/goto?guid=4959670838042357685">https://github.com/ddwhan0123/BlogSample/blob/master/ImitateWeChatImage/ImitateWeChatImage.zip?raw=true</a></p>    <p>来自: <a href="/misc/goto?guid=4959670838112791900" rel="nofollow">http://blog.csdn.net/ddwhan0123/article/details/51143191</a></p>