android 自定义view

     首先,我工作已经1年啦,也做过几个项目,虽然过程遇到一些问题,但是我都已经解决啦。后来发现,虽然解决啦问题,但是没有总结那些解决办法,也没有去思考如何哪种解决方式更有效果,以至于后来遇到的相同问题,很多东西已经忘记啦,还是古人说的好,好记性不如烂笔头。所以,我把现在很多基础东西或者遇到问题的解决方式记下来,方面自己总结,也方便大家查阅,利人利已。也希望看过这篇博客的同学,养成总结、记录的好习惯。废话不说啦,进入正题。

     首先,第一个问题,自定义view如何绑定xml属性?

     第一,要声明属性。自定义view,一般是继承view,关联xml的话,可以新建一个value类型的xml文件,然后使用declare-styleable标签建立一个view的属性集合,然后在该标签下使用attr属性来对属性进行命名和设置属性的类型,如下图所示:

<declare-styleable name="RectangleView">
        <attr name="backgroundColor" format="color"></attr>
    </declare-styleable>
    以上只是对属性进行了声明。
    第二,把属性跟实体类关联,并取出值,进行应用。我们需要重写2哥构造方法,如下所示:
public class RectangleView extends View {

    public RectangleView(Context context) {
        super(context);
    }

    /**
     * 布局文件里调用自定义控件,使用此构造函数
     * @param context
     * @param attrs
     */
    public RectangleView(Context context, AttributeSet attrs) {
        super(context, attrs);
        //把xml属性跟自定义view关联起来
        TypedArray ty = context.obtainStyledAttributes(attrs,R.styleable.RectangleView);
        //取出值,设置背景颜色
        setBackgroundColor(ty.getColor(R.styleable.RectangleView_backgroundColor, Color.RED));
        //使用完毕后, 一定一定要记得调用销毁方法
        ty.recycle();
    }

}
      第三,声明命名空间,才可以在xml中应用属性。如果是以前的eclipse项目,就必须重新命名空间,但如果是android studio项目,直接如下声明即可

xmlns:app="http://schemas.android.com/apk/res-auto"

      具体xml中使用自定义属性,如下所示:

<cn.yangshin.myrectview.RectangleView
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:layout_marginTop="30dp"
        app:backgroundColor="@color/colorAccent"
        />

     提示:调用属性必须使用命名空间的名字开头,例如上面的命名空间名字为app

     第二个问题,如何使用绘图API自定义视图?

   继承view,重写onDraw方法即可。对于自定义视图,google给出了api,我们可以通过重写onDraw方法,来实现自定义,这种方法很灵活,基本上任何图形都可以画。下面来看一个例子:

public class CircleView extends View {
    Paint mPaint; //画笔

    public CircleView(Context context) {
        super(context);
        initPaint();
    }

    public CircleView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initPaint();
    }


    /**
     * 画图
     * @param canvas
     */
    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);

    }

    /**
     * 初始化画笔
     */
    void initPaint(){
        mPaint = new Paint();
        mPaint.setColor(Color.BLUE);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //画圆
//        canvas.drawCircle(100,100,100,mPaint);

        //画圆角矩形
        //新建矩形r2
        RectF r2 = new RectF();
        r2.left = 50;
        r2.right = 250;
        r2.top = 200 ;
        r2.bottom = 300;
        canvas.drawRoundRect(r2,20,20,mPaint);
    }
}
    这种方式也可以在xml中直接调用,只要重写了关于xml的构造方法即可。 需要提示大家的是,在绘图api中,有draw方法和onDraw方法,一般的重写onDraw方法就行,这也是谷歌推荐的。如果有复杂的需求,请参考谷歌api文档,调用其他方法进行更复杂的自定义绘图

          第三个问题,如何给view自定义皮肤?

     通过drawble类型的xml文件可以做到自定义皮肤,比如,当按钮按下的时候换一种颜色。这种自定义皮肤,实现起来,也比较简单,首先,在xml中新建一个button,然后在drawble目录下新建一个drawble类型的xml文件,并且把这个xml文件设置为background,xml文件实例如下:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="false" android:drawable="@color/colorAccent"></item>
    <item android:state_pressed="true" android:drawable="@color/colorPrimaryDark"></item>
</selector>
          其实在item这个标签下,可以有更多的状态选择。

selector集合定义在xml文件里面,View对象背景颜色的选择取决于自身当前的状态,总共有pressed、focused、selected、checkable、checked、enabled、window_focused和default八种状态,View对象的每一种状态可以设置不同的背景色。但是要注意匹配规则,我们知道可以给一个对象的多种状态设置不同的背景颜色,那么对象是如何根据状态来匹配颜色呢?规则是:根据当前对象状态,在selector集合中从上到下匹配,被匹配到的第一项<item>作为对象的背景色。

        重要提示

1、因为匹配的第一项作为当前View对象的背景颜色,结束匹配。如果第一项每次都能被匹配到,就不会往下匹配,那么之后的状态也就失效了。然而每一个View对象都有默认状态,所以这也就是为什么默认状态不能放在开头,而要放到最后的原因。
2、不是所有的View子类都拥有八种状态,比如Button对象,拥有pressed、enabled、window_focused、default四种状态,如果设置selected是无效的,所以要根据组件的具体情况设置。
3、状态的顺序排放。
pressed->focused->selected->checkable->checked->enabled->window_focused->default
具体排放顺序还得根据当前View对象拥有的状态来排列。记住默认的权重是最大的,要放在最后面。


        


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值