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

转载请注明出处:王亟亟的大牛之路

昨天想着模仿写些什么,然后觉得什么仿京东啊,仿美团之类的外面都有,正好又找到点资源就写了这篇“高仿微信图片放大”

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

先是微信的

再是模仿的

包目录

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

这里总共有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.图片的缩放模式:http://blog.csdn.net/encienqi/article/details/7913262

2.Layout常用的属性:http://blog.csdn.net/richway2010/article/details/6587842

这个例子只是例子,部分坐标和样式是写死的,如果要运用到实际项目中还是要些许就该,在操作的过程中还对加载多图片进行了测试,暂未发生OOM的情况,补上内存使用情况图(一直很稳定)

代码地址:https://github.com/ddwhan0123/BlogSample/tree/master/ImitateWeChatImage

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

Thanks for DavidWang

时间: 2024-11-06 11:45:11

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

微信上 网页图片点击全屏放大

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

js 实现浏览器全屏效果

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>quanping</title> </head> <body> <div id="div" onclick="fullScreen()">全屏</div> <div

Android浏览图片,点击放大至全屏效果

最近做一个项目类似于QQ空间,做到照片浏览的功能,对于QQ空间中点击图片放大至全屏,感觉效果很赞,于是也做了个类似的效果.如下. 我不知道QQ那个是怎么做的,我的思路如下: 首先,从图片缩略界面跳转到图片详情页面,应该是从一个Activity跳转到另外一个Activity,应该图片详情页面也有很多操作,用View或者Dialog不是很好.所以现在难点就是,如何使得前一个界面的ImageView在另外一个界面做缩放切割动画. 一般缩略界面的ImageView的是如上图所示的正方形的,并且是CENT

10个Web前端值得收藏的背景全屏效果展示(附源码)(上)

作为一个前沿的 Web 开发者,对于 HTML5 和 现在流行的3D技术或多或少都有掌握.特别是在移动端大显身手.这篇文章挑选了10个绚丽的背景全景展示效果,希望对你有所帮助. 1.  JS图片背景全屏代码实现物理效果 玩法介绍:可以随意拖动鼠标.按住鼠标左键选中旋转物体.或者按住鼠标滑轮放大或者缩小,有不同的效果,赶紧来体验一下. 源码下载  /  在线演示 2.  CSS3学习 - 网站背景拉伸平铺jQuery插件 这个插件集成了一些非常好的 JavaScript 库,提供一个方便使用的文本

可嵌入图片视频jQuery全屏滑块

分享一款可嵌入图片视频jQuery全屏滑块.这是一款可定制的滑块幻灯片代码,支持键盘箭头切换.效果图如下: 在线预览   源码下载 实现的代码. html代码: <script type="text/javascript" src="js/jquery-1.10.0.min.js"></script> <script type="text/javascript" src="js/Animo.min.js&q

kindedtor点击全屏变空白页面

kindeditor编辑器点击全屏后显示一片空白,打开调试有美容,发现行内样式有一条height:1px; 1. 查找页面包含的kindeditor JS 处理文件,找到height:1px;将之屏蔽即可.

一行代码设置 DrawerLayout 全屏效果

DrawerLayout 默认使用时,侧拉出来的效果会有一点缩进效果,既然它是缩进,那我们直接反向操作,给它缩进一个负值不就好了嘛,直接看代码: <!-- 第二个视图放抽屉 --> <android.support.design.widget.NavigationView android:id="@+id/navigation_view" android:layout_width="match_parent" android:layout_heig

swiper.js-搭建微信、手机端全屏广告效果

swiper.js http://www.swiper.com.cn/  官方网站,下载的类库和要用那些api我们都需在这里查找 http://www.swiper.com.cn/demo/senior/index.html各种效果,我们要做的就是这种 我们简单发现,就是每一屛会出现动画(css3 animation),切换的当前屏会重新执行动画,可推出,没显示的屏删除了动画 看我们发现了什么?看第一张firebug截图 每一屛就是一个section标签, 在当前显示的section上有了其他兄

通过设置虚拟机(ubantu15.10)的分辨率达到全屏效果

最近搭建了一个ubantu 15.10虚拟机,怎么折腾都不能全屏显示.虽然我已经点了,  还是无法达到真正的全屏. 查了一下,http://jingyan.baidu.com/article/0964eca2351ed58285f5361d.html  这样可以哦. 提示 : Unkonwn Display时,别担心,继续点击apply应用即可.