zoukankan      html  css  js  c++  java
  • android仿win8

    在 eoe上偶然发现已经有人实现了这个功能的源码(地址:http://www.eoeandroid.com /forum.php?mod=viewthread&tid=327557),马上下载跑了一下,效果很炫,但是有些bug,比如点击速度特别 快时图像会被放大,以及点击时会触发两次点击事件。

    本例子基于eoe中这位大神的实现,做了一些简化,和bug的修复。

    效果:

    首先普及一个小知识点:

    我们在项目中有时候需要一个缓慢的梯度数据,例如:控件的宽度以一定的比例增加,然后以相同的比例还原到原来的长度。

    1. package com.zhy._01;  
    2.   
    3. public class Test2  
    4. {  
    5.     public static void main(String[] args)  
    6.     {  
    7.         float val = 1;   
    8.         float s = 0.85f;  
    9.         int i = 0;  
    10.         s = (float) Math.sqrt(1 / s);  
    1.                System.out.println(val);  
    2.     while (i < 5)  
    3.     {  
    4.         val = val *s ;  
    5.         System.out.println(val);  
    6.         i++;  
    7.     }  
    8.      s = 0.85f;  
    9.     i = 0;  
    10.     s = (float) Math.sqrt(s);  
    11.     while (i < 5)  
    12.     {  
    13.         val = val *s ;  
    14.         System.out.println(val);  
    15.         i++;  
    16.     }  
    17.   
    18. }  


    输出结果:

    1. 1.0  
    2. 1.0846523  
    3. 1.1764706  
    4. 1.2760615  
    5. 1.384083  
    6. 1.5012488  
    7. 1.384083  
    8. 1.2760615  
    9. 1.1764706  
    10. 1.0846523  
    11. 1.0  


    很完美吧,基本是个对称的梯度数据,梯度的幅度由代码中的s觉得,越接近1幅度越小,反之则反之。


    好了下面开始代码:

    1、布局文件

    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    3.     android:layout_width="fill_parent"  
    4.     android:layout_height="fill_parent"  
    5.     android:background="@drawable/bkg_img_default"  
    6.     android:gravity="center"  
    7.     android:orientation="vertical" >  
    8.   
    9.     <LinearLayout  
    10.         android:layout_width="wrap_content"  
    11.         android:layout_height="wrap_content"  
    12.         android:orientation="vertical" >  
    13.   
    14.         <LinearLayout  
    15.             android:layout_width="wrap_content"  
    16.             android:layout_height="wrap_content"  
    17.             android:orientation="horizontal" >  
    18.   
    19.             <LinearLayout  
    20.                 android:layout_width="wrap_content"  
    21.                 android:layout_height="wrap_content"  
    22.                 android:orientation="vertical" >  
    23.   
    24.                 <com.ljp.ani01.MyImageView  
    25.                     android:id="@+id/c_joke"  
    26.                     android:layout_width="wrap_content"  
    27.                     android:layout_height="wrap_content"  
    28.                     android:layout_margin="2dp"  
    29.                     android:scaleType="matrix"  
    30.                     android:src="@drawable/left_top" />  
    31.   
    32.                 <com.ljp.ani01.MyImageView  
    33.                     android:id="@+id/c_idea"  
    34.                     android:layout_width="wrap_content"  
    35.                     android:layout_height="wrap_content"  
    36.                     android:layout_margin="2dp"  
    37.                     android:scaleType="matrix"  
    38.                     android:src="@drawable/left_bottom" />  
    39.             </LinearLayout>  
    40.   
    41.             <com.ljp.ani01.MyImageView  
    42.                 android:id="@+id/c_constellation"  
    43.                 android:layout_width="wrap_content"  
    44.                 android:layout_height="wrap_content"  
    45.                 android:layout_margin="2dp"  
    46.                 android:scaleType="matrix"  
    47.                 android:src="@drawable/right" />  
    48.         </LinearLayout>  
    49.   
    50.         <com.ljp.ani01.MyImageView  
    51.             android:id="@+id/c_recommend"  
    52.             android:layout_width="wrap_content"  
    53.             android:layout_height="wrap_content"  
    54.             android:layout_margin="2dp"  
    55.             android:scaleType="matrix"  
    56.             android:src="@drawable/bottom" />  
    57.     </LinearLayout>  
    58.   
    59. </LinearLayout>  


    布局文件,完成了上面效果图的静态效果,如果你不需要添加点击动画,或者只需要很简单的点击效果,那么就已经完成这样的菜单的编写,再添加个backgroud自定义下点击效果就好了。当然,我们这里有个比较柔和的点击动画,有自定义的ImageView完成。

    2、MyImageView.Java

    1. package com.ljp.ani01;  
    2.   
    3. import android.content.Context;  
    4. import android.graphics.Matrix;  
    5. import android.graphics.drawable.BitmapDrawable;  
    6. import android.graphics.drawable.Drawable;  
    7. import android.os.Handler;  
    8. import android.util.AttributeSet;  
    9. import android.util.Log;  
    10. import android.view.MotionEvent;  
    11. import android.widget.ImageView;  
    12.   
    13. public class MyImageView extends ImageView  
    14. {  
    15.   
    16.     private static final String TAG = "MyImageView";  
    17.   
    18.     private static final int SCALE_REDUCE_INIT = 0;  
    19.     private static final int SCALING = 1;  
    20.     private static final int SCALE_ADD_INIT = 6;  
    21.   
    22.     /** 
    23.      * 控件的宽 
    24.      */  
    25.     private int mWidth;  
    26.     /** 
    27.      * 控件的高 
    28.      */  
    29.     private int mHeight;  
    30.     /** 
    31.      * 控件的宽1/2 
    32.      */  
    33.     private int mCenterWidth;  
    34.     /** 
    35.      * 控件的高 1/2 
    36.      */  
    37.     private int mCenterHeight;  
    38.     /** 
    39.      * 设置一个缩放的常量 
    40.      */  
    41.     private float mMinScale = 0.85f;  
    42.     /** 
    43.      * 缩放是否结束 
    44.      */  
    45.     private boolean isFinish = true;  
    46.   
    47.     public MyImageView(Context context)  
    48.     {  
    49.         this(context, null);  
    50.     }  
    51.   
    52.     public MyImageView(Context context, AttributeSet attrs)  
    53.     {  
    54.         this(context, attrs, 0);  
    55.     }  
    56.   
    57.     public MyImageView(Context context, AttributeSet attrs, int defStyle)  
    58.     {  
    59.         super(context, attrs, defStyle);  
    60.     }  
    61.   
    62.     /** 
    63.      * 必要的初始化 
    64.      */  
    65.     @Override  
    66.     protected void onLayout(boolean changed, int left, int top, int right, int bottom)  
    67.     {  
    68.         super.onLayout(changed, left, top, right, bottom);  
    69.         if (changed)  
    70.         {  
    71.             mWidth = getWidth() - getPaddingLeft() - getPaddingRight();  
    72.             mHeight = getHeight() - getPaddingTop() - getPaddingBottom();  
    73.   
    74.             mCenterWidth = mWidth / 2;  
    75.             mCenterHeight = mHeight / 2;  
    76.   
    77.             Drawable drawable = getDrawable();  
    78.             BitmapDrawable bd = (BitmapDrawable) drawable;  
    79.             bd.setAntiAlias(true);  
    80.         }  
    81.     }  
    82.   
    83.     @Override  
    84.     public boolean onTouchEvent(MotionEvent event)  
    85.     {  
    86.         switch (event.getAction())  
    87.         {  
    88.         case MotionEvent.ACTION_DOWN:  
    89.             float X = event.getX();  
    90.             float Y = event.getY();  
    91.             mScaleHandler.sendEmptyMessage(SCALE_REDUCE_INIT);  
    92.             break;  
    93.         case MotionEvent.ACTION_UP:  
    94.             mScaleHandler.sendEmptyMessage(SCALE_ADD_INIT);  
    95.             break;  
    96.         }  
    97.         return true;  
    98.     }  
    99.   
    100.     /** 
    101.      * 控制缩放的Handler 
    102.      */  
    103.     private Handler mScaleHandler = new Handler()  
    104.     {  
    105.         private Matrix matrix = new Matrix();  
    106.         private int count = 0;  
    107.         private float s;  
    108.         /** 
    109.          * 是否已经调用了点击事件 
    110.          */  
    111.         private boolean isClicked;  
    112.   
    113.         public void handleMessage(android.os.Message msg)  
    114.         {  
    115.             matrix.set(getImageMatrix());  
    116.             switch (msg.what)  
    117.             {  
    118.             case SCALE_REDUCE_INIT:  
    119.                 if (!isFinish)  
    120.                 {  
    121.                     mScaleHandler.sendEmptyMessage(SCALE_REDUCE_INIT);  
    122.                 } else  
    123.                 {  
    124.                     isFinish = false;  
    125.                     count = 0;  
    126.                     s = (float) Math.sqrt(Math.sqrt(mMinScale));  
    127.                     beginScale(matrix, s);  
    128.                     mScaleHandler.sendEmptyMessage(SCALING);  
    129.                 }  
    130.                 break;  
    131.             case SCALING:  
    132.                 beginScale(matrix, s);  
    133.                 if (count < 4)  
    134.                 {  
    135.                     mScaleHandler.sendEmptyMessage(SCALING);  
    136.                 } else  
    137.                 {  
    138.                     isFinish = true;  
    139.                     if (MyImageView.this.mOnViewClickListener != null && !isClicked)  
    140.                     {  
    141.                         isClicked = true;  
    142.                         MyImageView.this.mOnViewClickListener.onViewClick(MyImageView.this);  
    143.                     } else  
    144.                     {  
    145.                         isClicked = false;  
    146.                     }  
    147.                 }  
    148.                 count++;  
    149.   
    150.                 break;  
    151.             case 6:  
    152.                 if (!isFinish)  
    153.                 {  
    154.                     mScaleHandler.sendEmptyMessage(SCALE_ADD_INIT);  
    155.                 } else  
    156.                 {  
    157.                     isFinish = false;  
    158.                     count = 0;  
    159.                     s = (float) Math.sqrt(Math.sqrt(1.0f / mMinScale));  
    160.                     beginScale(matrix, s);  
    161.                     mScaleHandler.sendEmptyMessage(SCALING);  
    162.                 }  
    163.                 break;  
    164.             }  
    165.         }  
    166.     };  
    167.   
    168.     protected void sleep(int i)  
    169.     {  
    170.         try  
    171.         {  
    172.             Thread.sleep(i);  
    173.         } catch (InterruptedException e)  
    174.         {  
    175.             e.printStackTrace();  
    176.         }  
    177.     }  
    178.   
    179.     /** 
    180.      * 缩放 
    181.      *  
    182.      * @param matrix 
    183.      * @param scale 
    184.      */  
    185.     private synchronized void beginScale(Matrix matrix, float scale)  
    186.     {  
    187.         matrix.postScale(scale, scale, mCenterWidth, mCenterHeight);  
    188.         setImageMatrix(matrix);  
    189.     }  
    190.   
    191.     /** 
    192.      * 回调接口 
    193.      */  
    194.     private OnViewClickListener mOnViewClickListener;  
    195.   
    196.     public void setOnClickIntent(OnViewClickListener onViewClickListener)  
    197.     {  
    198.         this.mOnViewClickListener = onViewClickListener;  
    199.     }  
    200.   
    201.     public interface OnViewClickListener  
    202.     {  
    203.         void onViewClick(MyImageView view);  
    204.     }  
    205.   
    206. }  

    代码不算复杂,主要就是对onTouchEvent的Action_Down和Action_Up的监听,然后通过Handler结合matrix完成缩放的效果。这里简单说一个mScaleHandler里面代码的逻辑,当检测到ACTION_DOWN事件,会判断当前缩放是否完成,如果完成了则添加缩小的效果,如果没有,则一直检测。ACTION_UP也是同样的过程。缩放的梯度就用到了文章开始介绍的小知识点。

    有人会觉得使用Handler比较麻烦,这里一直使用Handler.sendMsg的原因是,利用了这个消息队列,队列先进先出,保证动画效果的流畅。因为ACTION_DOWN_与ACTION_UP一瞬点完成的,其实动画还在进行。如果你在onTouchEvent中用while集合sleep完成动画,会出现卡死,监听不到Up事件等问题。


    3、主Activity

    1. package com.ljp.ani01;  
    2.   
    3. import android.app.Activity;  
    4. import android.os.Bundle;  
    5. import android.view.View;  
    6. import android.view.View.OnClickListener;  
    7. import android.widget.Toast;  
    8.   
    9. public class TestRolateAnimActivity extends Activity  
    10. {  
    11.     MyImageView joke;  
    12.   
    13.     @Override  
    14.     public void onCreate(Bundle savedInstanceState)  
    15.     {  
    16.         super.onCreate(savedInstanceState);  
    17.         setContentView(R.layout.main);  
    18.   
    19.         joke = (MyImageView) findViewById(R.id.c_joke);  
    20.         joke.setOnClickIntent(new MyImageView.OnViewClickListener()  
    21.         {  
    22.   
    23.             @Override  
    24.             public void onViewClick(MyImageView view)  
    25.             {  
    26.                 Toast.makeText(TestRolateAnimActivity.this, "Joke", 1000).show();  
    27.             }  
    28.         });  
    29.     }  
    30.       
    31.       
    32. }  


    利用提供的回调接口注册了点击事件。这里说明一下,现在为ImageView设置OnClickLIstener是没有作用的,因为自定义的ImageView的onTouchEvent直接返回了true,不会往下执行click事件,如果你希望通过OnClickLIstener进行注册,你可以把ontouchevent里面返回值改成super.ontouchevent(event),并且需要将ImageView的clickable设置为true。这些都是Ontouch事件的传播机制,不了解的google下,还是很有必要的。

  • 相关阅读:
    异常处理
    弹出对话框
    ef——存储过程
    事务
    linq——常用方法
    Linq
    asp get与post获取的区别
    Web服务的调用
    AJAX控件——多层弹出Accordion
    数据绑定
  • 原文地址:https://www.cnblogs.com/gaara-zhang/p/5426427.html
Copyright © 2011-2022 走看看