您的位置:首页 > 移动开发 > Android开发

Android 自定义View 一般View定义

2014-03-20 22:44 295 查看
在我们编写android程序时一般是自定义以一个类继承自Activity 并且重写onCreate方法:

 @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

    }

 

setContentView()方法包含多个重载其中一个便是“setContentView(View view)”,也就是说可以直接通过一个View的实例来构建内容。我们尝试放入一个TextView,上面的代码变成了这样:

@Override

 public void onCreate(Bundle savedInstanceState) {

      super.onCreate(savedInstanceState);

  // setContentView(R.layout.main);

      TextView sayHello = new TextView(this);

      sayHello.setText("Hello world! I'm a TextView.");

      setContentView(sayHello);

        

    }

运行这段代码,在模拟器上你应该可以看到以下结果:



如此简单不是吗?好吧让我们再让它丰富点:

@Override

 public void onCreate(Bundle savedInstanceState) {

  super.onCreate(savedInstanceState);

  // setContentView(R.layout.main);

//  TextView sayHello = new TextView(this);

//  sayHello.setText("Hello world! I'm a TextView.");

  setContentView(new SayHello(this));

        

    }

 

 

 class SayHello extends View{

  public SayHello(Context context) {

   super(context);

  }

  @Override

  protected void onDraw(Canvas canvas) {

   super.onDraw(canvas);

   Paint mPaint=new Paint() ;

   mPaint.setTextSize(22f);

   mPaint.setColor(Color.RED);

   canvas.drawText("Hello world! I'm a TextView.", 0, 100, mPaint);

  }

 }

这次我们自定义了一个局部类SayHello 继承自View并且重写了 onDraw 方法(需要注意的是由于View没有无参构造函数所以我们为其指定实现哪一个构造函数)。在onDraw 方法中我们定义了一个Paint,现在你只需要理解它有绘画的功能即可,那么它要在哪里绘画呢?答案就是在Canvas上,可以把Canvas理解成画布。

现在我们设置mPaint的字体大小为22F  颜色为红色,然后在画布上写出“Hello world。。。”这几个红色的字,并且把onCreate里的setContentView 为setContentView(new SayHello(this));

最后在模拟器上你应该看到的是:

 


so cool! 不是吗?

不!不对,我们在Android的开发View不是这样的,它应该是通过 Xml.......@##¥%

好吧 让我们再把例子修改一下。

 首先我们将SayHello 类提取出来,并且将它放入一个单独的类文件中,接下来就是重点:我们需要添加另外的一些构造函数以便给View传递参数,最好你看到的SayHello 类应该是这样的:

public class SayHello extends View {

 

 public SayHello(Context context)

 {

  super(context);

 }

 public SayHello(Context context, AttributeSet attrs) {

  this(context, attrs,0);

 }

 

 public SayHello(Context context, AttributeSet attrs,int defStyle)

 {

  super(context, attrs, defStyle);

 }

 

 

 @Override

 protected void onDraw(Canvas canvas) {

  super.onDraw(canvas);

  Paint mPaint=new Paint() ;

  mPaint.setTextSize(22f);

  mPaint.setColor(Color.RED);

  canvas.drawText("Hello world! I'm a TextView.", 0, 100, mPaint);

 }

 

}

这里简单讲解一下新增的构造函数的作用,在新的构造函数中为View的构造函数传递了AttributeSet attrs,int defStyle两个参数,这代表着该View可以通过XML 来创建并且接受Style来设定样式。等到相关博文时会再具体讲解。

接下来,我们恢复Activity类里的onCreate方法让它看起来像这个样子:

@Override

 public void onCreate(Bundle savedInstanceState) {

  super.onCreate(savedInstanceState);

   setContentView(R.layout.main);

        

    }

和一开始没啥两样对吧。

  最后我们需要去修改布局文件main 在文件里加入以下 xml标签:

 <com.××××.customview.SayHello

        android:layout_width="fill_parent"

        android:layout_height="wrap_content" >

    </com.××××.customview.SayHello>

(注意××××,代表SayHello类所在的包,这里需要的是全名)。

然后再次运行程序,你应该看到以下结果:

 


是不是和我们平常定义View时很像了?

你感觉得还不够,还缺乏些什么?

好吧,你很聪明,我们的Text应该是在XML上通过某个属性配置而成的,而不是写在代码里!

为了将SayHello的属性暴露到XMl上首先我们需要在res/value 文件夹下新建一个XMl文件,命名为:atts。

在里面添加如下代码:

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

<resources>

 <declare-styleable name="SayHello">

     <attr name="content" format="string"></attr>

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

 </declare-styleable>

    

</resources>

 需要注意的是这里是没有智能提示的

然后我们需要修改SayHello类,还记得那个AttributeSet吗?我们将通过它来获取XML配置上的属性值。修改后的SayHello类代码是这样的:

private int mColor;

 private String mContent;

public SayHello(Context context, AttributeSet attrs, int defStyle) {

  super(context, attrs, defStyle);

  TypedArray typeArray = context.obtainStyledAttributes(attrs,

    R.styleable.SayHello);

  mColor=typeArray.getColor(R.styleable.SayHello_text_color, 0XFF00FF00);

  mContent=typeArray.getString(R.styleable.SayHello_content);

  

 }

@Override

 protected void onDraw(Canvas canvas) {

  super.onDraw(canvas);

  Paint mPaint = new Paint();

  mPaint.setTextSize(22f);

  mPaint.setColor(mColor);

  canvas.drawText(mContent, 0, 100, mPaint);

 }

现在可以去XML上为哥哥属性添加值了,不过先别着急我们的得将命名空间告诉它。

在布局文件的根源是上(通常是Layout)添加: xmlns:SayHello="http://schemas.android.com/apk/res/com.XXXX.customview"

SayHello 可以为您任意想要定义的名字,它将作为属性的前缀使用就像android:Layout 一样而我们的为:SayHello:content,后半段http://schemas.android.com/apk/res/ 为固定值,紧接着的是你整个APP的包命名,你不知道自己包名称?赶去去
AndroidManifest.xml文件中看看吧(注意该包名需要保持和manifest中的 package 保持一致,否则会提示无法找到XML属性)。

最后我们终于可以在XML上定义自己想要的字体颜色的内容了:

<com.XXXX.customview.SayHello

        android:layout_width="fill_parent"

        android:layout_height="wrap_content" 

        SayHello:text_color="#1212f0"

        SayHello:content="this is a xml attr view">

    </com.XXXX.customview.SayHello>

 运行程序您应该会看到以下结果:



 

 

这就是我们View 一般的定义方式和过程。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android 自定义view