過年放假前最後一天班,就想着作個簡單又有趣的小東西。因而決定來寫個自定義的LoadingView做爲這個App框架的加載效果吧 |
走過路過點歌Start O(∩_∩)O Github項目地址android
這篇文章叫你如何搭建手寫LoadingView,看完這篇文章你能學會:git
--------------------------------關門,上分割線------------------------------------------------ 先看看效果: github
1.建立item_loading_view.xml佈局,把樣式先寫出來
2.自定義View,加載這個自定義佈局
3.自定義View內作動畫處理
複製代碼
1.佈局:item_loading_view.xmlcanvas
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:padding="24dp"
android:layout_height="148dp">
<ImageView
android:id="@+id/iv_loading"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_above="@+id/tv_loading"
android:src="@drawable/ic_favorites" />
<TextView
android:id="@+id/tv_loading"
android:layout_width="wrap_content"
android:text="加載中..."
android:layout_marginTop="12dp"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:layout_height="wrap_content" />
</RelativeLayout>
複製代碼
2.自定義Viewbash
public class LoadingView extends FrameLayout {
public LoadingView(Context context) {
this(context,null);
}
public LoadingView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public LoadingView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// 加載佈局
LayoutInflater.from(mContext).inflate(R.layout.item_loading_view, this);
}
複製代碼
這個時候在Activity的佈局中引用的話,能看到這個loadingView的靜態效果了。最後最關鍵的一步 3.動畫效果實現: 這裏面涉及到兩個動畫效果,一個是那個愛心上下跳動,以及底下一個陰影縮放 愛心上下跳動效果:框架
private void logic() {
ValueAnimator animator = ValueAnimator.ofInt(0,mJumpHeightPx,0);
animator.setDuration(800);
animator.setRepeatMode(ValueAnimator.RESTART);
animator.setRepeatCount(ValueAnimator.INFINITE);
animator.setInterpolator(new AccelerateDecelerateInterpolator());
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int value = (int) animation.getAnimatedValue();
mIv.setTranslationY(-value);
// 爲了畫shadow
mMovePercent = value / 100f;
postInvalidate();
}
});
animator.start();
}
複製代碼
LoaingView構造函數中調用該方法(詳細見githun項目源碼) 實現思路:利用屬性動畫移動 關於屬性動畫做用的原理能夠去百度幾篇文章,一句話歸納就是,屬性動畫提供的是:使用某種變化規則去獲得一個不斷變化值,而後本身利用這個值去設置控件的屬性以達到動畫的效果。ide
shadow縮放效果:函數
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 陰影寬高的一半 最大不超過16 / 8
float shadowHalfWidth = Math.max(16f,(mIvRight - mIvLeft) / 2 );
float shadowHalfHeight = Math.max(8f,(mIvBottom - mIvTop) / 2 );
// 陰影區域中線位置(決定陰影所在位置) yCenter:垂直中線的縱座標 xCenter:水平中線的橫座標
float yCenter = mIvLeft + shadowHalfWidth;
float xCenter = mIvTop + shadowHalfHeight * 2;
// 縮放的變化量(決定陰影變化大小)
float horizontalDiff = Math.max(2,(1f - mMovePercent) * shadowHalfWidth * mShadowFlatX);
float verticalDiff = Math.max(2,(1f - mMovePercent) * shadowHalfHeight * mShadowFlatY);
Log.d("bigname", "onDraw: " + yCenter + "-----" + xCenter + "------" + horizontalDiff + "--------" + verticalDiff + "-------" + mMovePercent);
mShadowRectF.set(
yCenter - horizontalDiff,
xCenter - verticalDiff,
yCenter + horizontalDiff,
xCenter + verticalDiff
);
canvas.drawOval(mShadowRectF, mShadowPaint);
}
複製代碼
shadow利用畫布去實現: 首先在使用屬性動畫的時候將變化的值賦給全局變量mMovePercent;而且變化的時候調用postInvalidate()重繪,這樣的話在onDraw()方法中接口和mMovePercent就能知道當前動畫進行的進度。依此來控制shadow縮放。佈局
這個自定義LoadingView效果就已經實現了,接下來會對這個控件作些優化,增長更炫的動畫效果,而後作好封裝。post
源碼在上面的github連接
敬請期待---