模仿360水晶球的效果

public class MainActivity extends Activity implements View.OnClickListener{
    final int CLEANTASK = 1;
    final int CLEANNUMBER = 10;//水面每次变化是时,clipdrawable变化的程度,大家可以自己随意修改这个数值,用来控制水面变化的速度。

    ImageView imageSrc;//用来显示液体颜色的控件
    ImageView waterLevel;//用来显示睡眠的那张图片,有了这张图片的修饰,整个水晶球的水面才有了立体的效果。这个设计真的好巧妙
    final int TOTALLEVEL = 10000;//clipdrawable的切割范围,clipdrawable的切割范围是从0到10000
    int actualLevel;//表示clipdrawable实时的切割数值,在初始化方法中,我们会将它赋值为8000
    float radius;//液体颜色那张图片的半径

    private Timer timer;
    private TimerTask task;

    private Handler hand;

    boolean isDown = true;//这个变量用来判断水面现在是出于下降的状态还是上升的状态
    boolean isOver;//timer每次循环都会根据它来判断handler是否已经把上次的动画效果处理完,如果还没有处理完,那就不向handler发送新的消息

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        /**
         * 这个handler用来跟timer交互,实时更改水晶球水面的变化和背景颜色
         */
        hand = new Handler(){
            @Override
            public void handleMessage(Message msg) {
                // TODO Auto-generated method stub
                super.handleMessage(msg);
                if(msg.what == CLEANTASK){
                    //每次开始处理动画时,把isover设置成false,这样timer就不会再发新的消息过来了。
                    isOver = false;

                    //下面的代码用来判断水面是否已经下降到了底部或者回升到了最大值
                    if(isDown){
                        actualLevel = (actualLevel-CLEANNUMBER)>=0?(actualLevel-CLEANNUMBER):0;
                        if(actualLevel==0){
                            //当下降到最底部时,isDown设为false,后面handler在接受到消息时,就开始处理上升的动画
                            isDown = false;
                        }
                    }else{
                        actualLevel = (actualLevel+CLEANNUMBER)<=8000?(actualLevel+CLEANNUMBER):8000;
                        if(actualLevel==8000){
                            //当回升到最上层时,isDown设为true,本次动画过程彻底结束,timer控制器注销。
                            isDown = true;
                            task.cancel();
                            task = null;
                            timer.cancel();
                            timer = null;
                        }
                    }

                    //根据clipdrawable切割的范围,来更换背景颜色和立体水面的颜色。
                    if(actualLevel>=6000){
                        imageSrc.setImageResource(R.drawable.task_killer_full_clip);
                        waterLevel.setImageResource(R.mipmap.taskmanager_circle_full_waterlevel);
                    }else if(actualLevel<6000&&actualLevel>4000){
                        imageSrc.setImageResource(R.drawable.task_killer_mid_clip);
                        waterLevel.setImageResource(R.mipmap.taskmanager_circle_mid_waterlevel);
                    }else{
                        imageSrc.setImageResource(R.drawable.task_killer_low_clip);
                        waterLevel.setImageResource(R.mipmap.taskmanager_circle_min_waterlevel);
                    }

                    ClipDrawable clip = (ClipDrawable) imageSrc.getDrawable();
                    clip.setLevel(actualLevel);
                    waterLevelChange();

                    //每次动画处理结束后,把isover设置成true,这样timer又会发新的消息过来
                    isOver = true;
                }
            }
        };

        initData();
        initView();
    }

    /**
     * 初始化数据
     */
    void initData(){
        actualLevel = 8000;
        isOver = true;
    }

    /**
     * 初始化视图
     */
    void initView(){
        imageSrc = (ImageView)findViewById(R.id.image_back);
        waterLevel = (ImageView)findViewById(R.id.image_waterlevel);

        imageSrc.setOnClickListener(this);

        //这里获取clipdrawable的实例,获取背景图片的半径值,然后对clipdrawable进行切割,对水面进行平移缩放
        ClipDrawable clip = (ClipDrawable) imageSrc.getDrawable();
        radius = clip.getIntrinsicHeight()/2;
        clip.setLevel(actualLevel);
        waterLevelChange();
    }

    /**
     * 计算水面的那张图片,缩放的大小和上下平移的大小,运用勾股定理来计算
     */
    void waterLevelChange(){
        //默认水面那张图片处在中间位置,那么她随着水面上下移动的距离应该为:
        float transY = ((5000-actualLevel)/5000.0f)*radius;
        //根据上面的计算值,然后根据勾股定理,可以计算出水面在水平方向的缩放比例:
        float scaleX= 0.0f;
        if(actualLevel!=5000){
            scaleX = (float) (Math.sqrt(radius*radius - transY*transY)/radius);
        }else{
            scaleX = 1f;
        }
        //这里设置水面图片的上下平移值和水平缩放值
        waterLevel.setTranslationY(transY);
        waterLevel.setScaleX(scaleX);
    }

    @Override
    public void onClick(View v) {
        //每次点击时,看看现在水晶球是否处于动画状态,如果不处于,才进行新的动画处理。这里的判断规则可以随意规定,我就用最简单粗暴的方式来实现了。
        if(actualLevel==8000){
            timer = new Timer();
            task = new TimerTask() {
                @Override
                public void run() {
                    //timer每次循环都会根据它来判断handler是否已经把上次的动画效果处理完,如果还没有处理完,那就不向handler发送新的消息
                    if(isOver){
                        Message msg = new Message();
                        msg.what = CLEANTASK;
                        hand.sendMessage(msg);
                    }
                }
            };
            timer.schedule(task, 0, 1);
        }
    }

}

布局文件:

<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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <ImageView
        android:id="@+id/image_back"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:background="@mipmap/taskmanager_background"
        android:src="@drawable/task_killer_full_clip"/>

    <ImageView
        android:id="@+id/image_waterlevel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:src="@mipmap/taskmanager_circle_full_waterlevel"/>

    <ImageView
        android:id="@+id/image_top"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:src="@mipmap/taskmanager_water_top"/>
</RelativeLayout>

drawable文件里:

<clip xmlns:android="http://schemas.android.com/apk/res/android"   
    android:drawable="@mipmap/taskmanager_circle_full"
    android:clipOrientation="vertical"
    android:gravity="bottom">  
</clip>  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值