Android自定义控件开发入门与实战(10)Shader,android播放音频

return true;

case MotionEvent.ACTION_MOVE:

mDx = (int) event.getX();

mDy = (int) event.getY();

break;

case MotionEvent.ACTION_UP:

case MotionEvent.ACTION_CANCEL:

mDx = -1;

mDy = -1;

break;

}

postInvalidate();

return super.onTouchEvent(event);

}

最后重写onDraw函数

这里分成两步。第一步将图片mbitmapBG缩放到控件大小,以完全覆盖控件,否则就会使用BitmapShader的填充模式。

这里先新建一张空白的位图cavasbg,这张位图的大小与控件大小一致,然后对背景位图进行拉伸,画到这张空白的位图上。

第二步,在mDx、mDy都不是-1时,将新建的mBitmapBG作为BitmapShader设置给Paint,然后在手指所在的位置画圆,把圆圈部分的图像显示出来。

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

if (mBitmapBG == null) {

mBitmapBG = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);

Canvas canvasbg = new Canvas(mBitmapBG);

canvasbg.drawBitmap(mBitmap, null, new Rect(0, 0, getWidth(), getHeight()), mPaint);

}

if (mDx != -1 && mDy != -1) {

mPaint.setShader(new BitmapShader(mBitmapBG, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT));

canvas.drawCircle(mDx, mDy, 150, mPaint);

}

}

下面的示例来讲解生成不规则的头像。

首先初始化bitmap:

public AvatorView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.avator_xizuka);

mPaint = new Paint();

mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);

}

接下来,将BitmapShader缩放到与控件的宽、高一致(setScale),由于我们要画的是一幅圆形图像,所以必须将图像缩放成一个正方形,只要正方形的边长与控件的宽度一致即可。

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

Matrix matrix = new Matrix();

float scale = (float) getWidth() / mBitmap.getWidth();

matrix.setScale(scale, scale);

mBitmapShader.setLocalMatrix(matrix);

mPaint.setShader(mBitmapShader);

float half = getWidth() / 2;

canvas.drawCircle(half, half, getWidth() / 2, mPaint);

}

在这里插入图片描述

同样是缩放BitmapShader,这里使用Matrix进行缩放,而前面的望远镜示例则是通过新建一张位图来进行缩放,这两种缩放方式都可用。

在缩放BitmapShader以后,在控件的正中央画一个圆形,显示出一副圆形区域的图像。这就是我们想要的圆形头像。

Shader之LinearGradient


通过LinearGradient可以实现渐变的效果

下面是构造函数

public LinearGradient(float x0,float y0,float x1,float y1,int color0,int color1,TileMode tile)

其中(x0,y0) (x1,y1)分别表示起点、终点坐标。color0、color1表示起点终点颜色,tile和BitmapShader一样。

其中color用0xAARRGGBB显示,AA不能少。

第二个构造函数为:

public LinearGradient(float x0,float y0,float x1,float y1,int colors[],float positions[],TileMode tile)

其中colors[]用于指定颜色值数值,同样用0xAARRGGBB形式。

positions[]与渐变的颜色相对应,取值是0-1的Float类型数据。表示color中的每种颜色在渐变线中百分比的位置。

示例:闪光文字效果

这里做一个跑马灯式的文字渐变效果。

原理是做一个渐变的图像,和一段文字,然后渐变头像在文字上进行移动,使文字发光,变换颜色。

该渐变图像移动两个文字长度的距离。

首先我们让View继承自TextView,因为TextView本身可以绘制文字,不需要我们自己处理,所以这样方便一点。

public ShimmerTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

mPaint = getPaint();

int length = (int) mPaint.measureText(getText().toString());

createAnim(length);

createLinearGradient(length);

}

接下里就是创建动画,动画让LinearGradient去移动,所以动画的起始到终止值应该是(0,2*text_Length),每次有新进度则重绘文字:

private void createAnim(int length) {

ValueAnimator valueAnimator = ValueAnimator.ofInt(0, 2 * length);

valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

mDx = (int) animation.getAnimatedValue();

postInvalidate();

}

});

valueAnimator.setRepeatMode(ValueAnimator.RESTART);

valueAnimator.setRepeatCount(ValueAnimator.INFINITE);

valueAnimator.setDuration(2000);

valueAnimator.start();

}

然后创建LinearGradient,其大小和TextView大小一样

private void createLinearGradient(int length) {

mLinearGradient = new LinearGradient(-length, 0, 0, 0, new int[]{getCurrentTextColor(), 0xff00ff00, getCurrentTextColor()},

new float[]{0, 0.5f, 1}, Shader.TileMode.CLAMP);

}

最后重写onDraw方法,根据setTranslate(mDx,0)来让其移动:

@Override

protected void onDraw(Canvas canvas) {

Matrix matrix = new Matrix();

matrix.setTranslate(mDx,0);

mLinearGradient.setLocalMatrix(matrix);

mPaint.setShader(mLinearGradient);

super.onDraw(canvas);

}

效果如下:

在这里插入图片描述

Shader之Ra

《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》

【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享

dialGradient


RadialGradient就是放射源式的渐变,从一个中心点发散。

双色渐变构造函数如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值