Android自定义控件java
安卓在使用中大多数使用已有的一些控件,用法比较简单,还有一部分是比较复杂的、用户本身想的控件,这些就须要进行自定义控件,今天就来简单说一下自定义控件。android
一、绘制过程canvas
以上就是自定义控件的绘制过程。bash
二、主要内容解释ide
用于计算视图的大小,即视图的宽度和长度。在view中定义为final类型,要求子类不能修改。measure()函数中又会调用下面的函数:函数
(1)onMeasure(),肯定视图大小,也就是说measure只是对onMeasure的一个包装,子类能够覆写onMeasure()方法实现本身的计算视图大小的方式,并经过setMeasuredDimension(width, height)保存计算结果。布局
(2)关于MeasureSpec:学习
**UPSPECIFIED:**父容器对于子容器没有任何限制,子容器想要多大就多大.ui
**EXACTLY:**父容器已经为子容器设置了尺寸,子容器应当服从这些边界,不论子容器想要多大的空间.spa
**AT_MOST:**子容器能够是声明大小内的任意大小.
用于设置视图在屏幕中显示的位置。在view中定义为final类型,要求子类不能修改。layout()函数中有两个基本操做:
(1)setFrame(l,t,r,b),l,t,r,b即子视图在父视图中的具体位置,该函数用于将这些参数保存起来;
(2)onLayout(),在View中这个函数什么都不会作,提供该函数主要是为viewGroup类型布局子视图用的;
利用前两部获得的参数,将视图显示在屏幕上,到这里也就完成了整个的视图绘制工做。其内部定义了绘图的基本操做:
(1)绘制背景;
(2)若是要视图显示渐变框,这里会作一些前期工做;
(3)绘制视图自己,即调用onDraw()函数。在view中onDraw()是个空函数,也就是说具体的视图都要覆写该函数来实现本身的显示。
(4)绘制子视图,即dispatchDraw()函数。在view中这是个空函数,具体的视图不须要实现该方法,它是专门为容器类准备的,也就是容器类必须实现该方法;
(5)应用程序调用了setVerticalFadingEdge或者setHorizontalFadingEdge,若是须要能够开始绘制渐变框;
(6)绘制滚动条;
从上面能够看出自定义View须要最少覆写onMeasure()和onDraw()两个方法。
三、效果图展现
四、代码展现
在java代码中我加了不少注释,方便进行理解、学习。
布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<sample.sdk.qy.com.androiddemo.Customize
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="20dp"
/>
</LinearLayout>
复制代码
自定义控件类
public class Customize extends View {
private final static String TAG = Customize.class.getSimpleName();
private Paint mPaint;
private RectF oval;
public Customize(Context context) {
super(context);
init();
}
public Customize(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public Customize(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init(){
mPaint = new Paint();
mPaint.setAntiAlias(true);
oval=new RectF();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
switch (widthMode) {
case MeasureSpec.EXACTLY:
break;
case MeasureSpec.AT_MOST:
break;
case MeasureSpec.UNSPECIFIED:
break;
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//设置演颜色
mPaint.setColor(Color.GREEN);
// FILL填充, STROKE描边,FILL_AND_STROKE填充和描边
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
//获取控件的宽度和高度
int with = getWidth();
int height = getHeight();
//设置圆的半径
float radius = with / 4;
//画圆,设置颜色
canvas.drawCircle(with / 2, with / 2, radius, mPaint);
mPaint.setColor(Color.BLUE);
//用于定义的圆弧的形状和大小的界限
oval.set(with / 2 - radius, with / 2 - radius, with / 2
+ radius, with / 2 + radius);
//根据进度画圆弧
canvas.drawArc(oval, 270, 90, true, mPaint);
//画出另外一个圆弧
mPaint.setColor(Color.YELLOW);
canvas.drawArc(oval, 360, 120, true, mPaint);
}
}
复制代码
MainActivity类
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
复制代码
有兴趣的朋友或者有疑问的朋友欢迎留言讨论