首页 > 系统 > Android > 正文

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

2020-02-21 17:28:58
字体:
来源:转载
供稿:网友

说到微信想想大家都很熟悉,我们在使用微信的时候都会点击微信图片然后看全屏放大的图片,下文是武林技术频道小编介绍的Android仿微信图片点击全屏效果,大家学习的怎样呢?一起来看看吧!

废话不多说,先看下效果:

先是微信的

再是模仿的

先说下实现原理,再一步步分析

这里总共有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; @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;  } }}

具体业务类ShowImageActivity

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; }}

大致流程:
1.在 init()获取了屏幕信息,上一个类传来的参数,以及对坐标点进行了一些计算 ,然后用Handler来启动动画的效果

2.ShowImageView()处理了动画的实现,(动画效果是compile 'com.facebook.rebound:rebound:0.3.8' 实现的,这边不做教程了给出传送门:http://facebook.github.io/rebound/)

总结:

总体实现并不是太难,因为有框架的关系,使得复杂的动画部分不用自己去写,调用下在回调里做业务就行,这里补充下一些过程中用到的技术点

1.图片的缩放模式:
android:scaleType是控制图片如何resized/moved来匹对ImageView的size。

ImageView.ScaleType / android:scaleType值的意义区别:

CENTER /center  按图片的原来size居中显示,当图片长/宽超过View的长/宽,则截取图片的居中部分显示

CENTER_CROP / centerCrop  按比例扩大图片的size居中显示,使得图片长(宽)等于或大于View的长(宽)

CENTER_INSIDE / centerInside  将图片的内容完整居中显示,通过按比例缩小或原来的size使得图片长/宽等于或小于View的长/宽

FIT_CENTER / fitCenter  把图片按比例扩大/缩小到View的宽度,居中显示

FIT_END / fitEnd   把图片按比例扩大/缩小到View的宽度,显示在View的下部分位置

FIT_START / fitStart  把图片按比例扩大/缩小到View的宽度,显示在View的上部分位置

FIT_XY / fitXY  把图片不按比例扩大/缩小到View的大小显示

MATRIX / matrix 用矩阵来绘制,动态缩小放大图片来显示。

** 要注意一点,Drawable文件夹里面的图片命名是不能大写的

2.Layout常用的属性:

// 相对于给定ID控件 android: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的情况,补上内存使用情况图(一直很稳定)

好了,以上就是关于Android仿微信图片点击全屏效果的全部介绍,感谢大家的阅读和支持,希望这篇文章能够给大家带来帮助。还想了解更多,那就关注武林技术频道!

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表