Android仿微信图片点击全屏效果_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控件
<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的情况补上内存使用情况图一直很稳定

这里写图片描述

代码地址https://github.com/ddwhan0123/BlogSample/tree/master/ImitateWeChatImage
源码下载地址https://github.com/ddwhan0123/BlogSample/blob/master/ImitateWeChatImage/ImitateWeChatImage.zip?raw=true

以上就是本文的全部内容希望能够帮助大家实现Android仿微信图片点击全屏效果谢谢大家的阅读。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索android 图片点击全屏、android 全屏点击事件、android点击视频全屏、android 点击全屏、android点击波纹效果,以便于您获取更多的相关知识。

时间: 2024-09-07 16:31:30

Android仿微信图片点击全屏效果_Android的相关文章

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

废话不多说,先看下效果: 先是微信的 再是模仿的 先说下实现原理,再一步步分析 这里总共有2个Activity一个就是主页,一个就是显示我们图片效果的页面,参数通过Intent传送,素材内容均来自网络,(感谢聪明的蘑菇) 图片都是Glide异步下的,下的,下的重要的事情说三次,然后就是用动画做放大操作然后显示出来了(并没有做下载原图的实现,反正也是一样 下载下来Set上去而且动画都不需要更简便). OK,我们来看分析下 obj,目录下分别创建了2个对象,一个用来使用来处理显示页面的图片尺寸信息以

Android仿微信图片点击浏览的效果_Android

本篇我们来做一个类似于微信的图片点击浏览的效果,点击小图图片后会放大至全屏显示,且中间有一个2D平滑过渡的效果. 思路如下: 首先,从图片缩略界面跳转到图片详情页面,应该是从一个Activity跳转到另外一个Activity,应该图片详情页面也有很多操作,用View或者Dialog不是很好.所以现在难点就是,如何使得前一个界面的ImageView在另外一个界面做缩放切割动画. 其次,一般缩略界面的ImageView的是正方形的,并且是CENTER_CROP缩放属性的.CENTER_CROP属性会

Android仿微信底部实现Tab选项卡切换效果_Android

在网上看了比较多的关于Tab的教程,发现都很杂乱.比较多的用法是用TitlePagerTabStrip和ViewPaper.不过TitlePagerTabStrip有个很大的缺陷,Tab里面的内容刚进去是没有的,要滑一次才能加载出来.而且滑动的时候,Tab里面的内容位置不是固定的,滑倒最后会出现一片空白,非常不美观.虽然有其他的补救方法,但是非常的麻烦,所以我就按照自己的方法实现了一个,功能不错而且非常简单.  直接点击或者是滑动界面,都可以转到相应的页面. 效果图:  原理是用了三个按钮和Vi

关于微信上网页图片点击全屏放大效果_javascript技巧

实现微信上网页的图片点击后全屏还可以可以缩放,这个功能是别人做的,可是捏点击后屏幕直接黑屏了,图片没有显示出来.这个代码在网上搜一下,挺多类似的. 先上代码. function arrayToJson(o) { var r = []; if (typeof o == "string") return "\"" + o.replace(/([\'\"\\])/g, "\\$1").replace(/(\n)/g, "\

IOS中实现图片点击全屏预览_IOS

如果你感觉累,那就对了那是因为你在走上坡路..这句话似乎有点道理的样子,时常提醒自己无论走到哪都不要忘记自己当初为什么出发.有时想想感觉有的东西可以记录一下,就把它记录下来吧,这次想写一下关于单张图片点击全屏预览的问题,网上查了一些大神写的有的功能确实很强大但自己暂时想要的只是简单的功能就好,还有些方法自己也没弄出想要的效果,最后写了一个比较简单的点击单张图片的全屏预览和双指捏合缩小放大,可能有时要对图片做一些处理,这里放大后只是显示同一张图片并未做处理,下面直接贴出代码 // // ViewC

Android仿微信图片选择器_Android

很多项目要用到图片选择控件,每次都要写一大堆逻辑.于是基于图片选择组件(PhotoPicker)封装了一个控件PhotoUploadView.方便简易,一键集成,几句代码就可以添加类似微信的图片选择控件了.下面介绍一下该控件有些什么特点以及怎么使用.先看图: 效果如上图,点击加号弹出选择框,目前提供了两种形式,一个如图所见的PopupWindow,另一个是MaterialDialog,选择拍照或者从图库获取,从图库获取后就进入图二,选择完之后就图三或图四这里因为很多项目需要不一样,所以特别封装了

Android仿微信QQ设置图形头像裁剪功能_Android

最近在做毕业设计,想有一个功能和QQ一样可以裁剪头像并设置圆形头像,额,这是设计狮的一种潮流. 而纵观现在主流的APP,只要有用户系统这个功能,这个需求一般都是在(bu)劫(de)难(bu)逃(xue)! 图片裁剪实现方式有两种,一种是利用系统自带的裁剪工具,一种是使用开源工具Cropper.本节就为大家带来如何使用系统自带的裁剪工具进行图片裁剪~ 还是先来个简单的运行图. 额,简单说下,我待会会把代码写成小demo分享给大家,在文章末尾会附上github链接,需要的可以自行下载~ 下面来简单分

Android仿百度外卖自定义下拉刷新效果_Android

现如今的APP各式各样,同样也带来了各种需求,一个下拉刷新都能玩出花样了,前两天订饭的时候不经意间看到了"百度外卖"的下拉刷新,今天的主题就是它–自定义下拉刷新动画. 看一下实现效果吧: 动画 我们先来看看Android中的动画吧: Android中的动画分为三种: Tween动画,这一类的动画提供了旋转.平移.缩放等效果. Alpha – 淡入淡出 Scale – 缩放效果 Roate – 旋转效果 Translate – 平移效果 Frame动画(帧动画),这一类动画可以创建一个D

Android仿支付宝中余额宝的数字动画效果_Android

实现效果图: 下面是具体代码,可直接复制: package com.lcw.rabbit.widget; import android.animation.ObjectAnimator; import android.content.Context; import android.text.TextUtils; import android.util.AttributeSet; import android.view.animation.AccelerateDecelerateInterpola