自定义控件分析1

       对handler机制一直感觉不太懂,想写一篇handler分析类的,看别人写的都挺好,自己写,从哪开始都感觉不对劲。所以先搞一篇自定义控件练练。

      其实对于自定义控件感觉也不懂,每次用总是东拼西凑,东西是搞出来了。不知道怎么搞出来的。所以这次就先搞出来一段,分析下。权当总结记录

public class MyOneText extends View {
    String text;
    int msrc;

    public MyOneText(Context context, AttributeSet attrs) {
        super(context, attrs);
        int textId = attrs.getAttributeResourceValue(null, "text", 0);
        int srcId = attrs.getAttributeResourceValue(null, "src", 0);
        text = context.getResources().getText(textId).toString();
        msrc = srcId;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Paint paint=new Paint();
        InputStream inputStream = getResources().openRawResource(msrc);
        Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
        int height = bitmap.getHeight();
        int width = bitmap.getWidth();
        canvas.drawBitmap(bitmap,0,0,paint);
        canvas.drawText(text,width/2,30,paint);



    }
}
xml

<com.example.administrator.customcontrol2.MyOneText
    android:id="@+id/text"
    android:layout_width="wrap_content"
    text="@string/hello_world"
    src="@mipmap/ic_launcher"
    android:layout_height="wrap_content" />

MyOneText继承了view

为什么要继承view 那,view是所有图形的基类,不用不行~~~

view里面有三个需要注意的方法 measure() , layout() , draw() , 

1,measure 是计算视图大小用的 ,  主要调用了onmeasure方法,  如果有需要,子类可以覆写并实现自己的计算视图大小。并通过setMeasuredDimension保存。

2,layout 设置视图在屏幕中显示的位置,主要有两个需要注意,setFrame , onLayout , setFrame 设置子视图在父视图中的位置, onLayout , 这个是在你的控件是viewGroup类型时设置子视图使用的。

3,draw 将上两步设置的参数,绘制显示在屏幕上 内部定义了绘图的基本操作,具体可以参考View类的draw方法。自定义控件需要特别注意的方法就是这三个。既然是要自定义view,肯定是要用一些系统控件没有的属性或者属性组合。

自定义view增加属性的两种方法

1,上面的MyOneText 这个类用的就是view类中定义, 通过构造函数中的 AttributeSet 查找布局的属性名称,然后获得id进行使用。

2, 下面这种就是Android提供的标准写法,通过xml注册。

public class MyOneImage extends LinearLayout {

    public MyOneImage(Context context, AttributeSet attrs) {
        super(context, attrs);
        int resourcedId = -1;
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyOneImage);
        ImageView iv = new ImageView(context);
        TextView tv = new TextView(context);
        int n = typedArray.getIndexCount();
        for (int i = 0; i < n; i++) {
            int attr = typedArray.getIndex(i);
            switch (attr) {
                case R.styleable.MyOneImage_Oriental:
                    resourcedId = typedArray.getInt(R.styleable.MyOneImage_Oriental, 0);
                    this.setOrientation(resourcedId == 1 ? LinearLayout.HORIZONTAL : LinearLayout.VERTICAL);
                    break;
                case R.styleable.MyOneImage_Text:
                    resourcedId = typedArray.getResourceId(R.styleable.MyOneImage_Text, 0);
                    tv.setText(resourcedId > 0 ? typedArray.getResources().getText(resourcedId) : typedArray.getString(R.styleable.MyOneImage_Text));
                    break;
                case R.styleable.MyOneImage_Src:
                    resourcedId = typedArray.getInt(R.styleable.MyOneImage_Oriental, 0);
                    iv.setImageResource(resourcedId > 0 ? resourcedId : R.mipmap.ic_launcher);
                    break;
            }
        }
        addView(iv);
        addView(tv);
        typedArray.recycle();
    }


}
xml
在values中新建attrs
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MyOneImage">

        <attr name="Text" format="reference|string"></attr>
        <attr name="Oriental" >
            <enum name="Horizontal" value="1"></enum>
            <enum name="Vertical" value="0"></enum>
        </attr>
        <attr name="Src" format="reference|integer"></attr>
    </declare-styleable>
</resources>
<com.example.administrator.customcontrol2.MyOneImage android:layout_width="wrap_content" app:Text="@string/hello_world" app:Src="@mipmap/ic_launcher" app:Oriental="Vertical" android:layout_height="wrap_content"></com.example.administrator.customcontrol2.MyOneImage>

 
eclipse需要在用到自定义view的xml里面定义这个
xmlns:android="http://schemas.android.com/apk/res/com.example.administrator.customcontrol2.MyOneImage"
studio 则直接添上已经这个就可以了
xmlns:app="http://schemas.android.com/apk/res-auto"
上面是自定义view添加属性的两种方法。
自定义控件主要有三种实现方式
1,继承已有的控件进行扩展,已有的控件属性不够用了,扩展下

2,继承view类,加载一个布局文件实现, 组合控件可能用到,在构造方法里面通过inflater加载自定义控件的布局文件。再addView.

3, 继承view类,使用GDI直接绘制。一般这种用到没上面两种多。

http://blog.163.com/ppy2790@126/blog/static/103242241201382210910473/     其实就是按照自己的理解整理了一下,主要是为了加深记忆。

后边会搞一搞复杂一点的。


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值