人还是要有梦想,即使是咸鱼,也要做最咸的那条。
本篇文章以自定义圆形图片控件为例,介绍一下 Android 自定义控件的方法
开发工具 AndroidStudio 2.3.1
大概分为三个大步骤
一、自定义标签 attr
二、自定义类继承自View
三、引用自定义标签和类
一、自定义标签 attr
我们知道 Android 原生API中是有一个图片控件ImageView的:
<ImageView
android:id="@+id/img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/pic" />
使用该控件效果就是显示一张矩形的图片
那么,我们需要在页面上显示圆形的图片给如何做呢,这就需要我们自定义一个控件
我们需要我们自定义的控件也想ImageView控件一样,有一个 src 属性,这就需要使用 attr 自定义标签了
我们在新建项目的 value 文件夹下新建一个xml文件,取名为 attrs
我们在 attrs 文件里输入以下代码:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyCircleImageView">
<!-- reference:引用类型 -->
<attr name="src" format="reference"/>
</declare-styleable>
</resources>
这里,我们 declare-styleable 标签的 name 属性一般设置为自定义控件类的名字
我们新建一个 attr 便签,取名为 src ,与ImageView控件的属性对应,它的类型我们设置为 reference(参考某一资源ID) 引用类型。
二、自定义类继承自View
我们新建类 MyCircleImageView 继承自View
这里我们需要实现两个构造方法,一个是一个参数的,一个是两个参数的
在有两个参数的构造方法中:
public MyCircleImageView(Context context, AttributeSet attrs) {
super(context, attrs);
//获取自定义属性的集合
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyCircleImageView);
src = typedArray.getResourceId(R.styleable.MyCircleImageView_src, R.mipmap.ic_launcher);
//回收
typedArray.recycle();
}
这里我们使用 obtainStyledAttributes 方法,获取我们自定义的标签集合,返回一个 TypedArray 对象,这个集合对象就存储了我们自定义的所有标签,虽然我们只自定义了一个
然后,我们调用它的 getResourceId 方法获取自定义的src标签的值,将值赋给一个 int类型的值存储我们 src 属性的资源文件
最后,我们调用 TypedArray 对象的 recycle 方法,将集合回收
然后我们需要重写 onDraw 方法:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//src 绘制的图片内容
Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), src);
int w = srcBitmap.getWidth();
int h = srcBitmap.getHeight();
//desc 绘制需要的形状
//创建bitmap
Bitmap descBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_4444);
//绘制形状
RectF rect = new RectF(0, 0, w, h);
//获取bitmap的画布
Canvas descCanvas = new Canvas(descBitmap);
Paint mPaint = new Paint();
mPaint.setColor(Color.WHITE);
mPaint.setAntiAlias(true);//抗锯齿
mPaint.setDither(true);//防抖动
descCanvas.drawOval(rect, mPaint);
//设置显示相交部分的src
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
//将内容绘制在形状上
descCanvas.drawBitmap(srcBitmap, 0, 0, mPaint);
//绘制图片
canvas.drawBitmap(descBitmap, 0, 0, null);
}
这里有一个整体思路也就是核心思路是:
我们需要绘制一个圆形的图片,但是我们不能直接绘制一个圆形的图片。
所以,我们先将资源中的图片放到画布上,然后再绘制一个圆,然后将两个重叠起来,选取相交的部分,这样我们就拿到圆形的图片了
其中,descBitmap 就是我们绘制的圆
srcBitmap 就是我们获取的资源文件中的图片
然后我们使用 setXfermode 方法取到了两者相交的部分
然后,我们将图片绘制到形状上
最后,我们绘制相交的部分,就得到了一个圆形的图片!
三、引用自定义标签和类
好,所有东西都准备好了,下面只需要引用就可以了
我们在xml文件中使用比如
<yhb.win.agadmin.view.MyCircleImageView
android:id="@+id/img"
android:layout_width="100dp"
android:layout_height="100dp"
app:src="@drawable/pic" />
标签的前半部分为自定义类所在的包名,后半部分为自定义类的名称
这里需要注意,在输入src标签时, AndroidStudio 会自动为我们引入自定义的标签,也就是会在整部布局中自动生成
xmlns:app="http://schemas.android.com/apk/res-auto"
这一部分!