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

Posted

技术标签:

【中文标题】如何创建一个简单的自定义视图?【英文标题】:How to create a simple custom View? 【发布时间】:2010-12-14 13:05:10 【问题描述】:

我想在 android 上创建一个自定义 View。我试图尽可能简单地做到这一点,并创建了一个几乎空的类MyView 并在我的LinearLayout 中使用它,但应用程序以“强制关闭”开始时失败。我怎样才能做一个简单的自定义View?根据Building Custom Components,如果我不覆盖onMeasure()View 的大小为 100x100。

public class MyView extends View 

    public MyView(Context context) 
        super(context);
    

我在LinearLayout 中使用它:

<view
    class="com.example.MyView"
    android:layout_
    android:layout_
    android:layout_weight="0.0" />

我做错了什么?


如果我使用itemon 建议的构造函数以及对超类的相应调用。然后“强制关闭”就没有了,但是我的LinearLayout坏了,MyView后面的组件没有显示出来。

这是我的main.xml

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

【问题讨论】:

你可以在这里咨询一个好的样本:http://www.sgoliver.net/blog/?p=1457 我有类似的需求..你有你需要的吗。 .share一些代码plz 【参考方案1】:

也许你可以像这样定义另一个构造方法:

public MyView(Context context, AttributeSet attrs)

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

【讨论】:

谢谢,删除了“强制关闭”消息,但我的LinearLayout 坏了,后面的组件没有显示。【参考方案2】:

Android 开发人员指南中有一个名为“构建自定义组件”的部分。不幸的是,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:app="http://schemas.android.com/apk/res/com.mycompany.projectname"

在*** xml 元素中。

<com.mycompany.projectname.MyCustomView
    android:layout_
    android:layout_
    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_
    android:layout_
    app:text="Blue"app:textSize="20dp"/>

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

xmlns:app="http://schemas.android.com/apk/res/com.example.android.apis"

【讨论】:

以上是关于如何创建一个简单的自定义视图?的主要内容,如果未能解决你的问题,请参考以下文章

简单的自定义类扩展视图

如何在单独的自定义视图中为按钮创建操作

在 Interface Builder 中,如何将 UIViews 添加到属于我创建的自定义视图的子视图?

如何从情节提要中的自定义视图制作@IBAction?

创建自定义视图的步骤

简单的自定义视图问题