Android ProterDuff 文字加载效果
在上一章节实现了刮刮乐之后,我又回去重新看了一遍 PorterDuff.Mode
,又有一个新发现,那就是 PorterDuff.Mode.SRC_IN
它会把两者相交的地方绘制源图,我们不就能做出加载的动画了么?
Android 提供的 18 种图片混排模式
Android PorterDuff.Mode.SRC_IN 文字加载动画
-
首先,一个文字图片(透明背景) 或者 Bitmap;
-
初始化画笔,背景图片( DST ),矩形 Rect( SRC )
-
先保存图层,接着先绘制背景图,设置混排模式,然后绘制 Rect,清除混排模式 接着回复保存的图层,最后修改下 Rect 区域高度,调用
invalidate()
让 View 重绘
范例
-
创建一个 空的 Android 项目
cn.twle.android.LoadText
-
自定义 View 类: LoadTextView.java
package cn.twle.android.loadtext; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.view.View; import android.view.WindowManager; public class LoadTextView extends View { private PorterDuffXfermode mXfermode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN); private Bitmap backBitmap; private Paint mPaint; private int height = 200; private int mCurW, mCurTop; private Rect mDynamicRect; public LoadTextView(Context context) { this(context, null); } public LoadTextView(Context context, AttributeSet attrs) { super(context, attrs); WindowManager wm = (WindowManager) context. getSystemService(Context.WINDOW_SERVICE); DisplayMetrics dm = new DisplayMetrics(); wm.getDefaultDisplay().getMetrics(dm); mCurW = dm.widthPixels; init(); } public LoadTextView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } private void init() { //画笔初始化: mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setFilterBitmap(true); mPaint.setDither(true); mPaint.setColor(Color.RED); //背部图片的初始化 backBitmap = Bitmap.createBitmap(mCurW, height, Bitmap.Config.ARGB_8888); Canvas c = new Canvas(backBitmap); Paint p = new Paint(Paint.ANTI_ALIAS_FLAG); p.setColor(0xFF333333); p.setTextSize(64.0f); p.setTextAlign(Paint.Align.CENTER); Paint.FontMetrics fontMetrics = p.getFontMetrics(); float tp = fontMetrics.top; // 为基线到字体上边框的距离 float tb = fontMetrics.bottom; // 为基线到字体下边框的距离 int cY = (int) (height - (tb-tp)/2);//基线中间点的y轴计算公式 c.drawText("简单教程,简单编程",mCurW/2,cY,p); //设置当前的高度 mCurTop = height; mDynamicRect = new Rect(0, height, mCurW, height); //初始化原图 } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int saveLayerCount = canvas.saveLayer(0, 0, mCurW, height, mPaint, Canvas.ALL_SAVE_FLAG); canvas.drawBitmap(backBitmap, 0, 0, mPaint);// 绘制目标图 mPaint.setXfermode(mXfermode); //设置混排模式 canvas.drawRect(mDynamicRect, mPaint); //绘制源图 mPaint.setXfermode(null); //清除混排模式 canvas.restoreToCount(saveLayerCount); //恢复保存的图层 // 改变Rect区域,假如 mCurTop -= 2; if (mCurTop <= 0) { mCurTop = height; } mDynamicRect.top = mCurTop; invalidate(); //重绘 } }
-
修改
MainActivity.java
设置setContentView(new MsView(MainActivity.this))
package cn.twle.android.loadtext; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new LoadTextView(MainActivity.this)); } }