全国服务热线:0551-64931480

29
18-12

关于Android特殊形状ImageView的几种实现方式

云库科技 766347 0
最近在写直播PK要求进入直播入口实现如下图片效果

从图片可以看出我们要实现两个主播头像各占一半,并且是以斜杠分开

每个主播头像正好裁剪压缩显示在中间,第二四个角都是圆角。所以从以上三点出发我们只能重写imageview

方法一:BitmapShader方式

Shader 这个英文单词很多人没有见过,它的中文叫做「着色器」,也是用于设置绘制颜色的。「着色器」不是 Android 独有的,它是图形领域里一个通用的概念,它和直接设置颜色的区别是,着色器设置的是一个颜色方案,或者说是一套着色规则。当设置了 Shader 之后,Paint 在绘制图形和文字时就不使用 setColor/ARGB() 设置的颜色了,而是使用 Shader 的方案中的颜色。
在 Android 的绘制里使用 Shader ,并不直接用 Shader 这个类,而是用它的几个子类。这里我们用 BitmapShader :
用 Bitmap 来着色。其实也就是用 Bitmap 的像素来作为图形或文字的填充。大概像这样:
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.batman);  Shader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
paint.setShader(shader);
canvas.drawCircle(300, 300, 200, paint); 


所以我们需要做的就是画两个不一样的圆角梯形组合一起
Path path = new Path();
path.moveTo(100, 0);// 此点为多边形的起点
path.lineTo(200 - 12, 0);
path.quadTo(200, 0, 200, 12);
path.lineTo(200, 300 - 12);
path.quadTo(200, 300, 200 - 12, 300);
path.lineTo(0, 300);
path.close();

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.batman);  Shader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);  
paint.setShader(shader);
canvas.drawPath(path,paint);

方法二:ClipPath方式

ClipPath是Canvas提供对画布裁剪的方法之一画布裁剪后后面的Canvas操作,都会在对裁剪后的画布进行操作
所以呢,只要绘出一个圆角梯形的路径,然后用ClipPath裁剪,那么得到的画布就是圆角梯形的,那么后面的绘制自然也就是圆角梯形的了,解释很清楚了,直接上代码了,
public class MyImageView02 extends android.support.v7.widget.AppCompatImageView {
    public MyImageView02(Context context) {
        super(context);
    }
    public MyImageView02(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }
    public MyImageView02(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    @Override
    protected void onDraw(Canvas canvas) {
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(getResources().getColor(R.color.transparent));
        Path path = new Path();
        path.moveTo(100, 0);// 此点为多边形的起点
        path.lineTo(200 - 12, 0);
        path.quadTo(200, 0, 200, 12);
        path.lineTo(200, 300 - 12);
        path.quadTo(200, 300, 200 - 12, 300);
        path.lineTo(0, 300);
        path.close(); // 使这些点构成封闭的多边形
        canvas.drawPaint(paint);
        canvas.clipPath(path);
        super.onDraw(canvas);
    }

}

最后我们只需要布局用Relativelayout 做两个自定义imageview的相对布局就可以了,代码都是写死了,实际需要计算宽高

<RelativeLayout
    android:layout_width="154dp"
    android:layout_height="150dp"
    android:orientation="horizontal">
    <com.hencoder.hencoderpracticedraw2.sample.MyImageView
        android:id="@+id/myimage"
        android:layout_width="100dp"
        android:layout_height="150dp"
        android:layout_alignParentLeft="true"
        android:scaleType="centerCrop"
        android:src="@drawable/batman" />
    <com.hencoder.hencoderpracticedraw2.sample.MyImageView02
        android:id="@+id/myimage02"
        android:layout_width="100dp"
        android:layout_height="150dp"
        android:layout_alignParentRight="true"
        android:scaleType="centerCrop"
        android:src="@drawable/guide_3" />
    <ProgressBar
        style="@style/Widget.AppCompat.ProgressBar.Horizontal"
        android:layout_width="match_parent"
        android:layout_height="10dp"
        android:layout_alignParentBottom="true"
        android:layout_alignParentStart="true"
        android:max="100"
        android:progress="50"
        android:progressDrawable="@drawable/progressbar_drawable" />
</RelativeLayout>

以上两个方法都可以,但是更推荐方法二,不用对drawable进行修改。

评论列表(0)
暂无评论