仿Win8图标按下回弹效果

转载 2018年04月16日 16:52:54

本文参考鸿洋大神的文章
https://blog.csdn.net/lmj623565791/article/details/23441455

效果如图:
这里写图片描述

布局如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   tools:context="com.yeaper.contentproviderdemo.MainActivity"
   android:background="#af3fdf">

   <LinearLayout
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:orientation="vertical"
       android:layout_centerInParent="true">

       <com.yeaper.contentproviderdemo.widget.SFImageView
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:src="@drawable/timg"
           android:scaleType="matrix" />

       <LinearLayout
           android:layout_width="wrap_content"
           android:layout_height="wrap_content">

           <com.yeaper.contentproviderdemo.widget.SFImageView
               android:id="@+id/sf_iv_avatar"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:src="@drawable/timg"
               android:scaleType="matrix" />

           <com.yeaper.contentproviderdemo.widget.SFImageView
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:src="@drawable/timg"
               android:scaleType="matrix" />

       </LinearLayout>

       <com.yeaper.contentproviderdemo.widget.SFImageView
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:src="@drawable/timg"
           android:scaleType="matrix" />
   </LinearLayout>
</RelativeLayout>

自定义ImageView代码如下:

1. 缩放常量的取值

    float val = 1;   
    float s = 0.85f;  
    int i = 0;  
    s = (float) Math.sqrt(1 / s);  
    System.out.println(val);  
    while (i < 5)  
    {  
        val = val *s ;  
        System.out.println(val);  
        i++;  
    }  
    s = 0.85f;  
    i = 0;  
    s = (float) Math.sqrt(s);  
    while (i < 5)  
    {  
        val = val *s ;  
        System.out.println(val);  
        i++;  
    }  

输出结果如下:

    1.0  
    1.0846523  
    1.1764706  
    1.2760615  
    1.384083  
    1.5012488  
    1.384083  
    1.2760615  
    1.1764706  
    1.0846523  
    1.0  

基本是个对称的梯度数据,梯度的幅度由代码中的s控制

2.拦截点击事件,使用Handler,通过不断改变缩放值,控制缩放变换
共有三种状态:
1. SCALE_REDUCE_INIT 收缩开始
2. SCALING 缩放中
3. SCALE_ADD_INIT 扩大开始

3.matrix.postScale的使用
缩放锚点为图片的中心,即宽高的一半,postScale为前后乘matrix矩阵

整体代码:

public class SFImageView extends android.support.v7.widget.AppCompatImageView {

    private static final int SCALE_REDUCE_INIT = 0; //收缩开始状态
    private static final int SCALING = 1; //缩放中状态
    private static final int SCALE_ADD_INIT = 2; //扩张开始状态

    private int mWidth;
    private int mHeight;
    private float mCenterWidth;
    private float mCenterHeight;

    /**
     * 设置一个缩放的常量
     */
    private float mMinScale = 0.85f;
    /**
     * 缩放是否结束
     */
    private boolean isFinish = true;

    public SFImageView(Context context) {
        this(context, null);
    }

    public SFImageView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SFImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }


    @Override
    public void layout(int l, int t, int r, int b) {
        super.layout(l, t, r, b);

        mWidth = getWidth() - getPaddingLeft() - getPaddingRight();
        mHeight = getHeight() - getPaddingTop() - getPaddingBottom();

        mCenterWidth = mWidth/2;
        mCenterHeight = mHeight/2;

        Drawable drawable = getDrawable();
        BitmapDrawable bd = (BitmapDrawable) drawable;
        bd.setAntiAlias(true); //取消锯齿
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mScaleHandler.sendEmptyMessage(SCALE_REDUCE_INIT);
                break;
            case MotionEvent.ACTION_UP:
                mScaleHandler.sendEmptyMessage(SCALE_ADD_INIT);
                break;
        }
        return true;
    }

    /**
     * 控制缩放的Handler
     */
    @SuppressLint("HandlerLeak")
    private Handler mScaleHandler = new Handler() {

        private Matrix matrix = new Matrix();
        private int count = 0;
        private float s;
        private float v;
        /**
         * 是否已经调用了点击事件
         */
        private boolean isClicked = false;

        /**
         * 1.收缩时,s0=sqrt(0.85),v0=1;si=sqrt(0.85),vi+1=vi*si;
         * 2.扩大时,s0=sqrt(1/0.85),v0=1;=sqrt(1/0.85),vi+1=vi*si;
         *
         * 收缩前isFinish = true;收缩那一刻isFinish = false;收缩完isFinish = true
         * 扩大前isFinish = true;扩大那一刻isFinish = false;扩大完isFinish = true
         *
         *
         * @param msg
         */
        public void handleMessage(android.os.Message msg) {
            matrix.set(getImageMatrix());
            switch (msg.what) {
                case SCALE_REDUCE_INIT: //收缩
                    if (!isFinish) {
                        mScaleHandler.sendEmptyMessage(SCALE_REDUCE_INIT);
                    } else {
                        isFinish = false;
                        count = 0;
                        s = (float) Math.sqrt(Math.sqrt(mMinScale));
                        v = 1;
                        mScaleHandler.sendEmptyMessage(SCALING);
                    }
                    break;
                case SCALING: //缩放中
                    v = v * s;
                    beginScale(matrix, v);
                    if (count < 4) {
                        mScaleHandler.sendEmptyMessage(SCALING);
                    } else {
                        isFinish = true;
                        if (mOnViewClickListener != null && !isClicked) {
                            isClicked = true;
                            mOnViewClickListener.onViewClick(SFImageView.this);
                        } else {
                            isClicked = false;
                        }
                    }
                    count++;
                    break;
                case SCALE_ADD_INIT: //扩大
                    if (!isFinish) {
                        mScaleHandler.sendEmptyMessage(SCALE_ADD_INIT);
                    } else {
                        isFinish = false;
                        count = 0;
                        s = (float) Math.sqrt(Math.sqrt(1.0f / mMinScale));
                        v = 1;
                        mScaleHandler.sendEmptyMessage(SCALING);
                    }
                    break;
            }
        }
    };

    /**
     * 缩放
     *
     * @param matrix
     * @param scale
     */
    private synchronized void beginScale(Matrix matrix, float scale) {
        //改变scale值,通过Matrix进行缩放变换
        matrix.postScale(scale, scale, mCenterWidth, mCenterHeight);
        Log.i("SFImageView", "scale="+scale);
        setImageMatrix(matrix);
    }

    /**
     * 回调接口
     */
    private OnViewClickListener mOnViewClickListener;

    public void setOnClickIntent(OnViewClickListener onViewClickListener) {
        this.mOnViewClickListener = onViewClickListener;
    }

    public interface OnViewClickListener {
        void onViewClick(SFImageView view);
    }

}

SFImageView使用如下:
因为消费了点击事件,所以在按下并且收缩完成后,触发点击回调,并设置isClicked为true,扩大完成后,设置isClicked为false,完成一次点击事件

a = findViewById(R.id.sf_iv_avatar);
a.setOnClickIntent(new SFImageView.OnViewClickListener() {
    @Override
    public void onViewClick(SFImageView view) {
        Toast.makeText(MainActivity.this, "eeded", Toast.LENGTH_LONG).show();
    }
});

猫商城首页楼层效果

本套系列课程由后盾网高薪就业班一线讲师坐镇主讲,精仿天猫商城前端首页,大牛手把手教你如何开发大型网站前端页面,诸多技巧,让你大呼过瘾!核心知识点:html、div+css、JavaScript、jquery 。
  • 2016年03月08日 15:17

自定义控件之------仿ios下拉回弹效果

网上有很多类似的文章,大多数还是继承listview来实现(主要是listview.addHeaderView()和listview.addFooterView在listview的首尾添加view,也...
  • u012806692
  • u012806692
  • 2016-02-01 13:52:20
  • 1669

android仿QQ下拉回弹效果

最近在做android页面 总觉得QQ的scrollView还是比较好的。下拉到顶部的时候,往上拉了一点然后添了点动画 这种感觉能够增加用户体验的感觉。 因此觉得想着来实现一下。看一下QQ里面的效果。...
  • u013598660
  • u013598660
  • 2015-02-26 09:19:30
  • 2410

仿IOS回弹效果支持任何控件

仿IOS回弹效果,ScrollView,RecyclerView,ListView,Adapter,支持所有VIew回弹
  • maxiaoteng_321519
  • maxiaoteng_321519
  • 2017-08-04 17:28:33
  • 13729

html5仿ios下拉和上拉回弹功能

在网上搜索了“html5 下拉回弹” 或 “html5 仿ios下拉回弹”,几乎没有找到可用的代码,大都是在对-webkit-overflow-scrolling进行讨论的,没什么意思。 -web...
  • zgrkaka
  • zgrkaka
  • 2017-05-09 17:33:45
  • 1000

仿ios回弹效果scrollview

实现方法一import android.content.Context; import android.graphics.Rect; import android.util.AttributeSet;...
  • flower_danni
  • flower_danni
  • 2016-07-10 16:53:38
  • 412

Android仿IOS回弹效果 ScrollView回弹 总结

Android仿IOS回弹效果  ScrollView回弹 总结 应项目中的需求  需要仿IOS 下拉回弹的效果 , 我在网上搜了很多 大多数都是拿scrollview 改吧改吧 试了一些  发现总有...
  • aaawqqq
  • aaawqqq
  • 2014-07-13 17:22:50
  • 20123

[Android实例] 仿Win8磁铁效果,能够拖动改变Merto位置

最近公司一个同事让我做一个仿win8的效果,希望能够在固定的界面布局下进行拖动改变各个模块的位置,同时根据菜单内容数量不同展示相对应的Merto数量,就这样,我做了个Demo,可能有些粗糙,但是初步的...
  • jaycee110905
  • jaycee110905
  • 2014-10-16 09:54:40
  • 2183

一个仿WIN8磁铁效果的ImageView

源地址忘了 Java代码   import android.content.Context;  import android.graphics.Camera;  imp...
  • u013334392
  • u013334392
  • 2016-11-25 10:37:17
  • 727

android仿IOS页面回弹效果

码农同学们做过手机开发的相比一定对ios
  • hierophantzw
  • hierophantzw
  • 2014-06-19 16:18:32
  • 1273
收藏助手
不良信息举报
您举报文章:仿Win8图标按下回弹效果
举报原因:
原因补充:

(最多只允许输入30个字)