Android 如何自定义一个简单的组件和自定义的点击事件(中级)

这里自定义组件的代码是最初学习时下载的代码片段 忘了出处 

 直接上代码 注意看代码中的注释  

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

               xmlns:my="http://schemas.android.com/apk/res/com.skyoceanone.zidingyiView"

    android:orientation="vertical"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    >

<TextView  

    android:layout_width="fill_parent" 

    android:layout_height="wrap_content" 

    android:text="@string/hello"

    />

    <com.skyoceanone.zidingyiView.zidingyi

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    my:textColor="#ff00ff"

    my:textSize="10sp"

    android:id="@+id/zidingyi">

    </com.skyoceanone.zidingyiView.zidingyi>

</LinearLayout>

values中定义 attr.xml 来定义你的组件的属性 个人认为这个xml就是起到一个中介作用 连接 Layout和 代码的一个桥梁

<?xml version="1.0" encoding="utf-8"?>

<resources>

     <declare-styleable name="MyView">  

        <attr format="color" name="textColor" />

        <attr name="textSize" format="dimension"/>  

    </declare-styleable>

</resources>

import android.content.Context;

import android.content.res.TypedArray;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.graphics.Paint.Style;

import android.util.AttributeSet;

import android.view.KeyEvent;

import android.view.View;

/**

 * 1 这个是自定义的TextView.

 * 2至少需要重载构造方法和onDraw方法  

 * 3对于自定义的View如果没有自己独特的属性,可以直接在xml文件中使用就可以了 

 * 4如果含有自己独特的属性,那么就需要在构造函数中获取属性文件attrs.xml中自定义属性的名称 

 * 5并根据需要设定默认值,放在在xml文件中没有定义。

 * 6如果使用自定义属性,那么在应用xml文件中需要加上新的schemas

 *7比如这里是xmlns:my="http://schemas.android.com/apk/res/com.skyoceanone.zidingyiView"

 * 8其中xmlns后的“my”是自定义的属性的前缀,res后的是我们自定义 View所在的包 

 */

public class zidingyi extends View{

Paint mPaint;  // 画笔,包含了画几何图形、文本等的样式和颜色信息

private OnZidingyiListener onZidingyiListener;

public zidingyi(Context context) {

super(context);

// TODO Auto-generated constructor stub

}

public zidingyi(Context context,AttributeSet attrs) {

super(context,attrs);

mPaint=new Paint();

// TypedArray是一个用来存放由context.obtainStyledAttributes获得的属性的数组

// 在使用完成后,一定要调用recycle方法

// 属性的名称是styleable中的名称+“_”+属性名称

TypedArray mTypedArray=context.obtainStyledAttributes(attrs, R.styleable.MyView);

 // 提供默认值,放置未指定

int textcolor=mTypedArray.getColor(R.styleable.MyView_textColor, 0XFF00FF00);

float textsize=mTypedArray.getDimension(R.styleable.MyView_textSize, 100);

mPaint.setColor(textcolor);

mPaint.setTextSize(textsize);

mTypedArray.recycle();// 一定要调用,否则这次的设定会对下次的使用造成影响

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

// Canvas中含有很多画图的接口,利用这些接口,我们可以画出我们想要的图形

// mPaint = new Paint();

// mPaint.setColor(Color.RED);

mPaint.setStyle(Style.FILL);// 设置填充

canvas.drawRect(100, 100, 200, 200, mPaint);// 绘制矩形   还有很多形状 可以看方法

mPaint.setColor(Color.BLUE);

canvas.drawText("oy my good", 100, 100, mPaint);

// 下面两个注释的方法 也是经常用到的  

// invalidate();  如果你有其他需要画得 调用这个方法 会激发 onDRAW

// postInvalidate(); 在其他非主线程中使用 可以防止 ANR

}

//下面两个方法是自定义点击事件

@Override  //复写这个方法来实现判断是哪个按钮做出的事件

public boolean onKeyDown(int keyCode, KeyEvent event) {

if (KeyEvent.KEYCODE_ENTER == keyCode)

{

onZidingyiListener.onZDYClick(zidingyi.this, keyCode);

}

return super.onKeyDown(keyCode, event);

}

public void setOnZidingyiListener(OnZidingyiListener onZidingyiListener) {

this.onZidingyiListener = onZidingyiListener;

}

}

下面我们开始 自定义点击事件 

先看实现自定义组件显示和点击事件的 Main方法类代码

import android.app.Activity;

import android.os.Bundle;

import android.view.View;

public class mainactivity extends Activity {

@Override

protected void onCreate(Bundle savedInstanceState) {

// TODO Auto-generated method stub

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

zidingyi zidingyi = (com.tarena.zidingyiView.zidingyi) findViewById(R.id.zidingyi);

//调用自定义组件中 自定义的点击事件 方法   (看上面带桔色的方法)

//这个方法需要传入一个我们定义的接口        (下面红色的接口类)

//接口中的抽象方法 需要我们传入一个自定义组件 和识别点击事件的一个int

zidingyi.setOnZidingyiListener(new OnZidingyiListener() {

@Override

public void onZDYClick(com.tarena.zidingyiView.zidingyi zidingyi,

int keyCode) {

//写 需要的代码

}

});

}

}

 写一个接口类 模仿View的点击事件的接口 

import android.content.DialogInterface;

public interface OnZidingyiListener {

    public void onZDYClick(zidingyi zidingyi, int which);

}

出来的效果

大家看这个效果和我上面的代码设置的 左上坐标都是从100开始的 为什么我们文字没有在画的方框里呢 这个问题我想了半天 百思不得其解 结果我仔细看了下 恍然大悟 哈哈 这里先不给大家答案 如果大家也遇到这个问题 到时候记得问我把