知识运用Clip Drawable的知识,先看下图:
当点击红球是,他会下降,一次又红色变为黄色,再变为绿色,当到达底部时,又会回升。原理图如下:
由上面几个图可以知道,将这个圆划分为四分,
private static final float ONE_FORTH = 1.0f / 4;
private static final float TWO_FORTHS = 2.0f / 4;
private static final float THREE_FORTHS = 3.0f / 4;
private static final float ONE = 1.0f;
在ClipDrawable中,
ClipDrawable drawable = (ClipDrawable) ivFullBall.getDrawable();
drawable.setLevel(mCurrentState);// level from 0 (minimum) to 10000
setLevel方法中所设置的level的范围是0~10000,所分阶段分别为:2500,5000,7500,绿色【0,2500),黄色【2500,7500】,红色(7500,10000】。
在clipDrawable的xml文件,内容如下:
<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
android:clipOrientation="vertical"
android:drawable="@drawable/clt_circle_full"
android:gravity="bottom" >
</clip>
为了体现立体效果使用了,一张球面图片的移动,随着level的改变而改变图片的缩放比,主要运用的是一些数学点,勾股定理什么的呀。
此方法代码如下:
/**
* 随着level的改变,而将球面的那张图片进行等比缩放
*/
private void movePlaint() {
// 默认球面图片处在中间位置,那么她随着水面上下移动的距离应该为:
float transY = ((TWO_FORTHS * TOTAL_LEVEL - mCurrentState) / TWO_FORTHS * TOTAL_LEVEL)
* radius;
// 根据勾股定理,可以计算出水面在水平方向的缩放比例:
float scaleX = 0.0f;
if (mCurrentState != TWO_FORTHS * TOTAL_LEVEL) {
scaleX = (float) (Math.sqrt(radius * radius - transY * transY) / radius);
} else {
scaleX = 1f;
}
// 这里设置水面图片的上下平移值和水平缩放值
ivPlaint.setTranslationY(transY);
ivPlaint.setScaleX(scaleX);
}
核心代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
initView();
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case TASK_FULL:
if (isDown) {
mCurrentState = mCurrentState - ONCE_CHANGE_LEVEL;
if (mCurrentState == 0) {
isDown = false;
}
} else {
mCurrentState = mCurrentState + ONCE_CHANGE_LEVEL;
if (mCurrentState == TOTAL_LEVEL) {
isDown = true;
isClick = true;
timer.cancel();
timerTask.cancel();
timer = null;
timerTask = null;
}
}
if (mCurrentState <= ONE * TOTAL_LEVEL
&& mCurrentState >= THREE_FORTHS * TOTAL_LEVEL) {
ivFullBall.setImageResource(R.drawable.clt_full_clip);
} else if (mCurrentState < THREE_FORTHS * TOTAL_LEVEL
&& mCurrentState >= ONE_FORTH * TOTAL_LEVEL) {
ivFullBall.setImageResource(R.drawable.clt_mid_clip);
} else {
ivFullBall.setImageResource(R.drawable.clt_low_clip);
}
ClipDrawable onClickDrawable = (ClipDrawable) ivFullBall
.getDrawable();
onClickDrawable.setLevel(mCurrentState);
movePlaint();
break;
case TASK_EMPTY:
break;
default:
break;
}
}
};
}
/**
* Response the click event of imageview
*
* @param view
*/
public void clearTaskNow(View view) {
// 当我每次点击时,都会开启一个线程,因此需要添加一个条件:当我再次点击时,不让他又开启线程
Log.d("kagoy", "clearTaskNow" + "mCurrentState" + mCurrentState);
if (mCurrentState >= THREE_FORTHS * TOTAL_LEVEL && isClick) {//可以控制多次点击
isClick = false;
timer = new Timer();
timerTask = new TimerTask() {
@Override
public void run() {
mHandler.sendEmptyMessage(TASK_FULL);
}
};
timer.schedule(timerTask, 0, 1);
}
}
还有需要注意的是一些基础问题,在使用表达式赋值时需要慎重:
private static final float ONE_FORTH = 1.0f / 4;
private static final float TWO_FORTHS = 2.0f / 4;
private static final float THREE_FORTHS = 3.0f / 4;
private static final float ONE = 1.0f;
private static final float ONE_FORTH = 1 / 4;//这个值为0.