多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > 綜合技術 > 慕課網app下拉刷新圖標填充效果的實現

慕課網app下拉刷新圖標填充效果的實現

來源:程序員人生   發布時間:2015-04-01 08:17:50 閱讀次數:3478次

之前看到1種下拉刷新的效果,與以往的下拉效果都不1樣,大多數下拉刷新都是1個圓形進度條在旋轉,而這個下拉刷新則是1個不斷填充的效果。本以為這是個自定義View,后來反編譯慕課網的app后提取資源的時候看到好多的圖片,那大概慕課網app內部的實現應當是幀動畫到達這類效果。而當我看到這類效果的時候,由于前段時間在學自定義控件,所以本能的反應則是自定義的。首先我們看下慕課網的效果。以下圖

        

而我的也實現了1個這個圖標填充的簡單版。以下圖

    

全部實現使用圖形的混合模式+貝塞爾曲線,貝塞爾曲線的繪制參考自愛哥的博客  貝塞爾曲線內容

資源文件就只有下面這個圖標,該圖標提取自慕課網app,然后對內部的火焰進行透明處理過


既然是自定義View,那就要繼承View,實現onDraw,onMeasure等方法,為了簡單起見,這里將控件的寬度高度直接設置為圖片的寬度和高度,而沒有去實現相應的邏輯去判斷MeasureSpec的模式是哪一個從而進行處理。

先貼代碼

package cn.edu.zafu.view; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.util.AttributeSet; import android.view.View; /** * @author lizhangqu * * 2015⑶⑸ */ public class CustomView extends View { private PorterDuffXfermode porterDuffXfermode;// Xfermode private Paint paint;// 畫筆 private Bitmap bitmap;// 源圖片 private int width, height;// 控件寬高 private Path path;// 畫貝塞爾曲線需要用到 private Canvas mCanvas;// 在該畫布上繪制目標圖片 private Bitmap bg;// 目標圖片 private float controlX, controlY;// 貝塞爾曲線控制點,使用3階貝塞爾曲線曲線,需要兩個控制點,兩個控制點都在該變量基礎上生成 private float waveY;// 上升的高度 private boolean isIncrease;// 用于控制控制點水平移動 private boolean isReflesh = true;// 是不是刷新并產生填充效果,默許為true /** * @return 是不是刷新 */ public boolean isReflesh() { return isReflesh; } /** * 提供接口設置刷新 * * @param isReflesh */ public void setReflesh(boolean isReflesh) { this.isReflesh = isReflesh; } /** * @param context */ public CustomView(Context context) { this(context, null); } /** * @param context * @param attrs */ public CustomView(Context context, AttributeSet attrs) { this(context, attrs, 0); } /** * @param context * @param attrs * @param defStyle */ public CustomView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } /** * 初始化變量 */ private void init() { // 初始化畫筆 paint = new Paint(); paint.setAntiAlias(true); paint.setDither(true); paint.setStyle(Paint.Style.FILL); paint.setColor(Color.parseColor("#ffc9394a")); // 取得資源文件 bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.mooc); // 設置寬高為圖片的寬高 width = bitmap.getWidth(); height = bitmap.getHeight(); // 初始狀態值 waveY = 7 / 8F * height; controlY = 17 / 16F * height; // 初始化Xfermode porterDuffXfermode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN); // 初始化path path = new Path(); // 初始化畫布 mCanvas = new Canvas(); // 創建bitmap bg = Bitmap.createBitmap(width, height, Config.ARGB_8888); // 將新建的bitmap注入畫布 mCanvas.setBitmap(bg); } @Override protected void onDraw(Canvas canvas) { // 畫目標圖,存在bg上 drawTargetBitmap(); // 將目標圖繪制在當前畫布上,出發點為左側距,上邊距的交點 canvas.drawBitmap(bg, getPaddingLeft(), getPaddingTop(), null); if (isReflesh) { // 重繪,使用boolean變量isReflesh進行控制,并對外提供訪問的接口,默許為true且刷新 invalidate(); } } private void drawTargetBitmap() { // 重置path path.reset(); // 擦除像素 bg.eraseColor(Color.parseColor("#00ffffff")); // 當控制點的x坐標大于或等于終點x坐標時更改標識值 if (controlX >= width + 1 / 2 * width) { isIncrease = false; } // 當控制點的x坐標小于或等于出發點x坐標時更改標識值 else if (controlX <= ⑴ / 2 * width) { isIncrease = true; } // 根據標識值判斷當前的控制點x坐標是該加還是減 controlX = isIncrease ? controlX + 10 : controlX - 10; if (controlY >= 0) { // 波浪上移 controlY -= 1; waveY -= 1; } else { // 超越則重置位置 waveY = 7 / 8F * height; controlY = 17 / 16F * height; } // 貝塞爾曲線的生成 path.moveTo(0, waveY); // 兩個控制點通過controlX,controlY生成 path.cubicTo(controlX / 2, waveY - (controlY - waveY), (controlX + width) / 2, controlY, width, waveY); // 與下下邊界閉合 path.lineTo(width, height); path.lineTo(0, height); // 進行閉合 path.close(); // 以上畫貝塞爾曲線代碼參考自愛哥博客 // http://blog.csdn.net/aigestudio/article/details/41960507 mCanvas.drawBitmap(bitmap, 0, 0, paint);// 畫慕課網logo paint.setXfermode(porterDuffXfermode);// 設置Xfermode mCanvas.drawPath(path, paint);// 畫3階貝塞爾曲線 paint.setXfermode(null);// 重置Xfermode } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // 取得寬高丈量模式和大小 int widthMode = MeasureSpec.getMode(widthMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); // 保存丈量結果 int width, height; if (widthMode == MeasureSpec.EXACTLY) { // 寬度加左右內邊距 width = widthSize + getPaddingLeft() + getPaddingRight(); } else { // 寬度加左右內邊距 width = this.width + getPaddingLeft() + getPaddingRight(); ; if (widthMode == MeasureSpec.AT_MOST) { // 取小的那個 width = Math.min(width, widthSize); } } if (heightMode == MeasureSpec.EXACTLY) { // 高度加左右內邊距 height = heightSize + getPaddingTop() + getPaddingBottom(); } else { // 高度加左右內邊距 height = this.height + getPaddingTop() + getPaddingBottom(); ; if (heightMode == MeasureSpec.AT_MOST) { // 取小的那個 height = Math.min(height, heightSize); } } // 設置高度寬度為logo寬度和高度,實際開發中應當判斷MeasureSpec的模式,進行對應的邏輯處理,這里做了簡單的判斷丈量 setMeasuredDimension(width, height); } }

控件的使用

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/ll" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <cn.edu.zafu.view.CustomView android:id="@+id/cv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="20dp" android:layout_centerInParent="true" android:background="#0000ff" /> </RelativeLayout>

如果要停止其不斷填充的效果,通過函數setReflesh設置isReflesh變量為false便可。

全部實現進程還是相對簡單的,基本上注釋都講的很清楚了,這里也不再重復了,文章中觸及到的兩個知識點(圖形的混合模式和貝塞爾曲線)的相干內容參考下面兩篇文章

圖形混合模式 http://blog.csdn.net/aigestudio/article/details/41316141

貝塞爾曲線 http://blog.csdn.net/aigestudio/article/details/41960507

都是愛哥的文章,個人覺得寫得很細。

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 最近视频中文在线播放 | 在线欧美色| 亚洲精品一区二区三区在线观看 | 免费看的www视频网站视频 | 国产香蕉97碰碰久久人人 | 国产精品成人久久久久久久 | 黄色ab| 自拍偷自拍亚洲精品情侣 | 亚洲欧美日韩国产一区二区精品 | 欧美日本成人 | 国产一区二区三区亚洲欧美 | 国产一区二区高清在线 | 欧美18videosex性欧美老师 | 精品免费久久久久国产一区 | 交性大片欧美网 | 亚洲免费视| 欧美国产一区二区二区 | 国产精品久久久久久久久久久不卡 | 亚洲高清中文字幕一区二区三区 | 亚洲欧美自拍视频 | 国产欧美成人一区二区三区 | 美国人和狍xxxx视频 | free 欧美性 free 英国性xxxxhd | 欧美国产日韩一区二区三区 | 在线精品亚洲欧洲第一页 | free性欧美高清另类 | 欧美激情伦妇在线观看 | 国产理论自拍 | 欧洲亚洲综合一区二区三区 | 日本高清无卡码一区二区久久 | 日韩一区二区三区四区五区 | 亚洲不卡在线视频 | videoa性欧美 | 久久爱伊人 | 九九99久久精品在免费线bt | 乱在线伦视频免费 | 综合久久一区二区三区 | 中国精品自拍 | 日韩欧美一级a毛片欧美一级 | 国产亚洲欧美在线视频 | 欧美在线一级va免费观看 |