自定义的视图

自定义的视图

布局文件custom_view_1.xml的如下所示:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:app="http://schemas.android.com/apk/res/com.example.android.apis"
              android:orientation="vertical"
              android:layout_width="fill_parent"
              android:layout_height="wrap_content">
    <com.example.android.apis.view.LabelView
            android:background="@drawable/red"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            app:text="Red"/>
    <com.example.android.apis.view.LabelView
            android:background="@drawable/blue"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            app:text="Blue" app:textSize="20dp"/>
    <com.example.android.apis.view.LabelView
            android:background="@drawable/green"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            app:text="Green" app:textColor="#ffffffff" />
</LinearLayout>

这里使用的标签com.example.android.apis.view.LabelView不是Android框架层提供的View的一个子类,

是在自己的程序中实现的一个类。能在布局文件中使用的类,也都是android.view.View类的继承者。

这个com.example.android.apis.view.LabelView,在源文件LabView.java中实现,其主要片段如下所示:

import android.view.View;
public class LabelView extends View {
    public LabelView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initLabelView();
        TypedArray a = context.obtainStyledAttributes(attrs,
                R.styleable.LabelView);
        CharSequence s = a.getString(R.styleable.LabelView_text);
        if (s != null) {
            setText(s.toString());
        }
        setTextColor(a.getColor(R.styleable.LabelView_textColor, 0xFF000000));
        int textSize =
                a.getDimensionPixelOffset(R.styleable.LabelView_textSize, 0);
        if (textSize > 0) {
            setTextSize(textSize);
        }
        a.recycle();
    }
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawText(mText, getPaddingLeft(),
                getPaddingTop() - mAscent, mTextPaint);
    }
}
在 LabelView 的构造函数中,通过 context.obtainStyledAttributes 获得 LabelView 所特有的几个属性。

R.styleable.LabelView这些内容在res/values/的attrs.xml文件中进行了定义,内容如下所示:

<declare-styleable name="LabelView">
    <attr name="text" format="string" />
    <attr name="textColor" format="color" />
    <attr name="textSize" format="dimension" />
</declare-styleable>

根据LabView.java实现的类名称,这样自定义的控件也可以在布局文件中使用,使用标签与类名相一致。

R.styleable.LabelView_text,

R.styleable.LabelView_textColor和R.styleable.LabelView_textSize是在源代码中使用

的属性,它们与引用LabelView的布局文件中的app:text,app:textColor和app:textSize等几个属性相对应。

作为公共的属性,LabelView在实现上也应该具有公共的函数来设置这几个属性。这些函数如下所示:

public void setText(String text) {
    mText = text;
    requestLayout();
    invalidate();
}
public void setTextSize(int size) {
    mTextPaint.setTextSize(size);
    requestLayout();
    invalidate();
}
public void setTextColor(int color) {
    mTextPaint.setColor(color);
    invalidate();
}

以上的几个函数和几个XML中的属性对应的,如果没有他们,这些属性就只能在XML文件中指定,而不能在JAVA源文件中设置。

在Android的应用程序层,可以通过扩展android.view.View或者它的扩展者来实现自己的View。

相关推荐