高仿雷達掃描效果和仿水波紋中心擴散效果,手把手教你擼一個炫酷的自定義view。
於亞豪的部落格地址:
我們先看效果圖吧
對於仿水波紋中心擴脈衝效果
思路
大家一看就應該知道,一張圖片在不斷的放大,且顏色漸變。那不就是自定義屬性動畫嗎
沒錯就是這麼神奇。ScaleAnimation+AlphaAnimation
-
縮放動畫:
//建立一個AnimationSet物件,引數為Boolean型, //true表示使用Animation的interpolator,false則是使用自己的 animationSet = new AnimationSet(true); //引數1:x軸的初始值 //引數2:x軸收縮後的值 //引數3:y軸的初始值 //引數4:y軸收縮後的值 //引數5:確定x軸座標的型別 //引數6:x軸的值,0.5f表明是以自身這個控制元件的一半長度為x軸 //引數7:確定y軸座標的型別 //引數8:y軸的值,0.5f表明是以自身這個控制元件的一半長度為x軸 ScaleAnimation scaleAnimation = new ScaleAnimation( 1, animation_size,1,animation_size, Animation.RELATIVE_TO_SELF,0.5f, Animation.RELATIVE_TO_SELF,0.5f); scaleAnimation.setDuration(3000); animationSet.addAnimation(scaleAnimation);複製程式碼
-
漸變動畫
//建立一個AlphaAnimation物件,引數從完全的透明度,到完全的不透明 AlphaAnimation alphaAnimation = new AlphaAnimation(1, 0); //設定動畫執行的時間 alphaAnimation.setDuration(3000); //將alphaAnimation物件新增到AnimationSet當中 animationSet.addAnimation(alphaAnimation); //使用ImageView的startAnimation方法執行動畫 animationSet.setFillAfter(true); animationSet.setInterpolator(new AccelerateInterpolator()); animationSet.setAnimationListener(new AnimationListener() { public void onAnimationStart(Animation animation) { } public void onAnimationRepeat(Animation animation) { } public void onAnimationEnd(Animation animation) { imageview_01.startAnimation(animationSet); } }); imageview_01.startAnimation(animationSet);複製程式碼
高仿雷達掃描效果
思路
-
首先我們要確認要用什麼方式去實現
-
佈局的擺放
-
利用屬性動畫一張圖片或者是一個view在繞著中心點
-
自定義View進行矩陣旋轉
效果實現
-
自定義RelativeLayout進行擺設布
protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawBitmap(bitmap, getWidth() / 2 - bitmap.getWidth() / 2, getHeight() / 2 - bitmap.getHeight() / 2, null); canvas.drawBitmap(bitmap1, getWidth() / 2 - bitmap1.getWidth() / 2, getHeight() / 2 - bitmap1.getHeight() / 2, null); if(isSearching) invalidate(); }複製程式碼
-
動畫
Rect rMoon = new Rect(getWidth()/2-bitmap2.getWidth(),getHeight()/2,getWidth()/2,getHeight()/2+bitmap2.getHeight()); canvas.rotate(offsetArgs,getWidth()/2,getHeight()/2); canvas.drawBitmap(bitmap2,null,rMoon,null); offsetArgs = offsetArgs + 3;複製程式碼
自定義CircleWaveDivergenceView:
/**
* 類功能描述:</br>
* 仿雷達掃描View
* 部落格地址:http://blog.csdn.net/androidstarjack
* 公眾號:終端研發部
* @author yuyahao
* @version 1.0 </p> 修改時間:</br> 修改備註:</br>
*/
public class CircleWaveDivergenceView extends RelativeLayout{
public static final String TAG = "SearchDevicesView";
public static final boolean D = BuildConfig.DEBUG;
public Context context;
@SuppressWarnings("unused")
private long TIME_DIFF = 1500;
private float offsetArgs = 0;
private boolean isSearching = false;
private Bitmap bitmap;
private Bitmap bitmap1;
private Bitmap bitmap2;
public boolean isSearching() {
return isSearching;
}
public void setSearching(boolean isSearching) {
this.isSearching = isSearching;
offsetArgs = 0;
invalidate();
}
public CircleWaveDivergenceView(Context context) {
super(context);
this.context = context;
initBitmap();
}
public CircleWaveDivergenceView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
initBitmap();
}
public CircleWaveDivergenceView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.context = context;
initBitmap();
}
private void initBitmap(){
if(bitmap == null){
bitmap = Bitmap.createBitmap(BitmapFactory.decodeResource(context.getResources(), R.drawable.gplus_search_bg));
}
if(bitmap1 == null){
bitmap1 = Bitmap.createBitmap(BitmapFactory.decodeResource(context.getResources(), R.drawable.locus_round_click));
}
if(bitmap2 == null){
bitmap2 = Bitmap.createBitmap(BitmapFactory.decodeResource(context.getResources(), R.drawable.gplus_search_args));
}
}
@SuppressLint("DrawAllocation")
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(bitmap, getWidth() / 2 - bitmap.getWidth() / 2, getHeight() / 2 - bitmap.getHeight() / 2, null);
if(isSearching){
Rect rMoon = new Rect(getWidth()/2-bitmap2.getWidth(),getHeight()/2,getWidth()/2,getHeight()/2+bitmap2.getHeight());
canvas.rotate(offsetArgs,getWidth()/2,getHeight()/2);
canvas.drawBitmap(bitmap2,null,rMoon,null);
offsetArgs = offsetArgs + 3;
}else{
canvas.drawBitmap(bitmap2, getWidth() / 2 - bitmap2.getWidth() , getHeight() / 2, null);
}
canvas.drawBitmap(bitmap1, getWidth() / 2 - bitmap1.getWidth() / 2, getHeight() / 2 - bitmap1.getHeight() / 2, null);
if(isSearching) invalidate();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
handleActionDownEvenet(event);
return true;
case MotionEvent.ACTION_MOVE:
return true;
case MotionEvent.ACTION_UP:
return true;
}
return super.onTouchEvent(event);
}
private void handleActionDownEvenet(MotionEvent event){
RectF rectF = new RectF(getWidth() / 2 - bitmap1.getWidth() / 2,
getHeight() / 2 - bitmap1.getHeight() / 2,
getWidth() / 2 + bitmap1.getWidth() / 2,
getHeight() / 2 + bitmap1.getHeight() / 2);
if(rectF.contains(event.getX(), event.getY())){
if(D) Log.d(TAG, "click search device button");
if(!isSearching()) {
setSearching(true);
}else{
setSearching(false);
}
}
}
}複製程式碼
最終實現效果:
程式碼並沒有很多,需要的同學可以下載github Demo體驗和學習。
專案Github連結地址
下載慢?CSDN下載連結:
相信自己,沒有做不到的,只有想不到的
如果你覺得此文對您有所幫助,歡迎入群 QQ交流群 :232203809
微信公眾號:終端研發部