Android自定義view利用Xfermode實現(xiàn)動態(tài)文字加載動畫
對于Xfermode 可能很多人看了一些就放棄了,今天我就個人理解,舉簡單的我們生活中的例子,讓大家更容易理解這是個什么東西。其實并不是你們想象的那么難,你只要懂三步就夠了。先來看一看這次的效果圖,這個gif大家湊合看。
不要把Xfermode 想的這么難,我把Xfermode 理解成中學時 學的“集合” ,我們知道“集合”是處理 數(shù)據(jù)的。例如:
集合 A={1,2,3,4},集合B={3,4,5,6}。這兩個集合 有三個屬性,交集,并集,補集。
那么 Xfermode 我個人理解就是圖形集合,就是圖形A,圖形B 之間可以取,交集,并集,補集。當然這個 A和 B 之間取那種類型,形成什么樣的 效果,其實就是我們選取的 Xformode 的 屬性類型。
這個就引出了我們今天 的 第一步,雖然是三步,但是前提是你要對自定義view 有一定的了解比如你要知道 ondraw(),onmesure(),Paint 畫筆,canvars畫布這些內(nèi)容你要了解,對自定義不是很清楚的朋友可以去 看我的同類文章,文章從入門一步一步帶大家進入自定義view:
第一步:我們要熟悉一下這個圖
16個圖形結(jié)果,其實現(xiàn)在有18中。這個圖 我們也不用記,只要在用的時候選擇對應得 我們的目標圖形就行了。具體怎么使用 我們要引出我們今天主要的類 PorterDuffXfermode 這個類就是我們的Xformode 的類了,他還有另外被廢棄的兩兄弟,被廢棄了就不談了。既然是各類我們要使用就要創(chuàng)建對象,如下:
PorterDuffXfermode xfermode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN);
這里就是我們的 對象,在這里他的構(gòu)造參數(shù)中就是我們上圖 選擇的類型,最終圖形是兩個圖形的交集部分。當然你可以根據(jù)你的目標圖形 的效果自己選擇,兩個圖片的混排類型。
這就是 第一步,我們只要了解一下圖片的意義,和 PorterDuffXfermode 這個類的用法就夠了。我這里提到的 所有圖不只是圖片,還有我們繪制出來的 圓,矩形等繪制的圖。
第二步:
我們了解了 圖形 混排的模式,所以第二步我們要有兩個圖,不然怎么混排,從圖中我們可以看出這兩個圖,分別是 Src ,Dst。接下來我會介紹這兩個名字對應我們手機上那個圖形。因為我們要畫圖所以 我們就要來到 ondraw()方法了,這個方法有個類叫canvas 圖層,所以這就到了我們第二步的關(guān)鍵點:那就是設(shè)置圖層,調(diào)用方法
canvas.saveLayer( left, top, right, bottom, paint, saveFlags)
首先前四個方法比較簡單,就是我們要設(shè)置這個圖層 的大小,第5個方法就是我們的 畫筆,第6個方法我們使用:Canvas.ALL_SAVE_FLAG ,這是一個flag。
注意:我們在繪制圖形之前必須調(diào)用上面的方法,不然沒有效果。
下面是這個繪制的先后順序:
/** * 設(shè)置圖層 */ int layer = canvas.saveLayer(0,0,w,h,paint,Canvas.ALL_SAVE_FLAG); //繪制背景圖片 canvas.drawBitmap(bitmap,0,0,paint); //設(shè)置 xformode 模式 paint.setXfermode(xfermode); //繪制矩形 paint.setColor(Color.RED); RectF rectF = new RectF(0,y,bitmap.getWidth(),bitmap.getHeight()); canvas.drawRect(rectF,paint); //最后設(shè)置為空 paint.setXfermode(null); canvas.restoreToCount(layer);
第三步:
第三步我們還是圍繞著上邊的代碼講,因為就這幾行代碼,因為很簡單。設(shè)置好圖層之后,就要繪制圖形了,我們這里用canvas繪制了一個 bitmap 圖片。大家注意了我們此時 用的 paint 只是普通的 畫筆,到這個時候我們的 PorterDuffXfermode 模式還沒有使用呢!
再往下看 我們的畫筆調(diào)用了:
paint.setXfermode(xfermode);
這個方法,所以 如果我們再繪制圖形的畫,再用到的 畫筆 就和我們之前 繪制的圖形 不一樣了。這個方法可以說是一個分界點,在這個方法之前繪制的圖形 和 之后繪制的圖形 就分別對應了 我們 圖中 Src 和 Dst 的圖。這就決定我們最終的目標圖形是什么樣的。
最后就是把畫筆的 xformode 模式設(shè)置為空。再調(diào)用canvas的這個方法
canvas.restoreToCount(layer);
我們的繪制就結(jié)束了。我這里使用動畫動態(tài)的改變了 矩形 的高度。我把這個 圖片 貼給大家,圖片還是盜 別人的。哈哈。
大家可以下載使用。
把代碼也貼出來,大家參考。以上 都是我個人的理解 ,包括給大家舉的例子,如果有不妥之處請指出,謝謝。
public class XformodeView extends View { Paint paint ; //屏幕寬高 int w; int h; //定義一個矩形的高度變化 float y; //xformode 的 類型 選擇 PorterDuffXfermode xfermode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN); //圖片 Bitmap bitmap; public XformodeView(Context context) { this(context,null); } public XformodeView(Context context, @Nullable AttributeSet attrs) { this(context,attrs,0); } public XformodeView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); //畫筆 paint = new Paint(); paint.setAntiAlias(true); paint.setDither(true); init(context); } /** * 初始化 * @param context */ public void init(Context context){ //獲得屏幕寬高 WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); w = wm.getDefaultDisplay().getWidth(); h = wm.getDefaultDisplay().getHeight(); //加載bitmap 圖片 bitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.xxx); //開始動畫 animator(); } /** * 測量view */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); setMeasuredDimension(bitmap.getWidth(),bitmap.getHeight()); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); /** * 繪制 圖片 剪切 畫布 控制圖片顯示 */ // Path path = new Path(); // path.moveTo(0,y); // // path.lineTo(bitmap.getWidth(),y); // path.lineTo(bitmap.getWidth(),bitmap.getHeight()); // path.lineTo(0,bitmap.getHeight()); // canvas.clipPath(path); /** * 設(shè)置圖層 */ int layer = canvas.saveLayer(0,0,w,h,paint,Canvas.ALL_SAVE_FLAG); //繪制背景圖片 canvas.drawBitmap(bitmap,0,0,paint); //設(shè)置 xformode 模式 paint.setXfermode(xfermode); //繪制矩形 paint.setColor(Color.RED); RectF rectF = new RectF(0,y,bitmap.getWidth(),bitmap.getHeight()); canvas.drawRect(rectF,paint); //最后設(shè)置為空 paint.setXfermode(null); canvas.restoreToCount(layer); } /** * 動畫 */ public void animator(){ ValueAnimator animator = ValueAnimator.ofFloat(bitmap.getHeight(),0); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { y = (float) animation.getAnimatedValue(); invalidate(); } }); animator.setDuration(3000); animator.start(); } }
你也可以做一些復雜的效果,比如你不用矩形,你可以用波浪的效果讓他充滿。發(fā)揮想象力去做吧。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android開發(fā)之組件GridView簡單使用方法示例
這篇文章主要介紹了Android開發(fā)之組件GridView簡單使用方法,涉及Android GridView組件圖片瀏覽及保存圖片等相關(guān)操作技巧,需要的朋友可以參考下2019-03-03一文詳解Android無需權(quán)限調(diào)用系統(tǒng)相機拍照
這篇文章主要為大家介紹了Android無需權(quán)限調(diào)用系統(tǒng)相機拍照詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-03-03Android實現(xiàn)搜索功能并本地保存搜索歷史記錄
這篇文章主要為大家詳細介紹了Android實現(xiàn)搜索功能,并實現(xiàn)本地保存搜索歷史記錄,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-03-03Android 中 Activity顯示隱式跳轉(zhuǎn)
這篇文章主要介紹了Android 中 Activity顯示隱式跳轉(zhuǎn)的實現(xiàn)方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-02-02Android ListView之setEmptyView正確使用方法
這篇文章主要介紹了Android ListView之setEmptyView正確使用方法的相關(guān)資料,希望通過本文能幫助到大家使用該方法,需要的朋友可以參考下2017-09-09