自定义属性+接口回调Demo

自定义属性+接口回调Demo

自定义属性:
参考:原文写的很详细,在此,我收录了一些重点作为笔记
http://www.cnblogs.com/lonelyDog/archive/2012/06/28/2568519.html
自定义属性的实现流程:
1、在values目录下定义一个attrs.xml
2、在对应的类文件里生成某些组件
3、在layout布局文件里为这些属性赋值。

实现第一步:
在res/values/attr.xml中定义。

<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- 这里的MyView属性并不是一定要和自定义组件类名相同,只是为了好区分对应类的属性而已 -->
    <declare-styleable name = "MyView">
        <attr name= "TEXTCOLOR" format= "color" />
        <attr name= "TEXTSIZE" format= "dimension" />
        <attr name= "recWidth" format= "dimension" />
        <attr name= "recHeight" format= "dimension" />
    </declare-styleable>

</resources>

知识点:
1、declare-styleable
定义一个styleable对象,每个styleable对象就是一组attr属性的集合
2、attr子元素:
定义具体的属性
1.reference:参考指定Theme中资源ID,这个类型意思就是你传的值可以是引用资源
2.string:字符串,如果你想别人既能直接写值也可以用类似”@string/test”引用资源的方式,可以写成format=”string|reference”
3.Color:颜色
4.boolean:布尔值
5.dimension:尺寸值
6.float:浮点型
7.integer:整型
8.fraction:百分数
9.enum:枚举 ,如果你提供的属性只能让别人选择,不能随便传入,就可以写成这样

      <attr name="language">
                       <enum name="china" value="1"/>
                       <enum name="English" value="2"/>
                </attr>

10.flag:位或运算

实现第二步
自定义组件类
重点是获取自定义属性,关键代码如下:

TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.MyView);
        textsize = array.getDimension(R.styleable.MyView_TEXTSIZE, 30);// 放在在xml中未定义,设置默认值

完整代码如下

public class MyView extends ViewGroup implements OnClickListener{

    private Paint myPaint;
    private int textColor;
    private int recWidth;
    private int recHeight;
    private float textsize;
    private ImageView imgView;

    public MyView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyView(Context context) {
        this(context, null);
    }

    public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        myPaint = new Paint();
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.MyView);
        textsize = array.getDimension(R.styleable.MyView_TEXTSIZE, 30);// 放在在xml中未定义,设置默认值
        recHeight = (int) array.getDimension(R.styleable.MyView_recHeight, 30);// 放在在xml中未定义,设置默认值
        recWidth = (int) array.getDimension(R.styleable.MyView_recWidth, 30);// 放在在xml中未定义,设置默认值
        textColor = array.getColor(R.styleable.MyView_TEXTCOLOR, Color.YELLOW);
        myPaint.setColor(textColor);
        myPaint.setTextSize(textsize);
        array.recycle();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        myPaint.setColor(Color.RED);
        myPaint.setStyle(Style.FILL);
        canvas.drawRect(new Rect(10, 40, 100+recWidth, 100+recHeight), myPaint);
        myPaint.setColor(textColor);
        canvas.drawText("hellohelooe", 10, 100, myPaint);
    }

    @Override
    public void onClick(View view) {
        iMyView.rectClick(view);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        int count = getChildCount();
        for(int i = 0; i< count;i++){
            measureChild(getChildAt(i), widthMeasureSpec, heightMeasureSpec);
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onLayout(boolean changed, int arg1, int arg2, int arg3, int arg4) {
        if(changed){
            imgLayout();
        }
    }

    private void rotateCButton(View v, float start, float end, int duration) {

        RotateAnimation anim = new RotateAnimation(start, end, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        anim.setDuration(duration);
        anim.setFillAfter(true);//图形留在动画停止处
        v.startAnimation(anim);
    }

    private void imgLayout() {
        imgView = (ImageView) getChildAt(0);
        imgView.setOnClickListener(this);
        int width = imgView.getWidth();
        int height = imgView.getHeight();
        imgView.layout(0, 0, 300+width, 400+height);
    }


    private IMyView iMyView;
    public void setIMyView(IMyView iMyView) {
        this.iMyView = iMyView;
    }
    public interface IMyView{
        public void rectClick(View view);
    }
}

实现第三步
在布局中的设置

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:huqing="http://schemas.android.com/apk/res/com.example.typedarraydemo"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="fill_parent"
        android:layout_height="40dp"
        android:gravity="center"
        android:text="系统的控件" />

    <com.example.typedarraydemo.demo1.MyView
        android:id="@+id/ad_myView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        huqing:TEXTCOLOR="#42E61A"
        huqing:TEXTSIZE="120px"
        huqing:recHeight="500px"
        huqing:recWidth="500px" >

        <ImageView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:src="@drawable/ic_launcher" />
    </com.example.typedarraydemo.demo1.MyView>

</LinearLayout>

**在XML使用该组件的时候一定要为该自定义组件设置一个命名空间[xmlns:myandroid=”http://schemas.android.com/apk/res/cn.com.androidtest”],不然组件属性设置不了
命名空间写法:xmlns:空间名=”http://schemas.android.com/apk/res/自定义组件所在顶级包名”**

以上就实现了自定义属性的使用了。接下来实现接口定义。
在自定义View中加入

private IMyView iMyView;
    public void setIMyView(IMyView iMyView) {
        this.iMyView = iMyView;
    }
    public interface IMyView{
        public void rectClick(View view);
    }

调用的Activity代码如下

public class Demo1 extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.acty_demo1);

        MyView myView = (MyView)findViewById(R.id.ad_myView);
        myView.setIMyView(new IMyView() {

            @Override
            public void rectClick(View view) {
                Toast.makeText(Demo1.this, "这里使用到了接口回调", Toast.LENGTH_LONG).show();
            }
        });
    }
}

自定义View方法:
onFinishInflate() 回调方法,当应用从XML加载该组件并用它构建界面之后调用的方法
onMeasure() 检测View组件及其子组件的大小
onLayout() 当该组件需要分配其子组件的位置、大小时
onSizeChange() 当该组件的大小被改变时
onDraw() 当组件将要绘制它的内容时
onKeyDown 当按下某个键盘时
onKeyUp 当松开某个键盘时
onTrackballEvent 当发生轨迹球事件时
onTouchEvent 当发生触屏事件时
onWindowFocusChanged(boolean) 当该组件得到、失去焦点时
onAtrrachedToWindow() 当把该组件放入到某个窗口时
onDetachedFromWindow() 当把该组件从某个窗口上分离时触发的方法
onWindowVisibilityChanged(int): 当包含该组件的窗口的可见性发生改变时触发的方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值