如何创建简单的自定义视图?

时间:2010-12-14 13:05:10

标签: android view android-linearlayout custom-view

我想在Android上创建自定义View。我试图尽可能简单地创建它并创建了一个几乎为空的类MyView并在我的LinearLayout中使用它但是应用程序在启动时失败了“强制关闭”。如何进行简单的自定义View?根据{{​​3}} View如果我不覆盖onMeasure(),则public class MyView extends View { public MyView(Context context) { super(context); } } 的大小为100x100。

LinearLayout

我在<view class="com.example.MyView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="0.0" /> 中使用它:

LinearLayout

我做错了什么?


如果我使用Building Custom Components建议的构造函数和对超类的相应调用。然后“强制关闭”消失,但我的MyView被破坏,main.xml之后的组件未显示。

这是我的<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="0.0" android:background="#f00" android:text="Hello" /> <view class="com.example.MyView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="0.0" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="0.0" android:background="#00f" android:text="World" /> </LinearLayout>

{{1}}

2 个答案:

答案 0 :(得分:9)

可能是您可以定义另一个构造函数方法:

public MyView(Context context, AttributeSet attrs)

android框架将尝试使用上面构造函数中的视图构建UI。

答案 1 :(得分:9)

Android Developer Guide有一个名为Building Custom Components的部分。不幸的是,对XML属性的讨论仅包括声明布局文件中的控件而不是实际处理类初始化中的值。步骤如下:

在values \ attrs.xml中声明属性

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MyCustomView">
        <attr name="android:text"/>
        <attr name="android:textColor"/>            
        <attr name="extraInformation" format="string" />
    </declare-styleable>
</resources>

请注意在declare-styleable标记中使用非限定名称。像extraInformation这样的非标准android属性需要声明它们的类型。在超类中声明的标签将在子类中可用,而不必重新声明。

创建构造函数

由于有两个构造函数使用AttributeSet进行初始化,因此为构造函数调用创建单独的初始化方法很方便。

private void init(AttributeSet attrs){  
    TypedArray a=getContext().obtainStyledAttributes(attrs,R.styleable.MyCustomView);
    //Use a
    Log.i("test",a.getString(R.styleable.MyCustomView_android_text));
    Log.i("test",""+a.getColor(R.styleable.MyCustomView_android_textColor, Color.BLACK));
    Log.i("test",a.getString(R.styleable.MyCustomView_android_extraInformation));
    //Don't forget this
    a.recycle();
}

R.styleable.MyCustomView是一个自动生成的int []资源,其中每个元素都是属性的ID。通过将属性名称附加到元素名称,为XML中的每个属性生成属性。然后可以使用各种get函数从TypedArray中检索属性。如果未在XML中定义该属性,则返回null。当然,除非返回类型是基元,否则返回第二个参数。

如果您不想检索所有属性,可以手动创建此数组。标准android属性的ID包含在android.R.attr中,而此项目的属性位于R.attr

int attrsWanted[]=new int[]{android.R.attr.text, R.attr.textColor};

请注意,您不应该在android.R.styleable中使用任何内容,因为根据此主题,它可能在将来发生变化。它仍然在文档中,因为在一个地方查看所有这些常量是有用的。

在布局文件(例如layout \ main.xml)中使用它 包含名称空间声明

  

的xmlns:应用= “http://schemas.android.com/apk/res/com.mycompany.projectname”

在顶级xml元素中。

<com.mycompany.projectname.MyCustomView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@android:color/transparent"
    android:text="Test text"
    android:textColor="#FFFFFF"
app:extraInformation="My extra information";
/> 

使用完全限定名称引用自定义视图。

  

Android LabelView示例

如果您想要一个完整的示例,请查看android标签视图示例。

LabelView.java

TypedArray a=context.obtainStyledAttributes(attrs, R.styleable.LabelView);
CharSequences=a.getString(R.styleable.LabelView_text);
attrs.xml

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

custom_view_1.xml

<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"/>

这包含在具有命名空间属性的LinearLayout中:

  

的xmlns:应用= “http://schemas.android.com/apk/res/com.example.android.apis”